Unity使用DoTween实现抛物线效果
作者:轻风点语
这篇文章主要为大家详细介绍了Unity使用DoTween实现抛物线效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Unity使用DoTween实现抛物线效果,供大家参考,具体内容如下
概要
public partial class EMath { public static Vector3 Parabola(Vector3 start, Vector3 end, float height, float t) { float Func(float x) => 4 * (-height * x * x + height * x); var mid = Vector3.Lerp(start, end, t); return new Vector3(mid.x, Func(t) + Mathf.Lerp(start.y, end.y, t), mid.z); } public static Vector2 Parabola(Vector2 start, Vector2 end, float height, float t) { float Func(float x) => 4 * (-height * x * x + height * x); var mid = Vector2.Lerp(start, end, t); return new Vector2(mid.x, Func(t) + Mathf.Lerp(start.y, end.y, t)); } }
使用方法
public class Test : MonoBehaviour { public Transform start; public Transform target; public Transform ball; private float t; private void Start() { DOTween.To(setter: value => { Debug.Log(value); ball.position = Parabola(start.position, target.position, 10, value); }, startValue: 0, endValue: 1, duration: 5) .SetEase(Ease.Linear); } }
效果演示
之前小编收藏了一段抛物线代码,分享给大家:unity实现炮弹运动轨迹(抛物线)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Parabol : MonoBehaviour { private Rigidbody rgb; /// <summary> /// 目标 /// </summary> public GameObject target; /// <summary> /// 子弹的发射点 /// </summary> private Vector3 originPoint; private Vector3 aimPoint; /// <summary> /// 无弹道偏移的当前位置 /// </summary> private Vector3 myVirtualPosition; /// <summary> /// 定位最后一帧 /// </summary> private Vector3 myPreviousPosition; /// <summary> /// 是否可以发射 /// </summary> private bool sw = false; private bool actived = false; /// <summary> /// 最大发射距离 /// </summary> public float maxLaunch = 1f; /// <summary> /// 加速度计算计数器 /// </summary> private float counter; /// <summary> /// 刚刚启动时的速度 /// </summary> public float speed = 0.5f; /// <summary> /// 恒定加速度 /// </summary> public float speedUpOverTime = 0.1f; /// <summary> /// 弹道偏移量(与目标的距离) /// </summary> public float ballisticOffset = 0.5f; void Start() { rgb = GetComponent<Rigidbody>(); sw = true; if (target == null) { Destroy(gameObject); } else { aimPoint = target.transform.position; } originPoint = myVirtualPosition = myPreviousPosition = transform.position; } void Update() { if (target != null) { if (actived == false) { actived = true; PreLaunch(); } else { if (sw == true) { if (rgb.isKinematic == false) { Move(); } } } } } private void PreLaunch() { float xTarget = target.transform.position.x; float yTarget = target.transform.position.y; float zTarget = target.transform.position.z; float xCurrent = transform.position.x; float yCurrent = transform.position.y; float zCurrent = transform.position.z; //目标之间的值 float xDistance = Mathf.Abs(xTarget - xCurrent); float yDistance = yTarget - yCurrent; float zDistance = Mathf.Abs(zTarget - zCurrent); float fireAngle = 1.57075f - (Mathf.Atan((Mathf.Pow(maxLaunch, 2f) + Mathf.Sqrt(Mathf.Pow(maxLaunch, 4f) - 9.8f * (9.8f * Mathf.Pow(xDistance, 2f) + 2f * yDistance * Mathf.Pow(maxLaunch, 2f)+ 2f * zDistance * Mathf.Pow(maxLaunch, 2f)))) / (9.8f * xDistance))); float xSpeed = Mathf.Sin(fireAngle) * maxLaunch; float ySpeed = Mathf.Cos(fireAngle) * maxLaunch; float zSpeed = Mathf.Tan(fireAngle) * maxLaunch; //判断在左边还是右边 if ((xTarget - xCurrent) < 0f) { xSpeed = -xSpeed; } if ((zTarget - zCurrent) < 0f) { zSpeed = -zSpeed; } Calculation(ySpeed); sw = true; } private void Calculation(float speedy) { NextPosition(Time.time % ((speedy / 9.81f) * 2)); } private void NextPosition(float airtime) { float xTarget = target.transform.position.x; float yTarget = target.transform.position.y; float zTarget = target.transform.position.z; float speedy = target.GetComponent<Rigidbody>().velocity.y; float speedx = target.GetComponent<Rigidbody>().velocity.x; float speedz = target.GetComponent<Rigidbody>().velocity.z; Launch(xTarget + (speedx * airtime), yTarget + (speedy * airtime),zTarget+ (speedz * airtime)); } private void Launch(float xTarget, float yTarget, float zTarget) { rgb.isKinematic = false; float xCurrent = transform.position.x; float yCurrent = transform.position.y; float zCurrent = transform.position.z; float xDistance = Mathf.Abs(xTarget - xCurrent); float yDistance = yTarget - yCurrent; float zDistance = Mathf.Abs(zTarget - zCurrent); float fireAngle = 1.57075f - (Mathf.Atan((Mathf.Pow(maxLaunch, 2f) + Mathf.Sqrt(Mathf.Pow(maxLaunch, 4f) - 9.8f * (9.8f * Mathf.Pow(xDistance, 2f) + 2f * yDistance * Mathf.Pow(maxLaunch, 2f) + 2f * zDistance * Mathf.Pow(maxLaunch, 2f)))) / (9.8f * xDistance))); float xSpeed = Mathf.Sin(fireAngle) * maxLaunch; float ySpeed = Mathf.Cos(fireAngle) * maxLaunch; float zSpeed = Mathf.Tan(fireAngle) * maxLaunch; //判断在左边还是右边 if ((xTarget - xCurrent) < 0f) { xSpeed = -xSpeed; } if (!float.IsNaN(xSpeed) && !float.IsNaN(ySpeed)) { rgb.velocity = new Vector3(xSpeed, ySpeed, zSpeed); } else { maxLaunch = maxLaunch + 0.3f; PreLaunch(); } } private void Move() { counter += Time.fixedDeltaTime; //加速度提升 speed += Time.fixedDeltaTime * speedUpOverTime; if (target != null) { aimPoint = target.transform.position; } //计算从发射点到目标的距离 Vector3 originDistance = aimPoint - originPoint; //计算剩余距离 Vector3 distanceToAim = aimPoint - myVirtualPosition; //发射点和目标之间的矢量距离 //移动到目标 myVirtualPosition = Vector3.Lerp(originPoint, aimPoint, counter * speed / originDistance.magnitude);// vector nội suy giữa vị trí ban đầu và mục tiêu //向轨迹添加弹道偏移 transform.position = AddBallisticOffset(originDistance.magnitude, distanceToAim.magnitude); //将子弹旋转至弹道 //Debug.Log("最后一帧的位置:" + myPreviousPosition); LookAtDirection(transform.position - myPreviousPosition); myPreviousPosition = transform.position; } private Vector3 AddBallisticOffset(float originDistance, float distanceToAim) { if (ballisticOffset > 0f) { // 计算弯曲处偏移 float offset = Mathf.Sin(Mathf.PI * ((originDistance - distanceToAim) / originDistance)); offset *= originDistance; // 向轨迹添加偏移 return myVirtualPosition + (ballisticOffset * offset * Vector3.up); } else { return myVirtualPosition; } } /// <summary> /// 朝向目标 /// </summary> /// <param name="direction"></param> private void LookAtDirection(Vector3 direction) { Quaternion netPointQ = Quaternion.FromToRotation(direction, direction-transform.position); transform.rotation = Quaternion.Lerp(transform.rotation, netPointQ, 30f); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。