Files
Cielonos/Assets/Scripts/MainGame/Characters/Base/Subcontrollers/Render/RenderSubcontrollerBase.cs
SoulliesOfficial 649b7a5ddc 更新
2026-05-23 08:27:50 -04:00

181 lines
5.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using DG.Tweening;
using Lean.Pool;
using Sirenix.OdinInspector;
using UniRx;
using UnityEngine;
namespace Cielonos.MainGame.Characters
{
[ExecuteInEditMode]
public partial class RenderSubcontrollerBase : SubcontrollerBase<CharacterBase>
{
public List<SkinnedMeshRenderer> baseRenderers;
public List<Material> baseRenderMaterials;
[ValueDropdown("GetMeshTypeDropdown")]
public string meshType;
public IntReactiveProperty activeEffectCount = new IntReactiveProperty(0);
public GameObject effectContainer;
public List<string> effectPartNames;
public List<MeshEffectRendererInfo> meshEffectRenderers;
public Dictionary<string, MeshEffectUnit> meshEffectUnits;
[HideInEditorMode]
public Dictionary<string, List<Material>> effectRenderMaterials;
public Dictionary<string, ParticleSystem> particleEffects = new Dictionary<string, ParticleSystem>();
}
public partial class RenderSubcontrollerBase
{
private IEnumerable<string> GetMeshTypeDropdown()
{
return new[] { "Submesh", "SeparateMesh" };
}
}
public partial class RenderSubcontrollerBase
{
public override void Initialize()
{
base.Initialize();
baseRenderMaterials = new List<Material>();
foreach (SkinnedMeshRenderer renderer in baseRenderers)
{
baseRenderMaterials.AddRange(renderer.materials);
}
if (effectContainer == null) return;
activeEffectCount.Subscribe(count => { effectContainer.SetActive(count > 0); });
effectRenderMaterials = new Dictionary<string, List<Material>>();
SkinnedMeshRenderer[] effectRenderers = effectContainer.GetComponentsInChildren<SkinnedMeshRenderer>(true);
if (meshType == "SeparateMesh")
{
for (int i = 0; i < effectPartNames.Count; i++)
{
List<Material> mats = effectRenderers.Select(renderer => renderer.materials[i]).ToList();
effectRenderMaterials[effectPartNames[i]] = mats;
}
}
else if (meshType == "Submesh")
{
for (int i = 0; i < effectPartNames.Count; i++)
{
List<Material> mats = effectRenderers[i].materials.ToList();
effectRenderMaterials[effectPartNames[i]] = mats;
}
}
meshEffectUnits = new Dictionary<string, MeshEffectUnit>
{
{ "Weak", new MeshEffectUnit(this, "Weak") },
{ "Freeze", new MeshEffectUnit(this, "Freeze") },
{ "Burn", new MeshEffectUnit(this, "Burn") },
{ "ElectronicParalysis", new MeshEffectUnit(this, "ElectronicParalysis", false, true) }
};
}
}
#region GetHitBlink
public partial class RenderSubcontrollerBase
{
private Sequence getHitBlinkTween;
public void GetHitBlink()
{
getHitBlinkTween?.Kill(true);
getHitBlinkTween = DOTween.Sequence();
foreach (Material mat in baseRenderMaterials)
{
if (!mat.IsKeywordEnabled("_RIM_LIGHTING_ON"))
{
continue;
}
Tweener rimTween = mat.DOFloat(0.2f, "_RimAttenuation", 0.15f)
.From(0f)
.SetEase(Ease.OutQuad)
.SetLoops(2, LoopType.Yoyo);
getHitBlinkTween.Join(rimTween);
}
getHitBlinkTween.Play();
}
}
#endregion
#region Outline
public partial class RenderSubcontrollerBase
{
private Sequence outlineOnTween;
private Sequence outlineOffTween;
public void OutlineOn(Breakthrough.Type type, float width, float fadeInDuration)
{
outlineOffTween?.Kill(true);
outlineOnTween?.Kill(true);
outlineOnTween = DOTween.Sequence();
outlineOnTween.OnPlay(() => { activeEffectCount.Value++; });
foreach (Material mat in effectRenderMaterials["Outline"])
{
mat.SetFloat("_OutlineWidth", width);
mat.SetColor("_OutlineColor", MainGameManager.BaseCollection.outlineColorCollection[type] * Mathf.Pow(2, 4));
Tweener matTween = mat.DOFloat(1, "_OutlineScale", 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, "_OutlineScale", fadeOutDuration)
.SetEase(Ease.OutQuad);
outlineOffTween.Join(matTween);
}
outlineOffTween.OnComplete(() => { activeEffectCount.Value--; });
outlineOffTween.Play();
}
public void SpawnShatters(Breakthrough.Type type, Vector3 direction)
{
Color shatterColor = MainGameManager.BaseCollection.outlineColorCollection[type] * Mathf.Pow(2, 4);
var main = particleEffects["Shatters"].main;
main.startColor = shatterColor;
var velocityOverLifetime = particleEffects["Shatters"].velocityOverLifetime;
velocityOverLifetime.x = direction.x * 4f;
velocityOverLifetime.y = direction.y * 4f;
velocityOverLifetime.z = direction.z * 10f;
particleEffects["Shatters"].Play();
}
}
#endregion
}