在开发《Anchor》的时候发现Unity暂时不支持在代码中直接替换gradient,且无法expose在inspector中,因此想出个笨办法来解决。另在shader中做了大于2色的gradient。
Overview
- Sprite Unlit Master
- 用Shader创建Material并应用在sprite上
- shader一共三个部分:Original Gradient、Target Gradient、Lerp Control
Gradient
- Original和Target一样
- 按gradient的colorkey个数可以自行添加更多Lerp Node
- 如果实际效果分层明显,可以考虑在每个Color Mask节点与对应的Lerp节点间添加一个SmoothStep节点
Lerp Control
- LerpStatus可以看作是A到B的百分比进度,被限制在0到1之间,可以按需修改成Time Node等
属性总览
- 图一Reference就是图二Properties中的第一列,建议保持[Type]_[Name]的格式,[Name]可以修改成好识别的,比如Color_OriginalTop。这里偷懒没改。
代码
- 随便放在谁身上,inspector中调好想要的gradients
- 测试用,写的粗糙了点
public SpriteRenderer spriteRenderer;
//Inspector中自己设置的Gradients
public Gradient gradientOriginal;
public Gradient gradientTarget;
//储存colorkeys的list
List<Color> originalColors = new List<Color>();
List<Color> targetColors = new List<Color>();
//括号内红字是Property的名字,按上图
private static readonly int OriginalTop = Shader.PropertyToID("Color_EED7677C");
private static readonly int OriginalMid = Shader.PropertyToID("Color_73BE25BF");
private static readonly int OriginalBottom = Shader.PropertyToID("Color_D936B97");
private static readonly int TargetTop = Shader.PropertyToID("Color_A1B04C9A");
private static readonly int TargetMid = Shader.PropertyToID("Color_D4C6EBC5");
private static readonly int TargetBottom = Shader.PropertyToID("Color_5127E8E4");
private void Start()
{
foreach (var gradientColorKey in gradientOriginal.colorKeys)
{
originalColors.Add(gradientColorKey.color);
}
foreach (var gradientColorKey in gradientTarget.colorKeys)
{
targetColors.Add(gradientColorKey.color);
}
//设置shader中的gradient颜色
spriteRenderer.material.SetColor(OriginalTop, originalColors[2]);
spriteRenderer.material.SetColor(OriginalMid, originalColors[1]);
spriteRenderer.material.SetColor(OriginalBottom, originalColors[0]);
spriteRenderer.material.SetColor(TargetTop, targetColors[2]);
spriteRenderer.material.SetColor(TargetMid, targetColors[1]);
spriteRenderer.material.SetColor(TargetBottom, targetColors[0]);
}
//测试用
//控制Lerp的进度
private void Update()
{
if (Input.GetKey(KeyCode.UpArrow))
{
spriteRenderer.material.SetFloat(LerpControl,
spriteRenderer.material.GetFloat(LerpControl) + .01f);
}
if (Input.GetKey(KeyCode.DownArrow))
{
spriteRenderer.material.SetFloat(LerpControl,
spriteRenderer.material.GetFloat(LerpControl) - .01f);
}
最终效果
暂无关于此日志的评论。