39e4e51866
- Implemented PlayerController.cs to manage player movement and actions. - Created PlayerState.cs to track player lives, coins, and key status. - Added CameraFollow.cs for smooth camera movement following the player. - Developed Character.cs as an abstract class for character behavior. - Introduced Enums.cs for defining TreasureType and MapElementType. - Added IDoor interface for door interactions. - Created InputActions.cs for handling player input actions. - Implemented MainMenu.cs for basic menu functionality including play and exit options.
172 lines
4.5 KiB
C#
172 lines
4.5 KiB
C#
using UnityEngine;
|
|
using System;
|
|
|
|
public enum EnemyState
|
|
{
|
|
Patrol,
|
|
Investigate,
|
|
Chase,
|
|
Stunned
|
|
}
|
|
|
|
public class EnemyAI : Character
|
|
{
|
|
[SerializeField] private float _patrolSpeed = 1f;
|
|
[SerializeField] private float _patrolRange = 5f;
|
|
[SerializeField] private float _investigateRange = 8f;
|
|
[SerializeField] private float _chaseRange = 10f;
|
|
[SerializeField] private float _stunDuration = 1f;
|
|
[SerializeField] private bool _debugMode = false;
|
|
|
|
private EnemyState _currentState = EnemyState.Patrol;
|
|
private Vector3 _patrolTarget;
|
|
private Vector3 _investigatePosition;
|
|
private float _stunTimer = 0f;
|
|
private float _patrolDirection = 1f;
|
|
|
|
private static readonly Player _player = null;
|
|
|
|
public EnemyState CurrentState => _currentState;
|
|
|
|
protected override void SetClimbingAnimation(bool isClimbing)
|
|
{
|
|
// Implement climbing animation if needed
|
|
}
|
|
|
|
protected override void SetWalkingAnimation(bool isWalking)
|
|
{
|
|
_animator.SetBool("Walk", isWalking);
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_patrolTarget = transform.position;
|
|
SetState(EnemyState.Patrol);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
// Update stun timer
|
|
if (_currentState == EnemyState.Stunned)
|
|
{
|
|
_stunTimer -= Time.deltaTime;
|
|
if (_stunTimer <= 0f)
|
|
{
|
|
SetState(EnemyState.Patrol);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Get player position if available
|
|
var player = Player.Instance;
|
|
if (player == null)
|
|
{
|
|
HandlePatrol();
|
|
return;
|
|
}
|
|
|
|
float distanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
|
|
|
|
// State transitions
|
|
switch (_currentState)
|
|
{
|
|
case EnemyState.Patrol:
|
|
if (distanceToPlayer < _investigateRange)
|
|
{
|
|
SetState(EnemyState.Chase);
|
|
}
|
|
else
|
|
{
|
|
HandlePatrol();
|
|
}
|
|
break;
|
|
|
|
case EnemyState.Investigate:
|
|
if (distanceToPlayer < _chaseRange)
|
|
{
|
|
SetState(EnemyState.Chase);
|
|
}
|
|
else if (Vector3.Distance(transform.position, _investigatePosition) < 0.5f)
|
|
{
|
|
SetState(EnemyState.Patrol);
|
|
}
|
|
else
|
|
{
|
|
HandleInvestigate();
|
|
}
|
|
break;
|
|
|
|
case EnemyState.Chase:
|
|
if (distanceToPlayer > _chaseRange)
|
|
{
|
|
SetState(EnemyState.Patrol);
|
|
}
|
|
else
|
|
{
|
|
HandleChase(player.transform.position);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void SetState(EnemyState newState)
|
|
{
|
|
if (_currentState == newState)
|
|
return;
|
|
|
|
if (_debugMode)
|
|
Debug.Log($"[EnemyAI] State changed: {_currentState} -> {newState}");
|
|
|
|
_currentState = newState;
|
|
}
|
|
|
|
private void HandlePatrol()
|
|
{
|
|
// Simple back-and-forth patrol
|
|
if (Vector3.Distance(transform.position, _patrolTarget) < 0.3f)
|
|
{
|
|
_patrolDirection *= -1f;
|
|
_patrolTarget = transform.position + Vector3.right * _patrolRange * _patrolDirection;
|
|
}
|
|
|
|
float direction = _patrolTarget.x > transform.position.x ? 1f : -1f;
|
|
MoveTo(direction * _patrolSpeed, 0f);
|
|
}
|
|
|
|
private void HandleInvestigate()
|
|
{
|
|
float direction = _investigatePosition.x > transform.position.x ? 1f : -1f;
|
|
MoveTo(direction * _patrolSpeed, 0f);
|
|
}
|
|
|
|
private void HandleChase(Vector3 playerPosition)
|
|
{
|
|
float direction = playerPosition.x > transform.position.x ? 1f : -1f;
|
|
MoveTo(direction * _patrolSpeed, 0f);
|
|
}
|
|
|
|
public void OnNoise(Vector3 noisePosition)
|
|
{
|
|
if (_currentState == EnemyState.Stunned)
|
|
return;
|
|
|
|
if (_currentState != EnemyState.Chase)
|
|
{
|
|
_investigatePosition = noisePosition;
|
|
SetState(EnemyState.Investigate);
|
|
|
|
if (_debugMode)
|
|
Debug.Log($"[EnemyAI] Investigating noise at {noisePosition}");
|
|
}
|
|
}
|
|
|
|
public void OnHitByHammer(float stunDuration)
|
|
{
|
|
_stunTimer = stunDuration;
|
|
SetState(EnemyState.Stunned);
|
|
|
|
if (_debugMode)
|
|
Debug.Log($"[EnemyAI] Stunned for {stunDuration} seconds");
|
|
}
|
|
}
|