Hello BRian.
I’ve an error since few days according the Handle_ForceApplied method you had in chapter 36.
it happened when I added this line in the PlayerStateMachine ‘s Start method :
ForceReceiver.OnForceApplied += Handle_ForceApplied;
The console says me:
Assets\Scripts\States\Player\PlayerStateMachine.cs(61,13): error CS0123: No overload for ‘Handle_ForceApplied’ matches delegate ‘Action’
And the some in the EnemyStateMachine ‘s Start Method.
I’ve double check with the wike script database but don’t understand where I’m wrong.
Here are my 2 scripts, Player an enemy StateMachine.
using System;
using RPG.Abilities;
using RPG.Attributes;
using RPG.Combat;
using RPG.Control;
using RPG.Core;
using RPG.Movement;
using RPG.Stats;
using UnityEngine;
using UnityEngine.AI;
using Random = UnityEngine.Random;
namespace RPG.States.Enemies
{
public class EnemyStateMachine : StateMachine
{
[field: SerializeField] public Animator Animator { get; private set; }
[field: SerializeField] public CharacterController CharacterController { get; private set; }
[field: SerializeField] public ForceReceiver ForceReceiver { get; private set; }
[field: SerializeField] public NavMeshAgent Agent { get; private set; }
[field: SerializeField] public PatrolPath PatrolPath { get; private set; }
[field: SerializeField] public Fighter Fighter { get; private set; }
[field: SerializeField] public BaseStats BaseStats { get; private set; }
[field: SerializeField] public Health Health { get; private set; }
[field: SerializeField] public CooldownTokenManager CooldownTokenManager { get; private set; }
[field: SerializeField] public float PlayerChasingRange { get; private set; } = 10.0f;
[field: SerializeField] public float MovementSpeed { get; private set; } = 4.0f;
[field: SerializeField] public float RotationSpeed { get; private set; } = 45f;
[field: SerializeField] public float CrossFadeDuration { get; private set; } = .1f;
[field: SerializeField] public float AnimatorDampTime { get; private set; } = .1f;
[field: SerializeField] public float Cooldown { get; private set; } = 1f;
[field: SerializeField] public float ImpactCooldown { get; private set; } = 2.0f;
public float PlayerChasingRangedSquared { get; private set; }
public GameObject Player { get; private set; }
public Blackboard Blackboard = new Blackboard();
private void OnValidate()
{
if (!Animator) Animator = GetComponentInChildren<Animator>();
if (!CharacterController) CharacterController = GetComponent<CharacterController>();
if (!ForceReceiver) ForceReceiver = GetComponent<ForceReceiver>();
if (!Agent) Agent = GetComponent<NavMeshAgent>();
if (!Fighter) Fighter = GetComponent<Fighter>();
if (!BaseStats) BaseStats = GetComponent<BaseStats>();
if (!Health) Health = GetComponent<Health>();
}
private void Start()
{
Agent.updatePosition = false;
Agent.updateRotation = false;
PlayerChasingRangedSquared = PlayerChasingRange * PlayerChasingRange;
Player = GameObject.FindGameObjectWithTag("Player");
Blackboard["Level"] = BaseStats.GetLevel(); //Le niveau de l'enemi est maintenant stocké dans le blackboard
SwitchState(new EnemyIdleState(this));
if (Health.IsDead())
{
SwitchState(new EnemyIdleState(this));
}
Health.onDie.AddListener(() =>
{
SwitchState(new EnemyDeathState(this));
}); Health.onResurrection.AddListener(() =>
{
SwitchState(new EnemyIdleState(this)); //or EnemyIdleState() in EnemyStateMachine
});
Health.onResurrection.AddListener(() =>
{
SwitchState(new EnemyIdleState(this)); //or EnemyIdleState() in EnemyStateMachine
});
ForceReceiver.OnForceApplied += Handle_ForceApplied;
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, PlayerChasingRange);
}
private void Handle_ForceApplied(Vector3 force)
{
if (Health.IsDead()) return;
float forceAmount = Random.Range(0f, force.sqrMagnitude);
if (forceAmount > Random.Range(0f, BaseStats.GetLevel()))
{
SwitchState(new EnemyImpactState(this));
}
}
}
}
using RPG.Attributes;
using RPG.Combat;
using RPG.Combat.Targeting;
using RPG.Control;
using RPG.Core;
using RPG.Dialogue;
using RPG.InputReading;
using RPG.Inventories;
using RPG.Movement;
using RPG.Shops;
using RPG.Stats;
using UnityEngine;
namespace RPG.States.Player
{
public class PlayerStateMachine : StateMachine
{
[field: SerializeField] public InputReader InputReader { get; private set; }
[field: SerializeField] public CharacterController CharacterController { get; private set; }
[field: SerializeField] public Animator Animator { get; private set; }
[field: SerializeField] public AnimationEventRelay AnimationEventRelay { get; private set; }//oubli dans le tuto chap 26
[field: SerializeField] public ForceReceiver ForceReceiver { get; private set; }
[field: SerializeField] public Targeter Targeter { get; private set; }
[field: SerializeField] public Fighter Fighter { get; private set; }
[field: SerializeField] public PickupFinder PickupFinder { get; private set; }
[field: SerializeField] public ConversantFinder ConversantFinder { get; private set; }
[field: SerializeField] public PlayerConversant PlayerConversant { get; private set; }
[field: SerializeField] public ShopFinder ShopFinder { get; private set; }
[field: SerializeField] public Shopper Shopper { get; private set; }
[field: SerializeField] public Health Health { get; private set; }
[field: SerializeField] public BaseStats BaseStats { get; private set; }
[field: SerializeField] public CooldownTokenManager CooldownTokenManager { get; private set; }
[field: SerializeField] public float FreeLookMovementSpeed { get; private set; } = 6.0f;
[field: SerializeField] public float FreeLookRotationSpeed { get; private set; } = 15f;
[field: SerializeField] public float TargetingMovementSpeed { get; private set; } = 5.0f;
[field: SerializeField] public float CrossFadeDuration { get; private set; } = .15f;
[field: SerializeField] public float ImpactCooldown { get; private set; } = 2.0f;
public Transform MainCameraTransform { get; private set; }
void Start()
{
MainCameraTransform = Camera.main.transform;
if (Health.IsDead())
{
SwitchState(new PlayerDeathState(this));
}
else
{
SwitchState(new PlayerFreeLookState(this));
}
Health.onDie.AddListener(() =>
{
SwitchState(new PlayerDeathState(this));
});
Health.onResurrection.AddListener(() =>
{
SwitchState(new PlayerFreeLookState(this)); //or EnemyIdleState() in EnemyStateMachine
});
ForceReceiver.OnForceApplied += Handle_ForceApplied;
}
private void Handle_ForceApplied(Vector3 force)
{
if (Health.IsDead()) return;
if (CooldownTokenManager.HasCooldown("Impact")) return;
float forceAmount = force.magnitude;
if (forceAmount > Random.Range(0f, BaseStats.GetLevel()))
{
SwitchState(new PlayerImpactState(this));
}
}
private void OnValidate()
{
if (InputReader == null) InputReader = GetComponent<InputReader>();
if (CharacterController == null) CharacterController = GetComponent<CharacterController>();
if (Animator == null) Animator = GetComponentInChildren<Animator>();
if (AnimationEventRelay == null) AnimationEventRelay = GetComponentInChildren<AnimationEventRelay>();
if (ForceReceiver == null) ForceReceiver = GetComponent<ForceReceiver>();
if (Targeter == null) Targeter = GetComponentInChildren<Targeter>();
if (PickupFinder == null) PickupFinder = GetComponentInChildren<PickupFinder>();
if (ConversantFinder == null) ConversantFinder = GetComponentInChildren<ConversantFinder>();
if (PlayerConversant == null) PlayerConversant = GetComponentInChildren<PlayerConversant>();
if (Shopper == null) Shopper = GetComponentInChildren<Shopper>();
if (ShopFinder == null) ShopFinder = GetComponentInChildren<ShopFinder>();
if (Health == null) Health = GetComponent<Health>();
if (BaseStats == null) BaseStats = GetComponent<BaseStats>();
}
}
}
If you have an idea ?
I can’t actually test the rest of the tips you wrote like the cooldown and other.
Thanks for your help.
François
