UNITY - 朝枪所面对的方向发射炮弹
UNITY - Shoot Projectile on the direction of where the gun is facing
我有一把枪,它会产生一个弹丸,该弹丸会反弹对撞机(Ricochet)。它应该是朝着枪所面对的方向射击,但我得到的是弹丸总是向右向上 45 度射击,我知道这是因为我不断声明的矢量 2.
我试过使用 Vector2.up 但它阻止弹丸产生跳弹效果,因为它总是想向上移动。
我应该如何实施这些东西?我只希望射弹射向我的枪所面对的方向并在对撞机上弹跳。顺便说一句,这是一款 2D 游戏。我在下面附上了我的代码,所以你可以看到。谢谢!
射弹脚本:
private Rigidbody2D rb;
public static bool canMove = true;
void Start()
{
rb = GetComponent<Rigidbody2D>();
rb.velocity = new Vector2(10f, 10f);
}
void Update()
{
//transform.Translate(Vector2.up * speed * Time.deltaTime);
if (canMove)
{
rb.isKinematic = false;
}
else if (!canMove)
{
rb.isKinematic = true;
}
}
枪脚本:
float offset = -90f;
public GameObject projectile;
public Transform shotPoint;
public GameObject child;
void Start()
{
}
void Update()
{
Vector3 diff = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float rotZ = Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset);
if (Input.GetMouseButtonDown(0))
{
Instantiate(projectile, shotPoint.position, transform.rotation);
Projectile.canMove = true;
}
}
因为你告诉它这样做。
rb.velocity = new Vector2(10f, 10f);
向右 10 个,向上 10 个。
除非你的射弹有一个恒定的力作用于它,就像导弹一样,在射弹脚本中去掉所有与力或速度相关的东西。对你没有好处。
然后,在 gun 脚本上:
//...
if (Input.GetMouseButtonDown(0)) {
var projectileInstance = Instantiate(projectile, shotPoint.position, transform.rotation);
var rigidbody = projectileInstance.GetComponent<Rigidbody2D>();
rigidbody.velocity = transform.TransformDirection(yourDirectionVector);
Projectile.canMove = true;
}
其中 Transform.TransformDirection
是使 yourDirectionVector
相对于枪的方向转换为相对于世界的方向-space.
Rigodbody.velocity
在世界-Space坐标中。
当你传入时
rb.velocity = new Vector2(10f, 10f);
它将进入世界 space X 方向 10 个,Y 方向 10 个。
为了将其作为局部坐标传递,您不能总是依赖 Tramsform.InverseTransformDirection
作为 ,因为 Transform
组件。在这种特定情况下,它可能会起作用,但通常您在 FixedUpdate
中设置速度,而在那一刻 Transform
组件可能尚未更新!
但是 Rigidbody2D
组件通常可以使用 Rigidbody2D.GetRelativeVector
将相对于刚体的局部向量转换为世界坐标:
// Might also be Vector.up depending on your setup
rb.velocity = rb.GetRelativeVector(Vector2.right * speed);
注意:最好自己做
[SerializeField] private Rigidbody2D rb;
并且已经通过 Inspector 引用了它。然后你就可以摆脱昂贵的 GetComponent
电话。
我有一把枪,它会产生一个弹丸,该弹丸会反弹对撞机(Ricochet)。它应该是朝着枪所面对的方向射击,但我得到的是弹丸总是向右向上 45 度射击,我知道这是因为我不断声明的矢量 2.
我试过使用 Vector2.up 但它阻止弹丸产生跳弹效果,因为它总是想向上移动。
我应该如何实施这些东西?我只希望射弹射向我的枪所面对的方向并在对撞机上弹跳。顺便说一句,这是一款 2D 游戏。我在下面附上了我的代码,所以你可以看到。谢谢!
射弹脚本:
private Rigidbody2D rb;
public static bool canMove = true;
void Start()
{
rb = GetComponent<Rigidbody2D>();
rb.velocity = new Vector2(10f, 10f);
}
void Update()
{
//transform.Translate(Vector2.up * speed * Time.deltaTime);
if (canMove)
{
rb.isKinematic = false;
}
else if (!canMove)
{
rb.isKinematic = true;
}
}
枪脚本:
float offset = -90f;
public GameObject projectile;
public Transform shotPoint;
public GameObject child;
void Start()
{
}
void Update()
{
Vector3 diff = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float rotZ = Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset);
if (Input.GetMouseButtonDown(0))
{
Instantiate(projectile, shotPoint.position, transform.rotation);
Projectile.canMove = true;
}
}
因为你告诉它这样做。
rb.velocity = new Vector2(10f, 10f);
向右 10 个,向上 10 个。
除非你的射弹有一个恒定的力作用于它,就像导弹一样,在射弹脚本中去掉所有与力或速度相关的东西。对你没有好处。
然后,在 gun 脚本上:
//...
if (Input.GetMouseButtonDown(0)) {
var projectileInstance = Instantiate(projectile, shotPoint.position, transform.rotation);
var rigidbody = projectileInstance.GetComponent<Rigidbody2D>();
rigidbody.velocity = transform.TransformDirection(yourDirectionVector);
Projectile.canMove = true;
}
其中 Transform.TransformDirection
是使 yourDirectionVector
相对于枪的方向转换为相对于世界的方向-space.
Rigodbody.velocity
在世界-Space坐标中。
当你传入时
rb.velocity = new Vector2(10f, 10f);
它将进入世界 space X 方向 10 个,Y 方向 10 个。
为了将其作为局部坐标传递,您不能总是依赖 Tramsform.InverseTransformDirection
作为 Transform
组件。在这种特定情况下,它可能会起作用,但通常您在 FixedUpdate
中设置速度,而在那一刻 Transform
组件可能尚未更新!
但是 Rigidbody2D
组件通常可以使用 Rigidbody2D.GetRelativeVector
将相对于刚体的局部向量转换为世界坐标:
// Might also be Vector.up depending on your setup
rb.velocity = rb.GetRelativeVector(Vector2.right * speed);
注意:最好自己做
[SerializeField] private Rigidbody2D rb;
并且已经通过 Inspector 引用了它。然后你就可以摆脱昂贵的 GetComponent
电话。