using System.Collections; using System.Collections.Generic; using UnityEngine; public class ModelHighlight : MonoBehaviour { /// /// 高亮的颜色 /// public Color highLightColor = new Color(0.5f, 0.5f, 0.5f, 1); /// /// 高亮边缘 宽度 /// [Range(0.001f, 0.005f)] public float lineWidth = 0.005f; /// /// 高亮边缘 偏移调整 /// [Range(0, 2)] public float lineAjustMeng = 0.5f; /// /// 闪烁效果速度 0则不闪烁 /// [Range(0, 10)] public float highLightSpeed = 3f; /// /// 单例 /// public static ModelHighlight instance; /// /// 高亮 skinmesh数组 /// private SkinnedMeshRenderer[] highlightSkinnedRenderers; private SkinnedMeshRenderer[] existingSkinnedRenderers; /// /// 高亮 普通mesh数组 /// private MeshRenderer[] highlightRenderers; private MeshRenderer[] existingRenderers; /// /// 不需要高亮模型 数组 /// public GameObject[] hideHighlight; void Awake() { instance = this; } void Start() { } void Update() { } /// /// 模型高亮 /// /// 目标高亮父节点 所有子节点都会高亮 /// 模型是否 需要高亮 true-高亮 false-关闭高亮 public void SetModelHighlight(GameObject target ,bool isHighlight) { existingSkinnedRenderers = target.GetComponentsInChildren(true); highlightSkinnedRenderers = new SkinnedMeshRenderer[existingSkinnedRenderers.Length]; Material highlightMat = CreatMaterial(highLightColor); for (int skinnedIndex = 0; skinnedIndex < existingSkinnedRenderers.Length; skinnedIndex++) { if (existingSkinnedRenderers[skinnedIndex].transform.name.Contains("_Highlight")) { continue; } if (isHighlight) { if (existingSkinnedRenderers[skinnedIndex].transform.Find(existingSkinnedRenderers[skinnedIndex].transform.name + "_Highlight")) { existingSkinnedRenderers[skinnedIndex].transform.Find(existingSkinnedRenderers[skinnedIndex].transform.name + "_Highlight").gameObject.SetActive(true); continue; } else { SkinnedMeshRenderer existingSkinned = existingSkinnedRenderers[skinnedIndex]; if (ShouldIgnoreHighlight(existingSkinned)) continue; GameObject newSkinnedHolder = new GameObject("SkinnedHolder"); newSkinnedHolder.name = existingSkinned.transform.name + "_Highlight"; newSkinnedHolder.transform.parent = existingSkinned.transform; newSkinnedHolder.transform.localPosition = Vector3.zero; newSkinnedHolder.transform.localEulerAngles = Vector3.zero; newSkinnedHolder.transform.localScale = Vector3.one; SkinnedMeshRenderer newSkinned = newSkinnedHolder.AddComponent(); Material[] materials = new Material[existingSkinned.sharedMaterials.Length]; for (int materialIndex = 0; materialIndex < materials.Length; materialIndex++) { materials[materialIndex] = highlightMat; } newSkinned.sharedMaterials = materials; newSkinned.sharedMesh = existingSkinned.sharedMesh; newSkinned.rootBone = existingSkinned.rootBone; newSkinned.updateWhenOffscreen = existingSkinned.updateWhenOffscreen; newSkinned.bones = existingSkinned.bones; highlightSkinnedRenderers[skinnedIndex] = newSkinned; } } else { if (existingSkinnedRenderers[skinnedIndex].transform.Find(existingSkinnedRenderers[skinnedIndex].transform.name + "_Highlight")) { existingSkinnedRenderers[skinnedIndex].transform.Find(existingSkinnedRenderers[skinnedIndex].transform.name + "_Highlight").gameObject.SetActive(false); } } } MeshFilter[] existingFilters = target.GetComponentsInChildren(true); existingRenderers = new MeshRenderer[existingFilters.Length]; highlightRenderers = new MeshRenderer[existingFilters.Length]; for (int filterIndex = 0; filterIndex < existingFilters.Length; filterIndex++) { if (existingFilters[filterIndex].transform.name.Contains("_Highlight")) { continue; } if (isHighlight) { if (existingFilters[filterIndex].transform.Find(existingFilters[filterIndex].transform.name + "_Highlight")) { existingFilters[filterIndex].transform.Find(existingFilters[filterIndex].transform.name + "_Highlight").gameObject.SetActive(true); continue; } else { MeshFilter existingFilter = existingFilters[filterIndex]; MeshRenderer existingRenderer = existingFilter.GetComponent(); if (existingFilter == null || existingRenderer == null || ShouldIgnoreHighlight(existingFilter)) continue; GameObject newFilterHolder = new GameObject("FilterHolder"); newFilterHolder.name = existingFilter.transform.name + "_Highlight"; newFilterHolder.transform.parent = existingFilter.transform; newFilterHolder.transform.localPosition = Vector3.zero; newFilterHolder.transform.localEulerAngles = Vector3.zero; newFilterHolder.transform.localScale = Vector3.one; MeshFilter newFilter = newFilterHolder.AddComponent(); newFilter.sharedMesh = existingFilter.sharedMesh; MeshRenderer newRenderer = newFilterHolder.AddComponent(); Material[] materials = new Material[existingRenderer.sharedMaterials.Length]; for (int materialIndex = 0; materialIndex < materials.Length; materialIndex++) { materials[materialIndex] = highlightMat; } newRenderer.sharedMaterials = materials; highlightRenderers[filterIndex] = newRenderer; existingRenderers[filterIndex] = existingRenderer; } } else { if (existingFilters[filterIndex].transform.Find(existingFilters[filterIndex].transform.name + "_Highlight")) { existingFilters[filterIndex].transform.Find(existingFilters[filterIndex].transform.name + "_Highlight").gameObject.SetActive(false); } } } } /// /// 改变模型高亮颜色 /// /// 目标模型 所有子节点模型高亮颜色都会改变 /// 改变的颜色 RGB public void ChangeModelHighlightColor(GameObject target, Color color) { existingSkinnedRenderers = target.GetComponentsInChildren(true); highlightSkinnedRenderers = new SkinnedMeshRenderer[existingSkinnedRenderers.Length]; for (int skinnedIndex = 0; skinnedIndex < existingSkinnedRenderers.Length; skinnedIndex++) { if (existingSkinnedRenderers[skinnedIndex].transform.Find(existingSkinnedRenderers[skinnedIndex].transform.name + "_Highlight")) { existingSkinnedRenderers[skinnedIndex].transform.Find(existingSkinnedRenderers[skinnedIndex].transform.name + "_Highlight"). gameObject.GetComponent().materials[0].SetColor("g_vOutlineColor", color); continue; } } MeshFilter[] existingFilters = target.GetComponentsInChildren(true); existingRenderers = new MeshRenderer[existingFilters.Length]; highlightRenderers = new MeshRenderer[existingFilters.Length]; for (int filterIndex = 0; filterIndex < existingFilters.Length; filterIndex++) { if (existingFilters[filterIndex].transform.Find(existingFilters[filterIndex].transform.name + "_Highlight")) { existingFilters[filterIndex].transform.Find(existingFilters[filterIndex].transform.name + "_Highlight"). gameObject.GetComponent().materials[0].SetColor("g_vOutlineColor", color); continue; } } } /// /// 改变高亮模型闪烁的速度 /// /// 目标模型 所有子节点模型高亮闪烁速度都会改变 /// 闪烁速度 0-停止闪烁 速度越大闪烁越快 public void ChangeModelHighlightSpeed(GameObject target, float speed) { existingSkinnedRenderers = target.GetComponentsInChildren(true); highlightSkinnedRenderers = new SkinnedMeshRenderer[existingSkinnedRenderers.Length]; for (int skinnedIndex = 0; skinnedIndex < existingSkinnedRenderers.Length; skinnedIndex++) { if (existingSkinnedRenderers[skinnedIndex].transform.Find(existingSkinnedRenderers[skinnedIndex].transform.name + "_Highlight")) { existingSkinnedRenderers[skinnedIndex].transform.Find(existingSkinnedRenderers[skinnedIndex].transform.name + "_Highlight"). gameObject.GetComponent().materials[0].SetFloat("_FlickerTime", speed); continue; } } MeshFilter[] existingFilters = target.GetComponentsInChildren(true); existingRenderers = new MeshRenderer[existingFilters.Length]; highlightRenderers = new MeshRenderer[existingFilters.Length]; for (int filterIndex = 0; filterIndex < existingFilters.Length; filterIndex++) { if (existingFilters[filterIndex].transform.Find(existingFilters[filterIndex].transform.name + "_Highlight")) { existingFilters[filterIndex].transform.Find(existingFilters[filterIndex].transform.name + "_Highlight"). gameObject.GetComponent().materials[0].SetFloat("_FlickerTime", speed); continue; } } } /// /// 需要 隐藏高亮模型操作 /// /// /// private bool ShouldIgnoreHighlight(Component component) { return ShouldIgnore(component.gameObject); } private bool ShouldIgnore(GameObject check) { for (int ignoreIndex = 0; ignoreIndex < hideHighlight.Length; ignoreIndex++) { if (check == hideHighlight[ignoreIndex]) return true; } return false; } /// /// 生成材质球 /// /// /// private Material CreatMaterial(Color color) { Material tempMat = new Material(Shader.Find("Highlight/Silhouette")); tempMat.SetColor("g_vOutlineColor", color); tempMat.SetFloat("g_flOutlineWidth", lineWidth); tempMat.SetFloat("g_flCornerAdjust", lineAjustMeng); tempMat.SetFloat("_FlickerTime", highLightSpeed); return tempMat; } }