该脚本需要搭载在有 Camera 组件的物体下才能正确显示
using UnityEngine;
// 委托突出显示事件
public delegate void HighlightingEventHandler(bool state, bool zWrite);
[RequireComponent(typeof(Camera))]
public class HighlightingEffect : MonoBehaviour
{
// 事件,用于在向突出显示缓冲区呈现之前通知highlightable对象更改其材质
public static event HighlightingEventHandler highlightingEvent;
#region Inspector Fields
// 模板(高亮显示)缓冲深度 0 默认 1 强大 2 速度 3 质量
[Header("高亮显示缓冲深度")]
public int stencilZBufferDepth = 0;
// 模板(高亮显示)缓冲大小降低采样因子
[Header("高亮显示缓冲大小降低采样因子")]
public int _downsampleFactor = 4;
// 模糊迭代
[Header("模糊迭代")]
public int iterations = 2;
// 模糊最小传播
[Header("模糊最小传播")]
[Range(0.0f,3.0f)]
public float blurMinSpread = 0.65f;
// 每次迭代的模糊扩展
[Header("每次迭代的模糊扩展")]
[Range(0.0f, 3.0f)]
public float blurSpread = 0.25f;
// 模糊材质的模糊强度
[Header("模糊材质的模糊强度")]
[Range(0.0f, 1.0f)]
public float _blurIntensity = 0.3f;
// 这些属性只在编辑器中可用——我们不需要在独立构建中使用它们
#if UNITY_EDITOR
// z缓冲写状态getter/setter
public bool stencilZBufferEnabled
{
get
{
return (stencilZBufferDepth > 0);
}
set
{
if (stencilZBufferEnabled != value)
{
stencilZBufferDepth = value ? 16 : 0;
}
}
}
// 将采样因子getter / setter
public int downsampleFactor
{
get
{
if (_downsampleFactor == 1)
{
return 0;
}
if (_downsampleFactor == 2)
{
return 1;
}
return 2;
}
set
{
if (value == 0)
{
_downsampleFactor = 1;
}
if (value == 1)
{
_downsampleFactor = 2;
}
if (value == 2)
{
_downsampleFactor = 4;
}
}
}
// 模糊alpha强度的获取/设置
public float blurIntensity
{
get
{
return _blurIntensity;
}
set
{
if (_blurIntensity != value)
{
_blurIntensity = value;
if (Application.isPlaying)
{
blurMaterial.SetFloat("_Intensity", _blurIntensity);
}
}
}
}
#endif
#endregion
#region Private Fields
// 突出显示相机图层,剔除蒙版
private int layerMask = (1 << HighlightableObject.highlightingLayer);
// 这个GameObject引用
private GameObject go = null;
// 渲染模板缓冲游戏对象的摄像头
private GameObject shaderCameraGO = null;
// 渲染模板缓冲的摄像头
private Camera shaderCamera = null;
// 渲染纹理与模具缓冲
private RenderTexture stencilBuffer = null;
// 相机参考
private Camera refCam = null;
// 模糊材质
private static Shader _blurShader;
private static Shader blurShader
{
get
{
if (_blurShader == null)
{
_blurShader = Shader.Find("Hidden/Highlighted/Blur");
}
return _blurShader;
}
}
// 合成材质
private static Shader _compShader;
private static Shader compShader
{
get
{
if (_compShader == null)
{
_compShader = Shader.Find("Hidden/Highlighted/Composite");
}
return _compShader;
}
}
// 模糊材质
private static Material _blurMaterial = null;
private static Material blurMaterial
{
get
{
if (_blurMaterial == null)
{
_blurMaterial = new Material(blurShader);
_blurMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return _blurMaterial;
}
}
// 合成材质
private static Material _compMaterial = null;
private static Material compMaterial
{
get
{
if (_compMaterial == null)
{
_compMaterial = new Material(compShader);
_compMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return _compMaterial;
}
}
#endregion
void Awake()
{
go = gameObject;
refCam = GetComponent<Camera>();
}
void OnDisable()
{
if (shaderCameraGO != null)
{
DestroyImmediate(shaderCameraGO);
}
if (_blurShader)
{
_blurShader = null;
}
if (_compShader)
{
_compShader = null;
}
if (_blurMaterial)
{
DestroyImmediate(_blurMaterial);
}
if (_compMaterial)
{
DestroyImmediate(_compMaterial);
}
if (stencilBuffer != null)
{
RenderTexture.ReleaseTemporary(stencilBuffer);
stencilBuffer = null;
}
}
void Start()
{
// 如果不支持图像效果,请禁用
if (!SystemInfo.supportsImageEffects)
{
Debug.LogWarning("HighlightingSystem : Image effects is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
// 禁用如果渲染纹理不受支持
if (!SystemInfo.supportsRenderTextures)
{
Debug.LogWarning("HighlightingSystem : RenderTextures is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
// 如果不支持渲染纹理格式,请禁用
if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32))
{
Debug.LogWarning("HighlightingSystem : RenderTextureFormat.ARGB32 is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
// 如果不支持渲染纹理HighlightingStencilOpaque格式,请禁用
if (!Shader.Find("Hidden/Highlighted/StencilOpaque").isSupported)
{
Debug.LogWarning("HighlightingSystem : HighlightingStencilOpaque shader is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
// 如果HighlightingStencilTransparent着色器不支持,请禁用
if (!Shader.Find("Hidden/Highlighted/StencilTransparent").isSupported)
{
Debug.LogWarning("HighlightingSystem : HighlightingStencilTransparent shader is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
//如果 HighlightingStencilOpaqueZ 着色器不支持,请禁用
if (!Shader.Find("Hidden/Highlighted/StencilOpaqueZ").isSupported)
{
Debug.LogWarning("HighlightingSystem : HighlightingStencilOpaqueZ shader is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
//如果 HighlightingStencilTransparentZ 着色器不支持,请禁用
if (!Shader.Find("Hidden/Highlighted/StencilTransparentZ").isSupported)
{
Debug.LogWarning("HighlightingSystem : HighlightingStencilTransparentZ shader is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
//如果 HighlightingBlur 着色器不支持,请禁用
if (!blurShader.isSupported)
{
Debug.LogWarning("HighlightingSystem : HighlightingBlur shader is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
//如果 HighlightingComposite 着色器不支持,请禁用
if (!compShader.isSupported)
{
Debug.LogWarning("HighlightingSystem : HighlightingComposite shader is not supported on this platform! Disabling.");
this.enabled = false;
return;
}
// 在模糊着色器中设置初始强度
blurMaterial.SetFloat("_Intensity", _blurIntensity);
}
// 执行一次模糊迭代
public void FourTapCone(RenderTexture source, RenderTexture dest, int iteration)
{
float off = blurMinSpread + iteration * blurSpread;
blurMaterial.SetFloat("_OffsetScale", off);
Graphics.Blit(source, dest, blurMaterial);
}
// Downsamples源纹理
private void DownSample4x(RenderTexture source, RenderTexture dest)
{
float off = 1.0f;
blurMaterial.SetFloat("_OffsetScale", off);
Graphics.Blit(source, dest, blurMaterial);
}
// 将所有突出显示的对象呈现到模板缓冲区
void OnPreRender()
{
#if UNITY_4_0
if (this.enabled == false || go.activeInHierarchy == false)
#else
if (this.enabled == false || go.active == false)
#endif
return;
if (stencilBuffer != null)
{
RenderTexture.ReleaseTemporary(stencilBuffer);
stencilBuffer = null;
}
// 打开高亮着色器
if (highlightingEvent != null)
{
highlightingEvent(true, (stencilZBufferDepth > 0));
}
// 如果没有高光物体,我们不需要渲染场景
else
{
return;
}
stencilBuffer = RenderTexture.GetTemporary((int)GetComponent<Camera>().pixelWidth, (int)GetComponent<Camera>().pixelHeight, stencilZBufferDepth, RenderTextureFormat.ARGB32);
if (!shaderCameraGO)
{
shaderCameraGO = new GameObject("HighlightingCamera", typeof(Camera));
shaderCameraGO.GetComponent<Camera>().enabled = false;
shaderCameraGO.hideFlags = HideFlags.HideAndDontSave;
}
if (!shaderCamera)
{
shaderCamera = shaderCameraGO.GetComponent<Camera>();
}
shaderCamera.CopyFrom(refCam);
//shaderCamera.projectionMatrix = refCam.projectionMatrix; // 取消注释这一行,如果你有问题使用高亮系统与自定义投影矩阵对您的相机
shaderCamera.cullingMask = layerMask;
shaderCamera.rect = new Rect(0f, 0f, 1f, 1f);
shaderCamera.renderingPath = RenderingPath.VertexLit;
shaderCamera.allowHDR = false;
shaderCamera.useOcclusionCulling = false;
shaderCamera.backgroundColor = new Color(0f, 0f, 0f, 0f);
shaderCamera.clearFlags = CameraClearFlags.SolidColor;
shaderCamera.targetTexture = stencilBuffer;
shaderCamera.Render();
// 关闭高亮着色器
if (highlightingEvent != null)
{
highlightingEvent(false, false);
}
}
// 用高光合成最后一帧
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
// 如果由于某种原因没有创建stencilBuffer
if (stencilBuffer == null)
{
// 只需将framebuffer传输到目的地
Graphics.Blit(source, destination);
return;
}
// 创建两个缓冲区来模糊图像
int width = source.width / _downsampleFactor;
int height = source.height / _downsampleFactor;
RenderTexture buffer = RenderTexture.GetTemporary(width, height, stencilZBufferDepth, RenderTextureFormat.ARGB32);
RenderTexture buffer2 = RenderTexture.GetTemporary(width, height, stencilZBufferDepth, RenderTextureFormat.ARGB32);
// 复制模具缓冲到4x4的小纹理
DownSample4x(stencilBuffer, buffer);
// 模糊小纹理
bool oddEven = true;
for (int i = 0; i < iterations; i++)
{
if (oddEven)
{
FourTapCone(buffer, buffer2, i);
}
else
{
FourTapCone(buffer2, buffer, i);
}
oddEven = !oddEven;
}
// 构成
compMaterial.SetTexture("_StencilTex", stencilBuffer);
compMaterial.SetTexture("_BlurTex", oddEven ? buffer : buffer2);
Graphics.Blit(source, destination, compMaterial);
// 清除
RenderTexture.ReleaseTemporary(buffer);
RenderTexture.ReleaseTemporary(buffer2);
if (stencilBuffer != null)
{
RenderTexture.ReleaseTemporary(stencilBuffer);
stencilBuffer = null;
}
}
}
高亮控制
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class HighlightableObject : MonoBehaviour
{
#region Editable Fields
// 建立层预留给突出显示
public static int highlightingLayer = 7;
// 高光开启速度
private static float constantOnSpeed = 4.5f;
// 高亮关闭速度
private static float constantOffSpeed = 4f;
// 默认的透明截止值用于没有_Cutoff属性的着色器
private static float transparentCutoff = 0.5f;
#endregion
#region Private Fields
// 2 * PI常数要求闪烁
private const float doublePI = 2f * Mathf.PI;
// 缓存的材质
private List<HighlightingRendererCache> highlightableRenderers;
// 缓存的高亮对象层
private int[] layersCache;
// 需要重新安装材质布尔
private bool materialsIsDirty = true;
// 当前高亮状态
private bool currentState = false;
// 当前材质突出颜色
private Color currentColor;
// 转换活动布尔
private bool transitionActive = false;
// 当前过渡值
private float transitionValue = 0f;
// 闪烁的频率
private float flashingFreq = 2f;
// One-frame 高亮布尔
private bool once = false;
// One-frame 高亮颜色
private Color onceColor = Color.red;
// 闪烁布尔
private bool flashing = false;
// 闪烁颜色最小值
private Color flashingColorMin = new Color(0.0f, 1.0f, 1.0f, 0.0f);
// 闪烁的色彩最大值
private Color flashingColorMax = new Color(0.0f, 1.0f, 1.0f, 1.0f);
// 常量高亮状态布尔
private bool constantly = false;
// 持续颜色
private Color constantColor = Color.yellow;
// 遮光板
private bool occluder = false;
// 当前使用的着色器ZWriting状态
private bool zWrite = false;
// 遮挡颜色(不要碰这个!)
private readonly Color occluderColor = new Color(0.0f, 0.0f, 0.0f, 0.005f);
//
private Material highlightingMaterial
{
get
{
return zWrite ? opaqueZMaterial : opaqueMaterial;
}
}
// 常用(用于此组件)替换材质以突出不透明的几何图形
private Material _opaqueMaterial;
private Material opaqueMaterial
{
get
{
if (_opaqueMaterial == null)
{
_opaqueMaterial = new Material(opaqueShader);
_opaqueMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return _opaqueMaterial;
}
}
// 通用的(对于这个组件)替换材料不透明的几何图形突出显示与z缓冲写启用
private Material _opaqueZMaterial;
private Material opaqueZMaterial
{
get
{
if (_opaqueZMaterial == null)
{
_opaqueZMaterial = new Material(opaqueZShader);
_opaqueZMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return _opaqueZMaterial;
}
}
//
private static Shader _opaqueShader;
private static Shader opaqueShader
{
get
{
if (_opaqueShader == null)
{
_opaqueShader = Shader.Find("Hidden/Highlighted/StencilOpaque");
}
return _opaqueShader;
}
}
//
private static Shader _transparentShader;
public static Shader transparentShader
{
get
{
if (_transparentShader == null)
{
_transparentShader = Shader.Find("Hidden/Highlighted/StencilTransparent");
}
return _transparentShader;
}
}
//
private static Shader _opaqueZShader;
private static Shader opaqueZShader
{
get
{
if (_opaqueZShader == null)
{
_opaqueZShader = Shader.Find("Hidden/Highlighted/StencilOpaqueZ");
}
return _opaqueZShader;
}
}
//
private static Shader _transparentZShader;
private static Shader transparentZShader
{
get
{
if (_transparentZShader == null)
{
_transparentZShader = Shader.Find("Hidden/Highlighted/StencilTransparentZ");
}
return _transparentZShader;
}
}
#endregion
#region Common
// 渲染器缓存的内部类
private class HighlightingRendererCache
{
public Renderer rendererCached;
public GameObject goCached;
private Material[] sourceMaterials;
private Material[] replacementMaterials;
private List<int> transparentMaterialIndexes;
// 构造
public HighlightingRendererCache(Renderer rend, Material[] mats, Material sharedOpaqueMaterial, bool writeDepth)
{
rendererCached = rend;
goCached = rend.gameObject;
sourceMaterials = mats;
replacementMaterials = new Material[mats.Length];
transparentMaterialIndexes = new List<int>();
for (int i = 0; i < mats.Length; i++)
{
Material sourceMat = mats[i];
if (sourceMat == null)
{
continue;
}
string tag = sourceMat.GetTag("RenderType", true);
if (tag == "Transparent" || tag == "TransparentCutout")
{
Material replacementMat = new Material(writeDepth ? transparentZShader : transparentShader);
if (sourceMat.HasProperty("_MainTex"))
{
replacementMat.SetTexture("_MainTex", sourceMat.mainTexture);
replacementMat.SetTextureOffset("_MainTex", sourceMat.mainTextureOffset);
replacementMat.SetTextureScale("_MainTex", sourceMat.mainTextureScale);
}
replacementMat.SetFloat("_Cutoff", sourceMat.HasProperty("_Cutoff") ? sourceMat.GetFloat("_Cutoff") : transparentCutoff);
replacementMaterials[i] = replacementMat;
transparentMaterialIndexes.Add(i);
}
else
{
replacementMaterials[i] = sharedOpaqueMaterial;
}
}
}
// 基于给定的状态变量,将缓存的渲染器的材质替换为高亮显示的材质并返回
public void SetState(bool state)
{
rendererCached.sharedMaterials = state ? replacementMaterials : sourceMaterials;
}
// 设置指定的颜色作为所有透明材质的突出显示颜色
public void SetColorForTransparent(Color clr)
{
for (int i = 0; i < transparentMaterialIndexes.Count; i++)
{
replacementMaterials[transparentMaterialIndexes[i]].SetColor("_Outline", clr);
}
}
}
//
private void OnEnable()
{
StartCoroutine(EndOfFrame());
// 订阅高亮事件
HighlightingEffect.highlightingEvent += UpdateEventHandler;
}
//
private void OnDisable()
{
StopAllCoroutines();
// 取消订阅突出显示事件
HighlightingEffect.highlightingEvent -= UpdateEventHandler;
// 清楚缓存渲染器
if (highlightableRenderers != null)
{
highlightableRenderers.Clear();
}
// 将突出显示参数重置为默认值
layersCache = null;
materialsIsDirty = true;
currentState = false;
currentColor = Color.clear;
transitionActive = false;
transitionValue = 0f;
once = false;
flashing = false;
constantly = false;
occluder = false;
zWrite = false;
/*
// 重置高亮显示的自定义参数
onceColor = Color.red;
flashingColorMin = new Color(0f, 1f, 1f, 0f);
flashingColorMax = new Color(0f, 1f, 1f, 1f);
flashingFreq = 2f;
constantColor = Color.yellow;
*/
if (_opaqueMaterial)
{
DestroyImmediate(_opaqueMaterial);
}
if (_opaqueZMaterial)
{
DestroyImmediate(_opaqueZMaterial);
}
}
#endregion
#region Public Methods
///
/// 材质初始化
/// 如果突出显示的对象更改了它的材质或子对象,请调用此方法
/// 可以多次调用每更新-渲染器重新初始化只会发生一次
///
public void ReinitMaterials()
{
materialsIsDirty = true;
}
///
/// 立即恢复原始材料。过时了。使用ReinitMaterials ()
///
public void RestoreMaterials()
{
Debug.LogWarning("HighlightingSystem : RestoreMaterials() is obsolete. Please use ReinitMaterials() instead.");
ReinitMaterials();
}
///
/// 设置一帧高亮模式的颜色
///
///
/// 高亮颜色
///
public void OnParams(Color color)
{
onceColor = color;
}
///
/// 打开单帧高亮显示
///
public void On()
{
// 仅在此框架中突出显示对象
once = true;
}
///
/// 用指定的颜色打开单帧高亮显示
/// 可以多次调用每次更新,颜色只从最新的调用将被使用
///
///
/// Highlighting color.
///
public void On(Color color)
{
// 为一帧高亮设置新颜色
onceColor = color;
On();
}
///
/// 闪烁的参数设置
///
///
/// Starting color.
///
///
/// Ending color.
///
///
/// Flashing frequency.
///
public void FlashingParams(Color color1, Color color2, float freq)
{
flashingColorMin = color1;
flashingColorMax = color2;
flashingFreq = freq;
}
///
/// 打开闪烁
///
public void FlashingOn()
{
flashing = true;
}
///
/// 从颜色1切换到颜色2
///
///
/// Starting color.
///
///
/// Ending color.
///
public void FlashingOn(Color color1, Color color2)
{
flashingColorMin = color1;
flashingColorMax = color2;
FlashingOn();
}
///
/// 从color1到color2按指定频率打开闪烁
///
///
/// Starting color.
///
///
/// Ending color.
///
///
/// Flashing frequency.
///
public void FlashingOn(Color color1, Color color2, float freq)
{
flashingFreq = freq;
FlashingOn(color1, color2);
}
///
/// 按规定的频率打开闪光灯
///
///
/// Flashing frequency.
///
public void FlashingOn(float freq)
{
flashingFreq = freq;
FlashingOn();
}
///
/// 关掉闪光
///
public void FlashingOff()
{
flashing = false;
}
///
/// 切换闪光模式
///
public void FlashingSwitch()
{
flashing = !flashing;
}
///
/// 设置常量高亮颜色
///
///
/// 不断强调颜色
///
public void ConstantParams(Color color)
{
constantColor = color;
}
///
/// 淡入持续的高光
///
public void ConstantOn()
{
// 使不断凸显
constantly = true;
// 开始过渡
transitionActive = true;
}
///
/// 褪色在不断突出与给定的颜色
///
///
/// Constant highlighting color.
///
public void ConstantOn(Color color)
{
// 设置常量高亮颜色
constantColor = color;
ConstantOn();
}
///
/// 淡出持续的高光
///
public void ConstantOff()
{
// 禁用不断凸显
constantly = false;
// Start transition
transitionActive = true;
}
///
/// 切换不断凸显
///
public void ConstantSwitch()
{
// Switch constant highlighting
constantly = !constantly;
// Start transition
transitionActive = true;
}
///
/// 立即打开持续高亮(不褪色)
///
public void ConstantOnImmediate()
{
constantly = true;
// Set transition value to 1
transitionValue = 1f;
// Stop transition
transitionActive = false;
}
///
/// 立即用指定的颜色打开持续高亮(不褪色)
///
///
/// Constant highlighting color.
///
public void ConstantOnImmediate(Color color)
{
// Set constant highlighting color
constantColor = color;
ConstantOnImmediate();
}
///
/// 立即关闭持续高亮(不淡出)
///
public void ConstantOffImmediate()
{
constantly = false;
// Set transition value to 0
transitionValue = 0f;
// Stop transition
transitionActive = false;
}
///
/// 立即切换常量高亮(不淡入/淡出)
///
public void ConstantSwitchImmediate()
{
constantly = !constantly;
// Set transition value to the final value
transitionValue = constantly ? 1f : 0f;
// Stop transition
transitionActive = false;
}
///
/// 启用遮光板模式
///
public void OccluderOn()
{
occluder = true;
}
///
/// 关闭遮光板模式
///
public void OccluderOff()
{
occluder = false;
}
///
/// 切换遮光板模式
///
public void OccluderSwitch()
{
occluder = !occluder;
}
///
/// 关掉所有类型的高亮显示
///
public void Off()
{
// Turn off all types of highlighting
once = false;
flashing = false;
constantly = false;
// Set transition value to 0
transitionValue = 0f;
// Stop transition
transitionActive = false;
}
///
/// 销毁这个HighlightableObject组件
///
public void Die()
{
Destroy(this);
}
#endregion
#region Private Methods
// 材质的初始化
private void InitMaterials(bool writeDepth)
{
currentState = false;
zWrite = writeDepth;
highlightableRenderers = new List<HighlightingRendererCache>();
MeshRenderer[] mr = GetComponentsInChildren<MeshRenderer>();
CacheRenderers(mr);
SkinnedMeshRenderer[] smr = GetComponentsInChildren<SkinnedMeshRenderer>();
CacheRenderers(smr);
#if !UNITY_FLASH
//ClothRenderer[] cr = GetComponentsInChildren();
//CacheRenderers(cr);
#endif
currentState = false;
materialsIsDirty = false;
currentColor = Color.clear;
}
// 缓存给定的渲染器属性
private void CacheRenderers(Renderer[] renderers)
{
for (int i = 0; i < renderers.Length; i++)
{
Material[] materials = renderers[i].sharedMaterials;
if (materials != null)
{
highlightableRenderers.Add(new HighlightingRendererCache(renderers[i], materials, highlightingMaterial, zWrite));
}
}
}
// 更新突出显示颜色到一个给定的值
private void SetColor(Color c)
{
if (currentColor == c)
{
return;
}
if (zWrite)
{
opaqueZMaterial.SetColor("_Outline", c);
}
else
{
opaqueMaterial.SetColor("_Outline", c);
}
for (int i = 0; i < highlightableRenderers.Count; i++)
{
highlightableRenderers[i].SetColorForTransparent(c);
}
currentColor = c;
}
// 如果需要,设置新的颜色
private void UpdateColors()
{
// 如果高亮显示被禁用,不要更新颜色
if (currentState == false)
{
return;
}
if (occluder)
{
SetColor(occluderColor);
return;
}
if (once)
{
SetColor(onceColor);
return;
}
if (flashing)
{
// 闪光频率不受时间尺度的影响
Color c = Color.Lerp(flashingColorMin, flashingColorMax, 0.5f * Mathf.Sin(Time.realtimeSinceStartup * flashingFreq * doublePI) + 0.5f);
SetColor(c);
return;
}
if (transitionActive)
{
Color c = new Color(constantColor.r, constantColor.g, constantColor.b, constantColor.a * transitionValue);
SetColor(c);
return;
}
else if (constantly)
{
SetColor(constantColor);
return;
}
}
// 如果需要,计算新的转换值
private void PerformTransition()
{
if (transitionActive == false)
{
return;
}
float targetValue = constantly ? 1f : 0f;
// 是否完成过渡
if (transitionValue == targetValue)
{
transitionActive = false;
return;
}
if (Time.timeScale != 0f)
{
// 计算不受时间影响的时间增量
float unscaledDeltaTime = Time.deltaTime / Time.timeScale;
// 计算新的过渡值
transitionValue += (constantly ? constantOnSpeed : -constantOffSpeed) * unscaledDeltaTime;
transitionValue = Mathf.Clamp01(transitionValue);
}
else
{
return;
}
}
// 突出显示事件处理程序(主突出显示方法)
private void UpdateEventHandler(bool trigger, bool writeDepth)
{
// 更新并启用高亮显示
if (trigger)
{
// ZWriting状态是否改变
if (zWrite != writeDepth)
{
materialsIsDirty = true;
}
// 如果需要,初始化新材质
if (materialsIsDirty)
{
InitMaterials(writeDepth);
}
currentState = (once || flashing || constantly || transitionActive || occluder);
if (currentState)
{
UpdateColors();
PerformTransition();
if (highlightableRenderers != null)
{
layersCache = new int[highlightableRenderers.Count];
for (int i = 0; i < highlightableRenderers.Count; i++)
{
GameObject go = highlightableRenderers[i].goCached;
// 缓存层
layersCache[i] = go.layer;
// 临时设置层渲染由高亮效果相机
go.layer = highlightingLayer;
highlightableRenderers[i].SetState(true);
}
}
}
}
// 禁用高亮显示
else
{
if (currentState && highlightableRenderers != null)
{
for (int i = 0; i < highlightableRenderers.Count; i++)
{
highlightableRenderers[i].goCached.layer = layersCache[i];
highlightableRenderers[i].SetState(false);
}
}
}
}
IEnumerator EndOfFrame()
{
while (enabled)
{
yield return new WaitForEndOfFrame();
// 在场景中的每个高光效果完成渲染后,重置一帧高光状态
once = false;
}
}
#endregion
}
简单应用 可编写自定义脚本
前提:物体有碰撞盒
鼠标进入 物体闪烁
鼠标退出 物体停止闪烁
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Highlight_ZH : MonoBehaviour
{
protected HighlightableObject _HighlightableObject;
void Awake()
{
_HighlightableObject = gameObject.AddComponent<HighlightableObject>();
}
private void OnMouseEnter()
{
_HighlightableObject.FlashingOn(Color.cyan, Color.red, 1);
}
private void OnMouseExit()
{
_HighlightableObject.FlashingOff();
}
}
Camera 搭载
物体 搭载
这里面有所有的相关文件
下载地址: Unity 模型边缘 高亮插件.
暂时先这样吧,如果有时间的话就会更新,实在看不明白就留言,看到我会回复的。
路漫漫其修远兮,与君共勉。