是否有一个可行的解决方案可以启用/禁用 NavMeshAgent 组件而不丢失 NavMesh?
在开始之前,我先说一下我已经尽力做了功课。
Unity3D 如何连接 NavMesh 和 NavMeshAgent -- 建议我在代理接地后循环组件
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;
“无法创建 NavAgent”错误,但现在代理的行为就好像我没有给它指定目的地一样。 (世界大小为 750x750,随机距离设置为 100 米,起点为 Vector3.zero,因此我有理由确定 SamplePosition 不是问题,因为所选目的地不可能超出更重要的是,Idle 状态运行相同的 SetDestination() 方法,并输入相同的随机变量,直到 IsBeingAbducted 状态释放 Cow。并且它回到了寻路突然成为问题的地面)
使用 Unity 时收到警告“无法创建代理,因为没有有效的 Navmesh” -- 根本没有答案
unity 中的 NavMeshAgent 无法工作 -- 建议正确烘焙我的网格但是 -
另外,我已经查看了 Unity 的 API,但找不到我的错误。
所以这是我正在使用的代码 --
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)
{
}
}
以及相应的脚本 --
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;
}
}
所以总而言之,我需要一种方法将牛抬离地面,然后当把它放回地面时,我需要牛逃跑。这是一个简单的 StateMachine 实现,协程存在于静态类中,但由派生自 Monobehavior 的上下文运行。
就像我说的,我尝试的每个问题都会导致相同的错误 - 代理被降低、启用并分配了目的地,但什么也不做。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论