using UnityEngine; /// /// 挂在每个 ping 对象上。蓝色圆环闪烁描边,两阶段点击: /// 阶段0: 依次首次点击4个ping显示模型(全部显示后才进入阶段1) /// 阶段1: 点击ping显示对应chanrao并隐藏自己 /// touchArray 点击优先级更高。 /// public class PingClickHandler : MonoBehaviour { public GameObject chanraoObject; public GameObject nextPing; public int pingIndex; private MeshRenderer _meshRenderer; private LineRenderer _outlineRenderer; private bool _clickedOnce; private static int _firstClickCount = 0; void Start() { _meshRenderer = GetComponent(); if (_meshRenderer == null) _meshRenderer = GetComponentInChildren(); CreateBlueOutline(); StartCoroutine(BlinkOutline()); } void OnEnable() { _meshRenderer = GetComponent(); if (_meshRenderer == null) _meshRenderer = GetComponentInChildren(); if (_meshRenderer != null) _meshRenderer.enabled = false; // 隐藏所有子级 Renderer(确保模型不可见) var allRends = GetComponentsInChildren(); foreach (var r in allRends) r.enabled = false; CreateBlueOutline(); _clickedOnce = false; StopAllCoroutines(); StartCoroutine(BlinkOutline()); } void CreateBlueOutline() { if (_outlineRenderer != null) return; var ringGo = new GameObject("BlueRing"); ringGo.transform.SetParent(transform, false); _outlineRenderer = ringGo.AddComponent(); _outlineRenderer.useWorldSpace = true; _outlineRenderer.loop = true; _outlineRenderer.startWidth = 0.015f; _outlineRenderer.endWidth = 0.015f; _outlineRenderer.material = new Material(Shader.Find("Unlit/Color")); _outlineRenderer.material.color = new Color(0.2f, 0.5f, 1f); _outlineRenderer.startColor = new Color(0.2f, 0.5f, 1f); _outlineRenderer.endColor = new Color(0.2f, 0.5f, 1f); // 基于模型 Bounds 画矩形描边 Bounds b; if (_meshRenderer != null) b = _meshRenderer.bounds; else b = new Bounds(transform.position, new Vector3(0.3f, 0.01f, 0.3f)); float y = _meshRenderer != null ? _meshRenderer.bounds.max.y + 0.05f : transform.position.y + 0.1f; Vector3 p0 = new Vector3(b.min.x, y, b.min.z); Vector3 p1 = new Vector3(b.min.x, y, b.max.z); Vector3 p2 = new Vector3(b.max.x, y, b.max.z); Vector3 p3 = new Vector3(b.max.x, y, b.min.z); _outlineRenderer.positionCount = 5; _outlineRenderer.SetPosition(0, p0); _outlineRenderer.SetPosition(1, p1); _outlineRenderer.SetPosition(2, p2); _outlineRenderer.SetPosition(3, p3); _outlineRenderer.SetPosition(4, p0); } System.Collections.IEnumerator BlinkOutline() { while (true) { if (_outlineRenderer != null) _outlineRenderer.enabled = !_outlineRenderer.enabled; yield return new WaitForSeconds(0.4f); } } void OnMouseDown() { // touchArray 优先:如果同时命中 touchArray point,跳过 bool blocked = false; var allCams = Object.FindObjectsOfType(); foreach (var c in allCams) { if (!c.enabled) continue; var r = c.ScreenPointToRay(Input.mousePosition); foreach (var h in Physics.RaycastAll(r)) { if (h.collider != null && h.collider.transform.parent != null && h.collider.transform.parent.name == "touchArray") { blocked = true; break; } } if (blocked) break; } if (blocked) return; // 阶段0: 依次首次点击4个ping if (_firstClickCount < 4) { if (_clickedOnce) return; _clickedOnce = true; _firstClickCount++; StopAllCoroutines(); if (_meshRenderer != null) _meshRenderer.enabled = true; var allRends2 = GetComponentsInChildren(); foreach (var r in allRends2) r.enabled = true; if (_outlineRenderer != null) _outlineRenderer.enabled = true; if (nextPing != null) { nextPing.SetActive(true); Debug.Log($"[PingClick] {name} → {nextPing.name} 激活"); } Debug.Log($"[PingClick] {name} 第1击 (model显示, {_firstClickCount}/4)"); var sm = FindObjectOfType(); if (sm != null) sm.RecordPingStep(pingIndex, false); } // 阶段1: 全部显示后第二击显示chanrao else { if (!_clickedOnce) return; if (chanraoObject != null) { chanraoObject.SetActive(true); Debug.Log($"[PingClick] {chanraoObject.name} 已显示"); } StopAllCoroutines(); if (_meshRenderer != null) _meshRenderer.enabled = false; // 隐藏所有子级 Renderer(确保模型不可见) var allRends = GetComponentsInChildren(); foreach (var r in allRends) r.enabled = false; if (_outlineRenderer != null) _outlineRenderer.enabled = false; gameObject.SetActive(false); Debug.Log($"[PingClick] {name} 第2击 (chanrao显示)"); var sm = FindObjectOfType(); if (sm != null) sm.RecordPingStep(pingIndex, true); } } public void UndoSecondClick() { if (!_clickedOnce) return; _clickedOnce = false; _firstClickCount--; gameObject.SetActive(true); if (_meshRenderer != null) _meshRenderer.enabled = false; // 隐藏所有子级 Renderer(确保模型不可见) var allRends = GetComponentsInChildren(); foreach (var r in allRends) r.enabled = false; StopAllCoroutines(); StartCoroutine(BlinkOutline()); } public void UndoShow() { gameObject.SetActive(false); } }