简体   繁体   English

Unity - 弹丸运动,找到击中坐标 x,y 所需的角度

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

Plenty of questions asked around the same topic, but nothing seems to be working for me.围绕同一主题提出了很多问题,但似乎没有什么对我有用。

The problem is simple, a player and an enemy are on the x,y plane.问题很简单,一个玩家和一个敌人在 x,y 平面上。 I want to launch my projectile at a calculated angle in such way that the projectile will hit the enemy at it's coordinates.我想以计算出的角度发射我的射弹,这样射弹将在其坐标处击中敌人。

I've tried implementing both我试过同时实施

Angle of Reach and Angle required to hit x,y 到达x,y 所需 的到达角度角度

Both of these implementation end up doing the same for me;这两种实现最终对我来说都是一样的; Shooting but not hitting the target in this manner以这种方式射击但未击中目标

Any help or pointers would be much appreciated!任何帮助或指示将不胜感激! Thank you谢谢

Here is the code:这是代码:

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;
}

} }

Why not avoid the problem of finding the angle, and just move the bullet based on the direction on where it first saw the enemy.为什么不避免找角度的问题,而是根据第一次看到敌人的方向移动子弹。

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

It will return a Vector direction to the target.它将返回到目标的向量方向。

When the projectile moves, just move it based on this direction.当弹丸移动时,只需根据此方向移动即可。
No headache needed in calculating angles :)计算角度不需要头疼:)

Edit编辑

I made a function before to 'convert' an angle to direction:我之前做了一个函数来“转换”角度到方向:

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;
}

It takes in an angle, and converts it into a direction based on where the shooter is currently at.它接受一个角度,并根据射手当前所处的位置将其转换为方向。
The angle should start from Vector.down , and rotates clockwise.角度应从Vector.down开始,并顺时针旋转。

The next problem is to find out the angle between you and the enemy.下一个问题是找出你和敌人之间的角度。
This is the simplest solution I could think of, here is a diagram first:这是我能想到的最简单的解决方案,先上图:

图表

Notice that you can use TOACAHSOH on this?请注意,您可以在此使用TOACAHSOH吗?

So all you have to do, is to ' virtually ' align the Y axis of the shooter to the origin.因此,您所要做的就是“虚拟地”将射击者的 Y 轴与原点对齐。
(Apply the movement to the shooter too!) (也将动作应用到射手身上!)

Do the same thing for the shooter, but on the x-axis this time.对射手做同样的事情,但这次是在 x 轴上。

And you would be able to achieve that state where you have a triangle with a 90-degree.您将能够实现具有 90 度三角形的状态。
From there on, you can calculate the angle to rotate from Vector.down to the enemy.从那里开始,您可以计算从Vector.down到敌人的旋转角度。

Just make sure you move both of the objects back to it's initial position.只需确保将两个对象移回其初始位置即可。

After fighting this for a while I found a solution.在与此斗争了一段时间后,我找到了解决方案。

In the end I ended up using the Angle of Reach .最后,我最终使用了Angle of Reach The second error was that Mathf.Atan returns radians and not degrees, while Quantion.AngleAxis takes in angles.第二个错误是 Mathf.Atan 返回弧度而不是度数,而 Quantion.AngleAxis 接受角度。 The third and the final one was the fact that Unity uses left hand coordinate system as opposed to the usual right hand system which I was used to.第三个也是最后一个是 Unity 使用左手坐标系,而不是我习惯的通常的右手坐标系。

Here is the final piece of code:这是最后一段代码:

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;
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM