First project upload

This commit is contained in:
Rohan
2026-06-26 22:41:39 +05:30
parent 7f6e734b16
commit 604c0c786a
4637 changed files with 4299718 additions and 489307 deletions

View File

@@ -1,276 +1,276 @@
using UnityEngine;
using UnityEngine.AI;
using System.Collections;
//using UnityEngine;
//using UnityEngine.AI;
//using System.Collections;
/// <summary>
/// EnemyAIController - AI controller for ENEMY team characters.
/// These AI characters fight AGAINST the player, targeting player team members.
/// Used in Cash System mode for enemy team AI.
/// </summary>
[RequireComponent(typeof(TeamMember))]
public class EnemyAIController : MonoBehaviour
{
[Header("AI State")]
[SerializeField] private AIState currentState = AIState.Idle;
///// <summary>
///// EnemyAIController - AI controller for ENEMY team characters.
///// These AI characters fight AGAINST the player, targeting player team members.
///// Used in Cash System mode for enemy team AI.
///// </summary>
//[RequireComponent(typeof(TeamMember))]
//public class EnemyAIController : MonoBehaviour
//{
// [Header("AI State")]
// [SerializeField] private AIState currentState = AIState.Idle;
[Header("Detection Settings")]
[SerializeField] private float detectionRange = 15f;
[SerializeField] private float attackRange = 2f;
[SerializeField] private float aggroRange = 10f;
// [Header("Detection Settings")]
// [SerializeField] private float detectionRange = 15f;
// [SerializeField] private float attackRange = 2f;
// [SerializeField] private float aggroRange = 10f;
[Header("Behavior Settings")]
[SerializeField] private float decisionInterval = 0.5f;
[SerializeField] private bool aggressive = true;
// [Header("Behavior Settings")]
// [SerializeField] private float decisionInterval = 0.5f;
// [SerializeField] private bool aggressive = true;
[Header("References")]
private TeamMember teamMember;
private NavMeshAgent navAgent;
private Animator animator;
private CharacterAttacks characterAttacks;
// [Header("References")]
// private TeamMember teamMember;
// private NavMeshAgent navAgent;
// private Animator animator;
// private CharacterAttacks characterAttacks;
// Combat
private TeamMember currentTarget;
private float lastAttackTime;
private float attackCooldown = 1.5f;
// // Combat
// private TeamMember currentTarget;
// private float lastAttackTime;
// private float attackCooldown = 1.5f;
// Cash System integration
private CashCarrier cashCarrier;
private CashSystemAI cashAI;
// // Cash System integration
// private CashCarrier cashCarrier;
// private CashSystemAI cashAI;
public enum AIState
{
Idle,
Patrol,
ChaseEnemy,
Attack,
CollectCash,
DepositCash,
StealCash,
Retreat
}
// public enum AIState
// {
// Idle,
// Patrol,
// ChaseEnemy,
// Attack,
// CollectCash,
// DepositCash,
// StealCash,
// Retreat
// }
private void Awake()
{
teamMember = GetComponent<TeamMember>();
navAgent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
characterAttacks = GetComponent<CharacterAttacks>();
cashCarrier = GetComponent<CashCarrier>();
cashAI = GetComponent<CashSystemAI>();
// private void Awake()
// {
// teamMember = GetComponent<TeamMember>();
// navAgent = GetComponent<NavMeshAgent>();
// animator = GetComponent<Animator>();
// characterAttacks = GetComponent<CharacterAttacks>();
// cashCarrier = GetComponent<CashCarrier>();
// cashAI = GetComponent<CashSystemAI>();
// Ensure this character is on enemy team
if (teamMember != null)
{
teamMember.CurrentTeam = TeamMember.Team.EnemyTeam;
}
}
// // Ensure this character is on enemy team
// if (teamMember != null)
// {
// teamMember.CurrentTeam = TeamMember.Team.EnemyTeam;
// }
// }
private void OnEnable()
{
Debug.Log($"[EnemyAIController] Enabled on {gameObject.name}");
StartCoroutine(AIDecisionLoop());
}
// private void OnEnable()
// {
// Debug.Log($"[EnemyAIController] Enabled on {gameObject.name}");
// StartCoroutine(AIDecisionLoop());
// }
private void OnDisable()
{
Debug.Log($"[EnemyAIController] Disabled on {gameObject.name}");
StopAllCoroutines();
}
// private void OnDisable()
// {
// Debug.Log($"[EnemyAIController] Disabled on {gameObject.name}");
// StopAllCoroutines();
// }
private IEnumerator AIDecisionLoop()
{
yield return new WaitForSeconds(0.5f); // Initial delay
// private IEnumerator AIDecisionLoop()
// {
// yield return new WaitForSeconds(0.5f); // Initial delay
while (enabled)
{
MakeDecision();
yield return new WaitForSeconds(decisionInterval);
}
}
// while (enabled)
// {
// MakeDecision();
// yield return new WaitForSeconds(decisionInterval);
// }
// }
private void MakeDecision()
{
// Lazy re-cache: CashSystemAI is added AFTER our Awake() by ConfigureCharacterControllers,
// so the Awake-time GetComponent returns null. Re-check here once.
if (cashAI == null) cashAI = GetComponent<CashSystemAI>();
// private void MakeDecision()
// {
// // Lazy re-cache: CashSystemAI is added AFTER our Awake() by ConfigureCharacterControllers,
// // so the Awake-time GetComponent returns null. Re-check here once.
// if (cashAI == null) cashAI = GetComponent<CashSystemAI>();
// If CashSystemAI is attached and active, delegate ALL decisions to it
if (cashAI != null && cashAI.enabled)
{
// CashSystemAI handles the high-level decision making via its own Update()
return;
}
// // If CashSystemAI is attached and active, delegate ALL decisions to it
// if (cashAI != null && cashAI.enabled)
// {
// // CashSystemAI handles the high-level decision making via its own Update()
// return;
// }
// Standard enemy AI decision making
TeamMember nearestEnemy = teamMember.FindNearestEnemy(); // Player team
// // Standard enemy AI decision making
// TeamMember nearestEnemy = teamMember.FindNearestEnemy(); // Player team
// Priority 1: Attack nearby player team members
if (nearestEnemy != null)
{
float distanceToEnemy = Vector3.Distance(transform.position, nearestEnemy.transform.position);
// // Priority 1: Attack nearby player team members
// if (nearestEnemy != null)
// {
// float distanceToEnemy = Vector3.Distance(transform.position, nearestEnemy.transform.position);
if (distanceToEnemy <= attackRange)
{
SetState(AIState.Attack);
currentTarget = nearestEnemy;
PerformAttack();
return;
}
else if (distanceToEnemy <= aggroRange && aggressive)
{
SetState(AIState.ChaseEnemy);
currentTarget = nearestEnemy;
MoveToTarget(nearestEnemy.transform.position);
return;
}
}
// if (distanceToEnemy <= attackRange)
// {
// SetState(AIState.Attack);
// currentTarget = nearestEnemy;
// PerformAttack();
// return;
// }
// else if (distanceToEnemy <= aggroRange && aggressive)
// {
// SetState(AIState.ChaseEnemy);
// currentTarget = nearestEnemy;
// MoveToTarget(nearestEnemy.transform.position);
// return;
// }
// }
// Priority 2: Patrol or idle
if (aggressive && nearestEnemy != null)
{
float distanceToEnemy = Vector3.Distance(transform.position, nearestEnemy.transform.position);
if (distanceToEnemy <= detectionRange)
{
SetState(AIState.ChaseEnemy);
currentTarget = nearestEnemy;
MoveToTarget(nearestEnemy.transform.position);
return;
}
}
// // Priority 2: Patrol or idle
// if (aggressive && nearestEnemy != null)
// {
// float distanceToEnemy = Vector3.Distance(transform.position, nearestEnemy.transform.position);
// if (distanceToEnemy <= detectionRange)
// {
// SetState(AIState.ChaseEnemy);
// currentTarget = nearestEnemy;
// MoveToTarget(nearestEnemy.transform.position);
// return;
// }
// }
// Default: Idle
SetState(AIState.Idle);
StopMovement();
}
// // Default: Idle
// SetState(AIState.Idle);
// StopMovement();
// }
private void SetState(AIState newState)
{
if (currentState != newState)
{
currentState = newState;
Debug.Log($"[EnemyAIController] {gameObject.name} -> {newState}");
}
}
// private void SetState(AIState newState)
// {
// if (currentState != newState)
// {
// currentState = newState;
// Debug.Log($"[EnemyAIController] {gameObject.name} -> {newState}");
// }
// }
private void MoveToTarget(Vector3 position)
{
if (navAgent != null && navAgent.isActiveAndEnabled && navAgent.isOnNavMesh)
{
navAgent.isStopped = false;
navAgent.SetDestination(position);
// private void MoveToTarget(Vector3 position)
// {
// if (navAgent != null && navAgent.isActiveAndEnabled && navAgent.isOnNavMesh)
// {
// navAgent.isStopped = false;
// navAgent.SetDestination(position);
// Update animator
if (animator != null)
{
float speed = navAgent.velocity.magnitude / navAgent.speed;
animator.SetFloat("Speed", speed);
}
}
}
// // Update animator
// if (animator != null)
// {
// float speed = navAgent.velocity.magnitude / navAgent.speed;
// animator.SetFloat("Speed", speed);
// }
// }
// }
private void StopMovement()
{
if (navAgent != null && navAgent.isActiveAndEnabled && navAgent.isOnNavMesh)
{
navAgent.isStopped = true;
navAgent.velocity = Vector3.zero;
}
// private void StopMovement()
// {
// if (navAgent != null && navAgent.isActiveAndEnabled && navAgent.isOnNavMesh)
// {
// navAgent.isStopped = true;
// navAgent.velocity = Vector3.zero;
// }
if (animator != null)
{
animator.SetFloat("Speed", 0f);
}
}
// if (animator != null)
// {
// animator.SetFloat("Speed", 0f);
// }
// }
private void PerformAttack()
{
if (Time.time - lastAttackTime < attackCooldown) return;
// private void PerformAttack()
// {
// if (Time.time - lastAttackTime < attackCooldown) return;
// Face the target
if (currentTarget != null)
{
Vector3 direction = (currentTarget.transform.position - transform.position).normalized;
direction.y = 0;
if (direction.sqrMagnitude > 0.001f)
{
transform.rotation = Quaternion.LookRotation(direction);
}
}
// // Face the target
// if (currentTarget != null)
// {
// Vector3 direction = (currentTarget.transform.position - transform.position).normalized;
// direction.y = 0;
// if (direction.sqrMagnitude > 0.001f)
// {
// transform.rotation = Quaternion.LookRotation(direction);
// }
// }
// Perform attack using CharacterAttacks if available
if (characterAttacks != null)
{
// Choose a random attack
string[] attacks = { AnimationNames.Jab, AnimationNames.LowKick, AnimationNames.Haymaker };
string randomAttack = attacks[Random.Range(0, attacks.Length)];
// // Perform attack using CharacterAttacks if available
// if (characterAttacks != null)
// {
// // Choose a random attack
// string[] attacks = { AnimationNames.Jab, AnimationNames.LowKick, AnimationNames.Haymaker };
// string randomAttack = attacks[Random.Range(0, attacks.Length)];
characterAttacks.PunchAttacksDirectly(randomAttack);
lastAttackTime = Time.time;
}
else if (animator != null)
{
// Fallback to direct animation trigger
animator.SetTrigger("attack");
lastAttackTime = Time.time;
}
}
// characterAttacks.PunchAttacksDirectly(randomAttack);
// lastAttackTime = Time.time;
// }
// else if (animator != null)
// {
// // Fallback to direct animation trigger
// animator.SetTrigger("attack");
// lastAttackTime = Time.time;
// }
// }
private void Update()
{
// When CashSystemAI is driving, don't interfere with NavMeshAgent
if (cashAI != null && cashAI.enabled) return;
// private void Update()
// {
// // When CashSystemAI is driving, don't interfere with NavMeshAgent
// if (cashAI != null && cashAI.enabled) return;
// Continuous state updates
switch (currentState)
{
case AIState.Attack:
if (currentTarget != null)
{
float distance = Vector3.Distance(transform.position, currentTarget.transform.position);
if (distance > attackRange * 1.5f)
{
// Move closer
MoveToTarget(currentTarget.transform.position);
}
else
{
StopMovement();
PerformAttack();
}
}
break;
// // Continuous state updates
// switch (currentState)
// {
// case AIState.Attack:
// if (currentTarget != null)
// {
// float distance = Vector3.Distance(transform.position, currentTarget.transform.position);
// if (distance > attackRange * 1.5f)
// {
// // Move closer
// MoveToTarget(currentTarget.transform.position);
// }
// else
// {
// StopMovement();
// PerformAttack();
// }
// }
// break;
case AIState.ChaseEnemy:
if (currentTarget != null)
{
MoveToTarget(currentTarget.transform.position);
}
break;
}
}
// case AIState.ChaseEnemy:
// if (currentTarget != null)
// {
// MoveToTarget(currentTarget.transform.position);
// }
// break;
// }
// }
/// <summary>
/// Set a specific target for this AI to attack
/// </summary>
public void SetTarget(TeamMember target)
{
currentTarget = target;
if (target != null)
{
SetState(AIState.ChaseEnemy);
}
}
// /// <summary>
// /// Set a specific target for this AI to attack
// /// </summary>
// public void SetTarget(TeamMember target)
// {
// currentTarget = target;
// if (target != null)
// {
// SetState(AIState.ChaseEnemy);
// }
// }
/// <summary>
/// Command this AI to move to a specific position
/// </summary>
public void MoveTo(Vector3 position)
{
MoveToTarget(position);
}
// /// <summary>
// /// Command this AI to move to a specific position
// /// </summary>
// public void MoveTo(Vector3 position)
// {
// MoveToTarget(position);
// }
/// <summary>
/// Get current AI state
/// </summary>
public AIState GetCurrentState() => currentState;
}
// /// <summary>
// /// Get current AI state
// /// </summary>
// public AIState GetCurrentState() => currentState;
//}

