Unity 无法使子弹朝正确方向发射

huangapple go评论72阅读模式
英文:

Unity Can't get bullet to fire the right direction

问题

我试图让我的坦克朝着鼠标方向开火。目前坦克可以旋转以面向鼠标,但我不知道如何使子弹朝正确的方向前进!

目前位于顶部的炮塔可以正确旋转,我不确定该对象的旋转是否可以用于确定方向?

这是在Unity 3D中,但实际上是2.5D倾斜的俯视视角。

public class tankScript : MonoBehaviour
{
    public float rotateSpeed = 90;
    public float speed = 5.0f;
    public float fireInterval = 0.5f;
    public float bulletSpeed = 20;
    public Transform spawnPoint;
    public GameObject bulletObject;
    float nextFire;

    Camera cam;
    Collider planecollider;
    RaycastHit hit;
    Ray ray;
    Vector3 mouseDirection;

    void Start()
    {
        nextFire = Time.time + fireInterval;

        cam = GameObject.Find("Main Camera").GetComponent<Camera>();
        planecollider = GameObject.Find("Plane").GetComponent<Collider>();
    }

    void Update()
    {
        var transAmount = speed * Time.deltaTime;
        var rotateAmount = rotateSpeed * Time.deltaTime;

        if (Input.GetKey("w"))
        {
            transform.Translate(0, 0, transAmount);
        }
        if (Input.GetKey("s"))
        {
            transform.Translate(0, 0, -transAmount);
        }
        if (Input.GetKey("a"))
        {
            transform.Rotate(0, -rotateAmount, 0);
        }
        if (Input.GetKey("d"))
        {
            transform.Rotate(0, rotateAmount, 0);
        }
        if (Input.GetButtonDown("Fire1") && Time.time > nextFire)
        {
            nextFire = Time.time + fireInterval;
            fire();
        }
    }

    void fire()
    {
        ray = cam.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit))
        {
            if (hit.collider == planecollider)
            {
                mouseDirection = new Vector3(hit.point.x, 0.25f, hit.point.z);
                float step = bulletSpeed * Time.deltaTime;
                var bullet = Instantiate(bulletObject, spawnPoint.position, spawnPoint.rotation);
                bullet.GetComponent<Rigidbody>().transform.localPosition = Vector3.MoveTowards(transform.localPosition, mouseDirection, step);

            }
        }
    }
}
英文:

I'm trying to get my tank to shoot in the direction the mouse is facing. Currently the tank can rotate to look at the mouse, but I have no idea how to make the bullet go the right direction!

Currently the turret on the top does rotate correctly, I'm not sure if the rotation on that object can be used for the direction?

It is iin unity 3d but it is really 2.5d angled topdown.

public class tankScript : MonoBehaviour
{
    public float rotateSpeed = 90;
    public float speed = 5.0f;
    public float fireInterval = 0.5f;
    public float bulletSpeed = 20;
    public Transform spawnPoint;
    public GameObject bulletObject;
    float nextFire;

    Camera cam;
    Collider planecollider;
    RaycastHit hit;
    Ray ray;
    Vector3 mouseDirection;

    void Start()
    {
        nextFire = Time.time + fireInterval;

        cam = GameObject.Find(&quot;Main Camera&quot;).GetComponent&lt;Camera&gt;();
        planecollider = GameObject.Find(&quot;Plane&quot;).GetComponent&lt;Collider&gt;();
    }

    void Update()
    {
        var transAmount = speed * Time.deltaTime;
        var rotateAmount = rotateSpeed * Time.deltaTime;

        if (Input.GetKey(&quot;w&quot;))
        {
            transform.Translate(0, 0, transAmount);
        }
        if (Input.GetKey(&quot;s&quot;))
        {
            transform.Translate(0, 0, -transAmount);
        }
        if (Input.GetKey(&quot;a&quot;))
        {
            transform.Rotate(0, -rotateAmount, 0);
        }
        if (Input.GetKey(&quot;d&quot;))
        {
            transform.Rotate(0, rotateAmount, 0);
        }
        if (Input.GetButtonDown(&quot;Fire1&quot;) &amp;&amp; Time.time &gt; nextFire)
        {
            nextFire = Time.time + fireInterval;
            fire();
        }
    }

    void fire()
    {
        ray = cam.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit))
        {
            if (hit.collider == planecollider)
            {
                mouseDirection = new Vector3(hit.point.x, 0.25f, hit.point.z);
                float step = bulletSpeed * Time.deltaTime;
                var bullet = Instantiate(bulletObject, spawnPoint.position, spawnPoint.rotation);
                bullet.GetComponent&lt;Rigidbody&gt;().transform.localPosition = Vector3.MoveTowards(transform.localPosition, mouseDirection, step);

            }
        }
    }

答案1

得分: 1

以下是翻译好的部分:

"The key issue here is that you likely want to set the velocity of the rigidbody rather than moving it by setting the localPosition. Otherwise you lose all the benefits of the physics system, and won't be able to detect collisions correctly.

What value should you set it to, though? Well, velocity consists of two components:

  • Direction: This should be the difference between the mouse hit point and the spawn point.
  • Speed (magnitude): This should be bulletSpeed.

Let's change your script to see what using velocity instead of manually moving the bullet would look like:

void fire()
{
    ray = cam.ScreenPointToRay(Input.mousePosition);
    if (Physics.Raycast(ray, out hit))
    {
        if (hit.collider == planecollider)
        {
            mouseDirection = new Vector3(hit.point.x, 0.25f, hit.point.z);

            // This vector is the direction vector we want to fire along
            Vector3 firingDirection = mouseDirection - spawnPoint.position;

            var bullet = Instantiate(bulletObject, spawnPoint.position, spawnPoint.rotation);

            // Now, we set the velocity to firingDirection, but scaled to bulletSpeed 
            bullet.GetComponent<Rigidbody>().velocity = firingDirection.normalized * bulletSpeed;
        }
    }
}
英文:

The key issue here is that you likely want to set the velocity of the rigidbody rather than moving it by setting the localPosition. Otherwise you lose all the benefits of the physics system, and won't be able to detect collisions correctly.

What value should you set it to, though? Well, velocity consists of two components:

  • Direction: This should be the difference between the mouse hit point and the spawn point.
  • Speed (magnitude): This should be bulletSpeed.

Let's change your script to see what using velocity instead of manually moving the bullet would look like:

<!-- language: lang-cs -->

void fire()
{
    ray = cam.ScreenPointToRay(Input.mousePosition);
    if (Physics.Raycast(ray, out hit))
    {
        if (hit.collider == planecollider)
        {
            mouseDirection = new Vector3(hit.point.x, 0.25f, hit.point.z);

            // This vector is the direction vector we want to fire along
            Vector3 firingDirection = mouseDirection - spawnPoint.position;

            var bullet = Instantiate(bulletObject, spawnPoint.position, spawnPoint.rotation);

            // Now, we set the velocity to firingDirection, but scaled to bulletSpeed 
            bullet.GetComponent&lt;Rigidbody&gt;().velocity = firingDirection.normalized * bulletSpeed;

        }
    }
}

huangapple
  • 本文由 发表于 2023年2月27日 08:43:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575953.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定