我知道这个问题已经在其他帖子中解决了,比如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;
}
}
}
我建议使用而不是手动设置每个子弹的角度 像这样的:
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);
}
}
}