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 = ansform.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 = ansform.position.x;
float yTarget = ansform.position.y;
float zTarget = ansform.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 * xDi        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 = ansform.position.x;
float yTarget = ansform.position.y;
float zTarget = ansform.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 * xD        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 = ansform.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
//向轨迹添加弹道偏移
float uptransform.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);        ation = Quaternion.ation, netPointQ, 30f);
}
}
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。