有段时间没写东西了,最近有点小累啊。最近美术在K动画反映的问题,如果Image组件挂了新材质后,无法在Image上K材质中的效果。

使用MeshRenderer组件是可以K的,这里简单的给Image材质拓展了一个置灰的效果。如下图所示,MeshRenderer组件就可K材质动画。
所以我觉得,如果给Image组件同时在绑定MeshRenderer组件。动效师给MeshRenderer组件K动画,在Update中实时将数据同步给Image就可以了。如下图所示,脚本通过读取Image的材质取出所有属性,因为Update不需要将所有数据都同步,这里需要勾选那些数据进行同步。
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(Image))]
public class ImageAnim : MonoBehaviour
{
[System.Serializable]
public class Data
{
public string name;
public string type;
public bool enable;
}
public List<Data> Property = new List<Data>();
private Image m_Image;
private Material m_ImageMat;
private MeshRenderer m_MeshRenderer;
private MaterialPropertyBlock m_MaterialPropertyBlock;
private void Awake()
{
m_MeshRenderer = GetComponent<MeshRenderer>();
m_MaterialPropertyBlock = new MaterialPropertyBlock();
m_Image = GetComponent<Image>();
m_ImageMat = Instantiate(m_Image.material);
m_Image.material = m_ImageMat;
}
private void LateUpdate()
{
if (m_MeshRenderer.HasPropertyBlock())
{
m_MeshRenderer.GetPropertyBlock(m_MaterialPropertyBlock);
foreach (var item in Property)
{
if (item.enable)
{
SetValue(item.name, item.type);
}
}
}
}
void SetValue (string name, string type)
{
switch (type)
{
case "Color":
m_Image.color = m_MaterialPropertyBlock.GetColor(name);
break;
case "Float":
case "Range":
m_Image.material.SetFloat(name,m_MaterialPropertyBlock.GetFloat(name));
break;
case "Vector":
m_Image.material.SetVector(name, m_MaterialPropertyBlock.GetVector(name));
break;
default:
break;
}
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(ImageAnim))]
public class MyTestEditor : Editor
{
ImageAnim myTest;
MeshRenderer meshrenderer;
private void OnEnable()
{
myTest = (target as ImageAnim);
meshrenderer = myTest.GetComponent<MeshRenderer>();
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("refresh"))
{
myTest.Property = new List<ImageAnim.Data>();
Shader shader = meshrenderer.sharedMaterial.shader;
int count = shader.GetPropertyCount();
for (int i = 0; i < count; i++)
{
myTest.Property.Add(new ImageAnim.Data() { name = shader.GetPropertyName(i), type = shader.GetPropertyType(i).ToString() });
}
}
}
}
#endif
接着对image的MeshRenderer组件K一个Gray的置灰系数。
OK 大功告成,image已经可以由动画控制了。
这个方法只是我的一个思路,我也没有在项目中放手使用,有相关经验的朋友欢迎讨论。
- 本文固定链接: https://www.xuanyusong.com/archives/4881
- 转载请注明: 雨松MOMO于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!





大神的方法果然妙
需要做材质的实例化 在编辑器状态下预览就会导致各种资源丢失问题。其实都不需要Meshrender 只需要把材质属性弄出来 用一个脚本包裹一下K帧就行
啥都发布
使用另外一种方式实现。新建一个脚本,继承BaseMeshEffect。将需要修改的材质属性暴露出来,通过寄存器通道传递给shader处理。这样,做动画时,就可以直接控制暴露出来的变量。参考如下。https://www.zhihu.com/question/437168564/answer/1654231245
我们做过类似的方法, 但是美术同学比较抵制, 他们希望可以和MeshRenderer一样K动画的体验,如果不订制修改源码是实现不了的。。
大佬,但是不能对贴图的Offset 进行K帧,可有解决方案??
很好