123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- using System;
- using System.Linq;
- using UnityEngine;
- namespace TFramework
- {
- [DisallowMultipleComponent]
- public class Outline : MonoBehaviour
- {
- public enum Mode
- {
- /// <summary>
- /// 描边所有轮廓
- /// </summary>
- OutlineAll,
- /// <summary>
- /// 仅描边可见部分
- /// </summary>
- OutlineVisible,
- /// <summary>
- /// 仅描边隐藏部分
- /// </summary>
- OutlineHidden,
- /// <summary>
- /// 描边且剪影
- /// </summary>
- OutlineAndSilhouette,
- /// <summary>
- /// 仅描边
- /// </summary>
- SilhouetteOnly
- }
- /// <summary>
- /// 描边模式
- /// </summary>
- public Mode OutlineMode
- {
- get { return outlineMode; }
- set
- {
- outlineMode = value;
- _isChange = true;
- }
- }
- /// <summary>
- /// 描边颜色
- /// </summary>
- public Color OutlineColor
- {
- get { return outlineColor; }
- set
- {
- outlineColor = value;
- _isChange = true;
- }
- }
- /// <summary>
- /// 描边宽度
- /// </summary>
- public float OutlineWidth
- {
- get { return outlineWidth; }
- set
- {
- outlineWidth = value;
- _isChange = true;
- }
- }
- [SerializeField]
- private Mode outlineMode;
- [SerializeField]
- private Color outlineColor;
- [SerializeField, Range(0f, 10f)]
- private float outlineWidth = 2f;
- private Renderer[] renderers;
- private Material outlineMaskMaterial;
- private Material outlineFillMaterial;
- private bool _isChange=false;
- void Awake()
- {
- renderers = GetComponentsInChildren<Renderer>();
- // Instantiate outline materials
- outlineMaskMaterial = Instantiate(Main.GetMagr<EffectManager>().m_outlineMaskMaterial);
- outlineFillMaterial = Instantiate(Main.GetMagr<EffectManager>().m_outlineFillMaterial);
- outlineMaskMaterial.name = "OutlineMask (Instance)";
- outlineFillMaterial.name = "OutlineFill (Instance)";
- }
- void OnEnable()
- {
- foreach (var renderer in renderers)
- {
- var materials = renderer.sharedMaterials.ToList();
- materials.Add(outlineMaskMaterial);
- materials.Add(outlineFillMaterial);
- renderer.materials = materials.ToArray();
- }
- _isChange = true;
- }
- private void Update()
- {
- if(_isChange)
- {
- _isChange = false;
- UpdateMaterialProperties();
- }
- }
- void OnDisable()
- {
- foreach (var renderer in renderers)
- {
- // Remove outline shaders
- var materials = renderer.sharedMaterials.ToList();
- materials.Remove(outlineMaskMaterial);
- materials.Remove(outlineFillMaterial);
- renderer.materials = materials.ToArray();
- }
- }
- void OnDestroy()
- {
- Destroy(outlineMaskMaterial);
- Destroy(outlineFillMaterial);
- }
- void UpdateMaterialProperties()
- {
- // Apply properties according to mode
- outlineFillMaterial.SetColor("_OutlineColor", outlineColor);
- switch (outlineMode)
- {
- case Mode.OutlineAll:
- outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
- outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
- outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
- break;
- case Mode.OutlineVisible:
- outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
- outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
- outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
- break;
- case Mode.OutlineHidden:
- outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
- outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Greater);
- outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
- break;
- case Mode.OutlineAndSilhouette:
- outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
- outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
- outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
- break;
- case Mode.SilhouetteOnly:
- outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
- outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Greater);
- outlineFillMaterial.SetFloat("_OutlineWidth", 0f);
- break;
- }
- }
- }
- }
|