adjustments on cadence
This commit is contained in:
parent
998fd1e462
commit
c4e3723e07
@ -0,0 +1,85 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: f28542aec01041178adfbc30f7a2a82a, type: 3}
|
||||||
|
m_Name: Sentinel Config
|
||||||
|
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Gameplay.Entities.Player.Sentinel.SentinelConfig
|
||||||
|
walk:
|
||||||
|
speed: 5
|
||||||
|
run:
|
||||||
|
speed: 10
|
||||||
|
dashImpulse:
|
||||||
|
speed: 35
|
||||||
|
durationMS: 150
|
||||||
|
dashRecovery:
|
||||||
|
speed: 10
|
||||||
|
durationMS: 200
|
||||||
|
dashMaxAngleFromForward: 90
|
||||||
|
speedCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 1
|
||||||
|
inSlope: -1
|
||||||
|
outSlope: -1
|
||||||
|
tangentMode: 34
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0
|
||||||
|
outWeight: 0.33333334
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 1
|
||||||
|
value: 0
|
||||||
|
inSlope: -1
|
||||||
|
outSlope: -1
|
||||||
|
tangentMode: 34
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
dashLanding:
|
||||||
|
durationMS: 100
|
||||||
|
dashBreaking:
|
||||||
|
speed: 10
|
||||||
|
durationMS: 300
|
||||||
|
speedCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 1
|
||||||
|
inSlope: -1
|
||||||
|
outSlope: -1
|
||||||
|
tangentMode: 34
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0
|
||||||
|
outWeight: 0.33333334
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 1
|
||||||
|
value: 0
|
||||||
|
inSlope: -1
|
||||||
|
outSlope: -1
|
||||||
|
tangentMode: 34
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
fallLanding:
|
||||||
|
durationMS: 2000
|
||||||
|
knockdown:
|
||||||
|
knockoutTimeMultiplier: 0.1
|
||||||
|
knockdownDurationMS: 100
|
||||||
|
recoverDurationMS: 500
|
||||||
|
maxKnockdownStrength: 15
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0805cd1ce642240f5abe420367e78b5e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
File diff suppressed because one or more lines are too long
@ -2,23 +2,17 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Cadence
|
|||||||
{
|
{
|
||||||
public readonly struct CadenceEvaluation
|
public readonly struct CadenceEvaluation
|
||||||
{
|
{
|
||||||
public static CadenceEvaluation None = new(0f, 0f, CadenceBand.None, 0f, 0f);
|
public static CadenceEvaluation None = new(CadenceBand.None, 0f, 0f);
|
||||||
|
|
||||||
public float T { get; }
|
|
||||||
public float ElapsedAt { get; }
|
|
||||||
public CadenceBand Band { get; }
|
public CadenceBand Band { get; }
|
||||||
public float SettlementFactor { get; }
|
public float SettlementFactor { get; }
|
||||||
public float Recovery { get; }
|
public float Recovery { get; }
|
||||||
|
|
||||||
public CadenceEvaluation(
|
public CadenceEvaluation(
|
||||||
float t,
|
|
||||||
float elapsedAt,
|
|
||||||
CadenceBand band,
|
CadenceBand band,
|
||||||
float settlementFactor,
|
float settlementFactor,
|
||||||
float recovery)
|
float recovery)
|
||||||
{
|
{
|
||||||
T = t;
|
|
||||||
ElapsedAt = elapsedAt;
|
|
||||||
Band = band;
|
Band = band;
|
||||||
SettlementFactor = settlementFactor;
|
SettlementFactor = settlementFactor;
|
||||||
Recovery = recovery;
|
Recovery = recovery;
|
||||||
|
|||||||
@ -7,43 +7,19 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Cadence
|
|||||||
[CreateAssetMenu(fileName = "Cadence Profile", menuName = "GON/Services/Cadence/Cadence Profile")]
|
[CreateAssetMenu(fileName = "Cadence Profile", menuName = "GON/Services/Cadence/Cadence Profile")]
|
||||||
public sealed class CadenceProfile : ScriptableObject
|
public sealed class CadenceProfile : ScriptableObject
|
||||||
{
|
{
|
||||||
[SerializeField, Min(1f)] private float totalTimeMS = 370f;
|
[GroupConfigurations("Normalized Band End Points"), SerializeField, Range(0f, 1f)] private float strained;
|
||||||
|
[GroupConfigurations("Normalized Band End Points"), SerializeField, Range(0f, 1f)] private float aligned;
|
||||||
|
[GroupConfigurations("Normalized Band End Points"), SerializeField, Range(0f, 1f)] private float resonant;
|
||||||
|
|
||||||
[GroupConfigurations("Normalized Band End Points"), SerializeField, Range(0f, 1f)] private float strainedEndP = 0.25f;
|
[GroupConfigurations("Settlement"), SerializeField, Range(0f, 1f)] private float strainedSettlement;
|
||||||
[GroupConfigurations("Normalized Band End Points"), SerializeField, Range(0f, 1f)] private float alignedEndP = 0.65f;
|
[GroupConfigurations("Settlement"), SerializeField, Range(0f, 1f)] private float alignedSettlement;
|
||||||
[GroupConfigurations("Normalized Band End Points"), SerializeField, Range(0f, 1f)] private float resonantEndP = 1f;
|
|
||||||
|
|
||||||
[GroupConfigurations("Settlement"), SerializeField, Range(0f, 1f)] private float strainedSettlement = 1f;
|
|
||||||
[GroupConfigurations("Settlement"), SerializeField, Range(0f, 1f)] private float alignedSettlement = 0.5f;
|
|
||||||
[GroupConfigurations("Settlement"), SerializeField, Range(0f, 1f)] private float resonantSettlement;
|
[GroupConfigurations("Settlement"), SerializeField, Range(0f, 1f)] private float resonantSettlement;
|
||||||
[GroupConfigurations("Settlement"), SerializeField, Range(0f, 1f)] private float lateSettlement = 1f;
|
[GroupConfigurations("Settlement"), SerializeField, Range(0f, 1f)] private float lateSettlement;
|
||||||
|
|
||||||
[GroupConfigurations("Core Stability"), SerializeField, Range(0, 100)] private float maxCoreCost = 8f;
|
[GroupConfigurations("Core Stability"), SerializeField, Range(0, 50)] private float maxCoreCost;
|
||||||
[GroupConfigurations("Core Stability"), SerializeField, Range(0, 100)] private float resonantRecovery = 8f;
|
[GroupConfigurations("Core Stability"), SerializeField, Range(0, 50)] private float resonantRecovery;
|
||||||
|
|
||||||
public float TotalTimeMS => totalTimeMS;
|
|
||||||
|
|
||||||
public float TotalTime => TotalTimeMS * 0.001f;
|
|
||||||
|
|
||||||
public float StrainedEndP => strainedEndP;
|
|
||||||
public float AlignedEndP => alignedEndP;
|
|
||||||
public float ResonantEndP => resonantEndP;
|
|
||||||
|
|
||||||
// public float StrainedEndTime => TotalTime * strainedEndP;
|
|
||||||
// public float AlignedEndTime => TotalTime * alignedEndP;
|
|
||||||
// public float ResonantEndTime => TotalTime * resonantEndP;
|
|
||||||
//
|
|
||||||
// public float StrainedEndMS => totalTimeMS * strainedEndP;
|
|
||||||
// public float AlignedEndMS => totalTimeMS * alignedEndP;
|
|
||||||
// public float ResonantEndMS => totalTimeMS * resonantEndP;
|
|
||||||
|
|
||||||
public float StrainedSettlement => strainedSettlement;
|
|
||||||
public float AlignedSettlement => alignedSettlement;
|
|
||||||
public float ResonantSettlement => resonantSettlement;
|
|
||||||
public float LateSettlement => lateSettlement;
|
|
||||||
|
|
||||||
public float MaxCoreCost => maxCoreCost;
|
public float MaxCoreCost => maxCoreCost;
|
||||||
public float ResonantRecovery => resonantRecovery;
|
|
||||||
|
|
||||||
private void OnValidate()
|
private void OnValidate()
|
||||||
{
|
{
|
||||||
@ -53,21 +29,12 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Cadence
|
|||||||
[GroupDebug, Button(ButtonSizes.Medium)]
|
[GroupDebug, Button(ButtonSizes.Medium)]
|
||||||
private void Validate()
|
private void Validate()
|
||||||
{
|
{
|
||||||
totalTimeMS = Mathf.Max(1f, totalTimeMS);
|
strained = Mathf.Clamp01(strained);
|
||||||
|
aligned = Mathf.Clamp01(aligned);
|
||||||
|
resonant = Mathf.Clamp01(resonant);
|
||||||
|
|
||||||
strainedEndP = Mathf.Clamp01(strainedEndP);
|
if (aligned < strained) aligned = strained;
|
||||||
alignedEndP = Mathf.Clamp01(alignedEndP);
|
if (resonant < aligned) resonant = aligned;
|
||||||
resonantEndP = Mathf.Clamp01(resonantEndP);
|
|
||||||
|
|
||||||
if (alignedEndP < strainedEndP)
|
|
||||||
{
|
|
||||||
alignedEndP = strainedEndP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resonantEndP < alignedEndP)
|
|
||||||
{
|
|
||||||
resonantEndP = alignedEndP;
|
|
||||||
}
|
|
||||||
|
|
||||||
strainedSettlement = Mathf.Clamp01(strainedSettlement);
|
strainedSettlement = Mathf.Clamp01(strainedSettlement);
|
||||||
alignedSettlement = Mathf.Clamp01(alignedSettlement);
|
alignedSettlement = Mathf.Clamp01(alignedSettlement);
|
||||||
@ -78,55 +45,32 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Cadence
|
|||||||
resonantRecovery = Mathf.Max(0f, resonantRecovery);
|
resonantRecovery = Mathf.Max(0f, resonantRecovery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CadenceEvaluation Evaluate(float elapsedTime)
|
public CadenceEvaluation Evaluate(float t)
|
||||||
{
|
{
|
||||||
if (TotalTime <= 0f)
|
if (t < strained) return StrainedEvaluation();
|
||||||
{
|
if (t < aligned) return AlignedEvaluation();
|
||||||
return CadenceEvaluation.None;
|
if (t < resonant) return ResonantEvaluation();
|
||||||
|
return StrainedEvaluation();
|
||||||
}
|
}
|
||||||
|
|
||||||
var t = Mathf.Clamp01(elapsedTime / TotalTime);
|
public CadenceEvaluation StrainedEvaluation()
|
||||||
|
|
||||||
if (t < StrainedEndP)
|
|
||||||
{
|
{
|
||||||
return new CadenceEvaluation(
|
return new CadenceEvaluation(CadenceBand.Strained, strainedSettlement, 0f);
|
||||||
t,
|
|
||||||
elapsedTime,
|
|
||||||
CadenceBand.Strained,
|
|
||||||
StrainedSettlement,
|
|
||||||
0f
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t < AlignedEndP)
|
public CadenceEvaluation AlignedEvaluation()
|
||||||
{
|
{
|
||||||
return new CadenceEvaluation(
|
return new CadenceEvaluation(CadenceBand.Aligned, alignedSettlement, 0f);
|
||||||
t,
|
|
||||||
elapsedTime,
|
|
||||||
CadenceBand.Aligned,
|
|
||||||
AlignedSettlement,
|
|
||||||
0f
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t < ResonantEndP)
|
public CadenceEvaluation ResonantEvaluation()
|
||||||
{
|
{
|
||||||
return new CadenceEvaluation(
|
return new CadenceEvaluation(CadenceBand.Resonant, resonantSettlement, resonantRecovery);
|
||||||
t,
|
|
||||||
elapsedTime,
|
|
||||||
CadenceBand.Resonant,
|
|
||||||
ResonantSettlement,
|
|
||||||
ResonantRecovery
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CadenceEvaluation(
|
public CadenceEvaluation LateEvaluation()
|
||||||
t,
|
{
|
||||||
elapsedTime,
|
return new CadenceEvaluation(CadenceBand.Late, lateSettlement, 0f);
|
||||||
CadenceBand.Late,
|
|
||||||
LateSettlement,
|
|
||||||
0f
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Intrepid.Core.TimeControl;
|
||||||
|
using Intrepid.Diagnostics;
|
||||||
using Intrepid.Utilities;
|
using Intrepid.Utilities;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -8,88 +10,87 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Cadence
|
|||||||
[CreateAssetMenu(fileName = "Cadence Service", menuName = "GON/Services/Cadence/Cadence Service")]
|
[CreateAssetMenu(fileName = "Cadence Service", menuName = "GON/Services/Cadence/Cadence Service")]
|
||||||
public class CadenceService : SingletonScriptableObject<CadenceService>
|
public class CadenceService : SingletonScriptableObject<CadenceService>
|
||||||
{
|
{
|
||||||
private Timer CadenceTimer { get; set; } = new();
|
private Timer CadenceProfileTimer { get; set; } = new();
|
||||||
|
private Timer CadenceTotalTimer { get; set; } = new();
|
||||||
private CadenceProfile CurrentProfile { get; set; }
|
private CadenceProfile CurrentProfile { get; set; }
|
||||||
|
private float TargetTime { get; set; }
|
||||||
|
private float StartedProfileAt { get; set; }
|
||||||
|
|
||||||
public bool IsCadenceRunning => CadenceTimer.IsRunning;
|
public bool IsCadenceRunning => CadenceProfileTimer.IsRunning;
|
||||||
public float CadenceElapsedTime => (float)CadenceTimer.ElapsedTime;
|
private float CadenceProfileElapsedTime => (float)CadenceProfileTimer.ElapsedTime; // elapsed time since a single cadence began
|
||||||
|
public float TotalCadenceElapsedTime => (float)CadenceTotalTimer.ElapsedTime; // elapsed time since first cadence began
|
||||||
|
|
||||||
private float _startedAt;
|
|
||||||
|
|
||||||
protected override void WhenInstantiate(CadenceService s)
|
protected override void WhenInstantiate(CadenceService s)
|
||||||
{
|
{
|
||||||
base.WhenInstantiate(s);
|
base.WhenInstantiate(s);
|
||||||
ResetCadence();
|
ResetCadenceProfile();
|
||||||
|
CadenceTotalTimer.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginCadence(CadenceProfile profile, float elapsedTime)
|
public void BeginCadence(CadenceProfile profile, float targetTime)
|
||||||
{
|
{
|
||||||
if (profile is null)
|
if (profile is null || targetTime <= 0)
|
||||||
{
|
{
|
||||||
ResetCadence();
|
DLogger.LogError($"profile should not be null: (is null? {profile.IsNull()}); targetTime should be > 0: {targetTime}");
|
||||||
|
ResetCadenceProfile();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_startedAt = elapsedTime;
|
StartedProfileAt = TimeSimulation.Instance.ScaledElapsedTime;
|
||||||
CurrentProfile = profile;
|
CurrentProfile = profile;
|
||||||
CadenceTimer.Start();
|
TargetTime = targetTime;
|
||||||
|
CadenceProfileTimer.Start();
|
||||||
|
if (CadenceTotalTimer.IsNotRunning) CadenceTotalTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CadenceEvaluation EvaluateAndConsumeAt(float inputTimeAt)
|
public CadenceEvaluation EndCadence()
|
||||||
|
{
|
||||||
|
CadenceTotalTimer.Stop();
|
||||||
|
|
||||||
|
if (!IsCadenceRunning || CurrentProfile is null) // if cadence was already ended
|
||||||
|
{
|
||||||
|
return CadenceEvaluation.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cadenceEvaluation = CurrentProfile.LateEvaluation();
|
||||||
|
ResetCadenceProfile();
|
||||||
|
|
||||||
|
return cadenceEvaluation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CadenceEvaluation TryEndCadenceProfileWithInputAt(float inputAt)
|
||||||
{
|
{
|
||||||
if (!IsCadenceRunning || CurrentProfile is null)
|
if (!IsCadenceRunning || CurrentProfile is null)
|
||||||
{
|
{
|
||||||
return CadenceEvaluation.None;
|
return CadenceEvaluation.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
var elapsedAtInput = Mathf.Max(0f, inputTimeAt - _startedAt);
|
var elapsedAtInput = Mathf.Max(0f, inputAt - StartedProfileAt);
|
||||||
var evaluation = CurrentProfile.Evaluate(elapsedAtInput);
|
var evaluation = CurrentProfile.Evaluate(elapsedAtInput / TargetTime);
|
||||||
ResetCadence();
|
ResetCadenceProfile();
|
||||||
|
|
||||||
return evaluation;
|
return evaluation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CadenceEvaluation EvaluateAndConsume()
|
public bool UpdateCadence(float deltaTime)
|
||||||
{
|
{
|
||||||
if (!IsCadenceRunning || CurrentProfile is null)
|
|
||||||
{
|
|
||||||
return CadenceEvaluation.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
var evaluation = CurrentProfile.Evaluate(CadenceElapsedTime);
|
|
||||||
|
|
||||||
ResetCadence();
|
|
||||||
|
|
||||||
return evaluation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateCadence(out CadenceEvaluation autoSettlement)
|
|
||||||
{
|
|
||||||
autoSettlement = CadenceEvaluation.None;
|
|
||||||
|
|
||||||
if (!IsCadenceRunning || CurrentProfile is null)
|
if (!IsCadenceRunning || CurrentProfile is null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CadenceTimer.Update(Timer.ScaledTime);
|
CadenceProfileTimer.Update(deltaTime);
|
||||||
|
CadenceTotalTimer.Update(deltaTime);
|
||||||
if (!CadenceTimer.Check(CurrentProfile.TotalTime))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
autoSettlement = CurrentProfile.Evaluate(CadenceElapsedTime);
|
|
||||||
|
|
||||||
ResetCadence();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetCadence()
|
public void ResetCadenceProfile()
|
||||||
{
|
{
|
||||||
CadenceTimer.Stop();
|
CadenceProfileTimer.Stop();
|
||||||
CurrentProfile = null;
|
CurrentProfile = null;
|
||||||
|
TargetTime = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,3 @@
|
|||||||
using Intrepid.Gameplay.Entities.Player.Sentinel.Inputs;
|
|
||||||
using Intrepid.Utilities;
|
using Intrepid.Utilities;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -15,12 +14,18 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Cadence.UI
|
|||||||
[GroupInjections, SerializeField] private Slider effective;
|
[GroupInjections, SerializeField] private Slider effective;
|
||||||
[GroupInjections, SerializeField] private Slider projection;
|
[GroupInjections, SerializeField] private Slider projection;
|
||||||
|
|
||||||
|
private string _lastCadenceTimer;
|
||||||
|
private string _lastCadenceConnectedCounter;
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
cadenceTimer.text = CadenceService.Instance.IsCadenceRunning
|
if (CadenceService.Instance.IsCadenceRunning)
|
||||||
? CadenceService.Instance.CadenceElapsedTime.ToString("F2")
|
{
|
||||||
: "--";
|
_lastCadenceTimer = $"{CadenceService.Instance.TotalCadenceElapsedTime * 1000f:F2}ms";
|
||||||
btnElapsedTimes.text = controls.CadenceConnectedCounter.ToString();
|
_lastCadenceConnectedCounter = $"{controls.CadenceConnectedCounter}";
|
||||||
|
}
|
||||||
|
cadenceTimer.text = _lastCadenceTimer;
|
||||||
|
btnElapsedTimes.text = _lastCadenceConnectedCounter;
|
||||||
effective.value = CoreStabilityService.Instance.EffectiveStabilityP;
|
effective.value = CoreStabilityService.Instance.EffectiveStabilityP;
|
||||||
projection.value = CoreStabilityService.Instance.ProjectedStabilityP;
|
projection.value = CoreStabilityService.Instance.ProjectedStabilityP;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Intrepid.Core;
|
|
||||||
using Intrepid.Core.Camera;
|
|
||||||
using Intrepid.Core.Entities;
|
using Intrepid.Core.Entities;
|
||||||
using Intrepid.Core.Entities.Messages;
|
using Intrepid.Core.Entities.Messages;
|
||||||
using Intrepid.Core.Grounding;
|
|
||||||
using Intrepid.Core.TimeControl;
|
using Intrepid.Core.TimeControl;
|
||||||
using Intrepid.Gameplay.Entities.Player.ActionBelt;
|
using Intrepid.Gameplay.Entities.Player.ActionBelt;
|
||||||
using Intrepid.Gameplay.Entities.Player.Sentinel;
|
|
||||||
using Intrepid.Gameplay.Entities.Player.Sentinel.Cadence;
|
using Intrepid.Gameplay.Entities.Player.Sentinel.Cadence;
|
||||||
using Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine;
|
using Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine;
|
||||||
using Intrepid.Structures;
|
using Intrepid.Structures;
|
||||||
using Intrepid.Utilities;
|
using Intrepid.Utilities;
|
||||||
using Unity.Cinemachine;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Intrepid.Gameplay.Entities.Player.Sentinel
|
namespace Intrepid.Gameplay.Entities.Player.Sentinel
|
||||||
{
|
{
|
||||||
public class SentinelBrain : EntityBrain
|
public class SentinelBrain : EntityBrain
|
||||||
{
|
{
|
||||||
|
[GroupInjections, SerializeField] private SentinelConfig config;
|
||||||
[GroupInjections, SerializeField] private PlayerInputResolver inputResolver;
|
[GroupInjections, SerializeField] private PlayerInputResolver inputResolver;
|
||||||
[GroupInjections, SerializeField] private SentinelControls controls;
|
[GroupInjections, SerializeField] private SentinelControls controls;
|
||||||
[GroupInjections, SerializeField] private ActionBeltManager actionBeltManager;
|
[GroupInjections, SerializeField] private ActionBeltManager actionBeltManager;
|
||||||
@ -29,6 +25,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel
|
|||||||
|
|
||||||
public SentinelEntity Entity => RootEntity as SentinelEntity;
|
public SentinelEntity Entity => RootEntity as SentinelEntity;
|
||||||
public SentinelStateType CurrentState => StateMachine.CurrentImplementation.GetStateKey();
|
public SentinelStateType CurrentState => StateMachine.CurrentImplementation.GetStateKey();
|
||||||
|
public SentinelConfig Config => config;
|
||||||
public PlayerInputResolver InputResolver => inputResolver;
|
public PlayerInputResolver InputResolver => inputResolver;
|
||||||
public SentinelControls Controls => controls;
|
public SentinelControls Controls => controls;
|
||||||
public ActionBeltManager ActionBeltManager => actionBeltManager;
|
public ActionBeltManager ActionBeltManager => actionBeltManager;
|
||||||
@ -84,19 +81,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel
|
|||||||
StateMachine.CurrentImplementation.RunOnUpdate();
|
StateMachine.CurrentImplementation.RunOnUpdate();
|
||||||
StateMachine.CurrentImplementation.RunAfterUpdate();
|
StateMachine.CurrentImplementation.RunAfterUpdate();
|
||||||
|
|
||||||
if (CadenceService.Instance.UpdateCadence(out var evaluation))
|
CadenceService.Instance.UpdateCadence(Timer.ScaledTime);
|
||||||
{
|
|
||||||
// DLogger.LogDebug(
|
|
||||||
// $"CADENCE EXPIRED: {evaluation.Band} " +
|
|
||||||
// $"t={evaluation.T * 100f}% " +
|
|
||||||
// $"elapsedAt={evaluation.ElapsedAt * 1000f}ms " +
|
|
||||||
// $"set={evaluation.SettlementFactor} " +
|
|
||||||
// $"rec={evaluation.Recovery}"
|
|
||||||
// );
|
|
||||||
Controls.ExpireCadence();
|
|
||||||
CoreStabilityService.Instance.Settle(evaluation);
|
|
||||||
}
|
|
||||||
|
|
||||||
CoreStabilityService.Instance.UpdateCore(Timer.ScaledTime);
|
CoreStabilityService.Instance.UpdateCore(Timer.ScaledTime);
|
||||||
|
|
||||||
// state machine could take this responsibility in the future...
|
// state machine could take this responsibility in the future...
|
||||||
|
|||||||
@ -0,0 +1,117 @@
|
|||||||
|
using System;
|
||||||
|
using Intrepid.Utilities;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Intrepid.Gameplay.Entities.Player.Sentinel
|
||||||
|
{
|
||||||
|
[Serializable, HideLabel, GroupConfigurations("Walk")]
|
||||||
|
public class WalkConfig
|
||||||
|
{
|
||||||
|
[SerializeField, Range(0, 100)] private float speed = 5;
|
||||||
|
|
||||||
|
public float Speed => speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, HideLabel, GroupConfigurations("Run")]
|
||||||
|
public class RunConfig
|
||||||
|
{
|
||||||
|
[SerializeField, Range(0, 100)] private float speed = 10;
|
||||||
|
|
||||||
|
public float Speed => speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, HideLabel, GroupConfigurations("Dash Impulse")]
|
||||||
|
public class DashImpulseConfig
|
||||||
|
{
|
||||||
|
[SerializeField, Range(0, 50)] private float speed = 35f;
|
||||||
|
[SerializeField, Range(0, 5000)] private float durationMS = 150f;
|
||||||
|
|
||||||
|
public float Speed => speed;
|
||||||
|
public float Duration => durationMS * 0.001f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, HideLabel, GroupConfigurations("Dash Recovery")]
|
||||||
|
public class DashRecoveryConfig
|
||||||
|
{
|
||||||
|
[SerializeField, Range(0, 30)] private float speed = 10;
|
||||||
|
[SerializeField, Range(0, 5000)] private float durationMS = 200f;
|
||||||
|
[SerializeField, Range(15, 90)] private float dashMaxAngleFromForward = 90f;
|
||||||
|
[SerializeField] private AnimationCurve speedCurve;
|
||||||
|
|
||||||
|
public float Speed => speed;
|
||||||
|
public float Duration => durationMS * 0.001f;
|
||||||
|
public float DashMaxAngleFromForward => dashMaxAngleFromForward;
|
||||||
|
public AnimationCurve SpeedCurve => speedCurve;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, HideLabel, GroupConfigurations("Dash Landing")]
|
||||||
|
public class DashLandingConfig
|
||||||
|
{
|
||||||
|
[SerializeField, Range(0, 500)] private float durationMS = 100f;
|
||||||
|
|
||||||
|
public float Duration => durationMS * 0.001f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, HideLabel, GroupConfigurations("Dash Breaking")]
|
||||||
|
public class DashBreakingConfig
|
||||||
|
{
|
||||||
|
[SerializeField, Range(5, 30)] private float speed = 10;
|
||||||
|
[SerializeField, Range(0, 500)] private float durationMS = 300f;
|
||||||
|
[SerializeField] private AnimationCurve speedCurve;
|
||||||
|
|
||||||
|
public float Speed => speed;
|
||||||
|
public float Duration => durationMS * 0.001f;
|
||||||
|
public AnimationCurve SpeedCurve => speedCurve;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, HideLabel, GroupConfigurations("Fall Landing")]
|
||||||
|
public class FallLandingConfig
|
||||||
|
{
|
||||||
|
[SerializeField, Range(0, 5000)] private float durationMS = 2000f;
|
||||||
|
|
||||||
|
public float Duration => durationMS * 0.001f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, HideLabel, GroupConfigurations("Knockdown")]
|
||||||
|
public class KnockdownConfig
|
||||||
|
{
|
||||||
|
[SerializeField] private float knockoutTimeMultiplier = 0.1f;
|
||||||
|
[SerializeField, Range(0, 3000)] private float knockdownDurationMS = 100f;
|
||||||
|
[SerializeField, Range(0, 3000)] private float recoverDurationMS = 500f;
|
||||||
|
[SerializeField] private float maxKnockdownStrength = 15f;
|
||||||
|
|
||||||
|
public float KnockoutTimeMultiplier => knockoutTimeMultiplier;
|
||||||
|
public float KnockdownDuration => knockdownDurationMS * 0.001f;
|
||||||
|
public float RecoverDuration => recoverDurationMS * 0.001f;
|
||||||
|
public float MaxKnockdownStrength => maxKnockdownStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CreateAssetMenu(fileName = "Sentinel Config", menuName = "GON/Services/Sentinel/Config")]
|
||||||
|
public class SentinelConfig : ScriptableObject
|
||||||
|
{
|
||||||
|
[SerializeField] private WalkConfig walk;
|
||||||
|
[SerializeField] private RunConfig run;
|
||||||
|
|
||||||
|
[SerializeField] private DashImpulseConfig dashImpulse;
|
||||||
|
[SerializeField] private DashRecoveryConfig dashRecovery;
|
||||||
|
[SerializeField] private DashLandingConfig dashLanding;
|
||||||
|
[SerializeField] private DashBreakingConfig dashBreaking;
|
||||||
|
|
||||||
|
[SerializeField] private FallLandingConfig fallLanding;
|
||||||
|
|
||||||
|
[SerializeField] private KnockdownConfig knockdown;
|
||||||
|
|
||||||
|
public WalkConfig Walk => walk;
|
||||||
|
public RunConfig Run => run;
|
||||||
|
|
||||||
|
public DashImpulseConfig DashImpulse => dashImpulse;
|
||||||
|
public DashRecoveryConfig DashRecovery => dashRecovery;
|
||||||
|
public DashLandingConfig DashLanding => dashLanding;
|
||||||
|
public DashBreakingConfig DashBreaking => dashBreaking;
|
||||||
|
|
||||||
|
public FallLandingConfig FallLanding => fallLanding;
|
||||||
|
|
||||||
|
public KnockdownConfig Knockdown => knockdown;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f28542aec01041178adfbc30f7a2a82a
|
||||||
|
timeCreated: 1781369939
|
||||||
@ -74,27 +74,16 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void BeginCadencedActionAt(CadenceProfile profile, float actionTimeAt)
|
protected void KeepCadenceWithInputAt(CadenceProfile nextProfile, float targetTime, float inputAt)
|
||||||
{
|
|
||||||
LogAndProjectCadence(profile, CadenceService.Instance.EvaluateAndConsumeAt(actionTimeAt));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void BeginCadencedAction(CadenceProfile profile)
|
|
||||||
{
|
|
||||||
LogAndProjectCadence(profile, CadenceService.Instance.EvaluateAndConsume());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogAndProjectCadence(CadenceProfile profile, CadenceEvaluation previousEvaluation)
|
|
||||||
{
|
{
|
||||||
|
var previousEvaluation = CadenceService.Instance.TryEndCadenceProfileWithInputAt(inputAt);
|
||||||
if (previousEvaluation.Band != CadenceBand.None)
|
if (previousEvaluation.Band != CadenceBand.None)
|
||||||
{
|
{
|
||||||
// DLogger.LogDebug(
|
DLogger.LogDebug(
|
||||||
// $"CADENCE CONNECTED: {previousEvaluation.Band} " +
|
$"CADENCE CONNECTED: {previousEvaluation.Band} " +
|
||||||
// $"t={previousEvaluation.T * 100f}% " +
|
$"set={previousEvaluation.SettlementFactor} " +
|
||||||
// $"elapsedAt={previousEvaluation.ElapsedAt * 1000f}ms " +
|
$"rec={previousEvaluation.Recovery}"
|
||||||
// $"set={previousEvaluation.SettlementFactor} " +
|
);
|
||||||
// $"rec={previousEvaluation.Recovery}"
|
|
||||||
// );
|
|
||||||
|
|
||||||
Brain.Controls.CadenceConnectedCounterInc();
|
Brain.Controls.CadenceConnectedCounterInc();
|
||||||
CoreStabilityService.Instance.Settle(previousEvaluation);
|
CoreStabilityService.Instance.Settle(previousEvaluation);
|
||||||
@ -104,8 +93,20 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine
|
|||||||
Brain.Controls.ExpireCadence();
|
Brain.Controls.ExpireCadence();
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreStabilityService.Instance.ProjectCost(profile.MaxCoreCost);
|
CoreStabilityService.Instance.ProjectCost(nextProfile.MaxCoreCost);
|
||||||
CadenceService.Instance.BeginCadence(profile, TimeSimulation.Instance.ScaledElapsedTime);
|
CadenceService.Instance.BeginCadence(nextProfile, targetTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void EndCadence()
|
||||||
|
{
|
||||||
|
var evaluation = CadenceService.Instance.EndCadence();
|
||||||
|
DLogger.LogDebug(
|
||||||
|
$"CADENCE ENDED: {evaluation.Band} " +
|
||||||
|
$"set={evaluation.SettlementFactor} " +
|
||||||
|
$"rec={evaluation.Recovery}"
|
||||||
|
);
|
||||||
|
CoreStabilityService.Instance.Settle(evaluation);
|
||||||
|
Brain.Controls.ExpireCadence();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool TryConsumeDash()
|
protected bool TryConsumeDash()
|
||||||
@ -113,7 +114,8 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine
|
|||||||
if (Brain.InputResolver.Sentinel.TryConsumeDash(out var dashTimeAt)) // dash with no ground: this could be a feature to be unlocked
|
if (Brain.InputResolver.Sentinel.TryConsumeDash(out var dashTimeAt)) // dash with no ground: this could be a feature to be unlocked
|
||||||
//if (Brain.Entity.IsGrounded && Brain.InputResolver.TryConsumeDash(out var dashTimeAt))
|
//if (Brain.Entity.IsGrounded && Brain.InputResolver.TryConsumeDash(out var dashTimeAt))
|
||||||
{
|
{
|
||||||
BeginCadencedActionAt(Brain.Cadences.DashProfile, dashTimeAt);
|
var targetTime = Brain.Config.DashImpulse.Duration + Brain.Config.DashRecovery.Duration;
|
||||||
|
KeepCadenceWithInputAt(Brain.Cadences.DashProfile, targetTime, dashTimeAt);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -7,12 +7,8 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
public class SentinelStateDashBreaking : SentinelState
|
public class SentinelStateDashBreaking : SentinelState
|
||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip dashBreaking;
|
[GroupConfigurations, SerializeField] private AnimationClip dashBreaking;
|
||||||
[GroupConfigurations, SerializeField, Range(5, 30)] private float speed = 10;
|
|
||||||
[GroupConfigurations, SerializeField, Range(0, 500)] private float extraTimeMS = 300f;
|
|
||||||
[GroupConfigurations, SerializeField] private AnimationCurve speedCurve;
|
|
||||||
|
|
||||||
private Timer Timer { get; } = new();
|
private Timer Timer { get; } = new();
|
||||||
private float ExtraTime => extraTimeMS * 0.001f;
|
|
||||||
|
|
||||||
public override SentinelStateType GetStateKey()
|
public override SentinelStateType GetStateKey()
|
||||||
{
|
{
|
||||||
@ -25,6 +21,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
|
|
||||||
protected override void RunOnEnter(ParameterStore parameterStore)
|
protected override void RunOnEnter(ParameterStore parameterStore)
|
||||||
{
|
{
|
||||||
|
EndCadence();
|
||||||
Brain.Controls.ResetDash();
|
Brain.Controls.ResetDash();
|
||||||
Brain.Entity.ModelAnimation.Play(dashBreaking);
|
Brain.Entity.ModelAnimation.Play(dashBreaking);
|
||||||
Timer.Stop();
|
Timer.Stop();
|
||||||
@ -49,14 +46,15 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Brain.Entity.DesiredVelocity = Brain.Entity.Forward * speed;
|
Brain.Entity.DesiredVelocity = Brain.Entity.Forward * Brain.Config.DashBreaking.Speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Timer.IsNotRunning) return;
|
if (Timer.IsNotRunning) return;
|
||||||
Timer.Update(Time.deltaTime);
|
Timer.Update(Time.deltaTime);
|
||||||
var evaluation = speedCurve.Evaluate((float) Timer.ElapsedTime / ExtraTime);
|
var speedCurve = Brain.Config.DashBreaking.SpeedCurve;
|
||||||
Brain.Entity.DesiredVelocity = Brain.Entity.Forward * (speed * evaluation);
|
var evaluation = speedCurve.Evaluate((float) Timer.ElapsedTime / Brain.Config.DashBreaking.Duration);
|
||||||
if (Timer.Check(ExtraTime))
|
Brain.Entity.DesiredVelocity = Brain.Entity.Forward * (Brain.Config.DashBreaking.Speed * evaluation);
|
||||||
|
if (Timer.Check(Brain.Config.DashBreaking.Duration))
|
||||||
{
|
{
|
||||||
Timer.Stop();
|
Timer.Stop();
|
||||||
Brain.ChangeState(SentinelStateType.Idle);
|
Brain.ChangeState(SentinelStateType.Idle);
|
||||||
|
|||||||
@ -8,10 +8,6 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
public class SentinelStateDashImpulse : SentinelState
|
public class SentinelStateDashImpulse : SentinelState
|
||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip dash;
|
[GroupConfigurations, SerializeField] private AnimationClip dash;
|
||||||
[GroupConfigurations, SerializeField, Range(0, 100)] private float speed = 35;
|
|
||||||
[GroupConfigurations, SerializeField, Range(0, 5000)] private float targetTimeMS = 100f;
|
|
||||||
|
|
||||||
public float TargetTime => targetTimeMS * 0.001f;
|
|
||||||
|
|
||||||
private Timer Timer { get; } = new();
|
private Timer Timer { get; } = new();
|
||||||
|
|
||||||
@ -52,9 +48,9 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
{
|
{
|
||||||
Timer.Update(Time.deltaTime);
|
Timer.Update(Time.deltaTime);
|
||||||
|
|
||||||
Brain.Entity.DesiredVelocity = Brain.Entity.Forward * speed;
|
Brain.Entity.DesiredVelocity = Brain.Entity.Forward * Brain.Config.DashImpulse.Speed;
|
||||||
|
|
||||||
if (!Timer.Check(TargetTime))
|
if (!Timer.Check(Brain.Config.DashImpulse.Duration))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,10 +7,8 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
public class SentinelStateDashLanding : SentinelState
|
public class SentinelStateDashLanding : SentinelState
|
||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip dashLanding;
|
[GroupConfigurations, SerializeField] private AnimationClip dashLanding;
|
||||||
[GroupConfigurations, SerializeField, Range(0, 500)] private float landingTimeMS = 100f;
|
|
||||||
|
|
||||||
private Timer Timer { get; } = new();
|
private Timer Timer { get; } = new();
|
||||||
private float LandingTime => landingTimeMS * 0.001f;
|
|
||||||
|
|
||||||
public override SentinelStateType GetStateKey()
|
public override SentinelStateType GetStateKey()
|
||||||
{
|
{
|
||||||
@ -23,6 +21,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
|
|
||||||
protected override void RunOnEnter(ParameterStore parameterStore)
|
protected override void RunOnEnter(ParameterStore parameterStore)
|
||||||
{
|
{
|
||||||
|
EndCadence();
|
||||||
Brain.Controls.ResetDash();
|
Brain.Controls.ResetDash();
|
||||||
Brain.Entity.DesiredVelocity = Vector2.zero;
|
Brain.Entity.DesiredVelocity = Vector2.zero;
|
||||||
Brain.Entity.ModelAnimation.CrossFade(dashLanding, .1f);
|
Brain.Entity.ModelAnimation.CrossFade(dashLanding, .1f);
|
||||||
@ -39,7 +38,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
{
|
{
|
||||||
if (Timer.IsNotRunning) return;
|
if (Timer.IsNotRunning) return;
|
||||||
Timer.Update(Timer.ScaledTime);
|
Timer.Update(Timer.ScaledTime);
|
||||||
if (Timer.Check(LandingTime))
|
if (Timer.Check(Brain.Config.DashLanding.Duration))
|
||||||
{
|
{
|
||||||
Timer.Stop();
|
Timer.Stop();
|
||||||
Brain.ChangeState(SentinelStateType.Idle);
|
Brain.ChangeState(SentinelStateType.Idle);
|
||||||
|
|||||||
@ -8,12 +8,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
public class SentinelStateDashRecovery : SentinelState
|
public class SentinelStateDashRecovery : SentinelState
|
||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip dashRecovery;
|
[GroupConfigurations, SerializeField] private AnimationClip dashRecovery;
|
||||||
[GroupConfigurations, SerializeField, Range(0, 30)] private float speed = 10;
|
|
||||||
[GroupConfigurations, SerializeField, Range(15, 90)] private float dashMaxAngleFromForward = 60f;
|
|
||||||
[GroupConfigurations, SerializeField, Range(0, 5000)] private float targetTimeMS = 200f;
|
|
||||||
[GroupConfigurations, SerializeField] private AnimationCurve speedCurve;
|
|
||||||
|
|
||||||
public float TargetTime => targetTimeMS * 0.001f;
|
|
||||||
private Timer Timer { get; } = new();
|
private Timer Timer { get; } = new();
|
||||||
|
|
||||||
public override SentinelStateType GetStateKey()
|
public override SentinelStateType GetStateKey()
|
||||||
@ -55,7 +50,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
var movement = Brain.InputResolver.Sentinel.Movement();
|
var movement = Brain.InputResolver.Sentinel.Movement();
|
||||||
var forward = Brain.Entity.Forward;
|
var forward = Brain.Entity.Forward;
|
||||||
var direction = GonFunctions
|
var direction = GonFunctions
|
||||||
.ConstrainDirectionToForwardCone(movement, forward, dashMaxAngleFromForward);
|
.ConstrainDirectionToForwardCone(movement, forward, Brain.Config.DashRecovery.DashMaxAngleFromForward);
|
||||||
Brain.Entity.ChangeOrientation(direction);
|
Brain.Entity.ChangeOrientation(direction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -72,14 +67,15 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Timer.Update(Time.deltaTime);
|
Timer.Update(Time.deltaTime);
|
||||||
if (Timer.Check(TargetTime))
|
if (Timer.Check(Brain.Config.DashRecovery.Duration))
|
||||||
{
|
{
|
||||||
Timer.Stop();
|
Timer.Stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var speedFactor = 1f + speedCurve.Evaluate((float)Timer.ElapsedTime / TargetTime);
|
var speedCurve = Brain.Config.DashRecovery.SpeedCurve;
|
||||||
Brain.Entity.DesiredVelocity = Brain.Entity.Forward * (speed * speedFactor);
|
var speedFactor = 1f + speedCurve.Evaluate((float)Timer.ElapsedTime / Brain.Config.DashRecovery.Duration);
|
||||||
|
Brain.Entity.DesiredVelocity = Brain.Entity.Forward * (Brain.Config.DashRecovery.Speed * speedFactor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,6 +26,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
|
|
||||||
protected override void RunOnEnter(ParameterStore ps)
|
protected override void RunOnEnter(ParameterStore ps)
|
||||||
{
|
{
|
||||||
|
EndCadence();
|
||||||
Brain.Controls.ResetDash();
|
Brain.Controls.ResetDash();
|
||||||
Brain.Entity.ModelAnimation.CrossFade(fall, .1f);
|
Brain.Entity.ModelAnimation.CrossFade(fall, .1f);
|
||||||
Brain.Entity.DesiredVelocity = Vector2.zero;
|
Brain.Entity.DesiredVelocity = Vector2.zero;
|
||||||
|
|||||||
@ -7,7 +7,6 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
public class SentinelStateFallLanding : SentinelState
|
public class SentinelStateFallLanding : SentinelState
|
||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip fallLanding;
|
[GroupConfigurations, SerializeField] private AnimationClip fallLanding;
|
||||||
[GroupConfigurations, SerializeField, Range(0, 5)] private float fallLandingDuration = 2f;
|
|
||||||
|
|
||||||
private Timer Timer { get; } = new();
|
private Timer Timer { get; } = new();
|
||||||
|
|
||||||
@ -36,7 +35,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
{
|
{
|
||||||
if (Timer.IsNotRunning) return;
|
if (Timer.IsNotRunning) return;
|
||||||
Timer.Update(Timer.ScaledTime);
|
Timer.Update(Timer.ScaledTime);
|
||||||
if (!Timer.Check(fallLandingDuration)) return;
|
if (!Timer.Check(Brain.Config.FallLanding.Duration)) return;
|
||||||
Timer.Stop();
|
Timer.Stop();
|
||||||
Brain.ChangeState(SentinelStateType.Idle);
|
Brain.ChangeState(SentinelStateType.Idle);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using Intrepid.Diagnostics;
|
|
||||||
using Intrepid.Structures;
|
using Intrepid.Structures;
|
||||||
using Intrepid.Utilities;
|
using Intrepid.Utilities;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -9,10 +8,6 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip knockdown;
|
[GroupConfigurations, SerializeField] private AnimationClip knockdown;
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip knockout;
|
[GroupConfigurations, SerializeField] private AnimationClip knockout;
|
||||||
[GroupConfigurations, SerializeField] private float KnockoutTimeMultiplier = 0.1f;
|
|
||||||
[GroupConfigurations, SerializeField, Range(0, 3)] private float knockdownTime = .1f;
|
|
||||||
[GroupConfigurations, SerializeField, Range(0, 3)] private float recoverTime = .5f;
|
|
||||||
[GroupConfigurations, SerializeField] private float maxKnockdown = 15f;
|
|
||||||
|
|
||||||
private Vector2 KnockdownForce { get; set; }
|
private Vector2 KnockdownForce { get; set; }
|
||||||
private float KnockoutTime { get; set; }
|
private float KnockoutTime { get; set; }
|
||||||
@ -34,8 +29,8 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
Brain.Entity.ModelAnimation.CrossFade(knockdown, 0.1f);
|
Brain.Entity.ModelAnimation.CrossFade(knockdown, 0.1f);
|
||||||
KnockdownForce = ps.Get<Vector2>(SentinelConstants.Parameters.KnockdownForce);
|
KnockdownForce = ps.Get<Vector2>(SentinelConstants.Parameters.KnockdownForce);
|
||||||
Brain.Entity.ChangeOrientation(-KnockdownForce.normalized);
|
Brain.Entity.ChangeOrientation(-KnockdownForce.normalized);
|
||||||
KnockoutTime = KnockdownForce.sqrMagnitude * KnockoutTimeMultiplier;
|
KnockoutTime = KnockdownForce.sqrMagnitude * Brain.Config.Knockdown.KnockoutTimeMultiplier;
|
||||||
Brain.Entity.DesiredVelocity = Vector2.ClampMagnitude(KnockdownForce, maxKnockdown);
|
Brain.Entity.DesiredVelocity = Vector2.ClampMagnitude(KnockdownForce, Brain.Config.Knockdown.MaxKnockdownStrength);
|
||||||
KnockdownTimer.Start();
|
KnockdownTimer.Start();
|
||||||
KnockoutTimer.Stop();
|
KnockoutTimer.Stop();
|
||||||
RecoverTimer.Stop();
|
RecoverTimer.Stop();
|
||||||
@ -50,7 +45,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
if (RecoverTimer.IsRunning)
|
if (RecoverTimer.IsRunning)
|
||||||
{
|
{
|
||||||
RecoverTimer.Update(Timer.ScaledTime);
|
RecoverTimer.Update(Timer.ScaledTime);
|
||||||
if (RecoverTimer.Check(recoverTime))
|
if (RecoverTimer.Check(Brain.Config.Knockdown.RecoverDuration))
|
||||||
{
|
{
|
||||||
RecoverTimer.Stop();
|
RecoverTimer.Stop();
|
||||||
Brain.ChangeState(SentinelStateType.Idle);
|
Brain.ChangeState(SentinelStateType.Idle);
|
||||||
@ -62,7 +57,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
if (KnockoutTimer.IsRunning)
|
if (KnockoutTimer.IsRunning)
|
||||||
{
|
{
|
||||||
KnockoutTimer.Update(Timer.ScaledTime);
|
KnockoutTimer.Update(Timer.ScaledTime);
|
||||||
if (KnockoutTimer.Check(recoverTime))
|
if (KnockoutTimer.Check(Brain.Config.Knockdown.RecoverDuration))
|
||||||
{
|
{
|
||||||
KnockoutTimer.Stop();
|
KnockoutTimer.Stop();
|
||||||
RecoverTimer.Start();
|
RecoverTimer.Start();
|
||||||
@ -86,7 +81,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
}
|
}
|
||||||
|
|
||||||
KnockdownTimer.Update(Timer.ScaledTime);
|
KnockdownTimer.Update(Timer.ScaledTime);
|
||||||
if (KnockdownTimer.Check(knockdownTime))
|
if (KnockdownTimer.Check(Brain.Config.Knockdown.KnockdownDuration))
|
||||||
{
|
{
|
||||||
KnockdownTimer.Stop();
|
KnockdownTimer.Stop();
|
||||||
Brain.Entity.ModelAnimation.CrossFade(knockout, 0.1f);
|
Brain.Entity.ModelAnimation.CrossFade(knockout, 0.1f);
|
||||||
|
|||||||
@ -7,8 +7,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
public class SentinelStateRun : SentinelState
|
public class SentinelStateRun : SentinelState
|
||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip run;
|
[GroupConfigurations, SerializeField] private AnimationClip run;
|
||||||
[GroupConfigurations, SerializeField, Range(0, 100)] private float speed = 10;
|
[GroupConfigurations, SerializeField, Range(0, 10)] private float animationSpeed = 3f;
|
||||||
[GroupConfigurations, SerializeField, Range(0, 10)] private float animationSpeed = 1.2f;
|
|
||||||
|
|
||||||
private Vector2 Movement { get; set; }
|
private Vector2 Movement { get; set; }
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (CheckMovement()) return;
|
if (CheckMovement()) return;
|
||||||
Brain.Entity.DesiredVelocity = Movement * speed;
|
Brain.Entity.DesiredVelocity = Movement * Brain.Config.Run.Speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckMovement()
|
private bool CheckMovement()
|
||||||
|
|||||||
@ -7,8 +7,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
public class SentinelStateWalk : SentinelState
|
public class SentinelStateWalk : SentinelState
|
||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private AnimationClip walk;
|
[GroupConfigurations, SerializeField] private AnimationClip walk;
|
||||||
[GroupConfigurations, SerializeField, Range(0, 100)] private float speed = 5;
|
[GroupConfigurations, SerializeField, Range(0, 100)] private float animationSpeed = 2;
|
||||||
[GroupConfigurations, SerializeField, Range(0, 100)] private float animationSpeed = 3;
|
|
||||||
|
|
||||||
private Vector2 Movement { get; set; }
|
private Vector2 Movement { get; set; }
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (CheckMovement()) return;
|
if (CheckMovement()) return;
|
||||||
Brain.Entity.DesiredVelocity = Movement * speed;
|
Brain.Entity.DesiredVelocity = Movement * Brain.Config.Walk.Speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckMovement()
|
private bool CheckMovement()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user