232 lines
7.5 KiB
C#
232 lines
7.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using Cielonos.MainGame.Characters.Inventory;
|
|
using DG.Tweening;
|
|
using Opsive.BehaviorDesigner.Runtime;
|
|
using Sirenix.OdinInspector;
|
|
using SLSUtilities.FunctionalAnimation;
|
|
using SLSUtilities.General;
|
|
using UniRx;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
using Ease = DG.Tweening.Ease;
|
|
|
|
namespace Cielonos.MainGame.Characters
|
|
{
|
|
public partial class Automata : CharacterBase
|
|
{
|
|
public Player player => MainGameManager.Player;
|
|
|
|
[TitleGroup("Data & Presets")]
|
|
public FuncAnimDataCollection fullBodyFuncAnims;
|
|
public FuncAnimDataCollection upperBodyFuncAnims;
|
|
public AttackData attackData;
|
|
|
|
[HideInInspector]
|
|
private List<string> registeredFunctionNames = new List<string>();
|
|
|
|
[TitleGroup("Submodules")]
|
|
public ActionRecordSubmodule actionRecordSm;
|
|
|
|
[TitleGroup("Subcontrollers")]
|
|
public BehaviorSubcontroller behaviorSc;
|
|
|
|
private float getHitTimer;
|
|
|
|
protected override void Start()
|
|
{
|
|
base.Start();
|
|
RegisterFuncAnims();
|
|
RegisterFunctionsToAnimSc();
|
|
}
|
|
|
|
protected override void InitializeSubmodules()
|
|
{
|
|
base.InitializeSubmodules();
|
|
actionRecordSm = new ActionRecordSubmodule(this);
|
|
}
|
|
|
|
protected override void Update()
|
|
{
|
|
base.Update();
|
|
UpdateGetHit();
|
|
}
|
|
}
|
|
|
|
public partial class Automata
|
|
{
|
|
public override bool GetHit(BreakthroughType breakthroughType, out float recoveryTime,
|
|
DisruptionType disruptionType = DisruptionType.NormalExternal,
|
|
Vector3 direction = default, string funcAnimName = "")
|
|
{
|
|
if (string.IsNullOrEmpty(funcAnimName))
|
|
{
|
|
funcAnimName = GetHitFuncAnimName(breakthroughType, direction);
|
|
}
|
|
|
|
if (base.GetHit(breakthroughType, out recoveryTime, disruptionType, direction, funcAnimName))
|
|
{
|
|
if (getHitTimer <= 0)
|
|
{
|
|
if (behaviorSc.navMeshAgent.enabled)
|
|
{
|
|
behaviorSc.navMeshAgent.isStopped = true;
|
|
}
|
|
|
|
getHitTimer = recoveryTime;
|
|
}
|
|
else
|
|
{
|
|
getHitTimer = Mathf.Max(getHitTimer, recoveryTime);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
protected virtual void UpdateGetHit()
|
|
{
|
|
getHitTimer -= selfTimeSm.DeltaTime;
|
|
if (getHitTimer <= 0)
|
|
{
|
|
if (behaviorSc.navMeshAgent.enabled)
|
|
{
|
|
behaviorSc.navMeshAgent.isStopped = false;
|
|
}
|
|
//statusSm.RemoveStatus(StatusType.Stun);
|
|
}
|
|
}
|
|
}
|
|
|
|
public partial class Automata
|
|
{
|
|
public override void Die()
|
|
{
|
|
eventSm.onDeath.Invoke();
|
|
|
|
BattleManager.EnemySm.RemoveEnemy(this);
|
|
float deathProcessTime = 0f;
|
|
var deathFuncAnim = fullBodyFuncAnims.animDataList.Find(data => data.animInfo.animationName == "Death");
|
|
if (deathFuncAnim != null)
|
|
{
|
|
animationSc.fullBodyFuncAnimSm.Play("Death");
|
|
behaviorSc.mainBehaviorTree.StopBehavior();
|
|
behaviorSc.navMeshAgent.enabled = false;
|
|
collisionSc.DisableAllColliders();
|
|
deathProcessTime = deathFuncAnim.animationClip.length;
|
|
}
|
|
|
|
statusSm.isDead = true;
|
|
|
|
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();
|
|
|
|
}).AddTo(gameObject);
|
|
}
|
|
else
|
|
{
|
|
base.Die();
|
|
}
|
|
}
|
|
}
|
|
|
|
public partial class Automata
|
|
{
|
|
public Vector3 PredictPlayerPosition(float timeAhead)
|
|
{
|
|
Vector3 currentPosition = player.centerPoint.position;
|
|
Vector3 currentVelocity = player.landMovementSc.horizontalMovement / player.selfTimeSm.DeltaTime;
|
|
return currentPosition + currentVelocity * timeAhead;
|
|
}
|
|
}
|
|
|
|
public partial class Automata
|
|
{
|
|
public void RegisterFuncAnims()
|
|
{
|
|
if (fullBodyFuncAnims == null) return;
|
|
|
|
foreach (FuncAnimData funcAnim in fullBodyFuncAnims.animDataList)
|
|
{
|
|
animationSc.fullBodyFuncAnimSm.Add(funcAnim);
|
|
}
|
|
|
|
/*foreach (FuncAnimData funcAnim in upperBodyFuncAnims.animDataList)
|
|
{
|
|
animationSc.upperBodyFuncAnimSm.Add(funcAnim);
|
|
}*/
|
|
}
|
|
|
|
protected virtual void RegisterFunctionsToAnimSc(params Action[] functions)
|
|
{
|
|
if (fullBodyFuncAnims == null) return;
|
|
|
|
RegisterFunctionsToAnimSc();
|
|
|
|
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
|
|
{
|
|
registeredFunctionNames.Add(functionName);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void RegisterFunctionsToAnimSc()
|
|
{
|
|
if (fullBodyFuncAnims == null) return;
|
|
|
|
foreach (CustomFunction function in fullBodyFuncAnims.preloadFunctions)
|
|
{
|
|
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);
|
|
|
|
if (method == null)
|
|
{
|
|
Debug.LogWarning($"Function {functionName} not found in {this.GetType().Name}. Skipping registration.");
|
|
continue;
|
|
}
|
|
|
|
Action<RuntimeFuncAnim> action = Delegate.CreateDelegate(typeof(Action<RuntimeFuncAnim>), this, method) as Action<RuntimeFuncAnim>;
|
|
registeredFunctionNames.Add(functionName);
|
|
animationSc.registeredFunctions.TryAdd(functionName, action);
|
|
}
|
|
}
|
|
|
|
protected void RemoveAllRegisteredFunctions()
|
|
{
|
|
foreach (string functionName in registeredFunctionNames)
|
|
{
|
|
if (!animationSc.registeredFunctions.Remove(functionName))
|
|
{
|
|
Debug.LogWarning($"Function {functionName} is not found.");
|
|
}
|
|
}
|
|
registeredFunctionNames.Clear();
|
|
}
|
|
}
|
|
} |