Unity 中子弹弓箭射击脚本

一个非常牛逼的计算射击目标的脚本。主要用于计算从子弹发射点到目标的抛物线路径。

在很多游戏开发中都会用到子弹或者弓箭攻击对手的情况,如何能够计算出子弹或者箭头的运行轨迹,并能够让它准确的命中目标,是很多游戏开发者都会遇到的问题。这里就为大家提供一个能够快速计算子弹或者弓箭运行轨迹的脚本


#region Declare
/******************************************************************************************************************
 * File:        Info.cs
 * Author:     Haobel.com 2015 
 * CreateDate: 2015-12-30
 * Description:弓箭手射击脚本
 *****************************************************************************************************************/
#endregion
 
using UnityEngine;
using System.Collections;
public class BlasticVel : MonoBehaviour
{
    /// 射击的目标
    /// 
    public Transform target;
 
    /// 箭头预制
    /// 
    public GameObject grenadePrefab;
 
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            GameObject grenade = Instantiate(grenadePrefab, transform.position, Quaternion.identity) as GameObject;
            Vector3 throwForce = calculateBestThrowSpeed(transform.position, target.transform.position, 2);
            grenade.GetComponent<Rigidbody>().AddForce(throwForce, ForceMode.VelocityChange);
        }
    }
 
    /// 计算射击力度
    /// 
    /// 箭头发射位置,通常为射手的位置
    /// 将要射击的目标
    /// 从发射到射中目标需要的时间
    /// 
    private Vector3 calculateBestThrowSpeed(Vector3 origin, Vector3 target, float timeToTarget)
    {
        // calculate vectors
        Vector3 toTarget = target - origin;
        Vector3 toTargetXZ = toTarget;
        toTargetXZ.y = 0;
 
        // calculate xz and y
        float y = toTarget.y;
        float xz = toTargetXZ.magnitude;
 
        float t = timeToTarget;
        float v0y = y / t + 0.5f * Physics.gravity.magnitude * t;
        float v0xz = xz / t;
 
        // create result vector for calculated starting speeds
        Vector3 result = toTargetXZ.normalized;        // get direction of xz but with magnitude 1
        result *= v0xz;                                // set magnitude of xz to v0xz (starting speed in xz plane)
        result.y = v0y;                                // set y to v0y (starting speed of y plane)
 
        return result;
    }
 
    //==================以下代码是另外一个计算的方法,不是很好用,需要限制射击的目标不能太近并且高度也需要和目标高度一致
    void shoot()
    {
        var ang = ElevationAngle(target);
        var shootAng = ang + 15; // shoot 15 degree higher
        // limit the shoot angle to a convenient range:
        shootAng = Mathf.Clamp(shootAng, 15, 85);
        // and shoot:
        GameObject grenade = Instantiate(grenadePrefab, transform.position, Quaternion.identity) as GameObject;
        grenade.GetComponent<Rigidbody>().velocity = BallisticVel(target, shootAng);
    }
 
    /// 计算射击速度。
    /// 
    /// 
    /// 
    /// 
    Vector3 BallisticVel(Transform target, float angle)
    {
        Vector3 dir = target.position - transform.position; // get target direction 
        float h = dir.y; // get height difference 
        //dir.y = 0; // retain only the horizontal direction 
        var dist = dir.magnitude; // get horizontal distance 
        var a = angle * Mathf.Deg2Rad; // convert angle to radians
        dir.y = dist * Mathf.Tan(a); // set dir to the elevation angle 
        dist += h / Mathf.Tan(a); // correct for small height differences 
        // calculate the velocity magnitude 
        var vel = Mathf.Sqrt(dist * Physics.gravity.magnitude / Mathf.Sin(2 * a)); return vel * dir.normalized;
    }
 
    /// 计算和目标的相对角度
    /// 
    /// 
    /// 
    float ElevationAngle(Transform target)
    {
        // find the cannon->target vector:
        var dir = target.position - transform.position;
        // create a horizontal version of it:
        var dirH = new Vector3(dir.x, 0, dir.y);
        // measure the unsigned angle between them:
        var ang = Vector3.Angle(dir, dirH);
        // add the signal (negative is below the cannon):
        if (dir.y < 0) ang = -ang;
        return ang;
    }
 
}

你可能感兴趣的:(Unity 中子弹弓箭射击脚本)