using System.Collections.Generic; using Module.Log; using UnityEngine; public class RenderLine { private const string _txSmilePath = "TX_wuhun_01"; //划线端点的特效 private const string _txBigPath = "TX_wuhun_02"; //划线最后一个端点的特效 private const string _linePath = "TX_wuhun_03"; // 线段特效组件 private int _activeCount; private int _lastActiveCount; // 锁定当前更新 private bool _lockUpdate; private float _WaitLockTime = 0; private RenderLinePoint[] _linePoints; private GameObject _linePrefab; private readonly UICameraTexture _uiCameraTexture; private Transform _pointPrefab; private Transform _endPoint; private readonly List _middlePoints; private readonly List _lineRenderers; private const string _uiCameraLayerName = "UICameraTexture"; public RenderLine(UICameraTexture cameraTexture) { _middlePoints = new List(); _lineRenderers = new List(); _uiCameraTexture = cameraTexture; cameraTexture.onModelUpdate += OnUiCameraTextureUpdate; InitEffectPrefab(); } // 切换模型时临时屏蔽当前连线直到新模型加载完成 // 注:已知问题,无法防御快速切换模型的情况 public void LockUpdate() { _lockUpdate = true; if(_endPoint!=null) _endPoint.gameObject.SetActive(false); for (var i = 0; i < _middlePoints.Count; i++) _middlePoints[i].gameObject.SetActive(false); for (var i = 0; i < _lineRenderers.Count; i++) _lineRenderers[i].gameObject.SetActive(false); } public void UnLockUpdate() { _lockUpdate = false; _WaitLockTime = 1.0f; } private void InitEffectPrefab() { // 注:Prefab挂载在_uiCameraTexture下面。有可能特效在摄像机出现前加载成功 LoadAssetBundle.Instance.LoadGameObject(LoadAssetBundle.BUNDLE_PATH_EFFECT, _txSmilePath, (modelName, resObj, hashParam) => { // 直接使用resObj作为Prefab源 if (_pointPrefab == null && resObj != null) _pointPrefab = resObj.transform; }, null); LoadAssetBundle.Instance.LoadGameObject(LoadAssetBundle.BUNDLE_PATH_EFFECT, _txBigPath, (modelName, resObj, hashParam) => { if (_endPoint == null && resObj != null) { // 复制resObj直接作为实例物体 var endPointObj = Object.Instantiate(resObj); endPointObj.SetActive(false); endPointObj.SetLayerRecursively(_uiCameraLayerName); _endPoint = endPointObj.transform; _endPoint.SetParent(_uiCameraTexture.transform, false); _endPoint.localScale = Vector3.one; } }, null); LoadAssetBundle.Instance.LoadGameObject(LoadAssetBundle.BUNDLE_PATH_EFFECT, _linePath, (modelName, resObj, hashParam) => { if (_linePrefab == null && resObj != null) _linePrefab = resObj; }, null); } public void LateUpdate() { // 仅在全部特效加载完成后显示当前内容 if (_linePrefab != null && _pointPrefab != null && _endPoint != null) { _lastActiveCount = 0; // 隐藏当前显示内容 if (_lockUpdate || _linePoints == null || _activeCount < 0) { _endPoint.gameObject.SetActive(false); for (var i = 0; i < _middlePoints.Count; i++) _middlePoints[i].gameObject.SetActive(false); for (var i = 0; i < _lineRenderers.Count; i++) _lineRenderers[i].gameObject.SetActive(false); } else { if(_WaitLockTime>0) { _WaitLockTime -= Time.deltaTime; return; } _endPoint.gameObject.SetActive(true); if (_lastActiveCount != _activeCount || _activeCount == 0) { _lastActiveCount = _activeCount; for (var i = _lineRenderers.Count; i < _activeCount - 1; i++) { var lineItem = Object.Instantiate(_linePrefab); lineItem.SetLayerRecursively(_uiCameraLayerName); lineItem.layer = _uiCameraTexture.gameObject.layer; lineItem.transform.SetParent(_uiCameraTexture.transform); lineItem.transform.localScale = Vector3.one; lineItem.transform.rotation = Quaternion.identity; var lineRenderer = lineItem.AddComponent(); lineRenderer.Init(_uiCameraTexture._FakeObj.renderCamera.transform, 0.5f); _lineRenderers.Add(lineRenderer); } for (var i = _middlePoints.Count; i < _activeCount - 1; i++) { var middlePoint = Object.Instantiate(_pointPrefab); middlePoint.gameObject.SetLayerRecursively(_uiCameraLayerName); middlePoint.SetParent(_uiCameraTexture.transform); middlePoint.localScale = Vector3.one; middlePoint.rotation = Quaternion.identity; middlePoint.gameObject.layer = _uiCameraTexture.gameObject.layer; _middlePoints.Add(middlePoint); } for (var i = 0; i < _lineRenderers.Count; i++) _lineRenderers[i].gameObject.SetActive(i < _activeCount - 1); for (var i = 0; i < _middlePoints.Count; i++) _middlePoints[i].gameObject.SetActive(i < _activeCount - 1); } for (var i = 0; i < _activeCount -1; i++) { if (i < _linePoints.Length - 1) { _middlePoints[i].position = _linePoints[i].transform.position; _lineRenderers[i].UpdatePoint(_linePoints[i].transform.position, _linePoints[i + 1].transform.position); } else LogModule.WarningLog("模型特效绑定点少于需要激活的绑定点数目!"); } if (_linePoints.Length > 0 && _linePoints.Length >= _activeCount) { int index = _activeCount-1; _endPoint.position = _linePoints[index>=0?index:0].transform.position; } } } } public void SetActivePointCount(int pointCount) { _activeCount = pointCount; } private void OnUiCameraTextureUpdate(GameObject modelObj) { if (modelObj == null) _lockUpdate = true; else { _lockUpdate = false; _WaitLockTime = 1.0f; _linePoints = modelObj.GetComponentsInChildren(true); _linePoints.SortArray((a, b) => a.pointIndex.CompareTo(b.pointIndex)); } } }