在Unity编辑器中,我们可以直接在Inspector面板里对C#脚本的公开成员变量进行赋值,那么Cg代码怎样才能做到像C#脚本一样让我们能够在代码文件外对变量进行赋值呢?本篇将会介绍使用Properties语义块和uniform关键字来实现应用程序对Cg的数据传递。
1. Properties语义块:在Unity编辑器里传递值
Properties语义块能够让我们方便地在Unity编辑器里对块中的参数进行设置,然后就可以在Shader中使用这些参数,例如,我想要Unity传递给Shader一个颜色值,则可以这么写:
Properties
{
// 声明一个Color类型的属性
_FirstColor("First Color", color) = (1, 1, 1, 1)
}
如果我们想在Cg代码块里使用这个参数,那么我们需要在代码块里添加这个参数的一个声明:
// Properties中的参数声明
fixed4 _FirstColor;
2. uniform关键字:在C#脚本里传递值
uniform关键字能将Cg代码里的变量标识为可被外界修改,例如,我们在Cg代码块中再定义一个颜色值,并且在前面加上uniform关键字:
// 可被外界修改的变量
uniform fixed4 _SecondColor;
我们将材质和C#脚本挂载到同一个物体上,在C#脚本里添加如下代码来对该变量进行赋值:
GetComponent<Renderer>().material.SetVector("_SecondColor", new Vector4(1, 0, 0, 1));
这样,我们都能够实现C#脚本对Cg的数据传递了。
3. 简单的案例演示
接下来,我们用一个简单的案例来应用本篇所讲解知识。以下C#脚本实现了每0.5秒钟对物体颜色进行了改变:
public Vector4 Color;
int i = 0;
float timer = 1; // 计时器
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (timer >= 0.5)
{
if (i >= 3)
i = 0;
switch (i++)
{
case 0:
Color = new Vector4(1, 0, 0, 1);
break;
case 1:
Color = new Vector4(0, 1, 0, 1);
break;
case 2:
Color = new Vector4(0, 0, 1, 1);
break;
}
GetComponent<Renderer>().material.SetVector("_SecondColor", Color);
timer = 0;
}
timer += Time.deltaTime;
}
实现效果如下: