简体   繁体   中英

How can i dim a light component?

I have two lights components. First i'm finding both Lights and disable them. Then I want to enable them when changing some object scale and using the object scaling duration time for the lights dim.

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

public class DimLights : MonoBehaviour
{
    //Lights Change
    public Light[] lightsToDim = null;
    public float maxTime;

    private GameObject[] myLights;
    private float mEndTime = 0;
    private float mStartTime = 0;

    private void Start()
    {
        myLights = GameObject.FindGameObjectsWithTag("Light");
        mStartTime = Time.time;
        mEndTime = mStartTime + maxTime;
        LightsState(false);
    }

    public void LightsState(bool state)
    {
        foreach (GameObject go in myLights)
        {
            go.GetComponent<Light>().enabled = state;
        }
    }

    public void LightDim()
    {
        foreach (Light light in lightsToDim)
        {
            light.intensity = Mathf.InverseLerp(mStartTime, mEndTime, Time.time);
        }
    }
}

The second script is scaling some object:

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

public class ChangeScale : MonoBehaviour
{
    //Scaling change
    public GameObject objectToScale;
    public float duration = 1f;
    public Vector3 minSize;
    public Vector3 maxSize;

    private bool scaleUp = false;
    private Coroutine scaleCoroutine;

    //Colors change
    public Color startColor;
    public Color endColor;
    public float colorDuration; // duration in seconds

    private void Start()
    {
        startColor = GetComponent<Renderer>().material.color;
        endColor = Color.green;
        objectToScale.transform.localScale = minSize;
    }

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

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

            //Scale  up
            if (scaleUp)
            {
                //Start new coroutine and scale up within 5 seconds and return the coroutine reference
                scaleCoroutine = StartCoroutine(scaleOverTime(objectToScale, maxSize, duration));
            }

            //Scale Down
            else
            {
                //Start new coroutine and scale up within 5 seconds and return the coroutine reference
                scaleCoroutine = StartCoroutine(scaleOverTime(objectToScale, minSize, duration));
            }
        }

        if (Input.GetKeyDown(KeyCode.C))
        {
            StartCoroutine(ChangeColor());
        }
    }

    IEnumerator scaleOverTime(GameObject targetObj, Vector3 toScale, float duration)
    {
        float counter = 0;

        //Get the current scale of the object to be scaled
        Vector3 startScaleSize = targetObj.transform.localScale;

        while (counter < duration)
        {
            counter += Time.deltaTime;
            targetObj.transform.localScale = Vector3.Lerp(startScaleSize, toScale, counter / duration);
            yield return null;
        }
    }

    IEnumerator ChangeColor()
    {
        float t = 0;

        while (t < colorDuration)
        {
            t += Time.deltaTime;
            GetComponent<Renderer>().material.color = Color.Lerp(startColor, endColor, t / colorDuration);
            yield return null;
        }
    }
}

In the second script the ChangeScale i want inside the scaleOverTime method to dim the light using the method LightDim in the DimLights script.

It's not that complicated. You change the scaleOverTime function to work on light by copying it making a new function from it. The only thing to change is the Vector3.Lerp function to Mathf.Lerp function and also targetObj.transform.localScale to targetObj.intensity .

A simple Light dim function:

IEnumerator dimLightOverTime(Light targetObj, float toIntensity, float duration)
{
    float counter = 0;

    //Get the current intensity of the Light 
    float startIntensity = targetObj.intensity;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        targetObj.intensity = Mathf.Lerp(startIntensity, toIntensity, counter / duration);
        yield return null;
    }
}

Unfortunately, you are using an array so the function should be made to take an array:

IEnumerator dimLightOverTime(Light[] targetObj, float toIntensity, float duration)
{
    float counter = 0;
    //Get the current intensity of the Light 
    float[] startIntensity = new float[targetObj.Length];
    for (int i = 0; i < targetObj.Length; i++)
    {
        startIntensity[i] = targetObj[i].intensity;
    }

    while (counter < duration)
    {
        counter += Time.deltaTime;

        for (int i = 0; i < targetObj.Length; i++)
        {
            targetObj[i].intensity = Mathf.Lerp(startIntensity[i], toIntensity, counter / duration);
        }
        yield return null;
    }
}

This prevents having to start new coroutine for each Light and saving some time.

The new Update function:

public Light[] lightsToDim = null;
private Coroutine lightCoroutine;

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

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

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


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

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

Notice the new variable " lightCoroutine ". That's used to store the old coroutine just like we did for the scaleCoroutine .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM