손님 타임 리미터 제작, 블랙보드 기록 여부, string 키 입력 추가

IAIBlackboard 메서드를 제네릭 메서드로 변경
This commit is contained in:
김산 2025-08-29 13:35:46 +09:00
parent 2fe3bbb9ac
commit 015cadde31
11 changed files with 84 additions and 41 deletions

View File

@ -9,7 +9,9 @@ namespace DDD
/// </summary> /// </summary>
public interface IAISharedBlackboard public interface IAISharedBlackboard
{ {
void SetBlackboardGameObject(string key, GameObject inGameObject);
GameObject GetBlackboardGameObject(string key); void SetBlackboardValue<T>(string key, T inValue);
T GetBlackboardValue<T>(string key);
} }
} }

View File

@ -37,7 +37,7 @@ public override void OnStart()
_isLooking = false; _isLooking = false;
var blackboard = gameObject.GetComponent<IAISharedBlackboard>(); var blackboard = gameObject.GetComponent<IAISharedBlackboard>();
_cachedTarget = blackboard.GetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)); _cachedTarget = blackboard.GetBlackboardValue<GameObject>(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget));
} }
public override TaskStatus OnUpdate() public override TaskStatus OnUpdate()

View File

@ -41,7 +41,7 @@ public override void OnStart()
_isMoving = false; _isMoving = false;
var blackboard = gameObject.GetComponent<IAISharedBlackboard>(); var blackboard = gameObject.GetComponent<IAISharedBlackboard>();
_target = blackboard.GetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)); _target = blackboard.GetBlackboardValue<GameObject>(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget));
} }
public override TaskStatus OnUpdate() public override TaskStatus OnUpdate()

View File

