
目录
[Shader Graph节点实现](#Shader Graph节点实现)
前言
在 2D 游戏开发中,瓶子装液体的视觉效果是一种常见但又具有挑战性的表现形式。传统做法通常依赖复杂的物理模拟或额外的动画控制,而在 Unity 中,我们可以借助 Unity Shader Graph 以更轻量的方式实现这一效果。本文将介绍如何通过 Shader Graph 构建一个 2D 液体填充 Shader,使瓶子中的液体能够根据参数控制填充高度,并在瓶子移动时保持同步,同时在瓶子旋转时仍然保持水平的液面效果。该实现的核心思路是利用世界空间坐标与物体位置的差值计算像素的相对高度,从而生成液体遮罩区域。通过这一方法,我们无需复杂的物理系统即可实现稳定、可控且性能开销较低的液体表现效果,非常适合用于药水瓶、试剂瓶或能量容器等游戏视觉元素。
实现思路
从原理上来分析,液体填充的本质是一个高度遮罩,即通过控制遮罩的Y轴高度,来实现填充的效果。这里主要需要用到两个坐标,一个是物体的世界坐标,一个是物体的自身坐标。核心思路是获取物体像素对应的世界坐标,并拆出Y轴的高度,同时获取物体自身坐标的Y值,将两者相减获得像素相对于物体中心的高度值。然后将这个相对高度与一个可调浮点参数FillAmount进行比较,当像素的高度低于液体高度时可以认为该区域属于液体部分,从而生成液体的填充区域。这样做的好处在于液体高度是基于世界空间计算的,因此当瓶子发生旋转时,液体表面仍会保持水平。而通过减去物体自身坐标,又可以保证瓶子移动时液体能够跟随移动。最后再将生成的液体遮罩与瓶子贴图的透明通道值进行相乘,达到限制液体只显示在瓶子内部区域的目的,从而完成一个稳定且可控的2D液体填充效果。
Shader Graph节点实现
变量声明
声明名为MainTex的Texture 2D变量,声明名为FillAmount的浮点型变量控制液体的填充部分,声明名为LiquidColor的Color变量,用来控制液体的颜色。

液体填充
创建Position节点,并设置空间为世界坐标空间,用该坐标减去Subtract物体的自身坐标Object里的Position。得到的结果用Split节点进行拆分,获取到Y轴的值(即R的值)。然后将Y轴的值输入到Step节点,并用FillAmount变量作为Step节点的In输入。通过控制FillAmount的值就能够控制液体填充的多少。

液体颜色及遮罩限制
将关联的MainTex即贴图通过Sample Texture 2D节点进行采样,然后输出的数据的透明通道值与上面液体填充的输出值相乘,从而限制液体仅显示在贴图显示的部分。然后将液体填充的输出值与创建的LiquidColor的颜色变量相乘,从而控制液体的颜色。最后将没有和颜色相乘的数据连接到最终的输出透明通道上,将和颜色相乘的输出连接到Base Color上。

最终效果
创建一个对应的材质球,并将材质球关联到对应的Sprite Renderer上。然后设置一下液体的颜色和FillAmount的值,就可以的到下面的效果。

当旋转液体瓶角度时,液体也会保持水平,如下所示。
