最近遇到一个功能就是导弹到目标点要有随机曲线表现,重点要到目标点那里
实现思路
用根据时间流逝用sin函数来处理来回曲线的功能(坐标偏移),加个衰减距离(计算坐标偏移大小)
先上图,最下方有工程下载地址
主要实现代码如下
using UnityEngine;
using Random = UnityEngine.Random;
public enum RandomMoveCoordinates
{
None,
XY,
XZ,
YZ,
XYZ
}
public class EffectRandomMove : MonoBehaviour
{
/// <summary>
/// 随机偏移半径
/// </summary>
public float RandomMoveRadius;
/// <summary>
/// 随机偏移移动速度,根据时间累加通过sin算出弧线
/// </summary>
public float RandomMoveSpeed;
/// <summary>
/// 同上
/// </summary>
public float RandomRange;
/// <summary>
/// 衰减距离
/// </summary>
public float ReduceDistance = 1;
/// <summary>
/// 随机模式
/// </summary>
public RandomMoveCoordinates RandomMoveCoordinates = RandomMoveCoordinates.None;
/// <summary>
/// 控制主要插值到目标点速度
/// </summary>
public AnimationCurve Acceleration;
public float AcceleraionTime = 1;
/// <summary>
/// 是否朝向目标
/// </summary>
public bool IsLookAt;
/// <summary>
/// 移动方向速度,一定要比偏移移动速度要大
/// </summary>
public float MoveSpeed;
/// <summary>
/// 目标
/// </summary>
public Transform tTarget;
private Vector3 targetPos;
/// <summary>
/// 新的随机点和旧的随机点,用于计算差值
/// </summary>
private Vector3 smootRandomPos, oldSmootRandomPos;
private float deltaSpeed;
/// <summary>
/// 记录开始时间
/// </summary>
private float startTime;
/// <summary>
/// 随机数据
/// </summary>
private float randomSpeed, randomRadiusX, randomRadiusY;
private int randomDirection1, randomDirection2, randomDirection3;
private void Start()
{
InitializeDefault();
}
private void InitializeDefault()
{
smootRandomPos = new Vector3();
oldSmootRandomPos = new Vector3();
deltaSpeed = 0;
startTime = 0;
randomSpeed = 0;
randomRadiusX = 0;
randomRadiusY = 0;
randomDirection1 = 0;
randomDirection2 = 0;
randomDirection3 = 0;
if (IsLookAt)
transform.LookAt(tTarget);
InitRandomVariables();
}
private Vector3 GetTarPos()
{
if(null != tTarget)
{
return tTarget.position;
}
return targetPos;
}
private void Update()
{
Vector3 endPoint = GetTarPos();
float distance = Vector3.Distance(transform.position, endPoint);
Vector3 delta = new Vector3();
if (RandomMoveCoordinates != RandomMoveCoordinates.None)
{
//利用sin计算坐标差值
UpdateSmootRandomhPos();
delta = smootRandomPos - oldSmootRandomPos;
}
float accelerationY = 1;
if (Acceleration.length > 0)
{
float time = (Time.time - startTime) / AcceleraionTime;
accelerationY = Acceleration.Evaluate(time);
}
//不停插值目标位置,关键在于曲线,如果只够大的时候偏移坐标效果很小,感觉就是直接回到目标点
Vector3 moveDistance = Vector3.MoveTowards(transform.position, endPoint, MoveSpeed * Time.deltaTime * accelerationY);
//这里加了距离衰减偏移坐标
Vector3 moveDistanceRandom = moveDistance + delta * Mathf.Min(distance / ReduceDistance, 1);
transform.LookAt(moveDistanceRandom);
transform.position = moveDistanceRandom;
oldSmootRandomPos = smootRandomPos;
}
private void InitRandomVariables()
{
deltaSpeed = RandomMoveSpeed * Random.Range(1, 1000 * RandomRange + 1) / 1000 - 1;
startTime = Time.time;
randomRadiusX = Random.Range(RandomMoveRadius / 20, RandomMoveRadius * 100) / 100;
randomRadiusY = Random.Range(RandomMoveRadius / 20, RandomMoveRadius * 100) / 100;
randomSpeed = Random.Range(RandomMoveSpeed / 20, RandomMoveSpeed * 100) / 100;
randomDirection1 = Random.Range(0, 2) > 0 ? 1 : -1;
randomDirection2 = Random.Range(0, 2) > 0 ? 1 : -1;
randomDirection3 = Random.Range(0, 2) > 0 ? 1 : -1;
}
private void UpdateSmootRandomhPos()
{
float coord1, coord2;
float time = (Time.time - startTime);
float timeDegree = time * randomSpeed;
float delta = time * deltaSpeed;
coord1 = randomDirection2 * Mathf.Sin(timeDegree) * randomRadiusX;
coord2 = randomDirection3 * Mathf.Sin(timeDegree + (randomDirection1 * Mathf.PI / 2) * time + Mathf.Sin(delta)) * randomRadiusY;
if (RandomMoveCoordinates == RandomMoveCoordinates.XY)
smootRandomPos = new Vector3(coord1, coord2, 0);
if (RandomMoveCoordinates == RandomMoveCoordinates.XZ)
smootRandomPos = new Vector3(coord1, 0, coord2);
if (RandomMoveCoordinates == RandomMoveCoordinates.YZ)
smootRandomPos = new Vector3(0, coord1, coord2);
if (RandomMoveCoordinates == RandomMoveCoordinates.XYZ)
smootRandomPos = new Vector3(coord1, coord2, (coord1 + coord2) / 2 * randomDirection1);
}
}
下面是完整工程下载地址
链接:https://pan.baidu.com/s/13czuQWwAehu5D9vP3Gzpnw
提取码:js7u