@ -241,30 +241,35 @@ public void Execute(ref DynamicBuffer<BranchComponent> branchComponents,
public class SharedTimeLimiter : DecoratorNode public class SharedTimeLimiter : DecoratorNode
{ {
[Tooltip("최대 실행 시간(초)")] [Tooltip("최대 실행 시간(초)")]
[SerializeField] private SharedVariable<float> m_TimeLimit = 30f; [SerializeField] protected SharedVariable<float> _timeLimit = 30f;
[Tooltip("시간 초과 시 반환할 상태")] [Tooltip("시간 초과 시 반환할 상태")]
[SerializeField] private TaskStatus m_TimeoutStatus = TaskStatus.Failure; [SerializeField] protected TaskStatus _timeoutStatus = TaskStatus.Failure;
[Tooltip("하단 블랙보드 키에 현재 시간을 저장할 지")]
[SerializeField] protected bool _isBlackboardWriteEnabled = false;
[SerializeField] protected string _blackboardKey = "CurrentTime";
public SharedVariable<float> TimeLimit public SharedVariable<float> TimeLimit
{ {
get => m_TimeLimit; get => _timeLimit;
set => m_TimeLimit = value; set => _timeLimit = value;
} }
public TaskStatus TimeoutStatus public TaskStatus TimeoutStatus
{ {
get => m_TimeoutStatus; get => _timeoutStatus;
set => m_TimeoutStatus = value; set => _timeoutStatus = value;
} }
private float m_StartTime; protected float _startTime;
private float m_PauseTime = -1f; private float _pauseTime = -1f;
public override void OnStart() public override void OnStart()
{ {
base.OnStart(); base.OnStart();
m_StartTime = Time.time; _startTime = Time.time;
} }
public override TaskStatus OnUpdate() public override TaskStatus OnUpdate()
@ -272,15 +277,15 @@ public override TaskStatus OnUpdate()
var taskComponents = m_BehaviorTree.World.EntityManager.GetBuffer<TaskComponent>(m_BehaviorTree.Entity); var taskComponents = m_BehaviorTree.World.EntityManager.GetBuffer<TaskComponent>(m_BehaviorTree.Entity);
ref var child = ref taskComponents.ElementAt(Index + 1); ref var child = ref taskComponents.ElementAt(Index + 1);
if (Time.time - m_StartTime >= m_TimeLimit.Value) if (Time.time - _startTime >= _timeLimit.Value)
{ {
if (child.Status == TaskStatus.Running || child.Status == TaskStatus.Queued) if (child.Status == TaskStatus.Running || child.Status == TaskStatus.Queued)
{ {
child.Status = m_TimeoutStatus; child.Status = _timeoutStatus;
taskComponents[Index + 1] = child; taskComponents[Index + 1] = child;
} }
return m_TimeoutStatus; return _timeoutStatus;
} }
if (child.Status == TaskStatus.Success || child.Status == TaskStatus.Failure) if (child.Status == TaskStatus.Success || child.Status == TaskStatus.Failure)
@ -294,16 +299,16 @@ public override TaskStatus OnUpdate()
public override void OnBehaviorTreeStopped(bool paused) public override void OnBehaviorTreeStopped(bool paused)
{ {
base.OnBehaviorTreeStopped(paused); base.OnBehaviorTreeStopped(paused);
if (paused) m_PauseTime = Time.time; if (paused) _pauseTime = Time.time;
} }
public override void OnBehaviorTreeStarted() public override void OnBehaviorTreeStarted()
{ {
base.OnBehaviorTreeStarted(); base.OnBehaviorTreeStarted();
if (m_PauseTime >= 0f) if (_pauseTime >= 0f)
{ {
m_StartTime += (Time.time - m_PauseTime); _startTime += (Time.time - _pauseTime);
m_PauseTime = -1f; _pauseTime = -1f;
} }
} }
@ -312,14 +317,14 @@ public override void OnBehaviorTreeStarted()
public override object Save(World world, Entity entity) public override object Save(World world, Entity entity)
{ {
// [제한 시간, 경과 시간] 저장 // [제한 시간, 경과 시간] 저장
return new object[] { m_TimeLimit.Value, Time.time - m_StartTime }; return new object[] { _timeLimit.Value, Time.time - _startTime };
} }
public override void Load(object saveData, World world, Entity entity) public override void Load(object saveData, World world, Entity entity)
{ {
var data = (object[])saveData; var data = (object[])saveData;
m_TimeLimit.Value = (float)data[0]; _timeLimit.Value = (float)data[0];
m_StartTime = Time.time - (float)data[1]; _startTime = Time.time - (float)data[1];
} }
} }
} }

View File

@ -23,7 +23,7 @@ public override void OnStart()
public override TaskStatus OnUpdate() public override TaskStatus OnUpdate()
{ {
var blackboard = gameObject.GetComponent<IAISharedBlackboard>(); var blackboard = gameObject.GetComponent<IAISharedBlackboard>();
var target = blackboard?.GetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)); var target = blackboard?.GetBlackboardValue<GameObject>(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget));
IInteractable currentInteractable = target?.GetComponent<IInteractable>(); IInteractable currentInteractable = target?.GetComponent<IInteractable>();
if (_targetOrderType == RestaurantOrderType.Wait) if (_targetOrderType == RestaurantOrderType.Wait)
{ {
@ -34,7 +34,7 @@ public override TaskStatus OnUpdate()
return TaskStatus.Failure; return TaskStatus.Failure;
} }
var customerBlackboard = gameObject.GetComponent<IAISharedBlackboard>(); var customerBlackboard = gameObject.GetComponent<IAISharedBlackboard>();
customerBlackboard?.SetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget), currentInteractable.GetInteractableGameObject()); customerBlackboard?.SetBlackboardValue(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget), currentInteractable.GetInteractableGameObject());
} }
// Check order type of the current interactable // Check order type of the current interactable
@ -71,7 +71,7 @@ public override TaskStatus OnUpdate()
if (_targetOrderType == RestaurantOrderType.Busy) if (_targetOrderType == RestaurantOrderType.Busy)
{ {
var customerBlackboard = gameObject.GetComponent<IAISharedBlackboard>(); var customerBlackboard = gameObject.GetComponent<IAISharedBlackboard>();
customerBlackboard?.SetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget), null); customerBlackboard?.SetBlackboardValue<GameObject>(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget), null);
} }
return TaskStatus.Success; return TaskStatus.Success;

