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
{
    /// <summary>射击的目标
    /// </summary>
    public Transform target;
 
    /// <summary>箭头预制
    /// </summary>
    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);
        }
    }
 
    /// <summary>计算射击力度
    /// </summary>
    /// <param name="origin">箭头发射位置,通常为射手的位置</param>
    /// <param name="target">将要射击的目标</param>
    /// <param name="timeToTarget">从发射到射中目标需要的时间</param>
    /// <returns></returns>
    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);
    }
 
    /// <summary>计算射击速度。
    /// </summary>
    /// <param name="target"></param>
    /// <param name="angle"></param>
    /// <returns></returns>
    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;
    }
 
    /// <summary>计算和目标的相对角度
    /// </summary>
    /// <param name="target"></param>
    /// <returns></returns>
    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;
    }
 
}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值