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 Stop enforcing transform.rotation once target is reached.

Discussion in 'Scripting' started by IAmScoops, Jun 29, 2023.

  1. IAmScoops

    IAmScoops

    Joined:
    May 16, 2021
    Posts:
    9
    I'm attempting to code some rotation controls for a camera (Cam sits at a set position looking down at player, and is able to orbit ONLY on the Y-Axis0

    Currently this is done using Cinemachine and an empty game object that follows the player around. The camera is set as a child of this empty game object (this allows the player to rotate separately from the camera and vice-versa.) I've accomplished smooth camera rotation using the E and Q buttons, however I'm also attempting to add controls that rotates the camera to the nearest 45 degree angle (clockwise or counter clockwise depending on input) which I've successfully accomplished using eulerAngles, Mathf, and a Quaternion.Slerp however this is presenting a unique issue now.

    The camera will rotate to the desired 45* angle when I press the J and K keys, however if I were then try to rotate the camera using E or Q, it will move a bit then slide back to the previous 45* angle.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class orbMovement : MonoBehaviour
    6. {
    7.     public Transform objectToFollow;
    8.     public Transform self;
    9.     public Vector3 offset;
    10.     private float rotSpeed = 0f;
    11.     public float rotVar = 100f;
    12.     private float eights;
    13.     public float cornerRot;
    14.  
    15.  
    16.  
    17.     void Update()
    18.     {
    19.         if (Input.GetKeyDown(KeyCode.E) | Input.GetKeyUp(KeyCode.Q))
    20.         {
    21.             rotSpeed += rotVar;
    22.         }
    23.         if (Input.GetKeyUp(KeyCode.E) | Input.GetKeyDown(KeyCode.Q))
    24.         {
    25.             rotSpeed -= rotVar;
    26.         }
    27.  
    28.  
    29.         if (Input.GetKeyDown(KeyCode.K))
    30.         {
    31.             eights = self.eulerAngles.y;
    32.             eights += 45;
    33.             eights = (eights / 45);
    34.             eights = Mathf.Round(eights);
    35.             eights = ((Mathf.Floor(eights)) * 45);
    36.         }
    37.         if (Input.GetKeyDown(KeyCode.J))
    38.         {
    39.             eights = self.eulerAngles.y;
    40.             eights -= 45;
    41.             eights = (eights / 45);
    42.             eights = Mathf.Round(eights);
    43.             eights = ((Mathf.Ceil(eights)) * 45);
    44.         }
    45.  
    46.         transform.position = objectToFollow.position + offset;
    47.         transform.Rotate(0, Time.deltaTime * rotSpeed, 0);
    48.  
    49.         Quaternion start = transform.rotation;
    50.  
    51.         transform.rotation = Quaternion.Slerp(start, Quaternion.Euler(0, eights, 0), Time.deltaTime * cornerRot);
    52.  
    53.  
    54.  
    55.     }
    56.  
    57.  
    58. }
    Here's my current code (yes I know it needs some cleaning up, I plan to do so once I have a working system).

    So my ultimate question is as followes, how can use this system, but still allow smooth camera rotation with Q and E while also allowing smooth turns to nearest 45 degree angle.
     
  2. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    1,111
    You have two things fighting for control over the rotation
    transform.Rotate
    and transform.rotation.
    Not sure if this meets your criteria (I know too little about how you want that movement to behave), but try this:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class OrbMovement : MonoBehaviour
    4. {
    5.     [Header("Refs")]
    6.     public Transform ObjectToFollow;
    7.     public Transform Self;
    8.     public Vector3 Offset;
    9.  
    10.     [Header("Rotation Speed (in deg per sec)")]
    11.     public float RotationSpeed = 90f;
    12.     [Range(1f, 60f)]
    13.     public float LerpDelay = 50f;
    14.  
    15.     private float _targetAngle = 0f;
    16.  
    17.     void Update()
    18.     {
    19.         if (Input.GetKey(KeyCode.E) )
    20.         {
    21.             _targetAngle += RotationSpeed * Time.deltaTime;
    22.         }
    23.  
    24.         if (Input.GetKey(KeyCode.Q))
    25.         {
    26.             _targetAngle -= RotationSpeed * Time.deltaTime;
    27.         }
    28.  
    29.         float cornerDisplacement = 0f;
    30.         if (Input.GetKeyDown(KeyCode.K))
    31.         {
    32.             cornerDisplacement += 1f;
    33.         }
    34.         if (Input.GetKeyDown(KeyCode.J))
    35.         {
    36.             cornerDisplacement -= 1f;
    37.         }
    38.  
    39.         // Snap the targetAngle to the next 45 degree angle
    40.         if (!Mathf.Approximately(cornerDisplacement, 0f))
    41.         {
    42.             _targetAngle = _targetAngle / 45f;
    43.             _targetAngle = Mathf.Round(_targetAngle + cornerDisplacement) * 45f;
    44.         }
    45.  
    46.         // Update rotation
    47.         _targetAngle %= 360f;
    48.         float t = 1f / LerpDelay;
    49.         float deltaAngle = Mathf.DeltaAngle(transform.rotation.eulerAngles.y, _targetAngle) * t;
    50.         transform.Rotate(Vector3.up, deltaAngle, Space.Self);
    51.  
    52.         // Update position
    53.         transform.position = ObjectToFollow.position + Offset;
    54.     }
    55.  
    56.  
    57.     // A little trick to prefill "self" ;)
    58. #if UNITY_EDITOR
    59.     public void Reset()
    60.     {
    61.         if (Self == null)
    62.             Self = transform;
    63.     }
    64. #endif
    65.  
    66. }
    67.  
     
    Last edited: Jun 29, 2023
  3. IAmScoops

    IAmScoops

    Joined:
    May 16, 2021
    Posts:
    9
    I've lost access to my main workstation and stuck on a very old laptop (luckily I always set up remote projects ;P ) so I've only got to test this now that I've gotten everything set up. It works perfectly, AND this gives me something to do while I wait to get access to my main computer as I can spend time studying your code to better understand how to approach this in the future! Cheers!
     
    _geo__ likes this.