物体环绕旋转功能

有这样个需求
在这里插入图片描述

当然一开始是用展示空工程做的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;
        }


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

染指流年丨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值