Unity Shader:常用的C#与shader交互的方法

俗话说久病成医,虽然不是专业技术美术,但代码写久了自然会积累一些常用的shader交互方法。零零散散的,总结如下:

1,改变UGUI的材质球属性

有时候我们需要改变ui的一些属性,从而实现想要的效果。通常UGUI上有如下属性,而我们想要改变,就需要获取到Material这个属性:

这里拿Image来举例, 简单的调用示例如下(关联测试):

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 测试UI闪白效果
/// </summary>
public class TestUIShan : MonoBehaviour
{
    public Image image;

    public Material material;

    private bool isShan = false;

    // Start is called before the first frame update
    void Start()
    {
        material = image.material;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            isShan = !isShan;           
            material.SetFloat("_Switch", isShan ? 1 : 0);           
        }
    }
}

我们可以通过代码看出,我们可以直接获取到面板上的Material属性,然后通过SetFloat之类的Set方法,来改变UGUI的材质球属性。

2,改变物体的材质球属性

这里多了一步,不是直接改变Material,而是先new一个MaterialPropertyBlock然后再将其赋值给Renderer属性。实现示例代码如下:

cs 复制代码
 /// <summary>
    /// 改变子物体颜色
    /// </summary>
    public void ChangeColor(Transform _tran, bool _isHas)
    {
        var _render = _tran.GetComponent<MeshRenderer>();
        if (_render != null)
        {
            var _pro = new MaterialPropertyBlock();
            _pro.SetFloat("_IsEnable", _isHas ? 0 : 1);
            _render.SetPropertyBlock(_pro);
        }
        var _render1 = _tran.GetComponent<SkinnedMeshRenderer>();
        if (_render1 != null)
        {
            var _pro = new MaterialPropertyBlock();
            _pro.SetFloat("_IsEnable", _isHas ? 0 : 1);
            _render1.SetPropertyBlock(_pro);
        }
        if (_tran.childCount > 0) foreach (Transform idx in _tran) ChangeColor(idx, _isHas);
    }

这里是通过SetFloat来控制_IsEnable这个属性的开关,同理我们可以调用别的set方法来改变对应的属性。

3,替换shader

这个就更简单了,只需要得到Material的shader属性并替换即可,示例代码如下:

cs 复制代码
    /// <summary>
    /// 替换shader
    /// </summary>
    public void ChangeShader(Transform _tran, Shader _s)
    {

        if (_tran.name.Contains("diban") || _tran.name.Contains("qiang")) return;//0511佳琪定
        var _render = _tran.GetComponentInChildren<MeshRenderer>();
        if (_render != null)
        {
            _render.material.shader = _s;
        }
        var _render1 = _tran.GetComponentInChildren<SkinnedMeshRenderer>();
        if (_render1 != null)
        {
            _render1.material.shader = _s;
        }
        if (_tran.childCount > 0) foreach (Transform idx in _tran) ChangeShader(idx, _s);

    }

关键函数为 _render1.material.shader = _s; 直接赋值替换即可。

4,批量获取父节点下,所有具有某一属性的物体

其实通过2/3函数,我们可以看出用递归去获取父物体下所有具有renderer属性物体的方法,实现起来实在太繁琐了,那么有没有更简单的方法呢?

答案是有的,使用_tran.GetComponentsInChildren即可,示例代码如下:

cs 复制代码
var _ms = transform.GetComponentsInChildren<SkinnedMeshRenderer>();

5,改变全局shader属性

比如我们有很多使用了某一shader的物体,其中包括AI、场景等等,如果要频繁改变这些材质球的某一属性,不可能遍历去寻找的。

好在引擎为我们提供好了方法,示例函数如下:

objectivec 复制代码
 Shader.SetGlobalFloat("_YydInterval", _getTime);

同理我们可以用set来改变更多的属性,比如Shader.SetGlobalTexture来改变全局的贴图等等。

相关推荐
是嘟嘟啊11 小时前
【Unity DOTS】EntityCommandBuffer 与 JobHandle
unity·ecs·dots·unity dots·job·burst·burstjob
雪隐12 小时前
WPF + MVVM 实战系列01-一个老狗回炉重造 WPF 的 12 天血泪史
sqlite·c#·mvvm
xcLeigh12 小时前
Unity基础:Camera相机组件详解——透视投影与正交投影的区别
数码相机·unity·游戏引擎
在世修行13 小时前
从零打造 C# 工业视觉检测系统(四):海康威视 MVS SDK 入门与相机枚举实战
数码相机·c#·视觉检测
神秘的MT14 小时前
C# WinForm Socket 服务器 + 串口转发
服务器·网络·学习·c#
玖玥拾14 小时前
Unity3D RPG 入门项目(二)移动 Bug 修复、环绕相机、NPC 任务系统、UI 穿透处理
unity·游戏引擎
Yasin Chen16 小时前
Unity UGUI RectMask2D 原理
unity·游戏引擎
hashiqimiya16 小时前
unity---unity编译手机apk人物角色移动
unity·游戏引擎
LONGZETECH17 小时前
传统实训 vs 仿真实训:从技术架构拆解新能源汽车教学的范式之变
c语言·3d·unity·架构·汽车
czhc114007566318 小时前
8.4:今日概念与语法总结
c#