0
\$\begingroup\$

I have a bug with the rotation of a gun object that follows the mouse position. It has issues when the parent object player rotates. Example:

Example of rotation error

The player has a gravity script to keep them aligned with the 'planet' as you walk around it. The gun is a child of the player, and it's supposed to always rotate to point at where the mouse is (sorry you can't see it in the gif). The gun normally flips itself at 90 and -90 (top and bottom), and flips the player to face the same side the mouse is on.

The problem is that the player rotates to stay aligned with the planet, but the 90 and -90 angles that the gun uses to decide whether to flip itself and the player of course don't rotate.

Here's my code for the gun:

  Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
  difference.Normalize();
  float rotationZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;

  float startRotation = rotationZ + offset;

  float shotRotation = startRotation + Random.Range(-scatter, scatter);

  transform.rotation = Quaternion.Euler(0f, 0f, startRotation);

  //Flip the gun at top and bottom
  if (rotationZ < -90 || rotationZ > 90)
  {
      if (player.transform.eulerAngles.y == 0)
      {
          transform.localRotation = Quaternion.Euler(180, 0, -rotationZ + offset);
      }
      else if (player.transform.eulerAngles.y == 180)
      {
          transform.localRotation = Quaternion.Euler(180, 180, -rotationZ + offset);
      }
  }

  //Use gun rotation to set player direction
  //left
  if (rotationZ >= -90f || rotationZ <= 90f)
  {
      animator.SetFloat("Vertical", 0);
      animator.SetFloat("Horizontal", -1);
  }
  //right
  if (rotationZ <= -90f || rotationZ >= 90f)
  {
      animator.SetFloat("Vertical", 0);
      animator.SetFloat("Horizontal", 1);
  }
\$\endgroup\$
0
\$\begingroup\$

I think you can simplify this pretty massively. No trigonometry or angle calculations required.

// Point my gun's right vector in the direction of "difference" in world space,
// adjusting as needed for the parent's orientation.
transform.right = difference;

// This cross product gives us the direction to the right of the character,
// even if you've flipped them around to face left.
Vector3 playerRight = Vector3.Cross(player.transform.up, Vector3.forward);

// Detect whether this points the gun to the left side of the player character.
bool facingLeft = Vector3.Dot(difference, playerRight) < 0f;

// If so, flip the gun sprite vertically, so it doesn't look upside-down.
// (This replaces the 180 degree pitch you were using earlier).
gunSprite.flipY = facingLeft;

// Set animator variables accordingly.
animator.SetFloat("Vertical", 0);
animator.SetFloat("Horizontal", facingLeft ? -1 : 1);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.