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 start animation object from current position

Discussion in 'Animation' started by foxyyhappyw, May 12, 2023.

  1. foxyyhappyw

    foxyyhappyw

    Joined:
    Aug 8, 2022
    Posts:
    59
    Hi,

    is it possible to make a smooth transition between 2 animations using an animator and animation?
    I want the animation to start from where the object is currently located, not where the animation starts.

    I showed the problem in the video. When the player places an object on the tile, an animation is performed. However, the problem is that if the player puts it on and takes it off quickly, the animation does not work properly, because it always starts from a specific place set in the animation, not from its current position.



    I know that it is possible to make such a system with a script, but I am planning to make more advanced animations and creating them with a script will be terribly time-consuming, while creating them with an animation system is much easier.

    To control which animation is currently being executed, I use a simple script using boolean.
     
  2. ElXill

    ElXill

    Joined:
    Jun 2, 2017
    Posts:
    43
    If this is important and you want to make it really responsive and interactive, I think the decent way would be doing it with a script for this kind of thing. It would be easy to calculate the movement with script and would be much more resonsive.
    Another solution would be, locking interaction until animation ends so player can't do this too quickly or adding axit time to animation (which is practically the same).
    Also increasing the transition time and playing around with transition settings may help.
     
  3. foxyyhappyw

    foxyyhappyw

    Joined:
    Aug 8, 2022
    Posts:
    59

    Well, I thought that if I don't find a better idea, I'll do it with a script and maybe use curves for it.
    In general, I don't want to block the player from interacting during the animation.
     
  4. foxyyhappyw

    foxyyhappyw

    Joined:
    Aug 8, 2022
    Posts:
    59
    Okay, I just made a script to move objects.
    For others who would have a similar problem, I'm posting a simple script and a video that shows how it works :)

    Code (CSharp):
    1. /*
    2. *
    3. * Scriptable Moving Animation
    4. * Version 1.0.0
    5. *
    6. * Script created by foxxy for Unity Forum members
    7. * Free to use :)
    8. *
    9. * Contact: David@unitfox.games
    10. *
    11. * https://forum.unity.com/members/foxyyhappyw.10612254/
    12. * https://unitfox.games/
    13. * https://twitter.com/unitfoxgames
    14. *
    15. */
    16.  
    17. using System.Collections;
    18. using UnityEngine;
    19.  
    20. public class ScriptableMovingAnimation : MonoBehaviour
    21. {
    22.     [System.Serializable]
    23.     public class ObjectData
    24.     {
    25.         public GameObject Object; // The GameObject to be moved
    26.         [Space]
    27.         public Vector3 StartPosition; // The initial position of the object
    28.         public Vector3 FinalPosition; // The final position of the object
    29.         [HideInInspector] public Vector3 CurrentPosition; // The current position of the object (updated during movement)
    30.         [Space]
    31.         public AnimationCurve CurveToFinalPosition = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); // The animation curve for moving from start to final position
    32.         public float DurationToFinalPosition = 2; // The duration of the movement from start to final position
    33.         [Space]
    34.         public AnimationCurve CurveToStartPosition = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); // The animation curve for moving from final to start position
    35.         public float DurationToStartPosition = 2; // The duration of the movement from final to start position
    36.     }
    37.  
    38.     public ObjectData[] objectsArray;
    39.  
    40.     private bool isMoving = false; // Flag indicating whether any objects are currently being moved
    41.     private bool movingToFinalPos = true; // Flag indicating the direction of movement (true: start to final, false: final to start)
    42.  
    43.     private void Update()
    44.     {
    45.         if (Input.GetKeyDown(KeyCode.Space)) // Press Space (you can change it if you want)
    46.         {
    47.             if (isMoving)
    48.             {
    49.                 StopAllCoroutines();
    50.                 isMoving = false;
    51.  
    52.                 Execute();
    53.             }
    54.             else
    55.             {
    56.                 Execute();
    57.             }
    58.         }
    59.     }
    60.  
    61.     private void Execute()
    62.     {
    63.         if (movingToFinalPos)
    64.         {
    65.             StartCoroutine(MoveObjects(objectsArray, movingToFinalPos));
    66.         }
    67.         else
    68.         {
    69.             StartCoroutine(MoveObjects(objectsArray, movingToFinalPos));
    70.         }
    71.  
    72.         movingToFinalPos = !movingToFinalPos;
    73.     }
    74.  
    75.     private IEnumerator MoveObjects(ObjectData[] objectDataArray, bool moveToFinalPos)
    76.     {
    77.         isMoving = true;
    78.  
    79.         foreach (ObjectData objectData in objectDataArray)
    80.         {
    81.             objectData.CurrentPosition = objectData.Object.transform.localPosition;
    82.             Vector3 endPosition = moveToFinalPos ? objectData.FinalPosition : objectData.StartPosition;
    83.  
    84.             AnimationCurve curve = moveToFinalPos ? objectData.CurveToFinalPosition : objectData.CurveToStartPosition;
    85.             float duration = moveToFinalPos ? objectData.DurationToFinalPosition : objectData.DurationToStartPosition;
    86.  
    87.             StartCoroutine(MoveObject(objectData.Object, curve, objectData.CurrentPosition, endPosition, duration));
    88.         }
    89.  
    90.         float maxDuration = GetMaxDuration(objectDataArray);
    91.         yield return new WaitForSeconds(maxDuration);
    92.  
    93.         isMoving = false;
    94.     }
    95.  
    96.     private IEnumerator MoveObject(GameObject obj, AnimationCurve curve, Vector3 startPosition, Vector3 endPosition, float duration)
    97.     {
    98.         float timer = 0f;
    99.  
    100.         while (timer < duration)
    101.         {
    102.             float t = timer / duration;
    103.             float movementProgress = curve.Evaluate(t);
    104.  
    105.             Vector3 newPosition = Vector3.Lerp(startPosition, endPosition, movementProgress);
    106.             obj.transform.localPosition = newPosition;
    107.  
    108.             timer += Time.deltaTime;
    109.             yield return null;
    110.         }
    111.  
    112.         obj.transform.localPosition = endPosition;
    113.     }
    114.  
    115.     private float GetMaxDuration(ObjectData[] objectDataArray)
    116.     {
    117.         float maxDuration = 0f;
    118.         foreach (ObjectData objectData in objectDataArray)
    119.         {
    120.             if (movingToFinalPos)
    121.             {
    122.                 maxDuration = Mathf.Max(maxDuration, objectData.DurationToFinalPosition);
    123.             }
    124.             else
    125.             {
    126.                 maxDuration = Mathf.Max(maxDuration, objectData.DurationToStartPosition);
    127.             }
    128.         }
    129.         return maxDuration;
    130.     }
    131. }
    132.  
     

    Attached Files: