1 year ago
#337675
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