0
\$\begingroup\$

In the first script I'm doing a reference in the Start for the Colors script: In the Update I did that when i press once on the key C it will StartCoroutine and will change some objects color.

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

public class ObjectsManipulation : MonoBehaviour
{
    //Scaling
    private Scaling scaling;

    //Lights
    public DimLights dimlights;
    private Coroutine lightCoroutine;

    //Colors
    private Colors colors;

    //Rotating
    private Rotating rotating;

    private void Start()
    {
        scaling = GetComponent<Scaling>();
        scaling.Inits();

        colors = GetComponent<Colors>();
        colors.Initis();

        rotating = GetComponent<Rotating>();
    }

    // Use this for initialization
    void Update()
    {
        //Scaling
        if (Input.GetKeyDown(KeyCode.F))
        {
            //Flip the scale direction when F key is pressed
            scaling.scaleUp = !scaling.scaleUp;

            //Stop old coroutine
            if (scaling.scaleCoroutine != null)
                StopCoroutine(scaling.scaleCoroutine);

            if (lightCoroutine != null)
                StopCoroutine(lightCoroutine);


            //Scale  up
            if (scaling.scaleUp)
            {
                //Start new coroutine and scale up within 5 seconds and return the coroutine reference
                rotating.rotateBack = false;
                scaling.scaleCoroutine = StartCoroutine(scaling.scaleOverTime(scaling.objectToScale, scaling.maxSize, scaling.duration));
                lightCoroutine = StartCoroutine(dimlights.dimLightOverTime(1, scaling.duration));
            }

            //Scale Down
            else
            {
                //Start new coroutine and scale up within 5 seconds and return the coroutine reference
                rotating.rotateBack = true;
                scaling.scaleCoroutine = StartCoroutine(scaling.scaleOverTime(scaling.objectToScale, scaling.minSize, scaling.duration));
                lightCoroutine = StartCoroutine(dimlights.dimLightOverTime(0, scaling.duration)); ;
            }
        }

        //Change color
        if (Input.GetKeyDown(KeyCode.C))
        {
            StartCoroutine(colors.ChangeColor());
        }

        //Rotate
        if (Input.GetKey(KeyCode.R) && !scaling.scaleUp)
        {
            rotating.x += Time.deltaTime * rotating.rotationSpeed;
            scaling.objectToScale.transform.localRotation = Quaternion.Euler(0, 0, rotating.x);
            rotating.keyPressed = true;
        }
        if (Input.GetKeyUp(KeyCode.R))
        {
            rotating.keyPressed = false;
        }

        if (!rotating.keyPressed && !scaling.scaleUp && rotating.rotateBack == false
            && DetectInteractable.detected == false)
        {
            scaling.objectToScale.transform.rotation = Quaternion.LookRotation(Camera.main.transform.forward);
        }

        if (DetectInteractable.detected == true && !scaling.scaleUp)
        {
            rotating.x += Time.deltaTime * rotating.rotationSpeed;
            scaling.objectToScale.transform.localRotation = Quaternion.Euler(0, 0, rotating.x);
        }
    }
}

This is the Colors script. I have array of GameObject and i did two foreach loops:

The problem is that it's coloring all the objects at once and I set the colorDuration to 5 seconds. What I want is to color all the objects in the array in 5 seconds in colorDuration. Not each object in the array 5 seconds but all of them together at 5 seconds.

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

public class Colors : MonoBehaviour
{
    public GameObject[] objectsToColor;
    public Color startColor;
    public Color endColor;
    public float colorDuration;

    public void Initis()
    {
        foreach (GameObject rend in objectsToColor)
        {
            startColor = rend.GetComponent<Renderer>().material.color;
        }
        endColor = Color.green;
    }

    public IEnumerator ChangeColor()
    {
        float t = 0;

        while (t < colorDuration)
        {
            foreach (GameObject rend in objectsToColor)
            {
                t += Time.deltaTime;
                rend.GetComponent<Renderer>().material.color = Color.Lerp(startColor, endColor, t / colorDuration);
                yield return null;
            }
        }
    }
}
\$\endgroup\$
3
\$\begingroup\$

Your coroutine is yielding and increasing the time variable with every object you process. What you likely want to do is, in that order:

  1. increase the time variable
  2. update all the objects
  3. and then yield until the next frame

Like this:

while (t < colorDuration) {

    t += Time.deltaTime;    

    foreach (GameObject rend in objectsToColor) {
        rend.GetComponent<Renderer>().material.color = Color.Lerp(startColor, endColor, t / colorDuration);
    }

    yield return null;
 }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.