JJBB/Assets/Project/Script/RenderLine.cs
2024-08-23 15:49:34 +08:00

181 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<Transform> _middlePoints;
private readonly List<RenderLineScaler> _lineRenderers;
private const string _uiCameraLayerName = "UICameraTexture";
public RenderLine(UICameraTexture cameraTexture)
{
_middlePoints = new List<Transform>();
_lineRenderers = new List<RenderLineScaler>();
_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<RenderLineScaler>();
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<RenderLinePoint>(true);
_linePoints.SortArray((a, b) => a.pointIndex.CompareTo(b.pointIndex));
}
}
}