View File

@ -18,7 +18,7 @@ public override void OnStart()
GameObject interactionTarget = null; GameObject interactionTarget = null;
if (!gameObject.TryGetComponent<IAISharedBlackboard>(out var sharedBlackboard)) return; if (!gameObject.TryGetComponent<IAISharedBlackboard>(out var sharedBlackboard)) return;
interactionTarget = interactionTarget =
sharedBlackboard.GetBlackboardGameObject( sharedBlackboard.GetBlackboardValue<GameObject>(
nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)); nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget));
if (interactionTarget == null) if (interactionTarget == null)

View File

@ -11,26 +11,26 @@ public class CustomerBlackboardComponent : MonoBehaviour, ICustomerBlackboard, I
public void InitializeWithBehaviorTree(BehaviorTree inBehaviorTree) public void InitializeWithBehaviorTree(BehaviorTree inBehaviorTree)
{ {
_behaviorTree = inBehaviorTree; _behaviorTree = inBehaviorTree;
if (!_behaviorTree) return; SetBlackboardValue(nameof(RestaurantCustomerBlackboardKey.SelfGameObject), gameObject);
_behaviorTree.SetVariableValue(nameof(RestaurantCustomerBlackboardKey.SelfGameObject), gameObject);
} }
public void SetCustomerData(string inCustomerDataId) public void SetCustomerData(string inCustomerDataId)
{ {
if (!_behaviorTree) return; SetBlackboardValue(nameof(RestaurantCustomerBlackboardKey.CustomerDataId), inCustomerDataId);
_behaviorTree.SetVariableValue(nameof(RestaurantCustomerBlackboardKey.CustomerDataId), inCustomerDataId);
} }
public void SetBlackboardGameObject(string key, GameObject inGameObject) public void SetBlackboardValue<T>(string key, T inValue)
{ {
if (!_behaviorTree) return; if (!_behaviorTree) return;
_behaviorTree.SetVariableValue(key, inGameObject); _behaviorTree.SetVariableValue(key, inValue);
} }
public GameObject GetBlackboardGameObject(string key) public T GetBlackboardValue<T>(string key)
{ {
if (!_behaviorTree) return null; if (!_behaviorTree) return default;
return _behaviorTree.GetVariable<GameObject>(key)?.Value; SharedVariable<T> blackboardValue = _behaviorTree.GetVariable<T>(key);
return blackboardValue != null ? blackboardValue.Value : default;
} }
} }
} }

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dd35b9ad54934727805aa8a9e232cffd
timeCreated: 1756440681

View File

@ -0,0 +1,30 @@
using DDD;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using UnityEngine;
namespace _DDD.Restaurant
{
public class CustomerTimeLimiter : SharedTimeLimiter
{
private IAISharedBlackboard _blackboard;
public override void OnStart()
{
base.OnStart();
if (!_isBlackboardWriteEnabled) return;
if (!gameObject.TryGetComponent(out _blackboard))
{
Debug.LogError($"[{GetType().Name}] 블랙보드를 찾을 수 없습니다. 게임오브젝트 해시코드: {gameObject.GetHashCode()}");
}
}
public override TaskStatus OnUpdate()
{
if (_isBlackboardWriteEnabled && _blackboard != null)
{
_blackboard.SetBlackboardValue(_blackboardKey, Time.time - _startTime);
}
return base.OnUpdate();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 546f038ee64e401fb67a4ba7d8717b7f
timeCreated: 1756440694

BIN
ProjectSettings/EditorBuildSettings.asset (Stored with Git LFS)

Binary file not shown.