【问题标题】:Why when changing character mesh alpha color to 0 it's not making the character disappearing slowly?为什么将角色网格 Alpha 颜色更改为 0 时不会使角色缓慢消失?
【发布时间】:2020-05-15 14:18:29
【问题描述】:

主要的想法是创造某种缓慢消失的效果,这样当角色进入传送器时,它会使角色慢慢消失,就像将玩家慢慢地转移通过传送器一样。

角色网格渲染器是角色的子节点:

Character inspector mesh settings

如果我在编辑器中禁用蒙皮网格渲染器,它会使角色消失得不慢,但角色会消失。

接下来是向传送器添加一个脚本,然后尝试将角色网格的 alpha 颜色从 255 更改为 0:

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

public class Teleporting : MonoBehaviour
{
    public List<GameObject> teleporters = new List<GameObject>();
    public Renderer rendererToGetMaterial;
    public float fadeSpeed = 0.1f;
    public bool toTeleport = false;

    private List<Vector3> teleportersPositions = new List<Vector3>();

    // Start is called before the first frame update
    void Start()
    {
        teleporters.AddRange(GameObject.FindGameObjectsWithTag("Teleporter"));

        if (teleporters.Count > 0)
        {
            foreach (GameObject teleporter in teleporters)
            {
                teleportersPositions.Add(teleporter.transform.position);
            }
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        Teleport(other.gameObject);
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void Teleport(GameObject objectToTeleport)
    {
        TeleportingVisualEffect(objectToTeleport);
    }

    private void TeleportingVisualEffect(GameObject objectToTeleport)
    {
        var material = rendererToGetMaterial.material;
        StartCoroutine(FadeTo(material, 0f, 3f));
    }

    // Define an enumerator to perform our fading.
    // Pass it the material to fade, the opacity to fade to (0 = transparent, 1 = opaque),
    // and the number of seconds to fade over.
    IEnumerator FadeTo(Material material, float targetOpacity, float duration)
    {

        // Cache the current color of the material, and its initiql opacity.
        Color color = material.color;
        float startOpacity = color.a;

        // Track how many seconds we've been fading.
        float t = 0;

        while (t < duration)
        {
            // Step the fade forward one frame.
            t += Time.deltaTime;
            // Turn the time into an interpolation factor between 0 and 1.
            float blend = Mathf.Clamp01(t / duration);

            // Blend to the corresponding opacity between start & target.
            color.a = Mathf.Lerp(startOpacity, targetOpacity, blend);

            // Apply the resulting color to the material.
            material.color = color;

            // Wait one frame, and repeat.
            yield return null;
        }
    }
}

运行游戏时,我可以看到它正在将 vanguard_Mesh 着色器颜色 alpha 更改为 0 我也尝试在运行游戏之前自行更改它,但它不会让角色慢慢消失。

它对角色没有任何作用。

【问题讨论】:

标签: c# unity3d


【解决方案1】:

解决方案:

如果渲染模式设置为不透明,则仅更改 alpha 颜色将不起作用。 为了使它工作,我必须将渲染模式更改为透明。

由于无法直接访问渲染模式属性,我为它创建了一个小的新类:

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


public static class MaterialExtensions
{
    public static void ToOpaqueMode(this Material material)
    {
        material.SetOverrideTag("RenderType", "");
        material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
        material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
        material.SetInt("_ZWrite", 1);
        material.DisableKeyword("_ALPHATEST_ON");
        material.DisableKeyword("_ALPHABLEND_ON");
        material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
        material.renderQueue = -1;
    }

    public static void ToFadeMode(this Material material)
    {
        material.SetOverrideTag("RenderType", "Transparent");
        material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
        material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
        material.SetInt("_ZWrite", 0);
        material.DisableKeyword("_ALPHATEST_ON");
        material.EnableKeyword("_ALPHABLEND_ON");
        material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
        material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
    }
}

然后在这种情况下将它与脚本一起使用,我的脚本在问题中:

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

public class Teleporting : MonoBehaviour
{
    public List<GameObject> teleporters = new List<GameObject>();
    public Renderer rendererToGetMaterial;
    public float fadeSpeed = 0.1f;
    public bool toTeleport = false;

    private List<Vector3> teleportersPositions = new List<Vector3>();

    // Start is called before the first frame update
    void Start()
    {
        teleporters.AddRange(GameObject.FindGameObjectsWithTag("Teleporter"));

        if (teleporters.Count > 0)
        {
            foreach (GameObject teleporter in teleporters)
            {
                teleportersPositions.Add(teleporter.transform.position);
            }
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        Teleport(other.gameObject);
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void Teleport(GameObject objectToTeleport)
    {
        TeleportingVisualEffect(objectToTeleport);
    }

    private void TeleportingVisualEffect(GameObject objectToTeleport)
    {
        var material = rendererToGetMaterial.material;
        MaterialExtensions.ToFadeMode(material);
        StartCoroutine(FadeTo(material, 0f, 3f));
    }

    // Define an enumerator to perform our fading.
    // Pass it the material to fade, the opacity to fade to (0 = transparent, 1 = opaque),
    // and the number of seconds to fade over.
    IEnumerator FadeTo(Material material, float targetOpacity, float duration)
    {

        // Cache the current color of the material, and its initiql opacity.
        Color color = material.color;
        float startOpacity = color.a;

        // Track how many seconds we've been fading.
        float t = 0;

        while (t < duration)
        {
            // Step the fade forward one frame.
            t += Time.deltaTime;
            // Turn the time into an interpolation factor between 0 and 1.
            float blend = Mathf.Clamp01(t / duration);

            // Blend to the corresponding opacity between start & target.
            color.a = Mathf.Lerp(startOpacity, targetOpacity, blend);

            // Apply the resulting color to the material.
            material.color = color;

            // Wait one frame, and repeat.
            yield return null;
        }
    }
}

这一行:

MaterialExtensions.ToFadeMode(material);

现在效果很完美。现在我可以设置角色的随机位置以移动到另一个传送器,然后使用 ToOpaqueMode 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2018-05-30
    • 2016-03-04
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多