PlayerDecisionMaker.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using UnityEngine;
  2. using System.Linq;
  3. public class PlayerDecisionMaker : MonoBehaviour
  4. {
  5. private PlayerController playerController;
  6. private PuckController puck;
  7. private float decisionInterval = 0.5f;
  8. private float nextDecisionTime;
  9. void Start()
  10. {
  11. playerController = GetComponent<PlayerController>();
  12. puck = FindAnyObjectByType<PuckController>();
  13. }
  14. void Update()
  15. {
  16. if (Time.time >= nextDecisionTime)
  17. {
  18. MakeDecision();
  19. nextDecisionTime = Time.time + decisionInterval;
  20. }
  21. }
  22. void MakeDecision()
  23. {
  24. if (playerController.currentStrategy == null) return;
  25. bool hasPuck = playerController.HasPuck();
  26. PlayerAction action = playerController.currentStrategy.DecideAction(playerController, hasPuck);
  27. ExecuteAction(action);
  28. }
  29. void ExecuteAction(PlayerAction action)
  30. {
  31. switch (action)
  32. {
  33. case PlayerAction.Shoot:
  34. ExecuteShoot();
  35. break;
  36. case PlayerAction.Pass:
  37. ExecutePass();
  38. break;
  39. case PlayerAction.Check:
  40. ExecuteCheck();
  41. break;
  42. // Add other actions
  43. }
  44. }
  45. void ExecuteShoot()
  46. {
  47. if (!playerController.HasPuck()) return;
  48. // Determine which goal to shoot at
  49. Vector3 targetGoal = GetOpponentGoalPosition();
  50. Vector3 shootDirection = (targetGoal - transform.position).normalized;
  51. // Shoot with full power
  52. playerController.Shoot(shootDirection, 1.0f);
  53. }
  54. void ExecutePass()
  55. {
  56. if (!playerController.HasPuck()) return;
  57. // Find best teammate to pass to
  58. PlayerController bestTeammate = FindBestPassTarget();
  59. if (bestTeammate != null)
  60. {
  61. playerController.Pass(bestTeammate);
  62. }
  63. else
  64. {
  65. // No good pass available, hold onto puck or shoot
  66. Debug.Log($"{playerController.stats.playerName}: No pass target available");
  67. }
  68. }
  69. void ExecuteCheck()
  70. {
  71. // Find nearest opponent with puck
  72. PlayerController opponent = FindNearestOpponentWithPuck();
  73. if (opponent != null)
  74. {
  75. float distance = Vector3.Distance(transform.position, opponent.transform.position);
  76. // Only check if close enough
  77. if (distance <= 2f)
  78. {
  79. playerController.Check(opponent);
  80. }
  81. else
  82. {
  83. Debug.Log($"{playerController.stats.playerName}: Opponent too far to check");
  84. }
  85. }
  86. }
  87. Vector3 GetOpponentGoalPosition()
  88. {
  89. // Determine which goal to attack based on team
  90. bool isHomeTeam = playerController.CompareTag("HomeTeam");
  91. // Home team attacks away goal (positive Z), away team attacks home goal (negative Z)
  92. // Adjust these coordinates based on your rink layout
  93. if (isHomeTeam)
  94. {
  95. return new Vector3(0, 1, 30f); // Away goal
  96. }
  97. else
  98. {
  99. return new Vector3(0, 1, -30f); // Home goal
  100. }
  101. }
  102. PlayerController FindBestPassTarget()
  103. {
  104. PlayerController[] allPlayers = FindObjectsByType<PlayerController>(FindObjectsSortMode.None);
  105. PlayerController bestTarget = null;
  106. float bestScore = float.MinValue;
  107. foreach (PlayerController candidate in allPlayers)
  108. {
  109. // Skip self and opponents
  110. if (candidate == playerController || IsOpponent(candidate))
  111. continue;
  112. // Calculate pass score based on position and openness
  113. float distance = Vector3.Distance(transform.position, candidate.transform.position);
  114. // Prefer teammates at medium distance (not too close, not too far)
  115. if (distance < 3f || distance > 25f)
  116. continue;
  117. // Check if pass lane is relatively clear (simplified)
  118. float passScore = 100f - distance; // Base score
  119. // Bonus for forwards when we're in offensive zone
  120. if (candidate.stats.position == PlayerPosition.LW ||
  121. candidate.stats.position == PlayerPosition.RW ||
  122. candidate.stats.position == PlayerPosition.C)
  123. {
  124. passScore += 20f;
  125. }
  126. if (passScore > bestScore)
  127. {
  128. bestScore = passScore;
  129. bestTarget = candidate;
  130. }
  131. }
  132. return bestTarget;
  133. }
  134. PlayerController FindNearestOpponentWithPuck()
  135. {
  136. PlayerController[] allPlayers = FindObjectsByType<PlayerController>(FindObjectsSortMode.None);
  137. PlayerController nearest = null;
  138. float nearestDistance = float.MaxValue;
  139. foreach (PlayerController candidate in allPlayers)
  140. {
  141. // Only check opponents who have the puck
  142. if (!IsOpponent(candidate) || !candidate.HasPuck())
  143. continue;
  144. float distance = Vector3.Distance(transform.position, candidate.transform.position);
  145. if (distance < nearestDistance)
  146. {
  147. nearestDistance = distance;
  148. nearest = candidate;
  149. }
  150. }
  151. return nearest;
  152. }
  153. bool IsOpponent(PlayerController other)
  154. {
  155. // Players are opponents if they have different tags
  156. return playerController.CompareTag("HomeTeam") != other.CompareTag("HomeTeam");
  157. }
  158. }