折腾了几天的贝塞尔曲线(3个点的)导弹发射

来源:互联网 发布:知不知 编辑:程序博客网 时间:2024/05/17 06:30

     

       折腾了几天的贝塞尔曲线3个点的,最优化代码还是用抛物线,进行处理,真够折腾的,不说了,一把泪,代码发了吧,这代码用的也比较多

using UnityEngine;using System.Collections;public class cast : MonoBehaviour{    public GameObject target;    public float speed = 10;    private float distanceToTarget;    private bool move = true;public float angelmodu=30;    void Start ()    {        distanceToTarget = Vector3.Distance (this.transform.position, target.transform.position);        StartCoroutine (Shoot ());    }        IEnumerator Shoot ()    {                while (move) {            Vector3 targetPos = target.transform.position;            this.transform.LookAt (targetPos);            float angle = Mathf.Min (1, Vector3.Distance (this.transform.position, targetPos) / distanceToTarget) * angelmodu;            this.transform.rotation = this.transform.rotation * Quaternion.Euler (Mathf.Clamp (-angle, -42, 42), 0, 0);            float currentDist = Vector3.Distance (this.transform.position, target.transform.position);            print ("currentDist" + currentDist);            if (currentDist < 0.5f)                move = false;            this.transform.Translate (Vector3.forward * Mathf.Min (speed * Time.deltaTime, currentDist));            yield return null;        }    }        }

植物大战僵尸抛物线实现 
瀛洲海客,2013.10.29 
Key 
 
抛物线、植物大战僵尸、Unity脚本 
描述 
在游戏植物大战僵尸里,最美妙的事情是那些优美的抛物线,比如西瓜、卷心菜之类的攻击方式。 
与传统的抛物线不同,游戏中的抛物线是实时更新路径以保证始终能打击的目标。所以用抛物线的数学几何知识并不能完美实现抛物线的优美。 
物理数学计算 
通过分析,我们依然可以得出一些结论: 
1、 水平移动为匀速运动,设定水平速度成为Speed 2、 垂直方向上受重力控制,设重力加速度为G 于是用物理知识可以知道,在t时刻 
垂直方向上的位置为Y=0.5*G*t*t-vt,其中v为垂直方向上的初速度,未知 水平方向上的位置为X=Speed*t 
一般地,我们认为抛物线是对称的,也就是说上升到最高点和从最高点落下时间相同,位移相反: 
上升:MaxY=0.5*G*t*t 
下落:MaxY=-(0.5*G*t*t-vt) 
结合后得到垂直方向的速度关于t的函数,v=Gt 
而无论上升还是下降,t为运动总时间的一半,即t=0.5*len/Speed,其中len为目标和发射点之间的水平距离。 
所以v=0.5*G*len/Speed 
那么Y=0.5*G*t*t-0.5*G*len*t/Speed=0.5*G*(t*t-len*t/Speed) 也就得到了最终的结果 X关于t的函数:   X(t)  =Speed*t 
Y关于t和Len的函数: Y(t,Len) =0.5*G*(t*t-len*t/Speed)  












程序 
应用上述公式编程如下(这里假设发射点为原点,即在坐标0点): Class TargetParabola { 
float time;//运动时间 vector3 Target;//目标坐标 float Speed; float G; 
//定位函数 
voidRepos(float deltaTime) {   varlen=Target.x;   Self.x=Speed*time;//自身的x坐标   Self.Y=0.5*G*(t*t-len*t/Speed);//自身的y坐标   time+=deltatime } 

Unity脚本 
usingUnityEngine;  
public class Parabola : MonoBehaviour { 
public float Speed = 1; public float G = 1; 
public Transform Target;  
private float m_len = 5; private float m_time; private Vector3 m_ori; private float m_oldx; private float m_oldy;  
internal void Start()     { 
m_ori = transform.position; 
m_display = transform.GetChild(0);  
m_oldx = m_ori.x; m_oldy = m_ori.y;     } 












  
 //设置角度的子物体,如不需要,可以删除相关的代码 private Transform m_display; 
//设置角度函数 
public void SetXEuler(float x, float sign)     { 
if (m_display == null) m_display = transform; varey = 0; if (sign > 0) ey = 180; 
m_display.localEulerAngles = new Vector3(x, ey, 0);     }   
internal void Update()     { 
if (Target != null)         { 
m_len = Target.position.x - m_ori.x;         } 
        //位移变化 
var y = 0.5f * G * (m_time * m_time - Mathf.Abs(m_len) * m_time / Speed); var x = Mathf.Sign(m_len) * Speed * m_time; transform.position = m_ori + new Vector3(x, y, 0);  
        //角度变化,如果不需要,删除以下三行 var rad = Mathf.Atan2(y - m_oldy, x - m_oldx); varag = Mathf.Rad2Deg * rad; SetXEuler(ag, Mathf.Sign(m_len));  
m_oldx = x; m_oldy = y;  
m_time += Time.deltaTime; 
        if (transform.position.y< 0)//命中         { m_time = 0; 
Destroy(gameObject);         }     } }

原创粉丝点击