非同期処理を持つActionBehaviourとSubBehavourTreeのRestartOnFinishに関する不具合
Posted: 2024/03/06 08:10
unity ver 2022.3.19f1
arbor3 ver 3.10.0
Arbor3にお世話になっております。
fsmとbehaviour treeをネストしてAI作成を試みています。
ツリーには非同期処理を実装した独自のActionBehaviourを使用しています。
ツリー単体ではアクションを実行した後、ツリーが再開し次のアクションに移行しますので問題ありません。
しかし、fsmの内部にこのツリーをサブツリーとして導入した時、ツリーが一度だけ実行されその後再開されない現象が発生しています。
FSM側のSubBehaviourTreeの設定ではRestartOnFinishのフラグにチェックが入っています。
以下カスタムアクションのスクリプトです。
こちらはランダムな間隔でランダムなテキストを表示するためのアクションです。
using System.Collections.Generic;
using System.Threading;
using Arbor;
using Arbor.BehaviourTree;
using Cysharp.Threading.Tasks;
using UnityEngine;
public class SB_Speech : ActionBehaviour
{
[SerializeField] InputSlot<ISpeechable> speecherSlot = new();
[SerializeField] bool speechOnEnter = false;
[SerializeField] bool autoSpeech = false;
[SerializeField] List<string> texts = new();
ISpeechable speecher;
public string GetRandomText(){
return texts[Random.Range(0, texts.Count)];
}
const float MIN_INTERVAL = 5f;
const float MAX_INTERVAL = 10f;
float interval = 0;
void InitAutoSpeechTimer(){
interval = Random.Range(MIN_INTERVAL, MAX_INTERVAL);
}
bool isDone = false;
CancellationTokenSource source;
protected async override void OnStart()
{
source = new();
isDone = false;
speecherSlot.TryGetValue(out speecher);
if(speechOnEnter){
speecher.SpeechBase.Speech(GetRandomText());
}
if(autoSpeech){
InitAutoSpeechTimer();
try
{
await UniTask.WaitForSeconds(interval, cancellationToken: source.Token);
speecher.SpeechBase.Speech(GetRandomText());
}
catch (System.Exception)
{
}
}
isDone = true;
}
protected override void OnExecute()
{
if(isDone) FinishExecute(true);
}
protected override void OnEnd()
{
source.Cancel();
}
}
問題個所をご教示いただけると助かります。
arbor3 ver 3.10.0
Arbor3にお世話になっております。
fsmとbehaviour treeをネストしてAI作成を試みています。
ツリーには非同期処理を実装した独自のActionBehaviourを使用しています。
ツリー単体ではアクションを実行した後、ツリーが再開し次のアクションに移行しますので問題ありません。
しかし、fsmの内部にこのツリーをサブツリーとして導入した時、ツリーが一度だけ実行されその後再開されない現象が発生しています。
FSM側のSubBehaviourTreeの設定ではRestartOnFinishのフラグにチェックが入っています。
以下カスタムアクションのスクリプトです。
こちらはランダムな間隔でランダムなテキストを表示するためのアクションです。
using System.Collections.Generic;
using System.Threading;
using Arbor;
using Arbor.BehaviourTree;
using Cysharp.Threading.Tasks;
using UnityEngine;
public class SB_Speech : ActionBehaviour
{
[SerializeField] InputSlot<ISpeechable> speecherSlot = new();
[SerializeField] bool speechOnEnter = false;
[SerializeField] bool autoSpeech = false;
[SerializeField] List<string> texts = new();
ISpeechable speecher;
public string GetRandomText(){
return texts[Random.Range(0, texts.Count)];
}
const float MIN_INTERVAL = 5f;
const float MAX_INTERVAL = 10f;
float interval = 0;
void InitAutoSpeechTimer(){
interval = Random.Range(MIN_INTERVAL, MAX_INTERVAL);
}
bool isDone = false;
CancellationTokenSource source;
protected async override void OnStart()
{
source = new();
isDone = false;
speecherSlot.TryGetValue(out speecher);
if(speechOnEnter){
speecher.SpeechBase.Speech(GetRandomText());
}
if(autoSpeech){
InitAutoSpeechTimer();
try
{
await UniTask.WaitForSeconds(interval, cancellationToken: source.Token);
speecher.SpeechBase.Speech(GetRandomText());
}
catch (System.Exception)
{
}
}
isDone = true;
}
protected override void OnExecute()
{
if(isDone) FinishExecute(true);
}
protected override void OnEnd()
{
source.Cancel();
}
}
問題個所をご教示いただけると助かります。