Unity Shader当用户靠近的时候会出现吃鸡一样的光墙

本文介绍了一个Unity脚本,用于创建一个根据玩家位置动态变化的光墙效果。通过设置shader,当用户靠近墙壁时,光墙的不透明度会随距离减小而增加。

Unity动态光墙效果:根据玩家距离显示透明光幕

效果展示

靠近墙壁效果远离墙壁效果
靠近墙壁效果远离墙壁效果

实现原理

通过Shader计算玩家位置与墙面距离,动态调整透明度,结合UV动画创建流动效果。关键参数:

  • 渐变过渡范围(_EdgeRange)
  • UV流动速度(_uvSpeed)
  • 叠加颜色(_Color)

材质设置


优化后的脚本代码

[RequireComponent(typeof(MeshRenderer))]
public class WallEffectController : MonoBehaviour
{
    [Header("References")]
    [Tooltip("拖拽玩家角色到此字段")]
    [SerializeField] private Transform _player;

    [Header("Settings")]
    [SerializeField] private int _materialIndex = 0;

    private Material _wallMaterial;
    
    private void Start()
    {
        var renderer = GetComponent<MeshRenderer>();
        if (renderer && renderer.materials.Length > _materialIndex)
        {
            // 使用sharedMaterial避免创建实例
            _wallMaterial = renderer.sharedMaterials[_materialIndex];
        }
        else
        {
            Debug.LogError("材质获取失败,请检查MeshRenderer组件");
        }

        if (!_player)
        {
            Debug.LogError("玩家引用未设置,效果将无法正常工作");
        }
    }

    private void Update()
    {
        if (_wallMaterial && _player)
        {
            // 使用世界坐标的Y轴高度差进行计算
            Vector3 playerPos = _player.position;
            playerPos.y = transform.position.y; // 保持Y轴一致避免高度影响
            _wallMaterial.SetVector("_PlayerPos", playerPos);
        }
    }

    // 在编辑器模式下重置材质参数
    private void OnDisable()
    {
        if (_wallMaterial)
        {
            _wallMaterial.SetVector("_PlayerPos", Vector3.one * 1000);
        }
    }
}

优化后的Shader代码

Shader "Effects/DynamicWall"
{
    Properties
    {
        [Header(Textures)]
        _MainTex("Base Texture", 2D) = "white" {}
        _FlowNoise("Flow Noise", 2D) = "white" {}
        
        [Header(Settings)]
        _Color("Tint Color", Color) = (1,1,1,1)
        _FadeRange("Fade Range", Vector) = (2, 6, 0, 0)
        _FlowSpeed("Flow Speed", Vector) = (1, 0, 0, 0)
    }

    SubShader
    {
        Tags { 
            "RenderType" = "Transparent" 
            "Queue" = "Transparent+100" 
            "IgnoreProjector" = "True" 
        }
        
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float2 uvNoise : TEXCOORD1;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                float2 uvNoise : TEXCOORD1;
                float3 worldPos : TEXCOORD2;
            };

            sampler2D _MainTex, _FlowNoise;
            float4 _MainTex_ST, _FlowNoise_ST;
            float4 _Color;
            float2 _FadeRange;
            float2 _FlowSpeed;

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.uvNoise = TRANSFORM_TEX(v.uvNoise, _FlowNoise);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // UV动画
                float2 scrollUV = i.uvNoise + _Time.y * _FlowSpeed;
                
                // 纹理采样
                fixed4 baseTex = tex2D(_MainTex, i.uv);
                fixed4 noiseTex = tex2D(_FlowNoise, scrollUV);
                
                // 距离计算
                float dist = distance(i.worldPos, _PlayerPos.xyz);
                float alpha = 1 - smoothstep(_FadeRange.x, _FadeRange.y, dist);
                
                // 最终颜色合成
                fixed4 finalColor = baseTex * noiseTex * _Color;
                finalColor.a *= alpha;
                
                return finalColor;
            }
            ENDCG
        }
    }
}

使用

  1. 创建新材质并指定DynamicWall Shader

  2. 按需配置参数:

    • Base Texture:基础纹理
    • Flow Noise:流动噪波图
    • Fade Range:建议(2, 6)
    • Flow Speed:控制流动速度
  3. 将优化后的脚本挂载到墙面物体

  4. 将玩家角色拖拽到Player字段

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值