UNITY-在枪支朝向的方向射击弹丸

时间:2019-09-16 23:17:21

标签: c# unity3d game-physics

我有一把枪,它会产生弹丸,该弹丸会撞到对撞机上(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;
    }
}

2 个答案:

答案 0 :(得分:1)

因为您正在告诉它这样做。

  

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.TransformDirectionyourDirectionVector的来源,#pragma once #ifndef VC_EXTRALEAN #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #endif // Modify the following defines if you have to target a platform prior to the ones specified below. // Refer to MSDN for the latest info on corresponding values for different platforms. #ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. #define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. #endif #ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. #define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. #endif #ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. #endif #ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. #define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. #endif #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit ...... 是相对于枪支的一个方向,可以转换为相对于世界空间的一个。

答案 1 :(得分:0)

Rigodbody.velocity世界空间坐标中。

传递时

rb.velocity = new Vector2(10f, 10f);

它将在X方向的世界空间10和Y方向的空间10中飞行。


通常,为了将其作为局部坐标传递,由于Tramsform.InverseTransformDirection组件,您不能总是将Transform视作suggested here。在这种特定情况下,它可能会起作用,但是通常您在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;

,并且已经通过检查器对其进行了引用。然后,您可以摆脱昂贵的GetComponent通话。