1. 本代码实现了3D环境中物体朝着任意方向曲线运动。本质是通过物体的初速度向量和加速度向量来控制物体的运动,lifetime控制物体的飞行时间,currentAngle 控制物体的旋转角度
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class sc_flying : MonoBehaviour
{
public float speed_ratio_= 5f;
//每个飞行道具的运动数据
private Vector3 fly_velocity_; //速度
private Vector3 fly_acc_velocity_; //加速度
private float life_cycle_; //生命周期
private float time_spent_; //已经过去的时间
private Vector3 currentAngle_; //道具当前角度
public void Reset(Vector3 start_pos,Vector3 speed,Vector3 speed_acc,float life_cycle)
{
//重置飞行数据
transform.position = start_pos;
fly_velocity_ = speed * speed_ratio_;
fly_acc_velocity_ = speed_acc;
life_cycle_ = life_cycle;
currentAngle_ = Vector3.zero;
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
if (fly_velocity_ != Vector3.zero)
{
flying();
}
//飞行生命周期
life_cycle_ -= Time.fixedDeltaTime;
if (life_cycle_ <= 0f)
{
Destroy(gameObject);
}
}
/// <summary>
/// 控制飞行速度和位移
/// </summary>
private void flying()
{
//计算速度 V = v0 + at
fly_velocity_ += fly_acc_velocity_ * (time_spent_ += Time.fixedDeltaTime);
//位移轨迹
transform.position += (fly_velocity_) * Time.fixedDeltaTime;
//控制旋转
rotateZaxis();
rotateYaxis();
}
/// <summary>
/// 旋转道具的Z角度
/// </summary>
private void rotateZaxis()
{
//该算法使用速度的y/x 的正切值来控制物体绕着Z轴旋转
//因为除数不能为0,除数为0时使用 y/z 的正切值来控制
if (fly_velocity_.x != 0)
{
currentAngle_.z = Mathf.Atan((fly_velocity_.y) / Mathf.Abs(fly_velocity_.x)) * Mathf.Rad2Deg;
}
else
{
currentAngle_.z = Mathf.Atan((fly_velocity_.y) / Mathf.Abs(fly_velocity_.z)) * Mathf.Rad2Deg;
}
}
/// <summary>
/// 旋转道具的Y角度
/// </summary>
private void rotateYaxis()
{
Vector3 Speed_hori = new Vector3(fly_velocity_.x, 0f, fly_velocity_.z);
float angle = Vector3.Angle(Vector3.right, Speed_hori);
Vector3 nordir = Vector3.Cross(Vector3.right, Speed_hori);
//计算两个向量的点乘,点乘可得知两个向量夹角是否大于90度,cos(angle) < 0
float dot = Vector3.Dot(nordir, Vector3.down);
//将angle的范围从 0-180 转换成0-360
if (dot < 0)
{
angle *= -1;
angle += 360;
}
// angle和Unity中的旋转角度相反,因为unity使用的是左手坐标系
currentAngle_.y = angle * -1;
//Debug.Log("Y旋转角" + currentAngle.y);
transform.eulerAngles = currentAngle_;
}
//如果碰到其他物体不再飞行
/*
private void OnTriggerEnter(Collider other) {
if(other.gameObject)
{
fly_velocity = Vector3.zero;
}
}
*/
}
参考文章:unity抛物线_发射弓箭轨迹的实现_lizhenxiqnmlgb的博客-CSDN博客_unity 抛物线轨迹