淡入淡出游戏对象

7

我是编码新手,仍在努力培养逻辑思维以帮助我为游戏创建所需的解决方案。目前,我正在Unity中尝试创建一个2D游戏对象,它是一个隐藏秘密门的墙壁。当玩家游戏对象触发它时,我希望该游戏对象会淡出(大约90%),揭示后面的空间和隐藏的门。

到目前为止,我已经设法找出如何在触发器上使“秘密墙”游戏对象不活动,从而它消失了,但这并没有产生我想要的视觉效果。正如我所说,我仍在努力开发编码者的思维方式,因此虽然我已经做了很多研究来解决这个问题,但是其中许多结果我不容易理解。

这是我的代码:

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

public class SecretDoor1 : MonoBehaviour {

    void OnTriggerEnter2D (Collider2D SecretDoorTrig) {
         if (SecretDoorTrig.gameObject.tag == "Player") {
             GetComponent<SpriteRenderer> ().enabled = false;
         }
         else {
             GetComponent<SpriteRenderer> ().enabled = true;
         }
    }

    void OnTriggerExit2D (Collider2D SecretDoorTrig) {

         if (SecretDoorTrig.gameObject.tag == "Player") {

             GetComponent<SpriteRenderer> ().enabled = true;
         }
         else {
             GetComponent<SpriteRenderer> ().enabled = false;
         }
    }
}
2个回答

11

淡入/淡出一个 Sprite移动游戏对象类似,只是你需要修改它的透明度而不是它的位置。

关于淡化对象,最重要的三个要素是Time.deltaTimeMathf.Lerp/Color.Lerp 和协程。您需要了解这些如何共同使用。

启动协程,并使用Time.deltaTime来增加变量。该变量用于确定该函数运行了多少。在for/while循环中,使用每帧递增的变量和您想要淡化发生的持续时间来生成 alpha,借助Mathf.Lerp函数创建新颜色,并将其分配给 Sprite。

这样做,直到使用Time.deltaTime递增的变量达到您想要在其中发生淡化的持续时间为止。

这是一个简单的SpriteRenderer淡化函数:

public SpriteRenderer spriteToFade;

IEnumerator fadeOut(SpriteRenderer MyRenderer, float duration)
{
    float counter = 0;
    //Get current color
    Color spriteColor = MyRenderer.material.color;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        //Fade from 1 to 0
        float alpha = Mathf.Lerp(1, 0, counter / duration);
        Debug.Log(alpha);

        //Change alpha only
        MyRenderer.color = new Color(spriteColor.r, spriteColor.g, spriteColor.b, alpha);
        //Wait for a frame
        yield return null;
    }
}
如果您想要淡入效果,请将Mathf.Lerp(1, 0, counter / duration);更改为Mathf.Lerp(0, 1, counter / duration);,这将使alpha从0逐渐变为1,而不是从1逐渐变为0
从上面的示例中可以看出,编写淡出和淡入函数仅需要一种方法来告诉函数将alpha从10或从01进行更改。您可以使函数使用一个booleanenum变量来确定要执行哪种类型的淡入/淡出。当然,您可以将淡入/淡出函数分开,但将其放在一个函数中很好。
以下是扩展版本的函数,支持淡入和淡出,并支持几乎所有GameObject,例如MeshRenderer(3D)、SpriteRenderer(2D)、ImageRawImage...... 您可以扩展它以支持更多缺失的组件。
IEnumerator fadeInAndOut(GameObject objectToFade, bool fadeIn, float duration)
{
    float counter = 0f;

    //Set Values depending on if fadeIn or fadeOut
    float a, b;
    if (fadeIn)
    {
        a = 0;
        b = 1;
    }
    else
    {
        a = 1;
        b = 0;
    }

    int mode = 0;
    Color currentColor = Color.clear;

    SpriteRenderer tempSPRenderer = objectToFade.GetComponent<SpriteRenderer>();
    Image tempImage = objectToFade.GetComponent<Image>();
    RawImage tempRawImage = objectToFade.GetComponent<RawImage>();
    MeshRenderer tempRenderer = objectToFade.GetComponent<MeshRenderer>();
    Text tempText = objectToFade.GetComponent<Text>();

    //Check if this is a Sprite
    if (tempSPRenderer != null)
    {
        currentColor = tempSPRenderer.color;
        mode = 0;
    }
    //Check if Image
    else if (tempImage != null)
    {
        currentColor = tempImage.color;
        mode = 1;
    }
    //Check if RawImage
    else if (tempRawImage != null)
    {
        currentColor = tempRawImage.color;
        mode = 2;
    }
    //Check if Text 
    else if (tempText != null)
    {
        currentColor = tempText.color;
        mode = 3;
    }

    //Check if 3D Object
    else if (tempRenderer != null)
    {
        currentColor = tempRenderer.material.color;
        mode = 4;

        //ENABLE FADE Mode on the material if not done already
        tempRenderer.material.SetFloat("_Mode", 2);
        tempRenderer.material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
        tempRenderer.material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
        tempRenderer.material.SetInt("_ZWrite", 0);
        tempRenderer.material.DisableKeyword("_ALPHATEST_ON");
        tempRenderer.material.EnableKeyword("_ALPHABLEND_ON");
        tempRenderer.material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
        tempRenderer.material.renderQueue = 3000;
    }
    else
    {
        yield break;
    }

    while (counter < duration)
    {
        counter += Time.deltaTime;
        float alpha = Mathf.Lerp(a, b, counter / duration);

        switch (mode)
        {
            case 0:
                tempSPRenderer.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
            case 1:
                tempImage.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
            case 2:
                tempRawImage.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
            case 3:
                tempText.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
            case 4:
                tempRenderer.material.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
        }
        yield return null;
    }
}

使用方法:

需要淡出的游戏对象:

public GameObject SpriteRend;

3秒后淡出

StartCoroutine(fadeInAndOut(SpriteRend, false, 3f));

3秒淡入效果

StartCoroutine(fadeInAndOut(SpriteRend, true, 3f));

1
The way I have accomplished this has been to change the alpha value of the sprite color.
Color(R, G, B, A). Here, A represents alpha.
- SpriteRenderer.color = new Color(1f, 1f, 1f, 1f) is fully opaque. - SpriteRenderer.color = new Color(1f, 1f, 1f, .5f) is about 50% transparent. - SpriteRenderer.color = new Color(1f, 1f, 1f, 0f) is fully transparent, and the sprite cannot be seen.

2
值得注意的是,颜色对象可以被缓存到字段中并重复使用。 - Draco18s no longer trusts SE
@Laslos,我不想说,但我不知道如何实现那段代码。你能给我一个示例,告诉我如何插入它吗?我将对其他GO应用相同的效果,所以了解这些将会很有用。 - goodwiag
@goodwiag 要将门的透明度设置为90%,请设置门游戏对象的颜色:DoorGameObject.GetComponent<SpriteRenderer>().color = new Color(1f,1f,1f,.1f); - Laslos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接