using System; using System.Collections.Generic; using UnityEngine; namespace GameWrapper.Fight { public class InFightUnitFadeHandle { private GameObject _handleObj; private List _cacheMaterials = new List(); private List _cacheRenderers = new List(); private List _oldMaterials = new List(); private List _cacheHideObjs = new List(); public bool isFinished { get; private set; } private Shader _fadeShader; private float _fadeTime; private float _passTime; private static readonly int FadeAlpha = Shader.PropertyToID("_fadeAlpha"); private static readonly int MainTex = Shader.PropertyToID("_MainTex"); private static readonly int MaskTex = Shader.PropertyToID("_MaskTex"); private static readonly int ShadowScale = Shader.PropertyToID("_shadowScale"); private static readonly int SpecularScaleG = Shader.PropertyToID("_specularScaleG"); private static readonly int SpecularScaleB = Shader.PropertyToID("_specularScaleB"); private float _targetAlpha; private float _initAlpha; public InFightUnitFadeHandle(GameObject rootObj) { _handleObj = rootObj; } public void SetFadeParam(Shader fadeShader, float fadeTime, float startAlpha, float endAlpha) { _fadeShader = fadeShader; _fadeTime = fadeTime; isFinished = false; _passTime = 0; _targetAlpha = endAlpha; _initAlpha = startAlpha; _InitMaterials(); } public void ReFade(float fadeTime, float startAlpha, float endAlpha) { _fadeTime = fadeTime; isFinished = false; _passTime = 0; _targetAlpha = endAlpha; _initAlpha = startAlpha; // 重新设置初始透明度 for (var i = 0; i < _cacheMaterials.Count; ++i) { var mat = _cacheMaterials[i]; mat.SetFloat(FadeAlpha, _initAlpha); } } public void LogicUpdate(float dt) { _passTime += dt; var progress = Mathf.Clamp01(_passTime / _fadeTime); var setAlpha = Mathf.Lerp(_initAlpha, _targetAlpha, progress); for (var i = 0; i < _cacheMaterials.Count; ++i) { var mat = _cacheMaterials[i]; mat.SetFloat(FadeAlpha, setAlpha); } if (_passTime >= _fadeTime) { isFinished = true; } } public void RecoverMaterials() { _RestoreMaterials(); } public void Dispose() { _handleObj = null; for (int i = 0; i < _cacheMaterials.Count; i++) { var mat = _cacheMaterials[i]; UnityEngine.Object.Destroy(mat); } _cacheMaterials = null; _cacheRenderers = null; _oldMaterials = null; _cacheHideObjs = null; } private void _RestoreMaterials() { // 还原材质 for (var i = 0; i < _cacheRenderers.Count; ++i) { var renderer = _cacheRenderers[i]; renderer.sharedMaterial = _oldMaterials[i]; } // 还原隐藏的物体 foreach (var hideObj in _cacheHideObjs) { hideObj.SetActive(true); } } private void _InitMaterials() { var allRenders = _handleObj.GetComponentsInChildren(); _cacheMaterials = new List(); _cacheRenderers = new List(); _oldMaterials = new List(); _cacheHideObjs = new List(); foreach (var meshRender in allRenders) { // 移除描边 OutlineManager.instance.RemoveRenderer(meshRender); var oldMat = meshRender.material; // 只处理指定的材质 if (!oldMat.shader.name.StartsWith("NLD_URP/NLD_Charactor")) { meshRender.gameObject.SetActive(false); _cacheHideObjs.Add(meshRender.gameObject); continue; } var newMat = new Material(_fadeShader); // 复制属性 var oldTexture = oldMat.GetTexture(MainTex); newMat.SetTexture(MainTex, oldTexture); var oldMaskTex = oldMat.GetTexture(MaskTex); newMat.SetTexture(MaskTex, oldMaskTex); var oldShadowScale = oldMat.GetFloat(ShadowScale); newMat.SetFloat(ShadowScale, oldShadowScale); var oldSpecularScaleG = oldMat.GetFloat(SpecularScaleG); newMat.SetFloat(SpecularScaleG, oldSpecularScaleG); var oldSpecularScaleB = oldMat.GetFloat(SpecularScaleB); newMat.SetFloat(SpecularScaleB, oldSpecularScaleB); newMat.SetFloat(FadeAlpha, _initAlpha); newMat.renderQueue = 3100; // 设置渲染队列,确保在透明队列中渲染 meshRender.material = newMat; _cacheMaterials.Add(newMat); _cacheRenderers.Add(meshRender); _oldMaterials.Add(oldMat); } } } }