翻转角色时,角色武器的旋转向后

When fliping the character the rotation of character's weapon goes backward

我在场景中有两个游戏对象,1.Character(Parent Object) 和 2.Weapon(Child Object)。问题是当角色向右移动时,武器的旋转很好,它朝向角色面向的方向并按预期旋转,正如您在下面的 Gif 图像中看到的那样。但是,当我向左翻转时,一切都出错了,武器向后移动,当我按下箭头时,旋转上升,当按下向上箭头时,旋转下降,请参见下面的 Gif 图像。请帮助如何修复它。

这是我的代码:

 public float weaponRotationSpeed = 13f;

 private Animator anim;
 private float angle;

 void Awake()
 {
     anim = GetComponent<Animator>();
 }

 void Update()
 {
     Vector2 hv = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
     Vector3 changeParentScale = transform.localScale;

     if (hv != Vector2.zero)
     {
         if (Input.GetAxis("Horizontal") < 0)
         {
             changeParentScale.x = -5f;
             transform.localScale = changeParentScale;
         }
         else if (Input.GetAxis("Horizontal") > 0)
         {
             changeParentScale.x = 5f;
             transform.localScale = changeParentScale;
         }


         angle = Mathf.Atan2(hv.y, hv.x) * Mathf.Rad2Deg;

         transform.Find("Weapon").rotation = Quaternion.Lerp(transform.Find("Weapon").rotation,
             Quaternion.Euler(0, 0, angle),
             weaponRotationSpeed * Time.deltaTime);

         anim.SetBool("isRunning", true);
     }
     else
     {
         anim.SetBool("isRunning", false);
     }

那么你可能也想翻转旋转?例如。使用 Mathf.Sign

Quaternion.Euler(0,0, angle * Mathf.Sign(changeParentScale.x))

您的代码中还有其他一些小缺陷!

  • 你不应该使用 Find 每一帧.. 而是存储它 一次
  • 您正在重复使用 GetAxis 并且第一次也应该存储值.. 您不是已经在 hv 中有了它们吗?
  • Lerp 是一个很酷的工具,但你用错了 ;) 它使用给定的因子对每一帧进行插值。通常你想要一个固定的,例如0.5f 且未使用 Time.deltaTime

它可能更像是

 // You will have to adjust this value again
 // This needs to be a constant value between 0 and 1
 //  - 0: rotation isn't updated at all
 //  - 1: rotation immediately jumps to target
 //  - e.g. 0.5f: rotation is every frame set to the middle between current and target
 [Range(0f, 1f)]
 public float weaponRotationSpeed = 0.5f;

 // already reference these via the Inspector
 [SerializeField] private Animator anim;
 [SerializeField] private Transform weapon;
 private float angle;

 // As Fallback get them ONCE on runtime
 void Awake()
 {
     if(!anim) anim = GetComponent<Animator>();
     if(!weapon) weapon = transform.Find("Weapon");
 }

 void Update()
 {
     Vector2 hv = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
     Vector3 changeParentScale = transform.localScale;

     if (hv != Vector2.zero)
     {
         // get direction of Horizontal
         int sign = Mathf.Sign(hv.x);

         if (!Mathf.Approximately(hv.x, 0))
         {
             changeParentScale.x = 5f * sign;
             transform.localScale = changeParentScale;
         }

         angle = Mathf.Atan2(hv.y, hv.x) * Mathf.Rad2Deg;

         weapon.rotation = Quaternion.Lerp(weapon.rotation, Quaternion.Euler(0, 0, angle * sign), weaponRotationSpeed);

         anim.SetBool("isRunning", true);
     }
     else
     {
         anim.SetBool("isRunning", false);
     }
 }

或者你也可以通过不使用 rotation 而使用 localRotation 来旋转武器来解决它。