基于Unity的物体动画(移动加旋转)

再此处记录一下物体在给定点组,绘制出路径并依路径行走的编码过程及运行效果。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;

public class Car : MonoBehaviour
{
    public float m_radius = 1.0f;    //圆圈半径
    public Material m_material;      //材质
    public float m_lineWidth = 1.0f; //线宽
    public float m_fSpeed = 5.0f;    //移动速度
    public Vector3 ModelDir;        //模型的朝向
    private List<Path> vPath = new List<Path>();
    private int Id; //索引
    private bool m_bStart = false;
    // Start is called before the first frame update


    public class Path
    {
        public Vector3 Point;//路径点
        public Vector3 MoveDir;//移动的方向
        public float TotalLength;//移动总长度

    }

    void Start()
    {
        int count = 180;
        for (int i = 1; i <= (count + 1); i++)
        {
            Path path = new Path();
            if (i == (count + 1))
            {
                float x = Mathf.Cos(2 * Mathf.PI / count) * m_radius;
                float y = transform.localPosition.y;
                float z = Mathf.Sin(2 * Mathf.PI / count) * m_radius;
                path.Point = new Vector3(x, y, z);
                vPath.Add(path);
            }
            else
            {
                float x = Mathf.Cos(2 * Mathf.PI / count * i) * m_radius;
                float y = transform.localPosition.y;
                float z = Mathf.Sin(2 * Mathf.PI / count * i) * m_radius;
                path.Point= new Vector3(x, y, z);
                vPath.Add(path);
            }

        }

        GameObject lineGroup = new GameObject("LineGroup");
        GameObject lineObject = new GameObject("RadarLine");
        LineRenderer line = lineObject.AddComponent<LineRenderer>();
        line.material = m_material;
        line.useWorldSpace = false;
        line.positionCount = vPath.Count;
        line.startWidth = m_lineWidth;
        line.endWidth = m_lineWidth;
        for (int i = 0; i < vPath.Count; i++)
        {
            line.SetPosition(i, vPath[i].Point);
        }



        //计算出每两个点之间的总长度
        for (int i = 0; i < vPath.Count-1; i++)
        {
            Vector3 curDir = vPath[i+1].Point - vPath[i].Point;
            float length = curDir.sqrMagnitude;
            curDir.Normalize();
            vPath[i].MoveDir = curDir;
            vPath[i].TotalLength = length;
        }


        //设置初始位置
        transform.localPosition = vPath[0].Point;
        //获取物体的朝向
        Vector3 modelCur = transform.rotation * ModelDir;
        modelCur.Normalize();
        Vector3 firstCur = vPath[0].MoveDir;
        float angle = Mathf.Rad2Deg * Mathf.Acos(Vector3.Dot(modelCur, firstCur));
        Vector3 axis = Vector3.Cross(modelCur, firstCur);
        axis.Normalize();
        int nflag = 0;
        if (axis.y > 0)
        {
            nflag = 1;
        }
        else
        {
            nflag = -1;
        }
        transform.rotation *= Quaternion.Euler(0, 0, angle* nflag);
    }


    public void OnClicked()
    {
        m_bStart = true;
        Id = 0;
    }




    float curMoveLength = 0.0f;
    // Update is called once per frame
    void Update()
    {
        if(m_bStart)
        {

            if (Id < vPath.Count)
            {
                Path p = vPath[Id];
                
                
                if (curMoveLength < p.TotalLength)
                {
               
                    transform.localPosition += p.MoveDir * m_fSpeed * Time.deltaTime;

                    Vector3 cur = transform.localPosition - vPath[Id].Point;
                    curMoveLength = cur.sqrMagnitude;
                }
                else
                {
                    if(Id == (vPath.Count-1))
                    {
                        //获取物体的朝向
                        Vector3 firstCur = transform.localRotation * ModelDir;
                        firstCur.Normalize();
                        Vector3 secondCur = vPath[0].MoveDir;
                   
                        float angle = Mathf.Rad2Deg * Mathf.Acos(Vector3.Dot(firstCur, secondCur)) ;
                        Vector3 axis = Vector3.Cross(firstCur, secondCur);
                        axis.Normalize();
                        int nflag = 0;
                        if (axis.y > 0)
                        {
                            nflag = 1;
                        }
                        else
                        {
                            nflag = -1;
                        }
                        transform.rotation *= Quaternion.Euler(0, 0, angle* nflag);
                    }
                    else
                    {
                        Vector3 firstCur = vPath[Id].MoveDir;

                        Vector3 secondCur = vPath[Id + 1].MoveDir;

                        float angle = Mathf.Rad2Deg * Mathf.Acos(Vector3.Dot(firstCur,secondCur));

                        Vector3 axis = Vector3.Cross(firstCur, secondCur);
                        axis.Normalize();
                        int nflag = 0;
                        if(axis.y > 0)
                        {
                            nflag = 1;
                        }
                        else
                        {
                            nflag = -1;
                        }
                        if(Id != vPath.Count-2)
                        {
                            transform.localRotation *= Quaternion.Euler(0, 0, angle * nflag);
                        }
                        
                    }

                    Id++;
                    curMoveLength = 0;
                }

            }

        }
    }
}

运行效果如下:
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值