Files
Cielonos/Assets/Scripts/MainGame/Characters/Base/Subcontrollers/RenderSubcontrollerBase.cs

216 lines
7.8 KiB
C#
Raw Normal View History

2025-11-25 08:19:33 -05:00
using System;
using System.Collections.Generic;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
2025-12-08 05:27:53 -05:00
using Sirenix.OdinInspector;
2025-11-25 08:19:33 -05:00
using TrailsFX;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
namespace Cielonos.MainGame.Characters
{
[ExecuteInEditMode]
public partial class RenderSubcontrollerBase : SubcontrollerBase<CharacterBase>
{
public List<SkinnedMeshRenderer> baseRenderers;
public List<Material> baseRenderMaterials;
2025-12-08 05:27:53 -05:00
public Dictionary<string, GameObject> effectContainers;
[HideInEditorMode]
2025-11-25 08:19:33 -05:00
public Dictionary<string, List<SkinnedMeshRenderer>> effectRenderers;
2025-12-08 05:27:53 -05:00
[HideInEditorMode]
2025-11-25 08:19:33 -05:00
public Dictionary<string, List<Material>> effectRenderMaterials;
2025-12-08 05:27:53 -05:00
public List<TrailEffect> dashTrails;
2025-11-25 08:19:33 -05:00
}
public partial class RenderSubcontrollerBase
{
public override void Initialize()
{
base.Initialize();
baseRenderMaterials = new List<Material>();
foreach (SkinnedMeshRenderer renderer in baseRenderers)
{
baseRenderMaterials.AddRange(renderer.materials);
}
effectRenderers = new Dictionary<string, List<SkinnedMeshRenderer>>();
effectRenderMaterials = new Dictionary<string, List<Material>>();
2025-12-08 05:27:53 -05:00
foreach (KeyValuePair<string, GameObject> container in effectContainers)
2025-11-25 08:19:33 -05:00
{
2025-12-08 05:27:53 -05:00
effectRenderers[container.Key] = new List<SkinnedMeshRenderer>(container.Value.GetComponentsInChildren<SkinnedMeshRenderer>());
2025-11-25 08:19:33 -05:00
}
foreach (var kvp in effectRenderers)
{
List<Material> mats = new List<Material>();
foreach (SkinnedMeshRenderer renderer in kvp.Value)
{
mats.AddRange(renderer.materials);
}
effectRenderMaterials[kvp.Key] = mats;
}
}
}
public partial class RenderSubcontrollerBase
{
public void SetTransparency(bool isTransparent, float alpha)
{
foreach (Material mat in baseRenderMaterials)
{
// 获取当前颜色 (URP Lit Shader 使用 _BaseColor)
// 如果你的材质球使用的是标准颜色属性mat.color 也可以,但在 URP 中显式获取更安全
Color baseColor = mat.HasProperty("_BaseColor") ? mat.GetColor("_BaseColor") : mat.color;
if (isTransparent)
{
// === 1. 设置透明模式 ===
mat.SetFloat("_Surface", 1.0f); // Inspector 显示为 Transparent
mat.SetFloat("_Blend", 0.0f); // Inspector 显示为 Alpha
// === 关键修正:必须手动设置混合因子 ===
// SrcAlpha (5) 和 OneMinusSrcAlpha (10) 是标准透明混合公式
mat.SetInt("_SrcBlend", (int)BlendMode.SrcAlpha);
mat.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
// 关闭深度写入
mat.SetInt("_ZWrite", 0);
// 启用关键字
mat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
// 设置渲染队列
mat.renderQueue = (int)RenderQueue.Transparent;
// 设置带透明度的颜色
baseColor.a = alpha;
if (mat.HasProperty("_BaseColor"))
mat.SetColor("_BaseColor", baseColor);
else
mat.color = baseColor;
}
else
{
// === 2. 恢复不透明模式 ===
mat.SetFloat("_Surface", 0.0f); // Inspector 显示为 Opaque
mat.SetFloat("_Blend", 0.0f);
// === 关键修正:恢复不透明混合因子 ===
// One (1) 和 Zero (0) 意味着完全覆盖背景
mat.SetInt("_SrcBlend", (int)BlendMode.One);
mat.SetInt("_DstBlend", (int)BlendMode.Zero);
// 开启深度写入 (这非常重要,否则之前的刀光问题会复发)
mat.SetInt("_ZWrite", 1);
// 禁用关键字
mat.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
// 恢复默认渲染队列 (通常是 -1代表使用 Shader 默认值 2000)
mat.renderQueue = -1;
// 恢复完全不透明颜色
baseColor.a = 1.0f;
if (mat.HasProperty("_BaseColor"))
mat.SetColor("_BaseColor", baseColor);
else
mat.color = baseColor;
}
}
}
}
public partial class RenderSubcontrollerBase
{
private Sequence getHitBlinkTween;
public void GetHitBlink()
{
getHitBlinkTween?.Kill(true);
getHitBlinkTween = DOTween.Sequence();
getHitBlinkTween.OnPlay(() =>
{
2025-12-08 05:27:53 -05:00
effectContainers["GetHitBlink"].SetActive(true);
2025-11-25 08:19:33 -05:00
});
foreach (Material mat in effectRenderMaterials["GetHitBlink"])
{
TweenerCore<Color, Color, ColorOptions> matTween = mat.DOColor(Color.white * 0.25f, "_EmissionColor", 0.15f)
.OnStart(() => mat.EnableKeyword("_EMISSION"))
.From(Color.black)
.SetEase(Ease.OutQuad)
.OnComplete(() =>
{
mat.SetColor("_EmissionColor", Color.black);
mat.DisableKeyword("_EMISSION");
});
getHitBlinkTween.Join(matTween);
}
getHitBlinkTween.SetLoops(2, LoopType.Yoyo);
getHitBlinkTween.OnComplete(() =>
{
2025-12-08 05:27:53 -05:00
effectContainers["GetHitBlink"].SetActive(false);
2025-11-25 08:19:33 -05:00
});
getHitBlinkTween.Play();
}
}
public partial class RenderSubcontrollerBase
{
private Sequence outlineOnTween;
private Sequence outlineOffTween;
2025-12-08 05:27:53 -05:00
public void OutlineOn(BreakthroughType type, float width, float fadeInDuration)
2025-11-25 08:19:33 -05:00
{
outlineOffTween?.Kill(true);
outlineOnTween?.Kill(true);
outlineOnTween = DOTween.Sequence();
outlineOnTween.OnPlay(() =>
{
2025-12-08 05:27:53 -05:00
effectContainers["Outline"].SetActive(true);
2025-11-25 08:19:33 -05:00
});
foreach (Material mat in effectRenderMaterials["Outline"])
{
mat.SetColor("_Outline_Color", MainGameManager.BasePrefabs.outlineColorCollection[type]);
Tweener matTween = mat.DOFloat(width, "_Outline_Thickness", fadeInDuration)
.From(0.0f)
.SetEase(Ease.OutQuad);
outlineOnTween.Join(matTween);
}
outlineOnTween.Play();
}
public void OutlineOff(float fadeOutDuration)
{
outlineOnTween?.Kill(true);
outlineOffTween?.Kill(true);
outlineOffTween = DOTween.Sequence();
foreach (Material mat in effectRenderMaterials["Outline"])
{
Tweener matTween = mat.DOFloat(0.0f, "_Outline_Thickness", fadeOutDuration)
.SetEase(Ease.OutQuad);
outlineOffTween.Join(matTween);
}
outlineOffTween.OnComplete(() =>
{
2025-12-08 05:27:53 -05:00
effectContainers["Outline"].SetActive(false);
2025-11-25 08:19:33 -05:00
});
outlineOffTween.Play();
}
}
}