当物体进入碰撞射线的时候逐渐变成半透效果,离开射线时逐渐恢复原状
源码分享:
脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class XrayCameral : MonoBehaviour
{
private GameObject[] go;
public Transform tar;
// List<Transform> listHitObjLastSave = new List<Transform>();
// List<Transform> listHitObjLast = new List<Transform>();
List<Transform> listHitObj = new List<Transform>();
List<Transform> listObjAll = new List<Transform>();
List<Material> listM = new List<Material>();
int colorID;
void Start()
{
colorID = Shader.PropertyToID("_Color");
go = GameObject.FindGameObjectsWithTag("obs");
foreach (GameObject game in go)
{
listObjAll.Add(game.transform);
}
// Debug.Log(game.name);
}
void Update()
{
Vector3 tarDir = (tar.position - transform.position).normalized;
Debug.DrawLine(tar.position, transform.position, Color.red);
float tarDis = Vector3.Distance(tar.position, transform.position);
RaycastHit[] HitObj = Physics.RaycastAll(transform.position, tarDir, tarDis);
for (int i = 0; i < HitObj.Length; i++)
{
RaycastHit hit = HitObj[i];
if (hit.transform == tar.transform)
{
continue;
}
listHitObj.Add(hit.transform);
SetAlpha(listHitObj);
}
//listHitObjLastSave = listHitObj;
for (int i = 0; i < listObjAll.Count; i++)
{
bool isHave = false;
//bool isCount = false;
for (int j = 0; j < listHitObj.Count; j++)
{
if (listObjAll.Contains(listHitObj[j]))
{
isHave = true;
break;
}
else
{
isHave = false;
}
//for (int k = 0; k < listHitObjLastSave.Count; k++)
//{
// if (listHitObj[j] == listHitObjLastSave[k])
// {
// isCount = true;
// break;
// }
//}
}
//for (int k = 0; k < listHitObjLastSave.Count; k++)
//{
// for (int j = 0; j < listHitObj.Count; j++)
// {
// if (listHitObjLastSave[k] == listHitObj[j])
// {
// isCount = true;
// break;
// }
// }
//}
// Debug.Log(listHitObj.Count+ listHitObjLastSave.Count);
if (!isHave/* || !isCount*/)
{
SetNoAlpha(listObjAll);
}
}
listHitObj.Clear();
// listHitObjLastSave.Clear();
}
void SetAlpha(List<Transform> list)
{
float mTargetAlpha;
float mCurrentAlpha;
for (int k = 0; k < list.Count; ++k)
{
Renderer renderer = list[k].gameObject.GetComponent<Renderer>();
if (renderer)
{
listM.Add(renderer.material);
}
}
for (int j = 0; j < listM.Count; ++j)
{
listM[j].SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
listM[j].SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
listM[j].renderQueue = 3000;
Color c = listM[j].GetColor(colorID);
// c.a = mCurrentAlpha;
mCurrentAlpha = c.a;
// Debug.Log("isdown");
mTargetAlpha = 0.3f;
if (mCurrentAlpha > mTargetAlpha)
{
mCurrentAlpha -= Time.deltaTime;
}
else
{
mCurrentAlpha = mTargetAlpha;
}
c.a = mCurrentAlpha;
// Debug.Log(mCurrentAlpha);
// Debug.Log("setalpha " + mCurrentAlpha);
listM[j].SetColor(colorID, c);
}
listM.Clear();
}
void SetNoAlpha(List<Transform> list)
{
float mTargetAlpha;
float mCurrentAlpha;
for (int k = 0; k < list.Count; ++k)
{
Renderer renderer = list[k].gameObject.GetComponent<Renderer>();
if (renderer)
{
listM.Add(renderer.material);
}
}
for (int j = 0; j < listM.Count; ++j)
{
Color c = listM[j].GetColor(colorID);
// c.a = mCurrentAlpha;
mCurrentAlpha = c.a;
// Debug.Log("nodown");
mTargetAlpha = 1.0f;
if (mCurrentAlpha < mTargetAlpha)
{
mCurrentAlpha += Time.deltaTime;
}
else
{
mCurrentAlpha = mTargetAlpha;
listM[j].SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
listM[j].SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
listM[j].renderQueue = 2000;
}
c.a = mCurrentAlpha;
// Debug.Log("setnoalpha "+mCurrentAlpha);
listM[j].SetColor(colorID, c);
}
listM.Clear();
}
}
Shader
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Artist/Transparent/Diffuse - Obs" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
[Space(10)][Enum(UnityEngine.Rendering.BlendMode)]_SrcBlend("SrcBlend",float) = 1
[Enum(UnityEngine.Rendering.BlendMode)]_DstBlend("DstBlend",float) = 0
}
SubShader {
Tags {"RenderType"="Opaque" "Queue"="Geometry" "IgnoreProjector"="True" }
Blend[_SrcBlend][_DstBlend]
LOD 200
pass{
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma multi_compile_fwdbase
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
sampler2D _MainTex;
fixed4 _Color;
float4 _MainTex_ST;
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
SHADOW_COORDS(3)
};
v2f vert(a2v v) {
v2f o;
UNITY_INITIALIZE_OUTPUT(v2f, o);
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.worldNormal = UnityObjectToWorldNormal(v.normal);
TRANSFER_SHADOW(o);
return o;
}
fixed4 frag(v2f i) : SV_Target {
fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(i.worldNormal, lightDir));
UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
return fixed4(ambient + diffuse * atten , _Color.a);
}
ENDCG
}
}
Fallback "Legacy Shaders/VertexLit"
}