如何让霰弹枪子弹在unity 2d中散开

问题描述 投票:0回答:1

我知道这个问题已经在其他帖子中解决了,比如this,但我已经尝试实现它,但它仍然不起作用。它不起作用,因为子弹方向不正确,所以子弹总是飞向错误的方向。

子弹唯一一次飞向正确的方向就是在这种情况下:

我只是想在自上而下的射击游戏中散布霰弹枪的子弹。 首先,我创建中央子弹,然后创建其他 2 个子弹,它们旋转的角度是通过添加/减去中央子弹旋转的角度来计算的。

我会添加一个视频来更好地解释它,链接是这里

这是代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyShotgunnerScript : MonoBehaviour
{
    [SerializeField] GameObject bulletPrefab;
    private GameObject player;
    [SerializeField] float bulletSpeed;
    [SerializeField] int nBullets;
    [SerializeField] float bulletAngle;
    [SerializeField] Vector2 shootingDirection;
    [SerializeField] float rotationZ;
    private GameObject bullet;
    private Rigidbody2D Brb;
    // Start is called before the first frame update
    void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        Shoot();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Shoot();
        }
    }
    private void Shoot()
    {
        //straight-center bullet
        shootingDirection = new Vector2(player.transform.position.x - transform.position.x, player.transform.position.y - transform.position.y).normalized;
        //calculates the rotation of the bullet
        rotationZ = Mathf.Atan2(shootingDirection.y, shootingDirection.x) * Mathf.Rad2Deg;
        //creates the bullet
        bullet = Instantiate(bulletPrefab, transform.position, Quaternion.Euler(0, 0, rotationZ));
        //gets the bullet's rigidbody
        Brb = bullet.GetComponent<Rigidbody2D>();
        //modifies the velocity of the rigidbody to match his rotation
        Brb.velocity = shootingDirection * bulletSpeed;
        for (int i = 1; i < nBullets + 1; i++)
        {
            //first bullet
            //calculates the new rotation
            float nrotationZ = rotationZ + bulletAngle * i;
            //calculates the new x direction
            float xShootingDirection = Mathf.Cos(Mathf.Deg2Rad * (Mathf.Acos(shootingDirection.x) * Mathf.Rad2Deg - bulletAngle * i));
            //calculates the new y direction
            float yShootingDirection = Mathf.Sin(Mathf.Deg2Rad * (Mathf.Asin(shootingDirection.x) * Mathf.Rad2Deg - bulletAngle * i));
            //creates a vector with those 2 directions
            Vector2 nShootingDirection = new Vector2(xShootingDirection, yShootingDirection).normalized;
            //creates the bullet and rotates it
            bullet = Instantiate(bulletPrefab, transform.position, Quaternion.Euler(0, 0, nrotationZ));
            //gets the rigidbody2d
            Brb = bullet.GetComponent<Rigidbody2D>();
            //modifies the velocity of the rigidbody to match his rotation
            Brb.velocity = nShootingDirection * bulletSpeed;

            //second bullet (same process as before)
            //calculates the new rotation
            nrotationZ = rotationZ - bulletAngle * i;
            //calculates the new x direction
            xShootingDirection = Mathf.Cos(Mathf.Deg2Rad * (Mathf.Acos(shootingDirection.x) * Mathf.Rad2Deg + bulletAngle * i));
            //calculates the new y direction
            yShootingDirection = Mathf.Sin(Mathf.Deg2Rad * (Mathf.Asin(shootingDirection.x) * Mathf.Rad2Deg + bulletAngle * i));
            //creates a vector with those 2 directions
            nShootingDirection = new Vector2(xShootingDirection, yShootingDirection).normalized;
            //creates the bullet and rotates it
            bullet = Instantiate(bulletPrefab, transform.position, Quaternion.Euler(0, 0, nrotationZ));
            //gets the rigidbody2d
            Brb = bullet.GetComponent<Rigidbody2D>();
            //modifies the velocity of the rigidbody to match his rotation
            Brb.velocity = nShootingDirection * bulletSpeed;
        }
    }
}
c# unity-game-engine 2d game-development
1个回答
0
投票

我建议使用而不是手动设置每个子弹的角度 像这样的:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyShotgunnerScript : MonoBehaviour
{
    [SerializeField] GameObject bulletPrefab;
    private GameObject player;
    [SerializeField] float bulletSpeed;
    [SerializeField] int nBullets;
    [SerializeField] float bulletAngle;
    [SerializeField] Vector2 shootingDirection;
    [SerializeField] float rotationZ;
    private GameObject bullet;
    private Rigidbody2D Brb;
    // Start is called before the first frame update
    void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        Shoot();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Shoot();
        }
    }
    private void Shoot()
    {
      
        shootingDirection = new Vector2(player.transform.position.x - transform.position.x, player.transform.position.y - transform.position.y).normalized;
        rotationZ = Mathf.Atan2(shootingDirection.y, shootingDirection.x) * Mathf.Rad2Deg;

        float startAngle = -bulletAngle / 2;
        float angleStep = bulletAngle / (nBullets - 1);

        for (int i = 0; i < nBullets; i++)
        {
            float angle = startAngle + angleStep * i + rotationZ;
            var rot = Quaternion.Euler(0,0,angle);
            var bullet = Instantiate(bulletPrefab)
            var shootDir = (Vector2)(rot * Vector2.Right);
            bullet.GetComponent<Rigidbody2D>().AddForce(shootDir * 5, ForceMode2D.Impulse);

        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.