主要参考Highlighting System 插件。
效果:
被Plane挡住:
没有被plane挡住:
HighlightableObjectSimple 组件,挂上这个组件的物体更换所有的材质,更换物体的layer。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class HighlightableObjectSimple : MonoBehaviour {
private List<HighlightingRendererCache> highlightableRenderers;
private bool zWrite = false;
private static float transparentCutoff = 0.5f;
private bool materialsIsDirty = true;
private int[] layersCache;
public static int highlightingLayer = 7;
private Color currentColor;
private Material highlightingMaterial
{
get
{
return zWrite ? opaqueZMaterial : opaqueMaterial;
}
}
// Common (for this component) replacement material for opaque geometry highlighting
private Material _opaqueMaterial;
private Material opaqueMaterial
{
get
{
if (_opaqueMaterial == null)
{
_opaqueMaterial = new Material(opaqueShader);
_opaqueMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return _opaqueMaterial;
}
}
// Common (for this component) replacement material for opaque geometry highlighting with Z-Buffer writing enabled
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;
}
}
void Start()
{
InitMaterials(false);
}
private void InitMaterials(bool writeDepth)
{
highlightableRenderers = new List<HighlightingRendererCache>();
MeshRenderer[] mr = GetComponentsInChildren<MeshRenderer>();
CacheRenderers(mr);
SkinnedMeshRenderer[] smr = GetComponentsInChildren<SkinnedMeshRenderer>();
CacheRenderers(smr);
materialsIsDirty = false;
}
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 OnEnable()
{
HighlightingEffect.highlightingEvent += UpdateEventHandler;
}
private void OnDisable()
{
HighlightingEffect.highlightingEvent -= UpdateEventHandler;
if (highlightableRenderers != null)
{
highlightableRenderers.Clear();
}
// Reset highlighting parameters to default values
layersCache = null;
materialsIsDirty = true;
zWrite = false;
if (_opaqueMaterial)
{
DestroyImmediate(_opaqueMaterial);
}
if (_opaqueZMaterial)
{
DestroyImmediate(_opaqueZMaterial);
}
}
private void SetColor(Color c)
{
if (currentColor == c)
{
return;
}
if (zWrite)
{
opaqueZMaterial.SetColor("_Outline", c);
}
else
{
opaqueMaterial.SetColor("_Outline", c);
}