Advertisement
Pro_Unit

AnimalUtilityAI

Sep 9th, 2023
896
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.07 KB | None | 0 0
  1. using System.Threading;
  2.  
  3. using Cysharp.Threading.Tasks;
  4.  
  5. using Game.CameraLogic.Animals;
  6. using Game.Characteristics;
  7. using Game.Extensions;
  8.  
  9. using UniRx;
  10.  
  11. using UnityEngine;
  12.  
  13. using IAction = Game.UtilityAI.Actions.IAction;
  14.  
  15. namespace Game.UtilityAI
  16. {
  17.     [RequireComponent(typeof(Animal))]
  18.     public class AnimalUtilityAI : MonoBehaviour
  19.     {
  20.         private IUtilityAction[] _actions;
  21.         private INeed[] _needs;
  22.  
  23.         [SerializeField] private Game.Infrastructure.Logger _logger;
  24.         [SerializeField] private Animal _animal;
  25.  
  26.         private CancellationTokenSource _cancellationTokenSource;
  27.  
  28.         private void OnValidate()
  29.         {
  30.             _animal ??= GetComponent<Animal>();
  31.         }
  32.  
  33.         private void Awake()
  34.         {
  35.             _needs = GetComponents<INeed>();
  36.  
  37.             _actions = GetComponents<IUtilityAction>();
  38.             _cancellationTokenSource = new CancellationTokenSource();
  39.         }
  40.  
  41.         private async void Start()
  42.         {
  43.             _animal
  44.                 .SubscribeOnDead(OnDead)
  45.                 .AddTo(this);
  46.  
  47.             await Run();
  48.         }
  49.  
  50.         private void OnDead(Stat _)
  51.         {
  52.             enabled = false;
  53.             Debug.Log("Animal is dead");
  54.             CancelCurrentTask();
  55.         }
  56.  
  57.         private async UniTask Run()
  58.         {
  59.             while (enabled)
  60.                 await ExecuteBestAction();
  61.         }
  62.  
  63.         private void Update()
  64.         {
  65.             foreach(INeed need in _needs)
  66.                 need.Increase();
  67.         }
  68.  
  69.         private async UniTask ExecuteBestAction()
  70.         {
  71.             IAction bestAction = GetBestAction();
  72.  
  73.             await bestAction.Execute(_cancellationTokenSource.Token);
  74.         }
  75.  
  76.         [ContextMenu("Cancel current task")]
  77.         private void CancelCurrentTask() =>
  78.             _cancellationTokenSource.Cancel();
  79.  
  80.         private IAction GetBestAction()
  81.         {
  82.             float bestUtility = float.MinValue;
  83.             IAction bestAction = null;
  84.  
  85.             foreach(IUtilityAction action in _actions)
  86.             {
  87.                 float utility = action.GetUtility();
  88.  
  89.                 bool isNotBest = utility < bestUtility;
  90.  
  91.                 if (isNotBest)
  92.                     continue;
  93.  
  94.                 bestUtility = utility;
  95.                 bestAction = action;
  96.             }
  97.  
  98.             _logger.Log($"Best action is {bestAction.GetType().Name} with utility {bestUtility}");
  99.             return bestAction;
  100.         }
  101.  
  102.         private void OnDestroy()
  103.         {
  104.             CancelCurrentTask();
  105.         }
  106.     }
  107. }
  108.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement