Search Unity

Ignoring Parent rotation

Discussion in 'Scripting' started by dustypantz, Aug 10, 2019.

  1. dustypantz

    dustypantz

    Joined:
    Oct 30, 2013
    Posts:
    10
    Problem: While attaching (parenting) the player to a moving platform, the player would snap to the parent's rotation.
    Desire: I wanted the player to rotate independently from the platform.

    Attach script:
    Code (CSharp):
    1.  
    2. public class AttachPlayer : MonoBehaviour {
    3.   private void OnTriggerEnter(Collider other) {
    4.     if (other.CompareTag("Player")) {
    5.       other.transform.parent = transform;
    6.     }
    7.   }
    8.  
    9.   private void OnTriggerExit(Collider other) {
    10.     if (other.CompareTag("Player")) {
    11.       if (other.gameObject.transform.parent == transform) {
    12.         other.transform.parent = null;
    13.       }
    14.     }
    15.   }
    16. }
    Player rotation is handled from the MouseLook script from the Standard Assets' first person example. We have to remove the parent's rotation with Quaternion.Inverse() when attaching and add the rotation when detatching.

    Part of MouseLook:
    Code (CSharp):
    1. Quaternion? parentRotation = null;
    2.   bool isParented = false;
    3.  
    4.   public void Init(Transform character, Transform camera) {
    5.     m_CharacterTargetRot = character.localRotation;
    6.     m_CameraTargetRot = camera.localRotation;
    7.   }
    8.  
    9.   public void LookRotation(Transform character, Transform camera, float? x = null, float? y = null) {
    10.     if (!x.HasValue || !y.HasValue) {
    11.       x = Input.GetAxis("R_XAxis") > deadzone || Input.GetAxis("R_XAxis") < -deadzone ?
    12.         Input.GetAxis("R_XAxis") : 0;
    13.       y = Input.GetAxis("R_YAxis") > deadzone || Input.GetAxis("R_YAxis") < -deadzone ?
    14.         Input.GetAxis("R_YAxis") : 0;
    15.     }
    16.  
    17.     float yRot = x < 0 ? -(Mathf.Abs(Mathf.Pow(x.Value, RotPower) * XSensitivity)) : Mathf.Abs(Mathf.Pow(x.Value, RotPower) * XSensitivity);
    18.     float xRot = y < 0 ? -(Mathf.Abs(Mathf.Pow(y.Value, RotPower) * YSensitivity)) : Mathf.Abs(Mathf.Pow(y.Value, RotPower) * YSensitivity);
    19.  
    20.     if (!isVerticalActive) {
    21.       xRot = 0;
    22.     }
    23.  
    24.     m_CharacterTargetRot *= Quaternion.Euler(0f, yRot, 0f);
    25.     m_CameraTargetRot *= Quaternion.Euler(-xRot, 0f, 0f);
    26.  
    27.     if (character.parent != null && !isParented) {
    28.       // got a parent
    29.       isParented = true;
    30.       parentRotation = character.parent.rotation;
    31.       m_CharacterTargetRot *= Quaternion.Inverse(parentRotation.Value);
    32.     } else if (character.parent == null && parentRotation != null) {
    33.       // removed parent
    34.       m_CharacterTargetRot *= parentRotation.Value;
    35.       parentRotation = null;
    36.       isParented = false;
    37.     }
    38.  
    39.     if (clampVerticalRotation)
    40.       m_CameraTargetRot = ClampRotationAroundXAxis(m_CameraTargetRot);
    41.  
    42.     if (smooth) {
    43.       character.localRotation = Quaternion.Slerp(character.localRotation, m_CharacterTargetRot,
    44.         smoothTime * Time.deltaTime);
    45.       camera.localRotation = Quaternion.Slerp(camera.localRotation, m_CameraTargetRot,
    46.         smoothTime * Time.deltaTime);
    47.     } else {
    48.       character.localRotation = m_CharacterTargetRot;
    49.       camera.localRotation = m_CameraTargetRot;
    50.     }
    51.  
    52.     UpdateCursorLock();
    53.   }
    I had a bit of an issue with this so I hope it saves someone else some time.
     
  2. ismaelflorit

    ismaelflorit

    Joined:
    Apr 16, 2019
    Posts:
    38
    Hey,

    That's pretty cool, didn't know about Inverse().

    Out of curiosity, why did the player object have to be attached to the platform?
     
  3. dustypantz

    dustypantz

    Joined:
    Oct 30, 2013
    Posts:
    10
    The platform is moving. If the player is not parented, the player won't move with the platform. When moving to the side, the platform would move but the player wouldn't, and the player would have to walk with the platform or fall off. When moving up, the player had a chance that the platform's translation would clip the player's collider and drop through the platform.

    It doesn't have to be parented though. The same effect can be accomplished by applying the platform's translation to the player as well, but it is a quick fix just to parent.

    I just didn't realize at first that the rotation was affected too, until I changed one prefab and rotated it then the player was snapping 90 degrees entering the platform because of the parent. lol

    If you have or find a better / faster way to handle platforming, let me know. :)
     
    Last edited: Aug 10, 2019
  4. ismaelflorit

    ismaelflorit

    Joined:
    Apr 16, 2019
    Posts:
    38
    I would have gone with adding the platform's translation to the player whilst on the platform, but as always there's more than one way to solve things! Coding would be dull otherwise.

    Sounds like you have it sorted! Thanks for sharing.