Hey,
I have a Task that looks roughly like this (irrelevant bits cut out)
The first issue was when I tried using StopAllCoroutines(). It threw exceptions, and I solved it by calling StopCoroutine() instead on the coroutine that was actually running. I interpreted this as StopAllCoroutines() will try and stop non-running coroutines and then crashing, but I'm not sure about this.
The second, and my current, issue is that occasionally a NullReferenceException is thrown at the line I commented far down in the file. The problem is that occasionally the agent_ has become disabled while the coroutine is running. I have tested and verified that the agent (behaviour) is in fact enabled right before and right after stopping the coroutine. To me it seems like the coroutine doesn't stop immediately. A quickfix is to simply check if the agent is in fact enabled before using it, but I feel that is just hiding the underlying problem.
Hoping for some clarification on this matter!
I have a Task that looks roughly like this (irrelevant bits cut out)
C#:
using UnityEngine;
using UnityEngine.AI;
using System.Collections;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
public class MoveTowardsTarget : Action
{
[SerializeField]
private SharedTransform target;
[SerializeField]
private SharedBool walker_;
private bool inProgress_;
private Transform target_;
private NavMeshAgent agent_;
public override void OnStart()
{
agent_ = GetComponent<NavMeshAgent>();
target_ = target.GetValue() as Transform;
inProgress_ = true;
if (walker_.Value)
{
var pos = aiWalker_.getRandomPosition();
agent_.SetDestination(pos);
StartCoroutine(checkWalkerCompletion());
}
else
{
agent_.SetDestination(target_.position);
StartCoroutine(checkCompletion());
}
}
public override TaskStatus OnUpdate()
{
var status = inProgress_ ? TaskStatus.Running : TaskStatus.Success;
if (status == TaskStatus.Success)
{
stopCoroutines();
}
return status;
}
public override void OnEnd()
{
stopCoroutines();
}
private void stopCoroutines()
{
if (walker_.Value)
{
StopCoroutine(checkWalkerCompletion());
}
else
{
StopCoroutine(checkCompletion());
}
}
private IEnumerator checkCompletion()
{
while (true)
{
yield return new WaitForSeconds(0.5f);
inProgress_ = agent_.pathPending ||
agent_.remainingDistance >= agent_.stoppingDistance ||
agent_.velocity.sqrMagnitude > 0.0f;
}
}
private IEnumerator checkWalkerCompletion()
{
while (true)
{
yield return new WaitForSeconds(0.5f);
inProgress_ = agent_.remainingDistance > 4; // Occasional crash due to disabled Behavior
}
}
}
The first issue was when I tried using StopAllCoroutines(). It threw exceptions, and I solved it by calling StopCoroutine() instead on the coroutine that was actually running. I interpreted this as StopAllCoroutines() will try and stop non-running coroutines and then crashing, but I'm not sure about this.
The second, and my current, issue is that occasionally a NullReferenceException is thrown at the line I commented far down in the file. The problem is that occasionally the agent_ has become disabled while the coroutine is running. I have tested and verified that the agent (behaviour) is in fact enabled right before and right after stopping the coroutine. To me it seems like the coroutine doesn't stop immediately. A quickfix is to simply check if the agent is in fact enabled before using it, but I feel that is just hiding the underlying problem.
Hoping for some clarification on this matter!