using System.Collections.Generic; using UnityEngine; public class EnemyAI : MonoBehaviour { [Header("References")] public Transform player; [Header("Detection")] public float detectRange = 10f; public float moveSpeed = 3f; public float rotateSpeed = 50f; [Header("Artifact")] public bool playerHasArtifact; [Header("Laser")] public GameObject laserPrefab; public Transform firePoint; public float minShootDelay = 1f; public float maxShootDelay = 3f; private float nextShootTime; public Node behaviorTreeRoot; private void Start() { player = GameObject.FindGameObjectWithTag("Player").transform; nextShootTime = Time.time + Random.Range(minShootDelay, maxShootDelay); InitBehaviorTree(); } private void Update() { behaviorTreeRoot?.Evaluate(); } private void InitBehaviorTree() { // Player có artifact -> focus + shoot var laserSequence = new Sequence(new List { new TaskNode(CheckHasArtifact), new TaskNode(ActionFocusAndShoot) }); // Thấy player -> chạy tới var chaseSequence = new Sequence(new List { new TaskNode(CheckCanSeePlayer), new TaskNode(ActionMoveToPlayer) }); // Không thấy ai -> scan var scanNode = new TaskNode(ActionRotationScan); behaviorTreeRoot = new Selector(new List { laserSequence, chaseSequence, scanNode }); } #region CONDITIONS private NodeState CheckHasArtifact() { return playerHasArtifact ? NodeState.Success : NodeState.Failure; } private NodeState CheckCanSeePlayer() { if (player == null) return NodeState.Failure; float distance = Vector3.Distance(transform.position, player.position); if (distance <= detectRange) { return NodeState.Success; } return NodeState.Failure; } #endregion #region ACTIONS private NodeState ActionRotationScan() { Debug.Log("Scanning..."); transform.Rotate( Vector3.up, rotateSpeed * Time.deltaTime); return NodeState.Running; } private NodeState ActionMoveToPlayer() { if (player == null) return NodeState.Failure; Debug.Log("Chasing Player"); Vector3 dir = (player.position - transform.position).normalized; transform.position += dir * moveSpeed * Time.deltaTime; return NodeState.Running; } private NodeState ActionFocusAndShoot() { if (player == null) return NodeState.Failure; // Focus player Vector3 dir = player.position - transform.position; dir.y = 0f; if (dir != Vector3.zero) { Quaternion targetRotation = Quaternion.LookRotation(dir); transform.rotation = Quaternion.Slerp( transform.rotation, targetRotation, 5f * Time.deltaTime); } // Shoot with random delay if (Time.time >= nextShootTime) { ShootLaser(); nextShootTime = Time.time + Random.Range(minShootDelay, maxShootDelay); } return NodeState.Running; } private void ShootLaser() { if (laserPrefab == null || firePoint == null) return; Instantiate( laserPrefab, firePoint.position, firePoint.rotation); Debug.Log("Laser Shot!"); } #endregion }