Search Unity

Question animation timescale

Discussion in 'Animation' started by smallville7123, Dec 29, 2023.

  1. smallville7123

    smallville7123

    Joined:
    Nov 30, 2018
    Posts:
    35
    is there a way to apply a global timescale to everything an Animator component does?

    for example, all blend animations, non-blend animations, transitions, and others would all be affected by such timescale, while also still being affected by Time.timeScale

    eg

    Animator
    - timescale [ 2.0 ]

    Character Controller
    - timescale [ 2.0 ]

    World
    - timescale [ 1.0 ]


    in the above
    - the world would move at 1.0 timescale via Time.timeScale
    - the Animator would render all animations as if Time.timeScale was 2.0
    - the Character Controller would handle all movements as if Time.timeScale was 2.0

    the Animator and Character Controller would have synchronized timescale so animations stay in sync

    however can be desynced (eg, by setting Animator to 1.3 timescale) to give the appearance of "moving fast in style" (character moves fast but animations play in slow motion) tho this can easily become complex if animation transitioning is factored in and we have different timescales for different animations as well as run-time interpolated animation speed

    for now i just wish to real-time timescale (interpolate the timescale over time) the Animator itself without timescaling the entire world as well

    my current project is here

    https://github.com/mgood7123/unity__SuperSpeed/tree/35b1b567b3502bad510439b7ff9304a9b1836ccd

    the goal is to implement a timeScale for the player in which the player itself will have its own timeScale

    this would mean its movement speed, velocity, gravity, any and all animations (blend, non-blend, transitions, ect), would all be sped-up or slowed-down depending on the player timeScale

    for example, with
    Time.timeScale = 1.0f
    , and ignoring the world

    player.timeScale = 2.0
    would be equivalent to as-if
    Time.timeScale = 2.0
    had been done

    i currently have this implemented except for the
    velocity
    ,
    gravity
    and
    non-blend animations, transitions animations
    (eg, player jumping does not obey
    player.timeScale
    )

    player controller (manages player time scale) is at
    Assets\StarterAssets\ThirdPersonController\Scripts\ThirdPersonController.cs


    clock (manages world time scale) is at
    Assets\Clock.cs


    the current controls are:
    keyboard:
    move: arrow keys/wasd
    camera: mouse/touchpad
    jump: space
    slow_mo: enter

    gamepad:
    move: left analog stick
    camera: right analog stick
    jump: X (Playstation) / A (XBox)
    slow_mo: L1 (Playstation) / Left-Shoulder (XBox)
     
    Last edited: Dec 29, 2023
  2. smallville7123

    smallville7123

    Joined:
    Nov 30, 2018
    Posts:
    35
    i might have to try Unreal Engine and see if i can do what i want to do in there since it doesnt seem like i can do such in Unity without somehow replacing the Animator component to support timescaling
     
  3. myabrownn876

    myabrownn876

    Joined:
    Dec 30, 2023
    Posts:
    1
    In Unity, achieving a separate time scale for the Animator component without affecting the entire world can be done through scripting. One way to implement this is by introducing a custom time scale for the Animator and synchronizing it with the global time scale when needed.

    In your ThirdPersonController.cs script, you can add a variable to manage the player's individual time scale. Then, when updating the Animator component, multiply the time-dependent parameters by this custom time scale. Here's a simplified example:


    Code (CSharp):
    1. public class ThirdPersonController : MonoBehaviour
    2. {
    3.     public float playerTimeScale = 1.0f; // Custom time scale for the player
    4.  
    5.     void Update()
    6.     {
    7.         float deltaTime = Time.deltaTime * playerTimeScale; // Adjusted delta time
    8.  
    9.         // Update movement, velocity, gravity, etc. with adjusted delta time
    10.  
    11.         // Example: Update Animator playback speed
    12.         float animSpeed = 1.0f; // Adjust as needed
    13.         GetComponent<Animator>().speed = animSpeed * playerTimeScale;
    14.  
    15.         // Handle other aspects of the player's behavior with the adjusted delta time
    16.     }
    17. }
    18.  
    This way, you can control the player's time scale independently of the global time scale. Adjust other relevant parameters in a similar fashion to achieve the desired effect.

    Keep in mind the importance of synchronizing various components and animations within the player, ensuring their speeds are adjusted accordingly. Make precise adjustments as necessary, aligning with your specific requirements and interactions, perhaps even incorporating elements inspired by the thrilling desert safari dubai.

    For further details, refer to Unity's scripting documentation on time-related functions and Animator component manipulation. This approach provides flexibility and allows you to tailor the time scaling to your specific gameplay needs.
     
    Last edited: Jan 1, 2024
  4. smallville7123

    smallville7123

    Joined:
    Nov 30, 2018
    Posts:
    35

    what is the different between these?

    Code (csharp):
    1. _animator.speed = 0.5f;
    2. _animator.setFloat(Animator.StringToHash("Speed"), 0.5f);
     
  5. smallville7123

    smallville7123

    Joined:
    Nov 30, 2018
    Posts:
    35
    Code (csharp):
    1. private void Move() {
    2.     float anim_speed = _input.sprint ? SprintSpeed : MoveSpeed;
    3.     if (_input.move == Vector2.zero) anim_speed = 0.0f;
    4.     float targetSpeed = anim_speed * player_speed;
    5.  
    6.     float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
    7.  
    8.     float speedOffset = 0.1f;
    9.     float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f;
    10.  
    11.     if (currentHorizontalSpeed < targetSpeed - speedOffset ||
    12.         currentHorizontalSpeed > targetSpeed + speedOffset) {
    13.         _speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * (SpeedChangeRate * player_speed));
    14.  
    15.         _speed = Mathf.Round(_speed * 1000f) / 1000f;
    16.     } else {
    17.         _speed = targetSpeed;
    18.     }
    19.  
    20.     // _animationBlend *must* account for timescale
    21.     _animationBlend = Mathf.Lerp(_animationBlend, targetSpeed / player_speed, Time.deltaTime * (SpeedChangeRate * player_speed));
    22.     if (_animationBlend < 0.01f) _animationBlend = 0f;
    23.  
    24.     Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;
    25.  
    26.     if (_input.move != Vector2.zero) {
    27.         _targetRotation = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg + _mainCamera.transform.eulerAngles.y;
    28.  
    29.         transform.rotation = Quaternion.Euler(0.0f, Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity, RotationSmoothTime / player_speed), 0.0f);
    30.     }
    31.  
    32.  
    33.     Vector3 targetDirection = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;
    34.  
    35.     _controller.Move(targetDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
    36.  
    37.     if (_hasAnimator) {
    38.         _animator.SetFloat(_animIDSpeed, _animationBlend); // _animationBlend *must* account for timescale
    39.         _animator.SetFloat(_animIDMotionSpeed, inputMagnitude);
    40.         _animator.speed = 1.0f * player_speed; // animator timescale
    41.     }
    42. }
    ok i got the animator to timescale correctly