有这样个需求
当然一开始是用展示空工程做的demo
关于面向镜头时速度降低的做法: 每帧获得旋转中心与旋转物体位置形成的向量A 获得中心到相机的向量
用Vector3的API判断两个向量是否夹角小于一定的角度
是的话 就将这个物体的旋转速度提高 否的话就降低
整体的解决方案:
用dt做的步骤是
1.找到dotween里面能实时改变速度的方法,做个实验看行不行, 这个最重要 决定了后面要不要用dotween
2.找到dotween用圆形路径运动的api,做个实验看能不能圆形实时改变速度
3.将面向相机减速的逻辑加入进去
不用dtw的做法
1.用transform的方法实现绕着圆运动,绕着圆运动的时候 物体还要面对着相机 考虑是用父子层级的方式
2.将面向相机减速的逻辑加入
这里后面还加了竖直上下随机运动的功能
最后是代码,记得要先引入Dotween Pro 1.3 以上的插件 不是Pro版本没试过
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public enum UpOrDown
{
goUpFirst,
goDownFirst,
}
[System.Serializable]
public class Emblem
{
//����
public string name;
//Transform
public Transform emblemTrans;
//У�յĶ���
public Tween emblemTween;
//�˶��ٶȣ�ʱ�䣩
public float duration;
}
public class EmblemController : MonoBehaviour
{
//**Public**
//�洢У�յ�����
[SerializeField]public Emblem[] emblemsArray;
[Header("��������")]
public float floatRange = 2.0f;
[Header("�˶��ٶ����ֵ")]
public float maxSpeed = 5.0f;
[Header("�˶��ٶ���Сֵ")]
public float minSpeed = 1.0f;
//**Private**
//·��������
private Vector3[] pathPoints;
// Start is called before the first frame update
void Start()
{
for(int i=0;i< emblemsArray.Length; i++)
{
//���л�����Ԫ����
emblemsArray[i].name = "Emblem_" + i;
//��Ŀ���
Vector3 floatTargetPos_01 = new Vector3(
emblemsArray[i].emblemTrans.position.x,
emblemsArray[i].emblemTrans.position.y + floatRange,
emblemsArray[i].emblemTrans.position.z
);
//��Ŀ���
Vector3 floatTargetPos_02 = new Vector3(
emblemsArray[i].emblemTrans.position.x,
emblemsArray[i].emblemTrans.position.y - floatRange,
emblemsArray[i].emblemTrans.position.z
);
//��������ٶ�
emblemsArray[i].duration = Random.Range(minSpeed, maxSpeed);
//��������� 1 ���� 0
int randomTemp = Random.Range((int)0, (int)2);
//0 -> �������Ͽ�ʼ�˶�
if (randomTemp == 0)
{
pathPoints = new Vector3[3] { floatTargetPos_01, floatTargetPos_02, emblemsArray[i].emblemTrans.position };
}
//1 -> �������¿�ʼ�˶�
else if (randomTemp == 1)
{
pathPoints = new Vector3[3] { floatTargetPos_02, floatTargetPos_01, emblemsArray[i].emblemTrans.position };
}
//����
emblemsArray[i].emblemTween = DOTween.Sequence()
.SetLoops
(
-1
)
.Append
(
emblemsArray[i].emblemTrans.DOPath(pathPoints, emblemsArray[i].duration).SetEase(Ease.Linear)
)
.Insert
(
0.0f, //ͬʱ�ƶ�����ת
emblemsArray[i].emblemTrans.DORotate(new Vector3(0, 180, 0), emblemsArray[i].duration).SetEase(Ease.Linear)
);
}
}
// Update is called once per frame
void Update()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class TitleRotationController : MonoBehaviour
{
//**Public**//
[Header("�˶�����")]
public Transform tweenOBJ;
[Header("���ĵ�����")]
public Transform centerPoint;
[Header("����·�������")]
public int pointsNum = 20;
[Header("�û�")]
public Transform playerCam;
[Header("FOV")]
public float playerFOV = 60;
[Header("���建��ʱ���ٶ�")]
public float slowSpeed = 2.0f;
[Header("����ӿ�ʱ���ٶ�")]
public float quickSpeed = 0.5f;
//**Private**//
//�˶��뾶
private float circleRadius;
//·��������
private Vector3[] circlePoints;
//���ƶ�����Tween
private Tween tweenOfRotation;
// Start is called before the first frame update
void Start()
{
//��ʼ��·��������
circlePoints = new Vector3[pointsNum];
//����Բ��·���İ뾶
Vector3 disVector = (tweenOBJ.position - centerPoint.position);
disVector = new Vector3(disVector.x, 0, disVector.z); //ӳ��x-zƽ��
circleRadius = disVector.magnitude;
//�����ʼ�н�(����)
float angle = GetVectorAngle((tweenOBJ.position - centerPoint.position), centerPoint.forward);
angle = (angle * Mathf.PI) / 180;
//���ԭʼ����λ��Yֵ
float originalY = tweenOBJ.position.y;
//����Բ��·����
for (int i = 0; i < pointsNum-1; i++)
{
angle += (((360 / pointsNum) * Mathf.PI) / 180);
float pointX = centerPoint.position.x - circleRadius * Mathf.Sin(angle);
float pointZ = centerPoint.position.z + circleRadius * Mathf.Cos(angle);
circlePoints[i] = new Vector3(pointX, originalY, pointZ);
}
//���һ��·����Ϊ�����ʼλ�õĵ�
circlePoints[pointsNum-1] = tweenOBJ.transform.position;
//���ö���
tweenOfRotation = tweenOBJ
.DOPath
(
circlePoints, 10.0f, PathType.CatmullRom //·��Ϊ����
)
.SetEase
(
Ease.Linear
)
.SetLookAt
(
centerPoint
)
.SetLoops
(
-1
)
.SetOptions
(
true //�ջ�
);
}
// Update is called once per frame
void Update()
{
//�� -> �ٶȱ���
if (SpeedDetection())
{
//DOTween.timeScale = slowSpeed; ����ȫ�ֵ�timeScale
tweenOfRotation.timeScale =slowSpeed; //���Ǿֲ�������timeScale
}
//�� -> �ٶȱ��
if (!SpeedDetection())
{
tweenOfRotation.timeScale = quickSpeed;
}
}
//�������������н�
float GetVectorAngle(Vector3 fromVector, Vector3 toVector)
{
//���������֮��ļн�
float angle = Vector3.Angle(fromVector, toVector);
//��������������
Vector3 normal = Vector3.Cross(fromVector, toVector);
//���������������Ϸ���������ˣ����Ϊ1��-1��������ת����
angle *= Mathf.Sign(Vector3.Dot(normal, Vector3.up));
return angle;
}
//����������Ƿ����� ����Ҫ�����˶�������
bool SpeedDetection()
{
//������-�� ����û������Ƿ����˶��������Ҫ�����ķ�Χ�� �������ĵ㵽�˶����� �� ���ĵ㵽�û� ���������нǣ���
//���������ĵ��˶�����
Vector3 vector_CenToObj = (tweenOBJ.position - centerPoint.position);
//ӳ�䵽x-z��
vector_CenToObj = new Vector3(vector_CenToObj.x, 0.0f, vector_CenToObj.z);
//���������ĵ��û����
Vector3 vector_CenToPlayer = (playerCam.position - centerPoint.position);
//ӳ�䵽x-z��
vector_CenToPlayer = new Vector3(vector_CenToPlayer.x, 0.0f, vector_CenToPlayer.z);
//��н�
float vecAngle = GetVectorAngle(vector_CenToObj, vector_CenToPlayer);
/*
//��������������û���ͷ�Ƿ�����˶������ʱ�� �������ĵ㵽�˶����� �� ��ͷ���� ���������нǣ���
//��������ͷ���˶�����
Vector3 vector_CamToObj = (tweenOBJ.position - playerCam.position);
//ӳ�䵽x-z��
vector_CamToObj = new Vector3(vector_CamToObj.x, 0.0f, vector_CamToObj.z);
//��н�
float vecAngle = GetVectorAngle(vector_CamToObj, playerCam.forward);
*/
//Debug.Log("�нǣ�" + vecAngle);
if (vecAngle < (playerFOV / 2) && vecAngle > -(playerFOV / 2))
{
return true;
}
else
{
return false;
}
}
}