1 year ago

#337675

test-img

Eric Bramble

Is there a working solution to enabling/disabling a NavMeshAgent component without losing the NavMesh?

Before I begin, let me say I have tried hard to do the homework first.

Unity3D how to connect NavMesh and NavMeshAgent -- Suggested I cycle the component after the agent is grounded

        while (!stateManager.cow.isGrounded())
    {
        Debug.Log("Waiting");
        yield return new WaitForEndOfFrame();
    }
    Debug.Log("Did it");
    stateManager.cow.agent.enabled = false;
    stateManager.cow.agent.enabled = true;
    stateManager.cow.agent.SetDestination((Player.instance.gameObject.transform.position - stateManager.cow.gameObject.transform.position).normalized * 5);
    yield return null;

That stopped the 'Failed To Create NavAgent' error but now the agent acts as if I've given it no destination. (The world size is 750x750, the random distance is set to 100 meters, and the starting point is Vector3.zero, so I'm reasonably sure a SamplePosition isn't the issue as the chosen destination couldn't possible be outside of the realms of possible. What's more, the Idle state runs the same SetDestination() method with the same random variables fed in just fine. It isn't until the IsBeingAbducted state Releases the Cow and it returns to the ground that pathfinding suddenly becomes an issue)

Getting warning "Failed to create agent because there is no valid Navmesh" using Unity -- Has no Answers at all

NavMeshAgent in unity not working -- suggests to properly bake my mesh but -

Photo shows the blue overlay of a properly baked NavMesh

Plus I've reviewed the API from Unity, and I just can't find my error.

So here is the code I'm working with --

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BeingAbducted : CowState
{
    public override void EnterState(CattleStateManager stateManager)
    {
        //Debug.Log("Entering BeingAbducted State");

        // Set gravity use to false
        stateManager.cow.rigidBody.useGravity = false;
        // Disable agent control
        stateManager.cow.agent.enabled = false;
        // Set isBeingAbducted to true
        stateManager.cow.isBeingAbducted = true;
        // Set timer for abduction to starting value
        stateManager.cow.abductionTimer = 0.0f;
        // Play the moo hurt sound
        AudioManager.instance.Play(Sounds.HurtMoo_1, stateManager.cow.transform.position);

    }

    public override void UpdateState(CattleStateManager stateManager)
    {
        //Debug.Log("Updating BeingAbducted State");
        // Begin incrementing timer
        stateManager.cow.abductionTimer += Time.deltaTime;
        // Move towards raycast point
        Vector3 newCowPosition = 
        Vector3.MoveTowards(stateManager.cow.gameObject.transform.position, 
        Player.instance.tractorBeam.rayCastOrigin.position, 5 * Time.deltaTime);
        stateManager.cow.agent.baseOffset = newCowPosition.y * 120;
        stateManager.cow.gameObject.transform.position = newCowPosition;
        // suspend in air at set height

        if (stateManager.cow.gameObject.transform.position.y >= 7)
       {
            Vector3 lockedHeightVector = new Vector3(stateManager.cow.gameObject.transform.position.x, 7, stateManager.cow.gameObject.transform.position.z);
            stateManager.cow.gameObject.transform.position = lockedHeightVector;
       }
       // BeginTransition 
    stateManager.cow.skinnedMeshRenderer.material.SetFloat("_DissolveAmount", (stateManager.cow.abductionTimer / stateManager.cow.timeToAbductCow));

        if (stateManager.cow.abductionTimer >= stateManager.cow.timeToAbductCow)
        {
            stateManager.SwitchState(CattleState.Abducted);
        }
    }
    public override void ExitState(CattleStateManager stateManager)
    {
        //Debug.Log("Exiting BeingAbducted State");

        if (stateManager.cow.abductionTimer < stateManager.cow.timeToAbductCow)
        {
            stateManager.cow.skinnedMeshRenderer.material.SetFloat("_DissolveAmount", 0);
            stateManager.cow.rigidBody.useGravity = true;
            stateManager.cow.agent.baseOffset = 0;
        }

    }

    public override void OnCollisionEnter(CattleStateManager stateManager, Collision collision)
    {

    }
}

And the corresponding script --

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RunAway : CowState
{
    public override void EnterState(CattleStateManager stateManager)
    {
        Debug.Log("Entering RunAway State");
        // set agent destination to a random long distance opposite player
        stateManager.StartCoroutine(AgentGrounded(stateManager));
    }

    public override void UpdateState(CattleStateManager stateManager)
    {
        Debug.Log("Updating RunAway State");

        // run the path
        // increase the animation velocity to match the navagent velocity
        // moo a lot
        if (stateManager.cow.agent.isOnNavMesh)
        {
        
stateManager.cow.agent.SetDestination((Player.instance.gameObject.transform.position - stateManager.cow.gameObject.transform.position).normalized * 5);
        }

    }
    public override void ExitState(CattleStateManager stateManager)
    {
        Debug.Log("Exiting RunAway State");
    }

    public override void OnCollisionEnter(CattleStateManager stateManager, Collision collision)
    {

    }

    public IEnumerator AgentGrounded(CattleStateManager stateManager)
    {
        while (!stateManager.cow.isGrounded())
        {
            Debug.Log("Waiting");
            yield return new WaitForEndOfFrame();
        }
        Debug.Log("Did it");
        stateManager.cow.agent.enabled = false;
        stateManager.cow.agent.enabled = true;
        stateManager.cow.agent.SetDestination((Player.instance.gameObject.transform.position - stateManager.cow.gameObject.transform.position).normalized * 5);
        yield return null;
    }
}

So all in all I need a way to lift the cow off of the ground, then when returning it to the ground, I need the cow to run away. This is a simple StateMachine implementation and the Coroutine exists in the static class, yet is ran by the context which derives from Monobehavior.

Like I said though, every issue I try results in the same error -- the Agent get's lowered, enabled, and a destination assigned, yet does nothing.

unity-game-engine

agent

navmesh

0 Answers

Your Answer

Accepted video resources