View File

@@ -16,17 +16,18 @@ public class TeamMember : MonoBehaviour
/// </summary>
private static readonly List<TeamMember> _allMembers = new List<TeamMember>(16);
public static IReadOnlyList<TeamMember> AllMembers => _allMembers;
#endregion
/// <summary>
/// Team affiliation enum
/// </summary>
public enum Team
public enum Team
{
PlayerTeam, // The player's team (human + AI teammates)
EnemyTeam // The opposing team (all AI)
PlayerTeam,
EnemyTeam1,
EnemyTeam2
}
/// <summary>
/// Control type - determines who controls this character
/// </summary>
@@ -89,19 +90,19 @@ public class TeamMember : MonoBehaviour
}
}
/// <summary>
/// Event fired when control type changes (useful for camera, UI, input routing)
/// </summary>
// <summary>
// Event fired when control type changes (useful for camera, UI, input routing)
// </summary>
public event System.Action<ControlType> OnControlTypeChanged;
/// <summary>
/// Event fired when control status changes (backward compatible)
/// </summary>
// <summary>
// Event fired when control status changes (backward compatible)
// </summary>
public event System.Action<bool> OnControlChanged;
/// <summary>
/// Event fired when team changes
/// </summary>
// <summary>
// Event fired when team changes
// </summary>
public event System.Action<Team> OnTeamChanged;
private void Awake()
@@ -261,16 +262,18 @@ public class TeamMember : MonoBehaviour
}
}
/// <summary>
/// Check if another TeamMember is an enemy
/// </summary>
public bool IsEnemy(TeamMember other)
{
if (other == null) return false;
return other.CurrentTeam != this.CurrentTeam;
if (other == null)
return false;
return other.CurrentTeam != CurrentTeam;
}
/// <summary>
/// Check if another TeamMember is an ally
/// </summary>
@@ -297,20 +300,26 @@ public class TeamMember : MonoBehaviour
}
else
{
// AI teammate - still on player team but different handling
// AI teammate - still on player team but different handling
// Keep "Player" tag for combat targeting but mark as ally
gameObject.tag = "Player";
int playerLayer = LayerMask.NameToLayer("Player One");
if (playerLayer >= 0) gameObject.layer = playerLayer;
}
}
else // Enemy Team
else if (_team == Team.EnemyTeam1)
{
gameObject.tag = "Enemy";
gameObject.tag = "EnemyTeam1";
int enemyLayer = LayerMask.NameToLayer("Player Two");
if (enemyLayer >= 0) gameObject.layer = enemyLayer;
}
else if (_team == Team.EnemyTeam2)
{
gameObject.tag = "EnemyTeam2";
int enemyLayer = LayerMask.NameToLayer("Player Three");
if (enemyLayer >= 0) gameObject.layer = enemyLayer;
}
OnTeamChanged?.Invoke(_team);
}