You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 11:15:02