It appears to be happening some of the times
I think I see whatâs going on there⌠When the character is still in knockback, the Chase State is trying to move the character, but ForceReceiver is holding the NavMeshAgent disabled (as it should).
See if this fixes it in Chasing State
private void MoveToPlayer(float deltaTime)
{
if (stateMachine.Agent.enabled)
{
stateMachine.Agent.destination = stateMachine.Player.transform.position;
Vector3 desiredVelocity = stateMachine.Agent.desiredVelocity.normalized;
Move(desiredVelocity * stateMachine.MovementSpeed, deltaTime);
stateMachine.Agent.velocity = stateMachine.CharacterController.velocity;
stateMachine.Agent.nextPosition = stateMachine.transform.position;
}
else
{
Move(deltaTime);
}
}
Thanks,
It does fix the error in Chasing state.
Now the errors seem more consistent and only in Patrolling state, only when the player is knocked back
So the next step would be to fix the handling of the state switching?
At the moment it goes:
(finish) Attacking
Idle
Patrolling if has path, else it skips this step. (This is where the error happens)
Chasing
Either adding a IsInChaseRange() check on Enter() and SwitchState there as first check,
or extract the handling to BaseState
Is this correct?
EDIT:
Gave it a try,
added this to EnemyPatrolState enter:
IsInChaseRange check
if (IsInChaseRange())
{
stateMachine.SwitchState(new EnemyChasingState(stateMachine));
return;
}
It only got rid of the SetDestination error, the ResetPath error persisted obviously as we are still calling an Exit method that resets path
SetDestination error
"SetDestination" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.AI.NavMeshAgent:SetDestination (UnityEngine.Vector3)
RPG.States.Enemies.EnemyPatrollingState:Enter () (at Assets/Scripts/States/Enemies/EnemyPatrollingState.cs:63)
RPG.States.StateMachine:SwitchState (RPG.States.State) (at Assets/Scripts/States/StateMachine.cs:13)
EnemyIdleState:Enter () (at Assets/Scripts/States/Enemies/EnemyIdleState.cs:18)
RPG.States.StateMachine:SwitchState (RPG.States.State) (at Assets/Scripts/States/StateMachine.cs:13)
RPG.States.Enemies.EnemyAttackingState:Tick (single) (at Assets/Scripts/States/Enemies/EnemyAttackingState.cs:56)
RPG.States.StateMachine:Update () (at Assets/Scripts/States/StateMachine.cs:18)
Error after adding IsInChaseRange check
"ResetPath" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.StackTraceUtility:ExtractStackTrace ()
RPG.States.Enemies.EnemyPatrollingState:Exit () (at Assets/Scripts/States/Enemies/EnemyPatrollingState.cs:114)
RPG.States.StateMachine:SwitchState (RPG.States.State) (at Assets/Scripts/States/StateMachine.cs:11)
RPG.States.Enemies.EnemyPatrollingState:Enter () (at Assets/Scripts/States/Enemies/EnemyPatrollingState.cs:32)
RPG.States.StateMachine:SwitchState (RPG.States.State) (at Assets/Scripts/States/StateMachine.cs:13)
EnemyIdleState:Enter () (at Assets/Scripts/States/Enemies/EnemyIdleState.cs:18)
RPG.States.StateMachine:SwitchState (RPG.States.State) (at Assets/Scripts/States/StateMachine.cs:13)
RPG.States.Enemies.EnemyAttackingState:Tick (single) (at Assets/Scripts/States/Enemies/EnemyAttackingState.cs:56)
RPG.States.StateMachine:Update () (at Assets/Scripts/States/StateMachine.cs:18)
So hereâs your challengeâŚ
Both of these errors are occuring because the agent is disabled when the method is called⌠What did we do in the earlier instances to avoid this?
Well I added a statemachine.Agent.Enabled check before any ResetPath or SetDestination calls on either of the state.
this exact same rare bug happens occasionally as well when trying to gather resources from time to time, and the only way out is to restart the scene, by quitting to the main menu, and then returning to the game⌠Iâll try fix this on my own and keep you updated as we go (if this comment is not edited later, the bug still exists)
Just to be extremely clear, itâs the bug where the input does not get taken into consideration because of a Restoring State issue in âResourceSpawner.csâ (probably that or âResourceGathering.csâ, although it doesnât have a saving system in that script), so the computer thinks itâs probably a consumed resource, but itâs actually notâŚ
and here is my latest version of âResourceRespawner.csâ if that helps:
using System;
using System.Collections;
using GameDevTV.Saving;
using Newtonsoft.Json.Linq;
using UnityEngine;
// Advanced Resource Respawning System, for the Third Person Implementation
namespace RPG.ResourceManager {
[RequireComponent(typeof(JSONSaveableEntity))]
public class ResourceRespawner : MonoBehaviour, IJsonSaveable
{
[SerializeField] ResourceGathering resourceToSpawn;
[SerializeField] int hideTime;
private double destroyedTime;
private TimeKeeper timeKeeper;
private void Awake()
{
timeKeeper = TimeKeeper.GetTimeKeeper();
SpawnResource();
}
public ResourceGathering GetResource()
{
return GetComponentInChildren<ResourceGathering>();
}
public bool IsDestroyed()
{
return GetResource() == null;
}
public int GetQuantityLeft()
{
if (GetResource() == null) return 0;
return GetResource().GetQuantityLeft();
}
private void SpawnResource()
{
var resourceObject = Instantiate(resourceToSpawn, transform.position, Quaternion.identity);
resourceObject.transform.SetParent(transform);
resourceObject.OnResourceDestroyed += OnResourceDestroyed;
}
private IEnumerator WaitAndRespawn()
{
var elapsedTime = (float)(timeKeeper.GetGlobalTime() - destroyedTime);
// yield return new WaitForSeconds(hideTime - elapsedTime);
yield return new WaitForSecondsRealtime(hideTime - elapsedTime);
SpawnResource();
}
private void OnResourceDestroyed(ResourceGathering resourceNode)
{
resourceNode.OnResourceDestroyed -= OnResourceDestroyed;
destroyedTime = timeKeeper.GetGlobalTime();
StartCoroutine(WaitAndRespawn());
}
public JToken CaptureAsJToken()
{
var data = new ResourceData(destroyedTime, IsDestroyed(), GetQuantityLeft());
return JToken.FromObject(data);
}
public void RestoreFromJToken(JToken state)
{
var data = state.ToObject<ResourceData>();
destroyedTime = data.DestroyedTime;
var shouldBeDestroyed = data.ShouldBeDestroyed;
var quantityLeft = data.QuantityLeft;
if (shouldBeDestroyed && !IsDestroyed())
{
// Should be destroyed, but isn't... destroy it
var resourceObject = GetResource();
resourceObject.OnResourceDestroyed -= OnResourceDestroyed;
resourceObject.DestroyResource();
StartCoroutine(WaitAndRespawn());
}
else if (!shouldBeDestroyed && IsDestroyed())
{
// Shouldn't be destroyed, but it is... spawn it
SpawnResource();
GetResource().quantityLeft = quantityLeft;
}
else if (shouldBeDestroyed && IsDestroyed())
{
// Should be destroyed, and is indeed destroyed... reset the timer
StopAllCoroutines();
StartCoroutine(WaitAndRespawn());
}
else
{
// Shouldn't be destroyed, and isn't destroyed... reset the quantity
var resourceObject = GetResource();
GetResource().quantityLeft = quantityLeft;
}
}
}
[Serializable]
public struct ResourceData
{
public double DestroyedTime;
public bool ShouldBeDestroyed;
public int QuantityLeft;
public ResourceData(double destroyedTime, bool shouldBeDestroyed, int quantityLeft)
{
DestroyedTime = destroyedTime;
ShouldBeDestroyed = shouldBeDestroyed;
QuantityLeft = quantityLeft;
}
}
}
didnât fix the previous bug and just kinda squandered into nilly willy again, trying to make a pickaxe for my player⌠(apologies, xD)
My question for now is (along with my previous issue above ), where was the function responsible for assigning the integer of âAnimatorWeaponTypeâ againâŚ?! (not the âTryHit()â one in Fighter.cs that uses it, but the one that assigns it. I want to create a fourth weaponType for my animations (I literally just donât remember where that function went to), so I play a different blend tree when Iâm holding a pickaxe, hatchet or spear).
Long story short, I have a new nested blend tree I set up for long weapons in the âFreeLookStateâ Blend Tree, and I canât access it because I donât know where the function that assigns them is at, or what the name even was⌠(I just need to remember the name, thatâs all I seek)
I fried my brain trying to figure these two problems outâŚ
Itâs the ResourceGathering that should be the ITarget for the ResourceFinder. I thought we covered this issue in another thread weeks ago. The ResourceFinder should be subscribing to OnResourceDestroyed() and removing the object from the list if that method is called
Review this page: https://gitlab.com/tkraindesigns/rpgthirdperson/-/wikis/Blend%20Tree%20Madness
we did actually, we introduced an âOnResourceDestroyedâ event of some sort. However, that issue still pops up occasionally when I return to the game scene, and from recent experience with the pickup system, I automatically knew this was a restoring system issue with the respawner
Hence why I have provided you with my âResourceRespawner.csâ script to have a quick look at
Yup, fixed that, through personal try and error. Thanks again Brian
This bug drove me wild-nuts today⌠once we get the resource respawn occasional glitch done, Iâm more likely than not going straight up on this one, because itâs been annoying for months now (and Iâm 99% sure itâs a race condition, because no bug happens this frequently without something being a major headache because of itâŚ)
Edit: Another bug I noticed (and this isnât a bug, itâs just a system override), is that âAttack Forceâ from âAttack.csâ and âWeapon Damageâ in âWeaponConfig.csâ are both dealing damage, so it adds them up⌠which one is safer to delete? I donât want a mix and mash here
please donât forget to have a look at this bug, itâs a crucial one, and itâs been a real buzzy bug as of recently
I literally thought the respawning the player to the respawn point was fixed already⌠With the Malbers and all the other extra stuff, Iâm not sure if I CAN figure out whatâs going on⌠Youâre in uncharted territory againâŚ
Try not passing the weapon damage in GetAdditiveModifiers within the WeaponConfig.
the Malbers stuff honestly has nothing to do with the respawning, that system was a mess before hand as well anyway, and it has about 50% chance of working and another 50% of not working (itâs acting like a race condition as we speak, and I donât know with whatâŚ). All I did there was to avoid teleportation just âdeleteâ (didnât really delete it permanently, just off the player in the scene, but this was easily reversible), and then instead of warping, I used a transform.position. Again, the Malbers system has its own namespace, and it does not interrupt with my code in any way shape or form
Any other NavMesh-independent approaches for respawning you can possibly think of?
Make sure both your NavMeshAgent (if you have one) and your CharacterController(you have one) are disabled, and then set transform.position to the respawn point. Then you can re-enable the CharacterController and NavMeshAgent (if you have one).
OK Iâm giving that a bit of a try. Again, itâs a random bug, so sometimes itâll happen and sometimes it wonât (does respawning on a position off a NavMeshAgent really make a difference in how it works, though? I just noticed this was a potential issue)
For now, hereâs the extra code I placed in my script (for tracking purposes):
private CharacterController playerCharacterController;
// in 'Awake():'
playerCharacterController = GetComponent<CharacterController>();
// in 'RespawnPlayer():'
playerCharacterController.enabled = false;
// teleport
playerCharacterController.enabled = true;
(no NavMeshAgents for now as we speak)
That code looks correct.
It shouldnât matter if youâre not on the NavMesh, because youâre not using a NavMeshAgent. The only issue is if you respawn off of the NavMesh, the enemies canât get to you until you get on the NavMesh, and that may throw some warnings for the enemy if they try to chase you.
If it does happen, an error message (related to the player) would be extremely helpful.
No warnings when theyâre chasing me.
However, when they try to swing a hit against me, hereâs two errors:
"ResetPath" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.StackTraceUtility:ExtractStackTrace ()
RPG.States.Enemies.EnemyPatrolState:Exit () (at Assets/Project Backup/Scripts/State Machines/Enemy/EnemyPatrolState.cs:115)
RPG.States.StateMachine:SwitchState (RPG.States.State) (at Assets/Project Backup/Scripts/State Machines/StateMachine.cs:11)
RPG.States.Enemies.EnemyPatrolState:Tick (single) (at Assets/Project Backup/Scripts/State Machines/Enemy/EnemyPatrolState.cs:77)
RPG.States.StateMachine:Update () (at Assets/Project Backup/Scripts/State Machines/StateMachine.cs:18)
"SetDestination" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.AI.NavMeshAgent:SetDestination (UnityEngine.Vector3)
RPG.States.Enemies.EnemyPatrolState:Enter () (at Assets/Project Backup/Scripts/State Machines/Enemy/EnemyPatrolState.cs:61)
RPG.States.StateMachine:SwitchState (RPG.States.State) (at Assets/Project Backup/Scripts/State Machines/StateMachine.cs:13)
EnemyIdleState:Enter () (at Assets/Project Backup/Scripts/State Machines/Enemy/EnemyIdleState.cs:17)
RPG.States.StateMachine:SwitchState (RPG.States.State) (at Assets/Project Backup/Scripts/State Machines/StateMachine.cs:13)
RPG.States.Enemies.EnemyAttackingState:Tick (single) (at Assets/Project Backup/Scripts/State Machines/Enemy/EnemyAttackingState.cs:54)
RPG.States.StateMachine:Update () (at Assets/Project Backup/Scripts/State Machines/StateMachine.cs:18)
They do NOT affect the gameplay in anyway, but theyâre there
These are enemy-relevant errors, and they do NOT happen when the enemy is moving around, they only occur when he tries to swing an attack
I donât know what I recently fixed as well (just re-baked the NavMesh), but fortunately they are no longer able to chase me off the NavMesh. Itâs only me with the superpower of being able to walk on non-NavMeshAgent surfaces anymore
my guess is, based on what the errors say, itâs because theyâre trying to be way-too close to the playerâŚ?
These errors are happening when the enemy is exiting and entering the Patrol State.
Paste in your EnemyPatrolState.csâŚ
I doubt it, they should stop chasing you when they are within attack range.