How can I rotate multiple objects and make that some of them will start rotating in a different time?

by Dubi Duboni   Last Updated January 11, 2019 09:13 AM

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimatorController : MonoBehaviour
{
    [Header("Animators")]
    public Animator[] animators;
    [Space(5)]
    [Header("Movement Settings")]
    public Transform target;
    public float movingSpeed = 1f;
    public bool slowDown = false;
    [Space(5)]
    [Header("Rotation Settings")]
    public float rotationSpeed;

    private bool endRotation = false;
    private Vector3 targetCenter;
    private bool startWaitingAnim = true;

    // Use this for initialization
    void Start()
    {
        targetCenter = target.GetComponent<Renderer>().bounds.center;

        for (int i = 0; i < animators.Length; i++)
        {
            animators[i].SetFloat("Walking Speed", movingSpeed);
        }
    }

    // Update is called once per frame
    void Update()
    {
        float distanceFromTarget = Vector3.Distance(animators[2].transform.position, target.position);
        animators[2].transform.position = Vector3.MoveTowards(animators[2].transform.position, targetCenter, 0);

        if (slowDown)
        {
            if (distanceFromTarget < 10)
            {
                float speed = (distanceFromTarget / 10) / 1;
                for (int i = 0; i < animators.Length; i++)
                {
                    animators[i].SetFloat("Walking Speed", speed);
                }
            }
        }

        if (distanceFromTarget < 5f)
        {
            for (int i = 0; i < animators.Length; i++)
            {
                animators[i].SetBool("Idle", true);

                if (startWaitingAnim == true)
                {
                    StartCoroutine(WaitForAnimation());
                    startWaitingAnim = false;
                }
            }

            if (waitinganimation == true)
            {
                RotateAll(Quaternion.Euler(0, -90, 0),
                    Vector3.up, "Magic Pack", animators[2]);
            }

            RotateAll(Quaternion.Euler(0, 0, 0),
                    Vector3.down, "Rifle Aiming Idle", animators[0]);

            RotateAll(Quaternion.Euler(0, 0, 0),
                    Vector3.down, "Rifle Aiming Idle", animators[1]);
        }
    }

    private void ApplyRotation(Quaternion goalRotation,
         Vector3 axis, string AnimationName, Animator anim)
    {
        if (!endRotation)
        {
            float angleToGoal = Quaternion.Angle(
                    goalRotation,
                    anim.transform.localRotation);
            float angleThisFrame = Mathf.Min(angleToGoal, 100 * Time.deltaTime);

            anim.transform.Rotate(axis, angleThisFrame);

            endRotation = Mathf.Approximately(angleThisFrame, angleToGoal);
        }
        else
        {
            anim.SetBool(AnimationName, true);
        }
    }

    void RotateAll(Quaternion rotation,
        Vector3 axis,
        string AnimationName, params Animator[] anims)
    {
        foreach (var anim in anims)
            ApplyRotation(rotation, axis, AnimationName, anim); // However you want to actually apply the rotation
    }

    bool waitinganimation = false;
    IEnumerator WaitForAnimation()
    {
        yield return new WaitForSeconds(3);
        waitinganimation = true;
    }
}

Thep roblem is that animators[0] and animators[1] both start rotating once distanceFromTarget is less then 5:

RotateAll(Quaternion.Euler(0, 0, 0),
                        Vector3.down, "Rifle Aiming Idle", animators[0]);

RotateAll(Quaternion.Euler(0, 0, 0),
                        Vector3.down, "Rifle Aiming Idle", animators[1]);

And when they ended rotating inside the method ApplyRotation the variable flag bool endRotation will be true and therefore animators[2] will never rotate.

animators[2] is waiting for the flag bool waitinganimation to be true before it start rotating. But since endRotation is already true it will never rotate.

if (waitinganimation == true)
                {
                    RotateAll(Quaternion.Euler(0, -90, 0),
                        Vector3.up, "Magic Pack", animators[2]);
                }

How can I solve this problem ?

The main idea is to be able to rotate multiple objects some in the same time some in different time. Like in this case that animators[0] and [1] start rotating before animators[2].

Tags : unity c#


Related Questions


Updated July 12, 2015 13:05 PM

Updated July 13, 2015 13:05 PM

Updated March 18, 2016 08:05 AM