我如何调暗灯光组件?

How can i dim a light component?

我有两个灯组件。首先,我找到两个灯并禁用它们。 然后我想在更改某些对象比例并使用对象缩放持续时间来调暗灯光时启用它们。

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);
        }
    }
}

第二个脚本正在缩放某个对象:

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;
        }
    }
}

在第二个脚本中,我希望在 scaleOverTime 方法中使用 ChangeScale 在 DimLights 脚本中使用方法 LightDim 调暗灯光。

没那么复杂。您可以通过复制 scaleOverTime 函数从中创建一个新函数来更改它以在 light 上工作。唯一要改变的是 Vector3.Lerp 函数更改为 Mathf.Lerp 函数以及 targetObj.transform.localScale 更改为 targetObj.intensity

一个简单的调光功能:

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;
    }
}

不幸的是,您使用的是数组,因此函数应该采用数组:

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;
    }
}

这避免了为每个 Light 启动新协程并节省一些时间。

新的Update函数:

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)); ;
        }
    }
}

注意新变量“lightCoroutine”。就像我们为 scaleCoroutine.

所做的那样,它用于存储旧协程