Search Unity

Reorient movement relative to camera upon player stopping.

Discussion in 'Scripting' started by Anthony0506, May 11, 2018.

  1. Anthony0506

    Anthony0506

    Joined:
    Jan 2, 2018
    Posts:
    22
    Hi. I've got a top down camera that rotates upon key press. also have the movement reorient to camera upon rotation, but I can't figure out how to make this only occur if the player is stationary. if i'm moving, and i rotate the camera, I don't want the players movement to be affected by the camera rotation, but when he stops, i want the movement orientation to reset so that up is up, and down is down. i've tried adding bools to check if movement was occurring and disabling it then, but it doesn't work.

    does anyone have any ideas how I would go about doing this? I can restate if i'm not being clear about what I need help with, but I think it's understandable.

    Code (CSharp):
    1.    
    2.  
    3. using UnityEngine;
    4. {
    5.     [RequireComponent(typeof(Rigidbody))]
    6.     [RequireComponent(typeof(Collider))]
    7.     public class PlayerController : MonoBehaviour
    8.     {    public bool canMove = true;
    9.         private Transform camTransform;
    10.         public Vector3 MoveVector{ set; get;}
    11.         public float walkSpeed;
    12.         public bool IsMoving;
    13.         void Start()
    14.         {
    15.             rb = transform.GetComponent<Rigidbody>();
    16.         }
    17.         void FixedUpdate()
    18.         {
    19.             MoveVector = PoolInput ();
    20.             MoveVector = RotateWithView ();
    21.             Move ();
    22.         }
    23.         private Vector3 PoolInput () {
    24.             Vector3 direction = Vector3.zero;
    25.             direction.x = Input.GetAxis ("Horizontal");
    26.             direction.z = Input.GetAxis ("Vertical");
    27.             IsMoving = direction.x != 0 || direction.z != 0;
    28.             if (direction.magnitude > 1)
    29.                 direction.Normalize ();
    30.             return direction;
    31.         }
    32.         void Move ()
    33.         {
    34.             if (canMove == false) {
    35.                 float Speed = walkSpeed;
    36.                 MoveVector *= (Speed / 10f);
    37.                 var rot = MoveVector * (Speed / 10);
    38.                 if (/*attackTimer <= 0 && */MoveVector != Vector3.zero)
    39.                 {
    40.                     var newRotation = Quaternion.LookRotation(rot);
    41.                     rb.rotation = Quaternion.RotateTowards(transform.rotation, newRotation, 33f);
    42.                 }
    43.                 Vector3 characterMovement = transform.position + MoveVector;
    44.                     rb.MovePosition (characterMovement);
    45.             }
    46.         }
    47.         private Vector3 RotateWithView ()
    48.         {
    49.             if (camTransform != null) {
    50.                 Vector3 direction = camTransform.TransformDirection (MoveVector);
    51.                 direction.Set (direction.x, 0f, direction.z);
    52.                 return direction.normalized * MoveVector.magnitude;
    53.             }
    54.             else {
    55.                 camTransform = Camera.main.transform;
    56.                 return MoveVector;
    57.             }
    58.         }}
    59.  
    60.  
    61.  
    62.  




    i asked on unity questions, but then i rewrote the script hoping I could fix it to no avail. if you want to look at the previous script https://answers.unity.com/questions/1505058/how-can-i-make-movement-relative-to-camera-only-af.html. it's exactly the same effect, but this version is split into different functions. i was hoping I could just not call the rotate fix while moving, but it still didn't work.
     
    Last edited: May 11, 2018
  2. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    So when the player is stationary and you rotate, you want the player and camera to rotate (meaning the player continues to look towards the top of the screen).

    When the player is moving and you rotate, the player continues along their 'forward' path (i.e. does not rotate) but the camera rotates accordingly. As soon as you stop rotating, the camera returns to the players orientation so they face towards the top of the screen again.

    Is that right?
     
  3. Anthony0506

    Anthony0506

    Joined:
    Jan 2, 2018
    Posts:
    22
    When the player is stationary and the camera rotates, I want the camera to rotate, the player not to rotate, but the input, were I to press up, to make the player go up. this is as it is now.


    your second paragraph is correct
    when the player is moving and i rotate, i want the player to not rotate, but the camera to rotate.

    i should mention that this is all being applied to a billboarded sprite, however when the camera is rotated the rigidbody doesn't rotate unless it's moving, so it shouldnt make a difference.

    if you were to attach the above script to a cube and and hold W while rotating the camera, the cube wouldnt stay on a straight path, it would veer, which I want to prevent. however, once the cube becomes stationary, I want the controls to re-orient to W being up if the camera were to stay stationary.
     
    Last edited: May 12, 2018
  4. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    You could parent the camera GameObject to the player (i.e. player is parent, camera is child).

    Now when the player is stationary and you rotate the player, the camera will rotate in unison.

    Whilst walking, however, then when rotating you would only rotate the child camera. This would mean that the parent player would continue with its orientation untouched.

    So now, if the player is stationary and the camera is rotated, then when pressing 'W' to move forward, you would first need to set the player rotation to be that of the camera and then realign the camera back to the parent.
     
  5. Anthony0506

    Anthony0506

    Joined:
    Jan 2, 2018
    Posts:
    22
    I dont want the camera to rotate with the player when stationary. its a fixed camera that follows the player and can be rotated at 90 degree intervals pointing down at a 30 degree rotation. think like an old SNES game where you're in the center of the screen, but it also rotates if you press a button. it's locked to different views, not floaty. I have the camera targetting an empty that is set to the players position at every frame, and can be switched to different objects to change the focus, which I can't deviate from.

    i feel like theres just a couple lines of code I can't figure out to make this work. when i try a bool for only calling rotate with view when it's not moving, then it just never calls it at all. i need it to only rotate with the view when the camera hasnt been rotated, but if it has been rotated, not to call it.

    its like... the controls are in reset to camera mode constantly which needs to happen to prevent vertical axis always being Z+ , and i need them to re-reset upon stopping, instead of just being set to the camera constantly.
     
    Last edited: May 12, 2018
  6. Anthony0506

    Anthony0506

    Joined:
    Jan 2, 2018
    Posts:
    22
    So I think i'm on the right track to fixing this, but I'm still having issues. I'm using cases to simulate "getaxisup" for horizontal and vertical, and adding a condition for whether or not to use the old camera orientation movement or new orientation movement, but it seems to mess with the players movement. it doesnt rotate freely now, it feels very sticky. i can't go from facing z to facing x in a fluent manner. does anyone have any idea where I'm going wrong? revised code is as follows...
    Code (CSharp):
    1. enum XAxisState
    2.     {
    3.         Idle,
    4.         Down,
    5.         Held,
    6.         Up
    7.     }
    8.  
    9.     enum YAxisState
    10.     {
    11.         Idle,
    12.         Down,
    13.         Held,
    14.         Up
    15.     }
    16.  
    17.     XAxisState XaxisState;
    18.     float XdeadZone = .00000001f;
    19.  
    20.     YAxisState YaxisState;
    21.     float YdeadZone = .00000001f;
    22.  
    23.  
    24.     void Start()
    25.     {
    26.         rb = transform.GetComponent<Rigidbody>();
    27.         pause = GetComponent <Pause> ();
    28.        
    29.  
    30.     }
    31.  
    32.  
    33.     void Update()
    34.     {
    35.         IsGrounded = Physics.Raycast(transform.position, -Vector3.up, distToGround + groundDistanceOffset);
    36.         HandleAttack();
    37.         HandleJump();
    38.         HandleClimb ();
    39.         switch ( XaxisState )
    40.         {
    41.         case XAxisState.Idle :
    42.             if ( Input.GetAxis( "Horizontal" ) < -XdeadZone || Input.GetAxis( "Horizontal" ) > XdeadZone )
    43.  
    44.  
    45.             {
    46.                 XaxisState = XAxisState.Down;
    47.             }
    48.             break;
    49.  
    50.         case XAxisState.Down :
    51.             XaxisState = XAxisState.Held;
    52.             break;
    53.  
    54.         case XAxisState.Held :
    55.             if ( Input.GetAxis( "Horizontal" ) > -XdeadZone && Input.GetAxis( "Horizontal" ) < XdeadZone )
    56.             {
    57.                 XaxisState = XAxisState.Up;
    58.             }
    59.             break;
    60.  
    61.         case XAxisState.Up :
    62.             XaxisState = XAxisState.Idle;
    63.             break;
    64.         }
    65.  
    66.  
    67.  
    68.  
    69.         switch ( YaxisState )
    70.         {
    71.         case YAxisState.Idle :
    72.             if ( Input.GetAxis( "Vertical" ) < -YdeadZone || Input.GetAxis( "Vertical" ) > YdeadZone)
    73.  
    74.  
    75.             {
    76.                 YaxisState = YAxisState.Down;
    77.             }
    78.             break;
    79.  
    80.         case YAxisState.Down :
    81.             YaxisState = YAxisState.Held;
    82.             break;
    83.  
    84.         case YAxisState.Held :
    85.             if ( Input.GetAxis( "Vertical" ) > -YdeadZone && Input.GetAxis( "Vertical" ) < YdeadZone)
    86.             {
    87.                 YaxisState = YAxisState.Up;
    88.             }
    89.             break;
    90.  
    91.         case YAxisState.Up :
    92.             YaxisState = YAxisState.Idle;
    93.             break;
    94.         }
    95.  
    96.  
    97.  
    98.  
    99.  
    100.  
    101.  
    102.  
    103.  
    104.  
    105.  
    106.  
    107.  
    108.  
    109.  
    110.  
    111.  
    112.  
    113.  
    114.  
    115.  
    116.         MoveVector = PoolInput ();
    117.         if ( XaxisState == XAxisState.Up  || YaxisState == YAxisState.Up) {
    118.             MoveVector = RotateWithView ();
    119.             fixrotation = true;
    120.         } else if (XaxisState == XAxisState.Down || XaxisState == XAxisState.Held || YaxisState == YAxisState.Down || YaxisState == YAxisState.Held){
    121.             MoveVector = FixedPreviousMoveVector;
    122.             fixrotation = false;
    123.         }
    124.  
    125.    
    126.     }
    127.  
    128.     void FixedUpdate()
    129.     {
    130.         Move ();
    131.     }
    132.  
    133.     private Vector3 PoolInput () {
    134.  
    135.         Vector3 direction = Vector3.zero;
    136.  
    137.         direction.x = Input.GetAxis ("Horizontal");
    138.         direction.z = Input.GetAxis("Vertical");
    139.         IsMoving = direction.x != 0 || direction.z != 0;
    140.  
    141.  
    142.         return direction;
    143.  
    144.     }
    145.  
    146.  
    147.     void Move ()
    148.     {
    149.         if (canMove && pause.paused == false) {
    150.             float Speed = walkSpeed;
    151.             MoveVector *= (Speed / 10f);
    152.  
    153.  
    154.  
    155.             Vector3 rot = MoveVector * (Speed / 10);
    156.             Vector3 rotb = FixedPreviousMoveVector * (Speed / 10);
    157.  
    158.             if (/*attackTimer <= 0 && */MoveVector != Vector3.zero && fixrotation == true)
    159.             {
    160.                 Quaternion newRotation = Quaternion.LookRotation(rot);
    161.                 rb.rotation = Quaternion.RotateTowards(transform.rotation, newRotation, 360f);
    162.             }
    163.  
    164.             else if  (/*attackTimer <= 0 && */MoveVector != Vector3.zero && fixrotation == false)
    165.             {
    166.                 Quaternion newRotation = Quaternion.LookRotation(rotb);
    167.                 rb.rotation = Quaternion.RotateTowards(transform.rotation, newRotation, 360f);
    168.             }
    169.  
    170.  
    171.  
    172.  
    173.  
    174.             Vector3 characterMovement = transform.position + MoveVector;
    175.             Vector3 characterMovementB = transform.position + FixedPreviousMoveVector;
    176.  
    177.             if (attackTimer <= 0 || !IsGrounded && fixrotation == true) {
    178.                 rb.MovePosition (characterMovement);
    179.             }
    180.  
    181.             else if (attackTimer <= 0 || !IsGrounded && fixrotation == false) {
    182.                 rb.MovePosition (characterMovementB);
    183.             }
    184.  
    185.  
    186.  
    187.         }
    188.     }
    189.  
    190.     private Vector3 RotateWithView ()
    191.     {
    192.  
    193.         if (camTransform != null) {
    194.             Vector3 direction = camTransform.TransformDirection (MoveVector);
    195.             direction.Set (direction.x, 0f, direction.z);
    196.             PreviousMoveVector =  direction.normalized * MoveVector.magnitude;
    197.             FixedPreviousMoveVector = PreviousMoveVector;
    198.  
    199.  
    200.             return direction.normalized * MoveVector.magnitude;
    201.  
    202.  
    203.         }
    204.  
    205.         else {
    206.  
    207.             camTransform = Camera.main.transform;
    208.             return MoveVector;
    209.  
    210.         }
    211.     }