zoukankan      html  css  js  c++  java
  • Unity实现Bezier曲线的移动(三点之间的Bezier曲线的移动)

    直接上代码:

    BezierUtils类获得三点之间的所有可移动的位置:

    using UnityEngine;
    
    public class BezierUtils
    {
        /// <summary>
        /// 根据T值,计算贝塞尔曲线上面相对应的点
        /// </summary>
        /// <param name="t"></param>T值
        /// <param name="p0"></param>起始点
        /// <param name="p1"></param>控制点
        /// <param name="p2"></param>目标点
        /// <returns></returns>根据T值计算出来的贝赛尔曲线点
        private static Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2)
        {
            float u = 1 - t;
            float tt = t * t;
            float uu = u * u;
    
            Vector3 p = uu * p0;
            p += 2 * u * t * p1;
            p += tt * p2;
    
            return p;
        }
    
        /// <summary>
        /// 获取存储贝塞尔曲线点的数组
        /// </summary>
        /// <param name="startPoint"></param>起始点
        /// <param name="controlPoint"></param>控制点
        /// <param name="endPoint"></param>目标点
        /// <param name="segmentNum"></param>采样点的数量
        /// <returns></returns>存储贝塞尔曲线点的数组
        public static Vector3[] GetBeizerList(Vector3 startPoint, Vector3 controlPoint, Vector3 endPoint, int segmentNum)
        {
            Vector3[] path = new Vector3[segmentNum];
            for (int i = 1; i <= segmentNum; i++)
            {
                float t = i / (float)segmentNum;
                Vector3 pixel = CalculateCubicBezierPoint(t, startPoint,
                    controlPoint, endPoint);
                path[i - 1] = pixel;
            }
            return path;
    
        }
    
    }

    BezierMove类让物体在Bezier曲线上的所有点之间移动:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    
    /// <summary>
    /// 移动完成之后的回调
    /// </summary>
    public delegate void BezierMoveCompleteDel();
    public class BezierMove : MonoBehaviour
    {
    
        /// <summary>
        /// 贝赛尔曲线的路径点的数量,数量越多获得的曲线越完美,但是消耗也就越大
        /// </summary>
        private int _segmentNum = 100;
       
    
        /// <summary>
        /// 获得贝赛尔曲线所有的路径点
        /// </summary>
        private Vector3[] _allposArry;
    
        /// <summary>
        /// 移动的速度
        /// </summary>
        private float _speed = 10;
        /// <summary>
        /// 所有的路径点的索引值
        /// </summary>
        private int _index = 0;
    
        /// <summary>
        /// 需要移动的目标
        /// </summary>
        private  Transform _moveTargte;
    
        /// <summary>
        /// 是否完成移动
        /// </summary>
        private bool _isMoveComplete = false;
        /// <summary>
        ///  初始化贝赛尔曲线所有的路径点
        /// </summary>
        /// <param name="startPos">开始移动的位置</param>
        /// <param name="controlPos">中间点的位置,目的是改变物体移动的曲线弧度</param>
        /// <param name="endPos">最终移动的位置</param>
        /// <param name="moveTarget">需要移动的目标物体</param>
        /// <param name="moveSpeed">移动速度</param>
        /// <param name="segmentNum">三点之间Bezier曲线上所有点的数量</param>
        public void Init(Vector3 startPos, Vector3 controlPos, Vector3 endPos,Transform moveTarget,float moveSpeed,int segmentNum=100)
        {
            _moveTargte = moveTarget;
            _speed = moveSpeed;
            _allposArry = new Vector3[segmentNum];
            _allposArry = BezierUtils.GetBeizerList(startPos, controlPos, endPos, _segmentNum);
            _isMoveComplete = false;
        }
    
        /// <summary>
        ///  移动
        /// </summary>
        /// <param name="moveComplete">移动完成的回调</param>
        public void Move(BezierMoveCompleteDel moveComplete=null)
        {
            if (_allposArry == null|| _allposArry.Length==0)
            {
                Debug.LogError("没有初始化贝赛尔曲线的所有的路径点");
                return;
            }
            if(!_isMoveComplete)
            {
                if (Vector3.Distance(_moveTargte.position, _allposArry[_index]) <= 0.1f)
                {
                    _index++;
                    if (_index > _segmentNum - 1)
                    {
                        _index = _segmentNum - 1;
                        if (moveComplete != null)
                        {
                            moveComplete();
    
                        }
                        _isMoveComplete = true;
                    }
                }
                else
                {
                    _moveTargte.position = Vector3.Slerp(_moveTargte.position, _allposArry[_index], _speed * Time.deltaTime);
                }
            }
           
        }
    }
     

    testBezier测试脚本:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    using Spine;
    using Spine.Unity;
    using System;
    using Global;
    using Kernal;
    namespace Controll
    {
        public class testBezier : MonoBehaviour
        {
            int _segmentNum = 100;
    
            public Transform StartPos;
            public Transform ControlPos;
            public Transform EndPos;
    
            private Vector3[] posArry;
    
            public float Speed = 10;
            private int _index = 0;
    
            public Transform Targte;
            [SerializeField]
            private BezierMove _bezierMove;
            private void Start()
            {
                _bezierMove.Init(StartPos.position,ControlPos.position,EndPos.position,Targte, Speed, _segmentNum);
            }
            private void Update()
            {
                _bezierMove.Move(ONComplete);
            }
    
            private void ONComplete()
            {
                Debug.Log("移动完毕");
            }
        }
    }

    unity编辑器下的环境:

  • 相关阅读:
    围观窗体与组件01 零基础入门学习Delphi23
    浅谈Delphi过程与函数03 零基础入门学习Delphi22
    围观窗体与组件01 零基础入门学习Delphi23
    使用MASM09 Win32汇编语言017
    使用MASM10(变量的使用) Win32汇编语言018
    使用MASM08 Win32汇编语言016
    使用MASM08 Win32汇编语言016
    浅谈Delphi过程与函数03 零基础入门学习Delphi22
    游戏服务器设计探讨
    简单网络编程TCP客户端示例
  • 原文地址:https://www.cnblogs.com/weiqiangwaideshijie/p/10180077.html
Copyright © 2011-2022 走看看