小功能⭐️Unity中利用材质自发光实现物体闪烁效果

简介: 小功能⭐️Unity中利用材质自发光实现物体闪烁效果

本文基于VDer的文章《Unity中利用材质自发光实现物体闪烁效果》延伸开发

在实现了具有一个Material的物体闪烁发光之后,延伸开发了具有多个Material的自闪烁效果,感谢VDer的技术分享!

使用方法:直接将该脚本挂到物体上,AutoStart为自动闪烁。具体功能看脚本。


2019.12.21更新:

若物体不闪烁,参照ViveFocus博客:链接

2019.05.21更新:

该脚本所挂物体Start时现在可以处于关闭状态啦(原先初始化时必须激活,否则不闪烁)

2018.11.28更新:

增加当前是否发光状态监测:isGlinting


Code:

using System.Collections;
using UnityEngine;
 
public class Skode_Glinting : MonoBehaviour
{
    /// <summary>
    /// 闪烁颜色
    /// </summary>
    public Color color = new Color(61 / 255f, 226 / 255f, 131 / 255, 1);
 
    /// <summary>
    /// 最低发光亮度,取值范围[0,1],需小于最高发光亮度。
    /// </summary>
    [Tooltip("最低发光亮度,取值范围[0,1],需小于最高发光亮度。")]
    [Range(0.0f, 1.0f)]
    public float minBrightness = 0.0f;
 
    /// <summary>
    /// 最高发光亮度,取值范围[0,1],需大于最低发光亮度。
    /// </summary>
    [Tooltip("最高发光亮度,取值范围[0,1],需大于最低发光亮度。")]
    [Range(0.0f, 1)]
    public float maxBrightness = 0.5f;
 
    /// <summary>
    /// 闪烁频率,取值范围[0.2,30.0]。
    /// </summary>
    [Tooltip("闪烁频率,取值范围[0.2,30.0]。")]
    [Range(0.2f, 30.0f)]
    public float rate = 1;
 
    //是否闪烁
    [HideInInspector]
    public bool isGlinting = false;
 
 
    [Tooltip("勾选此项则启动时自动开始闪烁")]
    [SerializeField]
    private bool _autoStart = false;
 
    private float _h, _s, _v;           // 色调,饱和度,亮度
    private float _deltaBrightness;     // 最低最高亮度差
    private Renderer _renderer;
 
    //private Material _material;
    private Material[] _materials;
 
    private readonly string _keyword = "_EMISSION";
    private readonly string _colorName = "_EmissionColor";
 
    private Coroutine _glinting;
 
    private void OnEnable()
    {
        _renderer = gameObject.GetComponent<Renderer>();
 
        //_material = _renderer.material;
        _materials = _renderer.materials;
 
        if (_autoStart)
        {
            StartGlinting();
        }
    }
 
    /// <summary>
    /// 校验数据,并保证运行时的修改能够得到应用。
    /// 该方法只在编辑器模式中生效!!!
    /// </summary>
    private void OnValidate()
    {
        // 限制亮度范围
        if (minBrightness < 0 || minBrightness > 1)
        {
            minBrightness = 0.0f;
            Debug.LogError("最低亮度超出取值范围[0, 1],已重置为0。");
        }
        if (maxBrightness < 0 || maxBrightness > 1)
        {
            maxBrightness = 1.0f;
            Debug.LogError("最高亮度超出取值范围[0, 1],已重置为1。");
        }
        if (minBrightness >= maxBrightness)
        {
            minBrightness = 0.0f;
            maxBrightness = 1.0f;
            Debug.LogError("最低亮度[MinBrightness]必须低于最高亮度[MaxBrightness],已分别重置为0/1!");
        }
 
        // 限制闪烁频率
        if (rate < 0.2f || rate > 30.0f)
        {
            rate = 1;
            Debug.LogError("闪烁频率超出取值范围[0.2, 30.0],已重置为1.0。");
        }
 
        // 更新亮度差
        _deltaBrightness = maxBrightness - minBrightness;
 
        // 更新颜色
        // 注意不能使用 _v ,否则在运行时修改参数会导致亮度突变
        float tempV = 0;
        Color.RGBToHSV(color, out _h, out _s, out tempV);
    }
 
