Files
Cielonos/Assets/Scripts/MainGame/Characters/Automata/Automata.cs

252 lines
8.0 KiB
C#
Raw Normal View History

2025-11-25 08:19:33 -05:00
using System;
using System.Collections.Generic;
2025-12-08 05:27:53 -05:00
using System.Linq;
2026-03-20 12:07:44 -04:00
using System.Reflection;
using System.Text;
2026-05-23 08:27:50 -04:00
using Cielonos.MainGame.Inventory;
2026-05-10 11:47:55 -04:00
using DG.Tweening;
2025-11-25 08:19:33 -05:00
using Opsive.BehaviorDesigner.Runtime;
using Sirenix.OdinInspector;
using SLSUtilities.FunctionalAnimation;
2026-05-10 11:47:55 -04:00
using SLSUtilities.General;
2025-11-25 08:19:33 -05:00
using UniRx;
using UnityEngine;
using UnityEngine.AI;
2026-05-10 11:47:55 -04:00
using Ease = DG.Tweening.Ease;
2025-11-25 08:19:33 -05:00
namespace Cielonos.MainGame.Characters
{
public partial class Automata : CharacterBase
{
2025-12-08 05:27:53 -05:00
public Player player => MainGameManager.Player;
2026-05-23 08:27:50 -04:00
[TitleGroup("Data")] public FuncAnimDataCollection fullBodyFuncAnims;
[TitleGroup("Data")] public FuncAnimDataCollection upperBodyFuncAnims;
[TitleGroup("Data")] public AttackData attackData;
[TitleGroup("Data")] public TimerData timerData;
private List<string> _registeredFunctionNames = new List<string>();
[TitleGroup("Submodules")] [HideInEditorMode]
2025-12-08 05:27:53 -05:00
public ActionRecordSubmodule actionRecordSm;
2026-03-20 12:07:44 -04:00
2026-05-23 08:27:50 -04:00
[TitleGroup("Subcontrollers")] public BehaviorSubcontroller behaviorSc;
private float _getHitTimer;
2025-11-25 08:19:33 -05:00
protected override void Start()
{
base.Start();
2026-03-20 12:07:44 -04:00
RegisterFuncAnims();
RegisterFunctionsToAnimSc();
2025-11-25 08:19:33 -05:00
}
2025-12-08 05:27:53 -05:00
protected override void InitializeSubmodules()
{
base.InitializeSubmodules();
actionRecordSm = new ActionRecordSubmodule(this);
2026-05-23 08:27:50 -04:00
foreach (KeyValuePair<string, float> timer in timerData.timers)
{
2026-05-26 00:21:27 -04:00
selfTimeSm.coolDownTimers[timer.Key] = new CooldownTimer(timer.Value);
2026-05-23 08:27:50 -04:00
}
2025-12-08 05:27:53 -05:00
}
2026-02-13 09:22:11 -05:00
protected override void Update()
{
base.Update();
UpdateGetHit();
}
2025-11-25 08:19:33 -05:00
}
2026-05-10 11:47:55 -04:00
2025-11-25 08:19:33 -05:00
public partial class Automata
{
2026-05-23 08:27:50 -04:00
public override bool GetHit(Breakthrough.Type breakthroughType, out float recoveryTime,
2026-05-10 11:47:55 -04:00
DisruptionType disruptionType = DisruptionType.NormalExternal,
2026-03-20 12:07:44 -04:00
Vector3 direction = default, string funcAnimName = "")
2025-11-25 08:19:33 -05:00
{
2026-03-20 12:07:44 -04:00
if (string.IsNullOrEmpty(funcAnimName))
{
funcAnimName = GetHitFuncAnimName(breakthroughType, direction);
}
2026-05-10 11:47:55 -04:00
2026-03-20 12:07:44 -04:00
if (base.GetHit(breakthroughType, out recoveryTime, disruptionType, direction, funcAnimName))
2025-11-25 08:19:33 -05:00
{
2026-05-23 08:27:50 -04:00
CombatManager.CoordinatorSm.ReleaseAll(this);
if (_getHitTimer <= 0)
2026-02-13 09:22:11 -05:00
{
2026-05-10 11:47:55 -04:00
if (behaviorSc.navMeshAgent.enabled)
{
behaviorSc.navMeshAgent.isStopped = true;
}
2026-05-23 08:27:50 -04:00
_getHitTimer = recoveryTime;
2026-02-13 09:22:11 -05:00
}
else
2025-11-25 08:19:33 -05:00
{
2026-05-23 08:27:50 -04:00
_getHitTimer = Mathf.Max(_getHitTimer, recoveryTime);
2026-02-13 09:22:11 -05:00
}
2026-05-10 11:47:55 -04:00
2026-03-20 12:07:44 -04:00
return true;
2025-11-25 08:19:33 -05:00
}
2026-05-10 11:47:55 -04:00
2025-11-25 08:19:33 -05:00
return false;
}
2026-02-13 09:22:11 -05:00
2026-05-10 11:47:55 -04:00
2026-03-20 12:07:44 -04:00
2026-02-13 09:22:11 -05:00
protected virtual void UpdateGetHit()
{
2026-05-23 08:27:50 -04:00
_getHitTimer -= selfTimeSm.DeltaTime;
if (_getHitTimer <= 0)
2026-02-13 09:22:11 -05:00
{
2026-05-10 11:47:55 -04:00
if (behaviorSc.navMeshAgent.enabled)
{
behaviorSc.navMeshAgent.isStopped = false;
}
2026-02-13 09:22:11 -05:00
}
}
2025-11-25 08:19:33 -05:00
}
public partial class Automata
{
2025-12-08 05:27:53 -05:00
public override void Die()
{
2026-05-10 11:47:55 -04:00
eventSm.onDeath.Invoke();
2026-05-23 08:27:50 -04:00
CombatManager.CoordinatorSm.ReleaseAll(this);
2026-05-26 00:21:27 -04:00
2026-05-10 11:47:55 -04:00
float deathProcessTime = 0f;
var deathFuncAnim = fullBodyFuncAnims.animDataList.Find(data => data.animInfo.animationName == "Death");
2026-05-11 15:22:30 -04:00
if (deathFuncAnim != null)
2025-12-08 05:27:53 -05:00
{
animationSc.fullBodyFuncAnimSm.Play("Death");
2026-05-10 11:47:55 -04:00
behaviorSc.mainBehaviorTree.StopBehavior();
2026-05-11 15:22:30 -04:00
behaviorSc.navMeshAgent.enabled = false;
2025-12-08 05:27:53 -05:00
collisionSc.DisableAllColliders();
2026-05-10 11:47:55 -04:00
deathProcessTime = deathFuncAnim.animationClip.length;
2025-12-08 05:27:53 -05:00
}
2026-05-23 08:27:50 -04:00
2026-01-03 18:19:39 -05:00
statusSm.isDead = true;
2026-05-10 11:47:55 -04:00
if (deathProcessTime > 0)
{
Observable.Timer(TimeSpan.FromSeconds(deathProcessTime)).Subscribe(_ =>
{
Sequence fade = DOTween.Sequence();
foreach (Material mat in renderSc.baseRenderMaterials)
{
fade.Join(mat.DOFloat(1, "_FadeAmount", 1f).SetEase(Ease.InQuint));
//fade.Join(mat.DOColor(Color.clear, "_FadeBurnColor", 1f).SetEase(Ease.Linear));
}
fade.OnComplete(() => base.Die());
fade.Play();
2026-05-23 08:27:50 -04:00
2026-05-10 11:47:55 -04:00
}).AddTo(gameObject);
}
else
{
base.Die();
}
2025-12-08 05:27:53 -05:00
}
2025-11-25 08:19:33 -05:00
}
2025-12-08 05:27:53 -05:00
public partial class Automata
{
public Vector3 PredictPlayerPosition(float timeAhead)
{
2026-06-05 04:21:00 -04:00
Vector3 currentPosition = player.CenterPoint.position;
2025-12-08 05:27:53 -05:00
Vector3 currentVelocity = player.landMovementSc.horizontalMovement / player.selfTimeSm.DeltaTime;
return currentPosition + currentVelocity * timeAhead;
}
}
2026-05-23 08:27:50 -04:00
2025-11-25 08:19:33 -05:00
public partial class Automata
{
2026-05-23 08:27:50 -04:00
public virtual void RegisterFuncAnims()
2025-11-25 08:19:33 -05:00
{
2026-05-23 08:27:50 -04:00
if (fullBodyFuncAnims != null)
2025-11-25 08:19:33 -05:00
{
2026-05-23 08:27:50 -04:00
foreach (FuncAnimData funcAnim in fullBodyFuncAnims.animDataList)
{
animationSc.fullBodyFuncAnimSm.Add(funcAnim);
}
2025-11-25 08:19:33 -05:00
}
2026-05-23 08:27:50 -04:00
if (upperBodyFuncAnims != null)
2026-03-20 12:07:44 -04:00
{
2026-05-23 08:27:50 -04:00
foreach (FuncAnimData funcAnim in upperBodyFuncAnims.animDataList)
{
animationSc.upperBodyFuncAnimSm.Add(funcAnim);
}
}
2025-11-25 08:19:33 -05:00
}
2026-05-23 08:27:50 -04:00
2025-11-25 08:19:33 -05:00
protected virtual void RegisterFunctionsToAnimSc(params Action[] functions)
{
2026-03-20 12:07:44 -04:00
if (fullBodyFuncAnims == null) return;
2026-05-23 08:27:50 -04:00
2026-03-20 12:07:44 -04:00
RegisterFunctionsToAnimSc();
2026-05-23 08:27:50 -04:00
2025-11-25 08:19:33 -05:00
foreach (Action function in functions)
{
string functionName = function.Method.Name;
if (!animationSc.registeredFunctions.TryAdd(functionName, anim => function()))
{
Debug.LogWarning($"Function {functionName} is already registered.");
}
else
{
2026-05-23 08:27:50 -04:00
_registeredFunctionNames.Add(functionName);
2025-11-25 08:19:33 -05:00
}
}
}
2026-05-23 08:27:50 -04:00
2026-03-20 12:07:44 -04:00
protected virtual void RegisterFunctionsToAnimSc()
2025-11-25 08:19:33 -05:00
{
2026-03-20 12:07:44 -04:00
if (fullBodyFuncAnims == null) return;
2026-05-23 08:27:50 -04:00
2026-03-20 12:07:44 -04:00
foreach (CustomFunction function in fullBodyFuncAnims.preloadFunctions)
2025-11-25 08:19:33 -05:00
{
2026-03-20 12:07:44 -04:00
string functionName = function.functionName;
string FAPF_functionName = new StringBuilder(functionName).Insert(0, "FAPF_").ToString();
MethodInfo method = GetType().GetMethod(FAPF_functionName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
2026-05-23 08:27:50 -04:00
2026-03-20 12:07:44 -04:00
if (method == null)
2025-11-25 08:19:33 -05:00
{
2026-03-20 12:07:44 -04:00
Debug.LogWarning($"Function {functionName} not found in {this.GetType().Name}. Skipping registration.");
continue;
2025-11-25 08:19:33 -05:00
}
2026-05-23 08:27:50 -04:00
2026-03-20 12:07:44 -04:00
Action<RuntimeFuncAnim> action = Delegate.CreateDelegate(typeof(Action<RuntimeFuncAnim>), this, method) as Action<RuntimeFuncAnim>;
2026-05-23 08:27:50 -04:00
_registeredFunctionNames.Add(functionName);
2026-03-20 12:07:44 -04:00
animationSc.registeredFunctions.TryAdd(functionName, action);
2025-11-25 08:19:33 -05:00
}
}
2026-05-23 08:27:50 -04:00
2025-11-25 08:19:33 -05:00
protected void RemoveAllRegisteredFunctions()
{
2026-05-23 08:27:50 -04:00
foreach (string functionName in _registeredFunctionNames)
2025-11-25 08:19:33 -05:00
{
if (!animationSc.registeredFunctions.Remove(functionName))
{
Debug.LogWarning($"Function {functionName} is not found.");
}
}
2026-05-23 08:27:50 -04:00
_registeredFunctionNames.Clear();
}
}
#if UNITY_EDITOR
public partial class Automata
{
protected override void CollectSubcontrollers()
{
base.CollectSubcontrollers();
behaviorSc ??= GetComponent<BehaviorSubcontroller>();
2025-11-25 08:19:33 -05:00
}
}
2026-05-23 08:27:50 -04:00
#endif
2025-11-25 08:19:33 -05:00
}