Unity JellySurface果冻效果改造:实现持续触发而非仅受击生效求解
果冻形变不稳定问题修复方案
问题根因
- 点位坐标空间不匹配:如果
positions数组赋值的是对象本地相对坐标(比如在Inspector里手动填写的相对于史莱姆自身的点位),直接传给shader作为世界空间的_ImpactOrigin会导致触发点偏移,对象移动后会完全失效 - 数组空引用风险:未校验
positions数组是否为空、是否有合法元素,随机取值时可能触发索引越界错误,直接终止代码运行 - 命名冲突风险:触发形变的函数命名为
shader,和Unity/C#内置关键字存在冲突,部分编译环境下会偶发调用失败 - 材质参数覆盖风险:如果多脚本同时操作同一个材质的
_ControlTime参数,会出现数值被覆盖的问题
修复后代码
public class JellyClickReceiver : MonoBehaviour { Renderer modelRenderer; float controlTime; // Inspector中填写相对于当前对象的本地坐标点位即可 public Vector3[] localImpactPositions; void Start () { modelRenderer = GetComponent<MeshRenderer>(); // 提前校验点位数组合法性,为空则默认添加对象中心点作为触发位 if (localImpactPositions == null || localImpactPositions.Length == 0) { localImpactPositions = new Vector3[] { Vector3.zero }; } InvokeRepeating("TriggerJellyDeform", 1.0f, 6f); } void Update () { controlTime += Time.deltaTime; modelRenderer.material.SetFloat("_ControlTime", controlTime); } void TriggerJellyDeform() { controlTime = 0; int randomIndex = Random.Range(0, localImpactPositions.Length); // 本地坐标转世界坐标,适配对象移动场景 Vector3 worldImpactPos = transform.TransformPoint(localImpactPositions[randomIndex]); modelRenderer.material.SetVector("_ModelOrigin", transform.position); modelRenderer.material.SetVector("_ImpactOrigin", worldImpactPos); } }
额外排查项
如果修改后仍存在问题,请检查以下配置:
- 确认shader中
_ControlTime、_ModelOrigin、_ImpactOrigin三个属性的名称、类型和代码完全一致,属性名称大小写敏感 - 如果果冻对象包含多个子网格/多材质,需要遍历所有材质设置参数,不要仅设置第一个材质
- 不要将localImpactPositions填写为超出对象边界的坐标,会导致形变效果过弱几乎不可见
内容的提问来源于stack exchange,提问作者OmaeWAc
相关产品推荐
相关产品推荐