    /// <summary>
    /// 开始闪烁。
    /// </summary>
    public void StartGlinting()
    {
        isGlinting = true;
        if (_materials != null)
        {
            if (_materials.Length > 0)
            {
                //_material.EnableKeyword(_keyword);
                for (int i = 0; i < _materials.Length; i++)
                {
                    _materials[i].EnableKeyword(_keyword);
                }
 
                if (_glinting != null)
                {
                    StopCoroutine(_glinting);
                }
                _glinting = StartCoroutine(IEGlinting());
            }
        }
    }
 
    /// <summary>
    /// 停止闪烁。
    /// </summary>
    public void StopGlinting()
    {
        isGlinting = false;
        //_material.DisableKeyword(_keyword);
        for (int i = 0; i < _materials.Length; i++)
        {
            _materials[i].DisableKeyword(_keyword);
        }
 
        if (_glinting != null)
        {
            StopCoroutine(_glinting);
        }
    }
 
    /// <summary>
    /// 控制自发光强度。
    /// </summary>
    /// <returns></returns>
    private IEnumerator IEGlinting()
    {
        Color.RGBToHSV(color, out _h, out _s, out _v);
        _v = minBrightness;
        _deltaBrightness = maxBrightness - minBrightness;
 
        bool increase = true;
        while (true)
        {
            if (increase)
            {
                _v += _deltaBrightness * Time.deltaTime * rate;
                increase = _v <= maxBrightness;
            }
            else
            {
                _v -= _deltaBrightness * Time.deltaTime * rate;
                increase = _v <= minBrightness;
            }
            //_material.SetColor(_colorName, Color.HSVToRGB(_h, _s, _v));
 
            for (int i = 0; i < _materials.Length; i++)
            {
                _materials[i].SetColor(_colorName, Color.HSVToRGB(_h, _s, _v));
            }
            //_renderer.UpdateGIMaterials();
            yield return null;
        }
    }
}


相关文章
|
4月前
|
定位技术 C# 图形学
从零开始的unity3d入门教程(二)----基本功能讲解
这是一篇Unity3D入门教程,详细介绍了Unity界面操作、游戏物体创建修改、场景搭建、玩家控制、音效添加以及游戏测试和导出的全过程。
从零开始的unity3d入门教程(二)----基本功能讲解
|
4月前
|
前端开发 图形学
Unity精华☀️UI和物体可见性的判断方法
Unity精华☀️UI和物体可见性的判断方法
|
4月前
|
图形学
小功能⭐️Unity UnityEvent实现代码的选择
小功能⭐️Unity UnityEvent实现代码的选择
|
4月前
|
机器学习/深度学习 图形学 Windows
小功能⭐️unity3d KeyCode各键值说明
小功能⭐️unity3d KeyCode各键值说明
|
4月前
|
图形学 Android开发
小功能⭐️Unity调用Android常用事件
小功能⭐️Unity调用Android常用事件
|
4月前
|
图形学
小功能⭐️获取Unity游戏物体上,所挂载组件的名称
小功能⭐️获取Unity游戏物体上,所挂载组件的名称
|
4月前
|
图形学
小功能⭐️Unity截屏功能的实现
小功能⭐️Unity截屏功能的实现
|
3月前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
307 0
|
3月前
|
图形学 开发者
【独家揭秘】Unity游戏开发秘籍:从基础到进阶,掌握材质与纹理的艺术,打造超现实游戏视效的全过程剖析——案例教你如何让每一面墙都会“说话”
【8月更文挑战第31天】Unity 是全球领先的跨平台游戏开发引擎,以其高效性能和丰富的工具集著称,尤其在提升游戏视觉效果方面表现突出。本文通过具体案例分析,介绍如何利用 Unity 中的材质与纹理技术打造逼真且具艺术感的游戏世界。材质定义物体表面属性,如颜色、光滑度等;纹理则用于模拟真实细节。结合使用两者可显著增强场景真实感。以 FPS 游戏为例,通过调整材质参数和编写脚本动态改变属性,可实现自然视觉效果。此外,Unity 还提供了多种高级技术和优化方法供开发者探索。
59 0