最终效果:
准备工作:
打开unity新建一个2D场景,导入一张2D人物图片和一张透明的图片(用来接收影子),修改图片Texture Type为 Sprite 类型,
拖入2D人物精灵图到场景,然后拖拽透明图到人物精灵图节点下,命名为shadow,用来接收影子
然后新建一个材质球,拖拽到 shadow 节点上,shader选择我们将要新建的shadow.shader。
场景如下:
实现思路:
其实很简单,就是把人物的纹理传递给shadow shader, 把alpha值大于0的像素的rgb变为黑色即可。
shader:
Shader "lcl/selfDemo/playerShadow"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.uv.y = 1 - o.uv.y;
return o;
}
sampler2D _MainTex;
//通过c#获取到人物纹理传递过来
sampler2D _HeroTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_HeroTex, i.uv);
//当a大于0时,颜色变为黑色即可
if(col.a > 0 ){
col.rgb = 0;
}
return col;
}
ENDCG
}
}
}
c#:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerShadow : MonoBehaviour
{
public GameObject shadow;
void Start()
{
if (!shadow)
{
return;
}
//获取shadow 材质
var shadowMat = shadow.GetComponent<SpriteRenderer>().material;
//获取人物纹理
var heroTex = GetComponent<SpriteRenderer>().sprite.texture;
//传递给shadow shader
shadowMat.SetTexture("_HeroTex",heroTex);
}
}
最后把c#脚本拖拽到人物节点上,把shadow拖拽到shadow变量上,点击运行即可
最终效果: