Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to force the player character into a rotation (respawn)

Discussion in 'Scripting' started by cbfunky, Oct 1, 2020.

  1. cbfunky

    cbfunky

    Joined:
    Sep 11, 2020
    Posts:
    24
    I have a seemingly simple scenario: when the player dies, move the player object to the spawn point and rotate it in the spawn point direction. I get the teleport to the point fine, but I just can't get the rotation part to work.

    Looking for solutions online I came across simply assigning the transform.rotation to the spawnpoint.rotation (which does nothing) or using LookAt (if I use this the camera just starts spinning uncontrollably without any input). I messed around with the eulerAngles, created manual vectors, nothing seems to work.

    I use a Character Controller, could this be the reason? The movement code is largely from a tutorial, my additions are everything related to "respawn".

    The parts around respawn rotation look like this in my script (full code below):
    Code (CSharp):
    1. if (m_Respawn)
    2.             {
    3.                 CameraPosition.transform.eulerAngles = RespawnPoint.eulerAngles;
    4.             }
    5.             else CameraPosition.transform.localEulerAngles = currentAngles;
    6.  
    7.             if (m_Respawn)
    8.             {
    9.                 //transform.LookAt(RespawnPoint.forward * 3);
    10.                 //CameraPosition.transform.LookAt(RespawnPoint.forward * 3);
    11.                 transform.rotation = RespawnPoint.rotation;
    12.                 m_CharacterController.Move(new Vector3(0,0,0));
    13.             }
    (the second part here looks a bit messy because I kept adding and changing things around - this is just the latest iteration of the code, also not working)


    ----
    Full code (this is on the player object):

    Movement: lines 125-133
    Rotation/turning: lines 136-177

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Collections.Specialized;
    4. using System.Net.Mime;
    5. using UnityEngine;
    6. #if UNITY_EDITOR
    7. using UnityEditor;
    8. #endif
    9.  
    10. public class Controller : MonoBehaviour
    11. {
    12.     //Urg that's ugly, maybe find a better way
    13.     public static Controller Instance { get; protected set; }
    14.  
    15.     public Camera MainCamera;
    16.     public Transform CameraPosition;
    17.     public Transform RespawnPoint;
    18.  
    19.     [Header("Control Settings")]
    20.     public float MouseSensitivity = 10.0f;
    21.     public float PlayerSpeed = 5.0f;
    22.     public float RunningSpeed = 7.0f;
    23.     public float JumpSpeed = 5.0f;
    24.      
    25.     public float Speed { get; private set; } = 0.0f;
    26.     public bool LockControl { get; set; }
    27.     public bool CanPause { get; set; } = true;
    28.     public bool Grounded => m_Grounded;
    29.  
    30.     //private
    31.     float m_VerticalSpeed = 0.0f;
    32.     float m_GroundedTimer;
    33.     float m_SpeedAtJump = 0.0f;
    34.     float m_VerticalAngle, m_HorizontalAngle;
    35.     bool m_Grounded;
    36.     bool m_IsPaused = false;
    37.     bool m_Respawn = false;
    38.     CharacterController m_CharacterController;
    39.  
    40.     void Awake()
    41.     {
    42.         Instance = this;
    43.     }
    44.  
    45.     public void Respawn(Transform m_playerSpawn)
    46.     {
    47.         m_Respawn = true;
    48.         print("respawn");
    49.     }
    50.  
    51.     void Start()
    52.     {
    53.         Cursor.lockState = CursorLockMode.Locked;
    54.         Cursor.visible = false;
    55.  
    56.         m_IsPaused = false;
    57.         m_Grounded = true;
    58.  
    59.         MainCamera.transform.SetParent(CameraPosition, false);
    60.         MainCamera.transform.localPosition = Vector3.zero;
    61.         MainCamera.transform.localRotation = Quaternion.identity;
    62.         m_CharacterController = GetComponent<CharacterController>();
    63.  
    64.         m_VerticalAngle = 0.0f;
    65.         m_HorizontalAngle = transform.localEulerAngles.y;
    66.     }
    67.  
    68.     void Update()
    69.     {
    70.         /*
    71.         if (CanPause && Input.GetButtonDown("Menu"))
    72.         {
    73.             PauseMenu.Instance.Display();
    74.         }
    75.  
    76.         FullscreenMap.Instance.gameObject.SetActive(Input.GetButton("Map"));
    77.         */
    78.  
    79.         bool wasGrounded = m_Grounded;
    80.         bool loosedGrounding = false;
    81.  
    82.         //we define our own grounded and not use the Character controller one as the character controller can flicker
    83.         //between grounded/not grounded on small step and the like. So we actually make the controller "not grounded" only
    84.         //if the character controller reported not being grounded for at least .5 second;
    85.         if (!m_CharacterController.isGrounded)
    86.         {
    87.             if (m_Grounded)
    88.             {
    89.                 m_GroundedTimer += Time.deltaTime;
    90.                 if (m_GroundedTimer >= 0.5f)
    91.                 {
    92.                     loosedGrounding = true;
    93.                     m_Grounded = false;
    94.                 }
    95.             }
    96.         }
    97.         else
    98.         {
    99.             m_GroundedTimer = 0.0f;
    100.             m_Grounded = true;
    101.         }
    102.  
    103.         Speed = 0;
    104.         Vector3 move = Vector3.zero;
    105.         if (!m_IsPaused && !LockControl)
    106.         {
    107.             // Jump (we do it first as
    108.             if (m_Grounded && Input.GetButtonDown("Jump"))
    109.             {
    110.                 m_VerticalSpeed = JumpSpeed;
    111.                 m_Grounded = false;
    112.                 loosedGrounding = true;
    113.                 //FootstepPlayer.PlayClip(JumpingAudioCLip, 0.8f, 1.1f);
    114.             }
    115.  
    116.             bool running = Input.GetButton("Run");
    117.             float actualSpeed = running ? RunningSpeed : PlayerSpeed;
    118.  
    119.             if (loosedGrounding)
    120.             {
    121.                 m_SpeedAtJump = actualSpeed;
    122.             }
    123.  
    124.  
    125.             // Move around with WASD
    126.             move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
    127.             if (move.sqrMagnitude > 1.0f) move.Normalize();
    128.             float usedSpeed = m_Grounded ? actualSpeed : m_SpeedAtJump;
    129.          
    130.             move = move * usedSpeed * Time.deltaTime;
    131.          
    132.             move = transform.TransformDirection(move);
    133.             m_CharacterController.Move(move);
    134.  
    135.  
    136.             // Turn player
    137.             float turnPlayer = Input.GetAxis("Mouse X") * MouseSensitivity;
    138.             m_HorizontalAngle = m_HorizontalAngle + turnPlayer;
    139.  
    140.             if (m_HorizontalAngle > 360) m_HorizontalAngle -= 360.0f;
    141.             if (m_HorizontalAngle < 0) m_HorizontalAngle += 360.0f;
    142.  
    143.             Vector3 currentAngles = transform.localEulerAngles;
    144.             currentAngles.y = m_HorizontalAngle;
    145.  
    146.             if (m_Respawn) transform.eulerAngles = RespawnPoint.eulerAngles;
    147.             else transform.localEulerAngles = currentAngles;
    148.  
    149.  
    150.             // Camera look up/down
    151.             var turnCam = -Input.GetAxis("Mouse Y") * MouseSensitivity;
    152.             m_VerticalAngle = Mathf.Clamp(turnCam + m_VerticalAngle, -89.0f, 89.0f);
    153.             currentAngles = CameraPosition.transform.localEulerAngles;
    154.             currentAngles.x = m_VerticalAngle;
    155.             CameraPosition.transform.localEulerAngles = m_Respawn ? RespawnPoint.localEulerAngles : currentAngles;
    156.  
    157.             if (m_Respawn)
    158.             {
    159.                 CameraPosition.transform.eulerAngles = RespawnPoint.eulerAngles;
    160.             }
    161.             else CameraPosition.transform.localEulerAngles = currentAngles;
    162.  
    163.             ///*
    164.             if (m_Respawn)
    165.             {
    166.                 //transform.LookAt(RespawnPoint.forward * 3);
    167.                 //CameraPosition.transform.LookAt(RespawnPoint.forward * 3);
    168.                 transform.rotation = RespawnPoint.rotation;
    169.                 m_CharacterController.Move(new Vector3(0,0,0));
    170.             }
    171.             //*/
    172.  
    173.             Speed = move.magnitude / (PlayerSpeed * Time.deltaTime);
    174.  
    175.             //done with changes related to respawning
    176.             m_Respawn = false;
    177.         }
    178.  
    179.         // Fall down / gravity
    180.         m_VerticalSpeed = m_VerticalSpeed - 10.0f * Time.deltaTime;
    181.         if (m_VerticalSpeed < -10.0f) m_VerticalSpeed = -10.0f; // max fall speed
    182.         var verticalMove = new Vector3(0, m_VerticalSpeed * Time.deltaTime, 0);
    183.         var flag = m_CharacterController.Move(verticalMove);
    184.         if ((flag & CollisionFlags.Below) != 0)
    185.             m_VerticalSpeed = 0;
    186.  
    187.         if (!wasGrounded && m_Grounded)
    188.         {
    189.             //FootstepPlayer.PlayClip(LandingAudioClip, 0.8f, 1.1f);
    190.         }
    191.     }
    192.  
    193.     public void DisplayCursor(bool display)
    194.     {
    195.         m_IsPaused = display;
    196.         Cursor.lockState = display ? CursorLockMode.None : CursorLockMode.Locked;
    197.         Cursor.visible = display;
    198.     }
    199. }
    200.  
     
    Last edited: Oct 2, 2020
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,741
    On line 144 you overwrite the Y rotation with m_HorizontalAngle. Yes that one line doesn't happen on the frame you're respawning, but m_HorizontalAngle's value is still there. No matter what you set your rotation to one frame, the next frame, m_HorizontalAngle takes over. You have to reset that value when you reset your rotation.
     
    Joe-Censored and cbfunky like this.
  3. cbfunky

    cbfunky

    Joined:
    Sep 11, 2020
    Posts:
    24
    You're absolutely right. I stuck that line in the next if-!respawn check - however the problem still persists. It's not just the y angle - if I look at the sky, it also doesn't change.

    I also want to add that I'm currently also playing around with making player ghosts (i.e. an object that repeats your movement/actions) and setting rotation on the ghost works totally fine (which once again makes me think the Character Controller is somehow overriding it?)
     
  4. cbfunky

    cbfunky

    Joined:
    Sep 11, 2020
    Posts:
    24
    I want to add a more extensive list of things I've tried (this time commented out instead of replaced).

    Have not come any closer to finding a solution. Sorry for the bad formatting, couldn't manage to get it in line...

    Code (CSharp):
    1. //transform.eulerAngles = RespawnPoint.eulerAngles;                                         // <<< does nothing
    2. //transform.eulerAngles = new Vector3(0,0,3);                                             // <<< does nothing
    3. //transform.eulerAngles = new Vector3(0, 90, 0);                                         // <<< does nothing
    4. //CameraPosition.transform.eulerAngles = RespawnPoint.eulerAngles;     // <<< does nothing
    5. //CameraPosition.transform.eulerAngles = new Vector3(0,0,3);                  // <<< does nothing
    6. //CameraPosition.transform.eulerAngles = new Vector3(0,90,0);                // <<< makes the camera wobbly like SetLookRotation
    7.  
    8. //transform.LookAt(RespawnPoint.forward * 3);                                          // <<< makes the camera wobbly from then on (not just once)
    9. //CameraPosition.transform.LookAt(RespawnPoint.forward * 3);               // <<< does nothing
    10.  
    11. //transform.rotation.SetLookRotation(RespawnPoint.forward * 3);             // <<< makes the camera wobbly from then on, but different from the one above
    12.  
    13. //CameraPosition.transform.rotation = Quaternion.LookRotation(RespawnPoint.forward * 3);   // <<< does nothing
    14.  
    15. /*
    16. Quaternion rot = new Quaternion();                              //
    17. rot.SetLookRotation(RespawnPoint.forward * 3);        // <<< found this on unity answers but also does nothing
    18. transform.rotation = rot;                                               //
    19. */
    20.  
    21. //transform.rotation = Quaternion.Euler(0,90,0);                               // <<< does nothing
    22. //CameraPosition.transform.rotation = Quaternion.Euler(0,90,0);   // <<< does nothing