游戏中我们有时候会碰到计算物体的曲线运动,贝塞尔曲线就变得比较常用。
以下贴出主要代码:
BezierData.cs
using UnityEngine;
using System.Collections;
public struct BezierData
{
private Vector3 p0;
private Vector3 p1;
private Vector3 p2;
public void SetData(Vector3 startPos, Vector3 controlPos, Vector3 endPos)
{
this.p0 = startPos;
this.p1 = controlPos;
this.p2 = endPos;
// Debug.Log(this.p0 + " " + this.p1 + " " + this.p2);
}
public Vector3 Lerp(float t)
{
t = Mathf.Clamp01(t);
if (Mathf.Approximately(t,1))
{
return this.p2;
}
Vector3 pos0 = this.p0;
Vector3 pos1 = this.p1;
Vector3 pos2 = this.p2;
float x = pos0.x + t * (2 * (1 - t) * (pos1.x - pos0.x) + t * (pos2.x - pos0.x));
float y = pos0.y + t * (2 * (1 - t) * (pos1.y - pos0.y) + t * (pos2.y - pos0.y));
float z = pos0.z + t * (2 * (1 - t) * (pos1.z - pos0.z) + t * (pos2.z - pos0.z));
return new Vector3(x, y, z);
}
}
BulletThing.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ConfigData;
public class BulletThing : MonoBehaviour
{
public static Dictionary<BulletThing, bool> liveBullet = new Dictionary<BulletThing, bool>();
public BulletInfo info;
public EffectThing effect;
public Vector3 targetPos;
private float moveSpeed;
private float curMoveTime;
private float totalMoveTime;
//private
private BezierData bezierData;
public bool isPause;
//public bool isPau
private void OnEnable()
{
liveBullet[this] = true;
}
private void OnDisable()
{
liveBullet.Remove(this);
}
private void OnDestroy()
{
OnDisable();
}
public static BulletThing Create(BulletInfo info, IBaseThing owner)
{
//EffectManager
BindInfo bindInfo = new BindInfo();
bindInfo.position = new Vector3(info.posX, info.posY, info.posZ);
bindInfo.eulerAngle = new Vector3(info.angleX, info.angleY, info.angleZ);
bindInfo.scale = new Vector3(info.scaleX, info.scaleY, info.scaleZ);
if (bindInfo.scale == Vector3.zero)
bindInfo.scale = Vector3.one;
EffectThing effectThing = EffectManager.ins.AddEffectSceneWithBone(info.imgId, owner, bindInfo);
BulletThing bullet = UITools.GetOrCreateComponent<BulletThing>(effectThing.gameObject);
bullet.info = info;
bullet.effect = effectThing;
effectThing.isLoop = true;
//bullet.OnStart();
return bullet;
}
public void Update()
{
if(!this.isPause)
this.ManualUpdate(Time.deltaTime);
}
public virtual void ManualUpdate(float deltaTime)
{
if(info.flyType == BulletFlyType.LineMove)
{
HandlerLineMove(deltaTime);
}else if(info.flyType == BulletFlyType.BezierMove)
{
HandlerBezierMove(deltaTime);
}
}
private void MoveDone()
{
this.Clear();
this.enabled = false;
EffectManager.ins.RecoverEffect(this.effect);
}
public void HandlerLineMove(float deltaTime)
{
Vector3 curPos = this.transform.position;
Vector3 vector3 = targetPos - curPos;
float dis = vector3.magnitude;
float moveDis = this.moveSpeed * deltaTime;
if (moveDis >= dis)
{
this.transform.position = targetPos;
this.MoveDone();
}
else
{
vector3 = vector3.normalized;
this.transform.forward = vector3;
this.transform.position = curPos + vector3.normalized * moveDis;
}
}
private void InitBezierMove()
{
float height = this.info.centerHeight;
totalMoveTime = this.info.flyDuration;
//height = 20;
Vector3 centerPos = Vector3.Lerp(this.transform.position, targetPos, 0.5f);
centerPos.y = height;
//Mathf.Lerp(this.tra)
//targetPos - this.transform.position
bezierData = new BezierData();
bezierData.SetData(this.transform.position, centerPos, targetPos);
}
public void HandlerBezierMove(float deltaTime)
{
curMoveTime += deltaTime;
Vector3 newpos = bezierData.Lerp(curMoveTime / this.totalMoveTime);
Vector3 oldPos = this.transform.position;
this.transform.position = newpos;
if (curMoveTime >= totalMoveTime)
{
this.MoveDone();
}
else
{
Vector3 vecForward = (newpos - oldPos);
if(vecForward.sqrMagnitude > 0)
{
this.transform.forward = vecForward.normalized;
}
}
}
public void OnStart()
{
this.enabled = true;
this.curMoveTime = 0;
this.targetPos.y += this.info.targetOffsetY;
moveSpeed = this.info.moveSpeed;
//moveSpeed = 20;
if (this.info.flyType == BulletFlyType.BezierMove)
InitBezierMove();
}
public void Clear()
{
}
}
来源:https://blog.csdn.net/OneWord233/article/details/100527371