本文实例为大家分享了C#实现贝塞尔曲线的具体代码,供大家参考,具体内容如下
话不多直接上代码
public Transform[] controlPoints; //曲线的控制点 ,最少三个,起点,弧度点,终点
public GameObject codeGameObject; //要动的物体
private int _segmentNum = 50; //运动物体过程分的段数
private int numIndex = 1;
void Start()
{
moveGameObject(2);
}
void moveGameObject(float time)
{
numIndex = 1;
InvokeRepeating("setInterval", 0, time/50);
}
void setInterval()
{
int nodeIndex = 0;
float t = numIndex / (float)_segmentNum;
Vector3 pixel = CalculateCubicBezierPoint(t, controlPoints[nodeIndex].position,
controlPoints[nodeIndex + 1].position, controlPoints[nodeIndex + 2].position);
codeGameObject.gameObject.transform.position= pixel;
numIndex++;
if(numIndex> _segmentNum)
{
CancelInvoke("setInterval");
}
}
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;
}
项目里的截图:
运行就可以看到球在三个方块之间移动的曲线了
第二种方案使用DOTweenPath
/**
* @brief 播放道具飞行动画
*
* @param prop 道具
* @param sendPos 起始点
* @param endP 终点
* @param fHeight 贝塞尔曲线中间点的高度(控制曲线)
*
* @return 飞行动画时间
*/
public float PlaySendFlyAnim(GameObject prop, Vector3 sendPos, Vector3 endP, float fHeight, float time)
{
float fTime = 0.0f;
if (prop == null)
{
return fTime;
}
Vector3 startP = sendPos;
prop.transform.position = startP;
float x = Mathf.Min(startP.x, endP.x) + Mathf.Abs(startP.x - endP.x) / 2f;
float y = Mathf.Min(startP.y, endP.y) + Mathf.Abs(startP.y - endP.y) / 2f;
float z = startP.z;
Vector3 midP = new Vector3(x, y, z);
double length = Math.Sqrt(Math.Pow(sendPos.x - midP.x, 2) + Math.Pow(sendPos.y - midP.y, 2));
//midP.x = fHeight / (float)length * (sendPos.x - midP.x) + midP.x;
//midP.y = fHeight / (float)length * (sendPos.y - midP.y) + midP.y;
int rangeRadomNum = UnityEngine.Random.Range(0, 2);
if(rangeRadomNum == 1)
{
midP.x = fHeight / (float)length * (endP.x - midP.x) + midP.x;
midP.y = endP.y;
}
else
{
midP.y = fHeight / (float)length * (endP.y - midP.y) + midP.y;
midP.x = endP.x;
}
//fTime = 2.0f;
fTime = time;
List<Vector3> arrRecPos = new List<Vector3>();
arrRecPos.Add(startP);
arrRecPos.Add(midP);
arrRecPos.Add(endP);
prop.transform.DOPath(arrRecPos.ToArray(), fTime, PathType.CatmullRom, PathMode.Full3D).SetEase(Ease.Linear);
return fTime;
}
/// <param name="sendPos"> 玩家头像位置</param>
/// <param name="endP">筛子停止位置</param>
/// <param name="i">筛子大小</param>
/// <param name="radian">弧度</param>
/// <param name="time">时间</param>
/// <returns></returns>
public float PlayAddFriendAnim(Vector3 sendPos, Vector3 endP,int i,int radian = 0, float time = 1.5f)
{
GameObject shaizi = this.transform.Find("shaizi_anmi4_0").gameObject;
shaizi.GetComponent<Animator>().enabled = true;
SpriteRenderer _shaizhiV = shaizi.GetComponent<SpriteRenderer>();
float fTime = PlaySendFlyAnim(shaizi, sendPos, endP, radian, time);
DOTween.Sequence().AppendInterval(fTime).AppendCallback(() =>
{
if (shaizi != null)
{
shaizi.GetComponent<Animator>().enabled = false;
_shaizhiV.sprite = shaiziData[i-1];
StartCoroutine(Destroyshaizi(shaizi));
}
});
return fTime;
}