最终效果
shader代码
Shader "SurvivalTemplatePro/Interactable"
{
Properties
{
_ASEOutlineColor( "Outline Color", Color ) = (0.8962264,0.7633126,0.2832412,0)
_ASEOutlineWidth( "Outline Width", Float ) = 0.01
_Cutoff( "Mask Clip Value", Float ) = 0.5
_Color("Base Color", Color) = (1,1,1,0)
_MainTex("Base Color Map", 2D) = "white" {}
_MaskMap("Mask Map", 2D) = "white" {}
[Normal]_BumpMap("Normal Map", 2D) = "bump" {}
_LineMap("Line Map", 2D) = "white" {}
[HDR]_LineColor("Line Color", Color) = (1.991077,1.306363,0.3513666,1)
_LineAlpha("Line Alpha", Range( 0 , 1)) = 1
_LineSize("Line Size", Range( 0.1 , 2)) = 1
_LineSpeed("Line Speed", Range( 0.1 , 2)) = 1
[HideInInspector] _texcoord( "", 2D ) = "white" {}
[HideInInspector] __dirty( "", Int ) = 1
}
SubShader
{
Tags{ }
Cull Front
CGPROGRAM
#pragma target 3.0
#pragma surface outlineSurf Outline keepalpha noshadow noambient novertexlights nolightmap nodynlightmap nodirlightmap nometa noforwardadd vertex:outlineVertexDataFunc
struct Input {
half filler;
};
float4 _ASEOutlineColor;
float _ASEOutlineWidth;
void outlineVertexDataFunc( inout appdata_full v, out Input o )
{
UNITY_INITIALIZE_OUTPUT( Input, o );
v.vertex.xyz += ( v.normal * _ASEOutlineWidth );
}
inline half4 LightingOutline( SurfaceOutput s, half3 lightDir, half atten ) { return half4 ( 0,0,0, s.Alpha); }
void outlineSurf( Input i, inout SurfaceOutput o )
{
o.Emission = _ASEOutlineColor.rgb;
o.Alpha = 1;
}
ENDCG
Tags{ "RenderType" = "TransparentCutout" "Queue" = "Geometry+0" "IsEmissive" = "true" }
Cull Back
CGPROGRAM
#include "UnityShaderVariables.cginc"
#pragma target 3.0
#pragma surface surf Standard keepalpha addshadow fullforwardshadows exclude_path:deferred
struct Input
{
float2 uv_texcoord;
float3 worldPos;
};
uniform sampler2D _BumpMap;
uniform float4 _BumpMap_ST;
uniform float4 _Color;
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform float _LineAlpha;
uniform sampler2D _LineMap;
uniform float _LineSpeed;
uniform float _LineSize;
uniform float4 _LineColor;
uniform sampler2D _MaskMap;
uniform float4 _MaskMap_ST;
uniform float _Cutoff = 0.5;
void surf( Input i , inout SurfaceOutputStandard o )
{
float2 uv_BumpMap = i.uv_texcoord * _BumpMap_ST.xy + _BumpMap_ST.zw;
float3 tex2DNode2 = UnpackNormal( tex2D( _BumpMap, uv_BumpMap ) );
float3 NormalMap266 = tex2DNode2;
o.Normal = NormalMap266;
float2 uv_MainTex = i.uv_texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
float4 tex2DNode1 = tex2D( _MainTex, uv_MainTex );
o.Albedo = ( _Color * tex2DNode1 ).rgb;
float2 temp_cast_1 = (_LineSpeed).xx;
float3 ase_vertex3Pos = mul( unity_WorldToObject, float4( i.worldPos , 1 ) );
float2 temp_cast_2 = (( ase_vertex3Pos.x * _LineSize )).xx;
float2 panner243 = ( _Time.y * temp_cast_1 + temp_cast_2);
float4 temp_output_119_0 = ( tex2D( _LineMap, panner243 ) * _LineColor );
float3 desaturateInitialColor282 = float3( (tex2DNode2).xy , 0.0 );
float desaturateDot282 = dot( desaturateInitialColor282, float3( 0.299, 0.587, 0.114 ));
float3 desaturateVar282 = lerp( desaturateInitialColor282, desaturateDot282.xxx, 1.0 );
float4 lerpResult248 = lerp( float4( 0,0,0,0 ) , ( float4( 0,0,0,0 ) * temp_output_119_0 ) , float4( saturate( desaturateVar282 ) , 0.0 ));
float2 uv_MaskMap = i.uv_texcoord * _MaskMap_ST.xy + _MaskMap_ST.zw;
float4 tex2DNode3 = tex2D( _MaskMap, uv_MaskMap );
float4 lerpResult278 = lerp( float4( 0,0,0,0 ) , ( lerpResult248 + ( temp_output_119_0 * float4( 0.245283,0.245283,0.245283,0 ) ) ) , tex2DNode3.g);
float4 Line32 = ( _LineAlpha * lerpResult278 );
o.Emission = Line32.rgb;
o.Metallic = tex2DNode3.r;
o.Smoothness = tex2DNode3.a;
o.Occlusion = tex2DNode3.g;
o.Alpha = 1;
clip( tex2DNode1.a - _Cutoff );
}
ENDCG
}
Fallback "Diffuse"
}
线状映射图片
配置,按该shader新增材质
Outline Width控制描边
Line Speed控制闪光速度
当然,还可以修改对应的颜色
代码控制物品描边显示隐藏
using UnityEngine;
//拾取脚本
public class PickUpController : MonoBehaviour
{
public float maxDistance = 3f; // 最大检测距离
public LayerMask layerMask; // 检测层级
public GameObject uiText; // 显示物品名称的 UI 文本组件
Transform lastHitInfo;
void Start()
{
uiText.SetActive(false); // 初始状态下 UI 文本组件不可见
}
void Update()
{
// 从相机屏幕中心向前发射一条射线
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, maxDistance, layerMask))
{
lastHitInfo = hitInfo.transform;
uiText.SetActive(true);
//设置物品描边
SetOutline(lastHitInfo, 0.01f);
//hitInfo.transform.CompareTag("PickUpItem") 需要的话可以再加标签判断
if (Input.GetKeyDown(KeyCode.E))
{
PickUpItem(lastHitInfo);
}
}
else
{
uiText.SetActive(false);
if (lastHitInfo != null) SetOutline(lastHitInfo, 0f);
}
}
// 拾取物体逻辑
void PickUpItem(Transform item)
{
//。。。
}
//设置物品描边
void SetOutline(Transform obj, float width)
{
Renderer renderer = obj.GetComponent<Renderer>();
if (renderer != null)
{
Material material = renderer.material;
material.SetFloat("_ASEOutlineWidth", width);
}
foreach (Transform child in obj)
{
SetOutline(child, width);
}
}
}
效果演示
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~