NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/GameWrapper/Fight/InFightUnitFadeHandle.cs

165 lines
5.6 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace GameWrapper.Fight
{
public class InFightUnitFadeHandle
{
private GameObject _handleObj;
private List<Material> _cacheMaterials = new List<Material>();
private List<Renderer> _cacheRenderers = new List<Renderer>();
private List<Material> _oldMaterials = new List<Material>();
private List<GameObject> _cacheHideObjs = new List<GameObject>();
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<Renderer>();
_cacheMaterials = new List<Material>();
_cacheRenderers = new List<Renderer>();
_oldMaterials = new List<Material>();
_cacheHideObjs = new List<GameObject>();
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);
}
}
}
}