Search Unity

Bug Rotation not being affected globally until coroutine finishes

Discussion in 'Scripting' started by JevinLevin_, Feb 2, 2023.

  1. JevinLevin_

    JevinLevin_

    Joined:
    Jan 18, 2023
    Posts:
    10
    I have a dodge system in my 1st person game where pressing a key will dodge to the left and tilt the camera, however for some reason during the tilt if i move my mouse to adjust the camera during the tilt nothing happens, and it wont update until the tilt finishes. This happens with 2 different methods,

    Code (CSharp):
    1.     StartCoroutine(CameraTilt(dodgeDuration, Quaternion.Euler(0,0,19f)));
    2.  
    3.     IEnumerator CameraTilt(float duration, Quaternion tilt)
    4.     {
    5.         float tiltTime = 0f;
    6.  
    7.         Quaternion startTilt = playerCamera.transform.rotation;
    8.         Quaternion endTilt = startTilt * tilt;
    9.  
    10.         Quaternion newRot = playerCamera.transform.rotation;
    11.         Quaternion oldRot = playerCamera.transform.rotation;
    12.  
    13.         while (tiltTime < duration)
    14.             if (tiltTime <= duration/2)
    15.                 {
    16.                     playerCamera.transform.rotation = Quaternion.Slerp(startTilt, endTilt,Mathf.SmoothStep(0.0f,1.0f,tiltTime/duration));
    17.                     tiltTime += Time.deltaTime;
    18.                     yield return null;
    19.                 }
    20.             else
    21.                 {
    22.                     playerCamera.transform.rotation = Quaternion.Slerp(endTilt, startTilt,Mathf.SmoothStep(0.0f,1.0f,tiltTime/duration));
    23.                     tiltTime += Time.deltaTime;
    24.                     yield return null;
    25.                 }
    26.     }

    as well as when just using a simple tween

    Code (CSharp):
    1. playerCamera.transform.DORotate(new Vector3(0,0,10), dodgeDuration/2, RotateMode.LocalAxisAdd).SetLoops(2, LoopType.Yoyo).SetEase(Ease.InOutSine);
    any ideas what might be causing this?

     
  2. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,443
    If you StartCoroutine in your Update, then its code will be executed just after each Update until it completes. So once you trigger your tilting coroutine, it will basically be in charge of camera positions until it is done. Your code clobbers the current rotation (overwriting the older values with whole new values), so you're basically going to see no changes other than the tilting until it's done.

    Instead, I think you want your special effect to basically control the amount of tilt ONLY, and then calculate that added amount of tilt to your normally live-updated camera coordinates on each update (or each coroutine yield).

    One approach:

    Inside your
    while
    loop, take a fresh copy of your camera transform which may have been updated by the rest of your game logic. Convert to euler, throw out the roll component, replace the roll component ONLY with your current tilt slerp, convert euler back to a rotation, and put that into your camera transform.
     
  3. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    It's probably way easier just to have the loop set a variable called 'tilt' which is then applied to the rotation wherever the other updates to position & rotation are done (e.g. where the input is handled).
    Otherwise you might forget that there is some code somewhere that also updates the rotation, which will make debugging a lot harder.
     
    halley likes this.
  4. JevinLevin_

    JevinLevin_

    Joined:
    Jan 18, 2023
    Posts:
    10
    Apologies but I'm a bit confused on your suggested approach, do you mind explaining again with a bit more detail as im quite inexperienced with unity and rotations