Unity - Projectile Motion,找到击中坐标x,y所需的角度

Unity - Projectile Motion, find the angle needed to hit coordinates x,y

围绕同一主题提出了很多问题,但似乎对我没有任何帮助。

问题很简单,一个玩家和一个敌人在x,y平面上。我想以计算出的角度发射我的弹丸,这样弹丸就会在它的坐标处击中敌人。

我都尝试过实施两者

Angle of Reach and Angle required to hit x,y

这两个实现最终对我来说都是一样的; Shooting but not hitting the target in this manner

任何帮助或指点将不胜感激!谢谢

代码如下:

public Rigidbody projectile;
public float projectileSpeed;
public float Firerate = 9f;
private float nextfire;

private GameObject enemy;
private float gravity = Physics.gravity.y;
private Vector3 directionalVector;

// Start is called before the first frame update
void Start()
{
    enemy = GameObject.FindGameObjectWithTag("enemy");

}


void Update()
{
    directionalVector = enemy.transform.position - transform.position;

}
void FixedUpdate()
{

    nextfire = Time.time + (1 / Firerate);

    float projectileSpeed2 = projectileSpeed * projectileSpeed;
    float projectileSpeed4 = projectileSpeed2 * projectileSpeed2;
    float x = enemy.transform.position.x;
    float y = enemy.transform.position.y;
    float x2 = x * x;



    float theta = Mathf.Atan(projectileSpeed2-Mathf.Sqrt(projectileSpeed4-gravity*(gravity*x2+2*y*projectileSpeed2))/gravity*x);
    print(theta);

    Vector3 releaseVector = (Quaternion.AngleAxis(theta, Vector3.up) * directionalVector).normalized;

    Debug.DrawRay(transform.position, releaseVector, Color.red,0.5f);
    Rigidbody instantiatedProjectile = Instantiate(projectile, transform.position, transform.rotation) as Rigidbody;
    instantiatedProjectile.velocity = releaseVector * projectileSpeed;
}

}

为什么不回避找角度的问题,直接根据第一眼看到敌人的方向移动子弹

(target.transform.position - transform.position).normalized;

它将return一个矢量方向指向目标。

弹丸移动时,按照这个方向移动即可。
计算角度不需要头疼:)

编辑

我之前做了一个函数 'convert' 一个方向的角度:

protected Vector2 DetermineBulletMoveDirection(float shootingAngle) {
    // Determine the direction of the bullet travel on the x and y axis.
    float bulletDirectionX = transform.position.x + Mathf.Sin((shootingAngle * Mathf.PI) / 180);
    float bulletDirectionY = transform.position.y + Mathf.Cos((shootingAngle * Mathf.PI) / 180);

    // Determines the direction this bullet should be moving.
    Vector2 bulletDirection = new Vector2(bulletDirectionX, bulletDirectionY);
    return (bulletDirection - (Vector2)transform.position).normalized;
}

它接受一个角度,并根据射击者当前所在的位置将其转换为方向。
角度应该从Vector.down开始,顺时针旋转

下一个问题是找出你和敌人之间的角度。
这是我能想到的最简单的解决方案,先上图:

注意到您可以在此使用 TOACAHSOH 了吗?

因此,您所要做的就是“虚拟地”将射手的 Y 轴与原点对齐。
(将运动应用于射手也是!)

对射手做同样的事情,但这次是在 x 轴上。

并且您将能够达到 90 度三角形的状态。
从那里,你可以计算出从 Vector.down 旋转到敌人的角度。

只需确保将两个对象都移回其初始位置即可。

纠结了一段时间后,我找到了解决办法。

最后我使用了Angle of Reach。第二个错误是 Mathf.Atan returns 弧度而不是度数,而 Quantion.AngleAxis 包含角度。第三个也是最后一个是 Unity 使用左手坐标系而不是我习惯的通常的右手坐标系。

这是最后一段代码:

public class TargetAndShoot : MonoBehaviour
{
    public Rigidbody projectile;
    public float projectileSpeed;
    public float firerate;
    private float nextfire;

    private GameObject enemy;
    private float gravity = Physics.gravity.y;


    // Start is called before the first frame update
    void Start()
    {
        enemy = GameObject.FindGameObjectWithTag("enemy");

    }


    void Update()
    {
        if (Time.time >= nextfire)
        {
            nextfire = Time.time + (1 / firerate);
            float distance = enemy.transform.position.x - transform.position.x;
            Vector3 directionalVector = enemy.transform.position - transform.position;

            float v2 = projectileSpeed * projectileSpeed;
            float v4 = v2 * v2;

            float x = enemy.transform.position.x;
            float x2 = x * x;
            float y = enemy.transform.position.y;

            float theta = 0.5f*Mathf.Asin((gravity * distance) / (projectileSpeed * projectileSpeed));
            Vector3 releaseVector = (Quaternion.AngleAxis(theta * Mathf.Rad2Deg, -Vector3.forward) * directionalVector).normalized;
            Debug.DrawRay(transform.position, releaseVector*5, Color.cyan, 0.5f);

            Rigidbody instantiatedProjectile = Instantiate(projectile, transform.position, transform.rotation) as Rigidbody;
            instantiatedProjectile.velocity = releaseVector * projectileSpeed;
        }
    }

}