Death Bug Part 2

OK so… as you might be aware, I have a death bug in my game. Earlier, I was unable to get a stack trace, but I finally got my hands on it. This is what it looks like:

"Resume" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.StackTraceUtility:ExtractStackTrace ()
RPG.Movement.Mover:MoveTo (UnityEngine.Vector3,single) (at Assets/Project Backup/Scripts/Movement/Mover.cs:84)
RPG.Combat.Fighter:Update () (at Assets/Project Backup/Scripts/Combat/Fighter.cs:130)
"SetDestination" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.AI.NavMeshAgent:set_destination (UnityEngine.Vector3)
RPG.Movement.Mover:MoveTo (UnityEngine.Vector3,single) (at Assets/Project Backup/Scripts/Movement/Mover.cs:79)
RPG.Combat.Fighter:Update () (at Assets/Project Backup/Scripts/Combat/Fighter.cs:130)
"Stop" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.StackTraceUtility:ExtractStackTrace ()
RPG.Movement.Mover:Cancel () (at Assets/Project Backup/Scripts/Movement/Mover.cs:113)
RPG.Combat.Fighter:Update () (at Assets/Project Backup/Scripts/Combat/Fighter.cs:136)

These are all a result of my failed Death bug. In other words, everyone except the player knows the player is dead. He can’t move or respawn or do anything… he’s just stranded in his position there, trying to attack the enemy that killed him in any way shape or form, without moving from his position. So if he’s got a ranged or magic weapon, he’ll be firing that at his enemy from his position. If not, he’ll keep looking at his enemy until he’s close enough to the players’ melee distance, until he tries to attack him again

The worst part is, the enemy literally considers him as dead

First of all, context…
Is this after the character dies and you reset your character?
Are you turning the NavMeshAgent back on? (Re-enabling it, not just stopping it)

This is after the character dies, and when it happens he’ll never respawn… just stay still, until the real world player takes the game to the main menu and returns.

In ‘Mover.Update()’, there is this line:

navMeshAgent.enabled = !health.IsDead(); // makes sure the navMeshAgent only works when the player is alive (so we can walk over his dead body when he's dead)
      

P.S: I’m heading to work now, might take an hour or more to respond, please bear with me

Out of curiosity… are you using the RespawnManager that you use for the Enemies, or are you using the method described by Sam in Shops and Abilities? (Hint: One of these two won’t work, the other is proven tried and true)…

Im using the one described by Sam in the shops and abilities course

Let’s take a look at your Respawner component. In addition to the script, a screenshot of the inspector would help as well.

Sure, here is my ‘Respawner.cs’ script:

using UnityEngine;
using RPG.Attributes;
using UnityEngine.AI;
using System.Collections;
using RPG.SceneManagement;
using Cinemachine;

namespace RPG.Control {

    public class Respawner : MonoBehaviour {

        [SerializeField] Transform respawnLocation; // the location of the players' respawn
        [SerializeField] float respawnDelay = 3f;    // the time the game waits after the players' death before Respawning him
        [SerializeField] float fadeTime = 0.2f;    // the time for the fadeOut and fadeIn effect to cycle within, when we are respawning our player to his respawn position
        [SerializeField] float healthRegenPercentage; // health Regeneration Percentage (Percentage of Player health to be returned to the Player)
        [SerializeField] float enemyHealthRegenPercentage; // the health percentage, regenerated to enemies, if the Player dies in combat

        private void Awake() {
            // Listen for Player Death, so we respawn him to his respawn location if he dies:
            GetComponent<Health>().onDie.AddListener(Respawn);
        }

        private void Start() {

            // This line fixes the bug of our player being dead if we return to a saved game, which concluded with him dying
            if (GetComponent<Health>().IsDead()) Respawn();

        }
        
        private void Respawn() {

            // Respawning (Warping) the player to his Respawn Location, a few moments after his death:
            StartCoroutine(RespawnRoutine());

        }

        internal IEnumerator RespawnRoutine()
        {

            // Instantly save the game, if the player dies, before he quits the game and tries reloading it:
            SavingWrapper savingWrapper = FindObjectOfType<SavingWrapper>();
            savingWrapper.Save();

            // 1. Wait for 'respawnDelay' seconds
            // 2. Get a hold of the fader, from 'RPG.SceneManagement'
            // 3. Fade Out
            // 4. Warp the Player to his 'respawnLocation' position
            // 5. Fade Back In to the game

            // waiting for 'respawnDelay' seconds after death, prior to respawning the player at Respawn Location:
            yield return new WaitForSeconds(respawnDelay);

            // getting a hold of the fader:
            Fader fader = FindObjectOfType<Fader>();

            // Fade Out:
            yield return fader.FadeOut(fadeTime);
            
            // Respawn the Player:
            RespawnPlayer();

            // Reset the Enemies:
            ResetEnemies();

            // Saving the game (again) before Fading back into the game:
            savingWrapper.Save();

            // Fade In:
            yield return fader.FadeIn(fadeTime);

        }

        private void ResetEnemies() {

            // Resetting our Enemies, so they don't keep trying to kill us each time we respawn:
            foreach (AIController enemyControllers in FindObjectsOfType<AIController>())
            {

                // If he ain't dead, reboost part of his health:
                Health health = enemyControllers.GetComponent<Health>();

                // Only heal and reset enemies that are NOT dead (dead ones are handled by 'RespawnManager.cs')
                if (health && !health.IsDead())
                {

                    // Reset the Enemy AI Controller (Warp Position + AI Variables):
                    enemyControllers.Reset();
                    // Heal the enemies' health, which beat the player:
                    health.Heal(health.GetMaxHealthPoints() * enemyHealthRegenPercentage / 100);

                }

            }

        }

        private void RespawnPlayer()
        {

            // This function will deal with the Cinemachine respawn location, and the Player respawn mechanisms

            // The distance the CineMachine camera will move when respawning our player
            Vector3 positionDelta = respawnLocation.position - transform.position;
            
            // This function includes with the mechanics that respawn the player

            // 1. placing (Warping) the player back to his original respawn location:
            // (it's done in a Coroutine so we can give the player some time rather than instantly respawning)
            GetComponent<NavMeshAgent>().Warp(respawnLocation.position);

            // 2. Restore the Player Health (specific Percentage):
            Health health = GetComponent<Health>();
            health.Heal(health.GetMaxHealthPoints() * healthRegenPercentage / 100);

            // 3. Fixing the Respawn Issue of our Cinemachine Camera:
            ICinemachineCamera activeVirtualCamera = FindObjectOfType<CinemachineBrain>().ActiveVirtualCamera;
            
            // 4. throw the camera to the players' position, and halt it there:
            if (activeVirtualCamera.Follow == transform) {

                activeVirtualCamera.OnTargetObjectWarped(transform, positionDelta);

            }

        }
    
    }

}

The screenshot might take a while though, because this condition is a rare one… it happens, but it’s rare when it does so (about 20-30% of the time). It’ll take a little bit of testing prior to being able to get it

So… not every time… call me when it happens again… if it’s sporadic, there are likely error messages… I’ll probably want to see them.

Fair enough, let’s keep this topic open until then :slight_smile:

I added an “UpdateState()” within the “if(IsDead())” statement, and changed that to an if-else to add a second UpdateState() in the else, and it seems to be just fine for now

Let’s still keep this topic open though, in case it comes back

Privacy & Terms