博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity C# 计算导弹抛物线弹道和转向
阅读量:6695 次
发布时间:2019-06-25

本文共 5690 字,大约阅读时间需要 18 分钟。

在三维空间中,利用抛物线公式计算弹道,得到一个发射初速度,让导弹打击到指定地点

效果:
弹道效果

脚本属性

脚本使用:只需指定目标点即可
可以通过Hight调整导弹的飞行高度
可以通过Gravity调整导弹的飞行速度

通过以下两个脚本实现。工具脚本计算弹道,Missile脚本每帧更新导弹位置

PhysicsUtil.cs

using UnityEngine;///  物理计算工具/// 
ZhangYu 2018-05-10
///
public static class PhysicsUtil { /**findInitialVelocity * Finds the initial velocity of a projectile given the initial positions and some offsets * @param Vector3 startPosition - the starting position of the projectile * @param Vector3 finalPosition - the position that we want to hit * @param float maxHeightOffset (default=0.6f) - the amount we want to add to the height for short range shots. We need enough clearance so the * ball will be able to get over the rim before dropping into the target position * @param float rangeOffset (default=0.11f) - the amount to add to the range to increase the chances that the ball will go through the rim * @return Vector3 - the initial velocity of the ball to make it hit the target under the current gravity force. * * Vector3 tt = findInitialVelocity (gameObject.transform.position, target.transform.position); Rigidbody rigidbody = gameObject.GetComponent
(); Debug.Log (tt); rigidbody.AddForce(tt*rigidbody.mass,ForceMode.Impulse); */ public static Vector3 GetParabolaInitVelocity(Vector3 from, Vector3 to, float gravity = 9.8f, float heightOff = 0.0f, float rangeOff = 0.11f) { // get our return value ready. Default to (0f, 0f, 0f) Vector3 newVel = new Vector3(); // Find the direction vector without the y-component /// /找到未经y分量的方向矢量// Vector3 direction = new Vector3(to.x, 0f, to.z) - new Vector3(from.x, 0f, from.z); // Find the distance between the two points (without the y-component) //发现这两个点之间的距离(不y分量)// float range = direction.magnitude; // Add a little bit to the range so that the ball is aiming at hitting the back of the rim. // Back of the rim shots have a better chance of going in. // This accounts for any rounding errors that might make a shot miss (when we don't want it to). range += rangeOff; // Find unit direction of motion without the y component Vector3 unitDirection = direction.normalized; // Find the max height // Start at a reasonable height above the hoop, so short range shots will have enough clearance to go in the basket // without hitting the front of the rim on the way up or down. float maxYPos = to.y + heightOff; // check if the range is far enough away where the shot may have flattened out enough to hit the front of the rim // if it has, switch the height to match a 45 degree launch angle //if (range / 2f > maxYPos) // maxYPos = range / 2f; if (maxYPos < from.y) maxYPos = from.y; // find the initial velocity in y direction /// /发现在y方向上的初始速度// float ft; ft = -2.0f * gravity * (maxYPos - from.y); if (ft < 0) ft = 0f; newVel.y = Mathf.Sqrt(ft); // find the total time by adding up the parts of the trajectory // time to reach the max //发现的总时间加起来的轨迹的各部分// //时间达到最大// ft = -2.0f * (maxYPos - from.y) / gravity; if (ft < 0) ft = 0f; float timeToMax = Mathf.Sqrt(ft); // time to return to y-target //时间返回到y轴的目标// ft = -2.0f * (maxYPos - to.y) / gravity; if (ft < 0) ft = 0f; float timeToTargetY = Mathf.Sqrt(ft); // add them up to find the total flight time //把它们加起来找到的总飞行时间// float totalFlightTime; totalFlightTime = timeToMax + timeToTargetY; // find the magnitude of the initial velocity in the xz direction /// /查找的初始速度的大小在xz方向// float horizontalVelocityMagnitude = range / totalFlightTime; // use the unit direction to find the x and z components of initial velocity //使用该单元的方向寻找初始速度的x和z分量// newVel.x = horizontalVelocityMagnitude * unitDirection.x; newVel.z = horizontalVelocityMagnitude * unitDirection.z; return newVel; } ///
计算抛物线物体在下一帧的位置 ///
初始位置 ///
移动速度 ///
重力加速度 ///
飞行时间 ///
public static Vector3 GetParabolaNextPosition(Vector3 position, Vector3 velocity, float gravity, float time) { velocity.y += gravity * time; return position + velocity * time; }}

Missile.cs

using UnityEngine;/// /// 抛物线导弹/// 
计算弹道和转向
///
ZhangYu 2019-02-27
///
public class Missile : MonoBehaviour { public Transform target; // 目标 public float hight = 16f; // 抛物线高度    public float gravity = -9.8f; // 重力加速度 private Vector3 position; // 我的位置 private Vector3 dest; // 目标位置 private Vector3 velocity; // 运动速度    private float time = 0; // 运动时间    private void Start() { dest = target.position; position = transform.position; velocity = PhysicsUtil.GetParabolaInitVelocity(position, dest, gravity, hight, 0); transform.LookAt(PhysicsUtil.GetParabolaNextPosition(position, velocity, gravity, Time.deltaTime)); }    private void Update() {        // 计算位移 float deltaTime = Time.deltaTime; position = PhysicsUtil.GetParabolaNextPosition(position, velocity, gravity, deltaTime); transform.position = position; time += deltaTime; velocity.y += gravity * deltaTime; // 计算转向 transform.LookAt(PhysicsUtil.GetParabolaNextPosition(position, velocity, gravity, deltaTime)); // 简单模拟一下碰撞检测 if (position.y <= dest.y) enabled = false; }}

转载地址:http://lqvoo.baihongyu.com/

你可能感兴趣的文章
pip升级时报错--- No module named 'pip._internal'
查看>>
大白话搞懂什么是同步/异步/阻塞/非阻塞
查看>>
Fiddler抓包工具总结二(转自小坦克)
查看>>
JSP----动态网页开发的基础
查看>>
CentOS 6.5下部署日志服务器 Rsyslog+LogAnalyzer+MySQL
查看>>
LoadRunner使用之变量参数化
查看>>
asp.net运行原理
查看>>
canvas实现芝麻信用评分效果
查看>>
053(五十三)
查看>>
【Spark篇】---Spark中yarn模式两种提交任务方式
查看>>
最短路专题解题报告
查看>>
什么是FSO
查看>>
Python 3
查看>>
实现主从关系Form中汇总行金额/数量
查看>>
Python学习笔记:协程
查看>>
原生js完成拼图小游戏
查看>>
[WP7]关于退出时确认对话框的实现
查看>>
Centos硬件信息
查看>>
如何在一个Activity里使用另一个xml布局文件
查看>>
饼图图例中显示百分比值
查看>>