BattleSetup.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.AI;
  4. public class BattleSetup : MonoBehaviour
  5. {
  6. List<GameObject> unplacedEnemyCharacters = new List<GameObject>();
  7. List<GameObject> placedPlayerCharacters = new List<GameObject>();
  8. List<GameObject> placedEnemyCharacters = new List<GameObject>();
  9. private List<GameObject> playerCharacters = new List<GameObject>();
  10. private List<GameObject> enemyCharacters = new List<GameObject>();
  11. private List<CharacterSelection> playerSelections = new List<CharacterSelection>();
  12. private List<CharacterSelection> enemySelections = new List<CharacterSelection>();
  13. [Tooltip("Select the layer(s) that represent the ground for raycasting.")]
  14. public LayerMask groundLayerMask;
  15. public GameObject playerPrefab; // Assign in the inspector or through GameManager
  16. public GameObject enemyPrefab; // Assign in the inspector or through GameManager
  17. public GameObject SwordPrefab; // Assign in the inspector or through GameManager
  18. public GameObject BowPrefab; // Assign in the inspector or through GameManager
  19. GameObject playerSpawnArea;
  20. GameObject enemySpawnArea;
  21. Bounds playerSpawnBounds;
  22. private Camera mainCamera;
  23. private GameObject currentPlacingCharacterInstance;
  24. private int nextPlayerCharacterPrefabIndex = 0;
  25. private bool isPlacingPlayerCharacters = false;
  26. void Awake()
  27. {
  28. mainCamera = Camera.main;
  29. if (mainCamera == null)
  30. {
  31. Debug.LogError("Main camera not found. Please ensure there is a camera tagged as 'MainCamera' in the scene.");
  32. enabled = false;
  33. return;
  34. }
  35. playerCharacters.Clear();
  36. enemyCharacters.Clear();
  37. // Store the selections for use during placement
  38. playerSelections = new List<CharacterSelection>(BattleSetupData.playerSelections);
  39. enemySelections = new List<CharacterSelection>(BattleSetupData.enemySelections);
  40. // Initialize the lists with characters from the game manager or other sources
  41. playerSpawnArea = GameObject.Find("PlayerSpawnArea");
  42. enemySpawnArea = GameObject.Find("EnemySpawnArea");
  43. if (playerSpawnArea == null)
  44. {
  45. Debug.LogError("PlayerSpawnArea GameObject not found in scene. Please ensure there is a GameObject named 'PlayerSpawnArea' in the scene.");
  46. enabled = false;
  47. return;
  48. }
  49. Collider playerSpawnAreaCollider = playerSpawnArea.GetComponent<Collider>();
  50. if (playerSpawnAreaCollider == null)
  51. {
  52. Debug.LogError("PlayerSpawnArea does not have a collider component.");
  53. enabled = false;
  54. return;
  55. }
  56. playerSpawnBounds = playerSpawnAreaCollider.bounds;
  57. if (enemySpawnArea == null)
  58. {
  59. // Enemy placement might still work if unplacedEnemyCharacters is empty
  60. Debug.LogWarning("EnemySpawnArea GameObject not found in the scene. Enemy placement might be affected.");
  61. }
  62. // Call the setup methods to place characters
  63. PlaceEnemyCharacters();
  64. InitiatePlayerCharacterPlacement();
  65. }
  66. // Helper method to get WeaponItem from CombatDataTransfer if available
  67. WeaponItem GetEnhancedWeaponItem(string characterName, bool isPlayer)
  68. {
  69. Debug.Log($"🔍 GetEnhancedWeaponItem called for '{characterName}', isPlayer: {isPlayer}");
  70. if (!CombatDataTransfer.HasValidSession())
  71. {
  72. Debug.Log($"🔍 No valid CombatDataTransfer session");
  73. return null;
  74. }
  75. var session = CombatDataTransfer.GetCurrentSession();
  76. if (session == null)
  77. {
  78. Debug.Log($"🔍 CombatDataTransfer session is null");
  79. return null;
  80. }
  81. Debug.Log($"🔍 Session has {session.playerTeam.Count} players and {session.enemies.Count} enemies");
  82. if (isPlayer)
  83. {
  84. // Debug: List all available player characters
  85. Debug.Log($"🔍 Available players in session:");
  86. foreach (var player in session.playerTeam)
  87. {
  88. Debug.Log($" - Player: '{player.characterName}', Weapon: {(player.equippedWeaponItem != null ? player.equippedWeaponItem.name : "NULL")}");
  89. }
  90. // Find player character in enhanced data (match by base name, ignoring suffixes)
  91. foreach (var player in session.playerTeam)
  92. {
  93. if (player.characterName == characterName && player.equippedWeaponItem != null)
  94. {
  95. Debug.Log($"🎯 Found enhanced WeaponItem for player {characterName}: {player.equippedWeaponItem.name}");
  96. return player.equippedWeaponItem;
  97. }
  98. // Also try matching without the numbered suffix (e.g., "Player 1" vs "Player")
  99. if (characterName.StartsWith(player.characterName) && player.equippedWeaponItem != null)
  100. {
  101. Debug.Log($"🎯 Found enhanced WeaponItem for player {characterName} (matched base name {player.characterName}): {player.equippedWeaponItem.name}");
  102. return player.equippedWeaponItem;
  103. }
  104. }
  105. Debug.Log($"🔍 No matching player found for '{characterName}'");
  106. }
  107. else
  108. {
  109. // Find enemy character in enhanced data (match by base name, ignoring suffixes)
  110. foreach (var enemy in session.enemies)
  111. {
  112. if (enemy.enemyName == characterName && enemy.preferredWeaponItem != null)
  113. {
  114. Debug.Log($"🎯 Found enhanced WeaponItem for enemy {characterName}: {enemy.preferredWeaponItem.name}");
  115. return enemy.preferredWeaponItem;
  116. }
  117. // Also try matching the base name (e.g., "Skeleton Warrior_1" vs "Skeleton Warrior")
  118. if (characterName.StartsWith(enemy.enemyType) && enemy.preferredWeaponItem != null)
  119. {
  120. Debug.Log($"🎯 Found enhanced WeaponItem for enemy {characterName} (matched base type {enemy.enemyType}): {enemy.preferredWeaponItem.name}");
  121. return enemy.preferredWeaponItem;
  122. }
  123. }
  124. }
  125. return null;
  126. }
  127. // Enhanced weapon equipping with WeaponItem support
  128. void EquipWeapon(Character character, WeaponItem weaponItem)
  129. {
  130. Debug.Log($"🔧 EquipWeapon called for {character.CharacterName} with WeaponItem: {(weaponItem != null ? weaponItem.name : "null")}");
  131. Weapon weapon = null;
  132. if (weaponItem != null)
  133. {
  134. Debug.Log($"🔧 Using WeaponItem.CreateWeaponInstance() for {weaponItem.name}");
  135. // Use the WeaponItem's CreateWeaponInstance method to preserve all attributes
  136. weapon = weaponItem.CreateWeaponInstance(character.transform);
  137. if (weapon != null)
  138. {
  139. weapon.SetWielder(character);
  140. Debug.Log($"✅ Successfully created weapon from WeaponItem: {weapon.weaponName}");
  141. }
  142. else
  143. {
  144. Debug.LogWarning($"⚠️ WeaponItem.CreateWeaponInstance() returned null for {weaponItem.name}. Falling back to string-based creation.");
  145. // Fallback to string-based weapon creation
  146. EquipWeapon(character, weaponItem.weaponType.ToString());
  147. return;
  148. }
  149. }
  150. else
  151. {
  152. Debug.LogWarning($"No WeaponItem provided for {character.CharacterName}. Equipping with fists as fallback.");
  153. EquipWeapon(character, "Fists");
  154. return;
  155. }
  156. if (weapon != null)
  157. {
  158. // Attach weapon to the character
  159. Transform attachPoint = character.transform.Find("WeaponAttachPoint");
  160. if (attachPoint != null)
  161. {
  162. weapon.transform.SetParent(attachPoint, false);
  163. weapon.transform.localPosition = Vector3.zero;
  164. weapon.transform.localRotation = Quaternion.identity;
  165. }
  166. else
  167. {
  168. weapon.transform.SetParent(character.transform, false);
  169. weapon.transform.localPosition = new Vector3(0.5f, 0, 0);
  170. }
  171. character.Weapon = weapon;
  172. weapon.SetWielder(character);
  173. Debug.Log($"✅ Successfully equipped {weapon.weaponName} to {character.CharacterName}");
  174. }
  175. else
  176. {
  177. Debug.LogError($"❌ Failed to create weapon for {character.CharacterName}");
  178. }
  179. }
  180. // Fallback weapon equipping using string types (for backward compatibility)
  181. void EquipWeapon(Character character, string weaponType)
  182. {
  183. Debug.Log($"🔧 EquipWeapon called for {character.CharacterName} with weaponType: '{weaponType}'");
  184. Weapon weapon = null;
  185. // Handle null or empty weapon types
  186. if (string.IsNullOrEmpty(weaponType))
  187. {
  188. Debug.LogWarning($"No weapon type specified for {character.CharacterName}. Equipping with fists as fallback.");
  189. weaponType = "Fists";
  190. }
  191. Debug.Log($"🔧 Processing weapon type: '{weaponType}' for {character.CharacterName}");
  192. if (weaponType == "Sword")
  193. {
  194. Debug.Log($"⚔️ Creating Sword for {character.CharacterName}");
  195. var weaponObj = Instantiate(SwordPrefab, character.transform);
  196. weapon = weaponObj.GetComponent<Weapon>();
  197. }
  198. else if (weaponType == "Bow")
  199. {
  200. Debug.Log($"🏹 Creating Bow for {character.CharacterName}");
  201. var weaponObj = Instantiate(BowPrefab, character.transform);
  202. weapon = weaponObj.GetComponent<Weapon>();
  203. }
  204. else if (weaponType == "Fists")
  205. {
  206. Debug.Log($"👊 Creating Fists for {character.CharacterName}");
  207. // Create a fists weapon directly using SimpleSword as base
  208. GameObject fistsObj = new GameObject("Fists");
  209. fistsObj.transform.SetParent(character.transform, false);
  210. SimpleSword fistsWeapon = fistsObj.AddComponent<SimpleSword>();
  211. // Override the sword's properties to make it act like fists
  212. fistsWeapon.weaponName = "Fists";
  213. fistsWeapon.description = "Bare fists - a basic unarmed attack.";
  214. fistsWeapon.attackSpeed = 1.0f;
  215. weapon = fistsWeapon;
  216. }
  217. else
  218. {
  219. Debug.LogWarning($"❓ Unknown weapon type: '{weaponType}' for {character.CharacterName}. Equipping with fists as fallback.");
  220. // Create a fists weapon as fallback using SimpleSword as base
  221. GameObject fistsObj = new GameObject("Fists");
  222. fistsObj.transform.SetParent(character.transform, false);
  223. SimpleSword fistsWeapon = fistsObj.AddComponent<SimpleSword>();
  224. // Override the sword's properties to make it act like fists
  225. fistsWeapon.weaponName = "Fists";
  226. fistsWeapon.description = "Bare fists - a basic unarmed attack.";
  227. fistsWeapon.attackSpeed = 1.0f;
  228. weapon = fistsWeapon;
  229. }
  230. if (weapon != null)
  231. {
  232. Transform attachPoint = character.transform.Find("WeaponAttachPoint");
  233. if (attachPoint != null)
  234. {
  235. weapon.transform.SetParent(attachPoint, false);
  236. weapon.transform.localPosition = Vector3.zero;
  237. weapon.transform.localRotation = Quaternion.identity;
  238. }
  239. else
  240. {
  241. weapon.transform.SetParent(character.transform, false);
  242. weapon.transform.localPosition = new Vector3(0.5f, 0, 0);
  243. }
  244. character.Weapon = weapon;
  245. weapon.SetWielder(character);
  246. Debug.Log($"✅ Successfully equipped {weapon.weaponName} to {character.CharacterName}");
  247. }
  248. else
  249. {
  250. Debug.LogError($"❌ Failed to create weapon for {character.CharacterName}");
  251. }
  252. }
  253. void Update()
  254. {
  255. if (!isPlacingPlayerCharacters || currentPlacingCharacterInstance == null)
  256. {
  257. return;
  258. }
  259. HandleCharacterPlacement();
  260. }
  261. private void InitiatePlayerCharacterPlacement()
  262. {
  263. if (playerSelections.Count == 0)
  264. {
  265. return;
  266. }
  267. isPlacingPlayerCharacters = true;
  268. nextPlayerCharacterPrefabIndex = 0;
  269. SpawnNextPlayerCharacterForPlacement();
  270. }
  271. private void SpawnNextPlayerCharacterForPlacement()
  272. {
  273. if (currentPlacingCharacterInstance != null)
  274. {
  275. // This case should ideally not happen if logic flows correctly,
  276. // but as a safeguard if a previous instance wasn't cleaned up.
  277. Destroy(currentPlacingCharacterInstance);
  278. currentPlacingCharacterInstance = null;
  279. }
  280. if (nextPlayerCharacterPrefabIndex < playerSelections.Count)
  281. {
  282. var selection = playerSelections[nextPlayerCharacterPrefabIndex];
  283. currentPlacingCharacterInstance = Instantiate(playerPrefab);
  284. currentPlacingCharacterInstance.name = selection.characterName;
  285. var character = currentPlacingCharacterInstance.GetComponent<Character>();
  286. if (character != null)
  287. {
  288. Debug.Log($"🔍 SpawnNextPlayerCharacterForPlacement: Character '{selection.characterName}' with weapon '{selection.weaponType}'");
  289. // Try to get enhanced weapon data first
  290. WeaponItem enhancedWeapon = GetEnhancedWeaponItem(selection.characterName, true);
  291. Debug.Log($"🔍 Enhanced weapon lookup for '{selection.characterName}': {(enhancedWeapon != null ? enhancedWeapon.name : "NULL")}");
  292. if (enhancedWeapon != null)
  293. {
  294. Debug.Log($"🎯 Using enhanced weapon: {enhancedWeapon.name}");
  295. EquipWeapon(character, enhancedWeapon);
  296. }
  297. else
  298. {
  299. Debug.Log($"🔍 No enhanced weapon found, falling back to selection.weaponType: '{selection.weaponType}'");
  300. EquipWeapon(character, selection.weaponType);
  301. }
  302. character.CharacterName = selection.characterName + " " + (nextPlayerCharacterPrefabIndex + 1);
  303. }
  304. currentPlacingCharacterInstance.GetComponent<NavMeshAgent>().enabled = false;
  305. // Optionally disable AI or other components that might interfere with placement
  306. // e.g., currentPlacingCharacterInstance.GetComponent<AIController>()?.enabled = false;
  307. }
  308. else
  309. {
  310. FinalizePlayerPlacement();
  311. }
  312. }
  313. private void HandleCharacterPlacement()
  314. {
  315. Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
  316. Debug.DrawRay(ray.origin, ray.direction * 200f, Color.yellow); // Visualize the ray
  317. if (Physics.Raycast(ray, out RaycastHit hit, 200f, groundLayerMask))
  318. {
  319. Vector3 targetPosition = hit.point;
  320. // Clamp position to playerSpawnArea bound (X and Z axis)
  321. targetPosition.x = Mathf.Clamp(targetPosition.x, playerSpawnBounds.min.x, playerSpawnBounds.max.x);
  322. targetPosition.z = Mathf.Clamp(targetPosition.z, playerSpawnBounds.min.z, playerSpawnBounds.max.z);
  323. // Y is determined by the raycast hit on the ground
  324. // --- Direct Y Position Calculation for Mouse-Following Character ---
  325. // This approach was found to be more stable than repeatedly calling AdjustCharacterOnGround.
  326. // It assumes a standard Unity CapsuleCollider where the pivot is at the center.
  327. Vector3 finalCharacterPosition = targetPosition; // targetPosition.y is from the ground hit (hit.point.y)
  328. CapsuleCollider capCollider = currentPlacingCharacterInstance.GetComponent<CapsuleCollider>();
  329. if (capCollider != null)
  330. {
  331. // For a capsule, its pivot is typically at its center.
  332. // To place its bottom on targetPosition.y (ground level),
  333. // its center (pivot) needs to be at targetPosition.y + (height / 2).
  334. // We also account for the character's local scale.
  335. finalCharacterPosition.y = targetPosition.y + (capCollider.height * currentPlacingCharacterInstance.transform.localScale.y / 2f);
  336. }
  337. else
  338. {
  339. // Fallback if not a capsule or if a different pivot is used.
  340. // This might need adjustment based on your character's actual pivot and collider.
  341. Debug.LogWarning($"'{currentPlacingCharacterInstance.name}' does not have a CapsuleCollider. Using default Y offset for placement. Adjust if incorrect.");
  342. finalCharacterPosition.y = targetPosition.y + 0.5f; // Example offset, adjust as needed
  343. }
  344. currentPlacingCharacterInstance.transform.position = finalCharacterPosition;
  345. // AdjustCharacterOnGround(currentPlacingCharacterInstance); // No longer called every frame for mouse-follow
  346. }
  347. else
  348. {
  349. }
  350. // Else mouse is not over valid ground, character stays at last valid position or initial spawn
  351. if (Input.GetMouseButtonDown(0))
  352. { // Left-click to place character
  353. // Check if the current position is valid (within bounds and not overlapping)
  354. // The position is already clamped and on ground due to the logic above.
  355. // We primarily need to check for overlaps.
  356. if (!IsOverlappingOtherCharacters(currentPlacingCharacterInstance))
  357. {
  358. PlaceCurrentCharacter();
  359. }
  360. else
  361. {
  362. Debug.LogWarning("Cannot place character: Overlapping with another character.");
  363. // Optionally, you could provide feedback to the player about the overlap (e.g. change color?).
  364. }
  365. }
  366. if (Input.GetMouseButtonDown(1))
  367. { // Right-click to cancel placement
  368. if (placedPlayerCharacters.Count > 0)
  369. {
  370. FinalizePlayerPlacement();
  371. }
  372. else
  373. {
  374. }
  375. }
  376. }
  377. private void PlaceCurrentCharacter()
  378. {
  379. placedPlayerCharacters.Add(currentPlacingCharacterInstance);
  380. currentPlacingCharacterInstance = null;
  381. nextPlayerCharacterPrefabIndex++;
  382. SpawnNextPlayerCharacterForPlacement(); // Spawn next character for placement
  383. }
  384. private void AdjustCharacterOnGround(GameObject character)
  385. {
  386. if (character == null)
  387. {
  388. return;
  389. }
  390. Collider charCollider = character.GetComponent<Collider>();
  391. if (charCollider != null)
  392. {
  393. // This ensured the lowest point of the collider is at character.transform.position.y
  394. // (which should be the ground hit point)
  395. // currentY is the Y-coordinate of the character's pivot.
  396. // We want the character's collider bottom (feet) to be at this Y-level.
  397. float currentY = character.transform.position.y;
  398. float colliderMinYWorld = charCollider.bounds.min.y;
  399. float verticalOffset = currentY - colliderMinYWorld;
  400. const float tolerance = 0.001f; // Small tolerance to avoid floating point issues
  401. if (Mathf.Abs(verticalOffset) > tolerance)
  402. {
  403. character.transform.position += Vector3.up * verticalOffset;
  404. }
  405. }
  406. else
  407. {
  408. Debug.LogWarning($"Character: {character.name} has no collider. Cannot accurately adjust to ground.");
  409. }
  410. }
  411. private bool IsOverlappingOtherCharacters(GameObject character)
  412. {
  413. Collider newCharCollider = character.GetComponent<Collider>();
  414. if (newCharCollider == null)
  415. {
  416. Debug.LogWarning($"Character: {character.name} has no collider. Cannot check for overlaps.");
  417. return false; // Or true to precent placement if no collider
  418. }
  419. Bounds newCharBounds = newCharCollider.bounds;
  420. foreach (GameObject placedCharacter in placedPlayerCharacters)
  421. {
  422. Collider otherCollider = placedCharacter.GetComponent<Collider>();
  423. if (otherCollider != null && newCharBounds.Intersects(otherCollider.bounds))
  424. {
  425. return true;
  426. }
  427. }
  428. foreach (GameObject placedEnemy in placedEnemyCharacters)
  429. {
  430. Collider otherCollider = placedEnemy.GetComponent<Collider>();
  431. if (otherCollider != null && newCharBounds.Intersects(otherCollider.bounds))
  432. {
  433. return true;
  434. }
  435. }
  436. return false;
  437. }
  438. private void FinalizePlayerPlacement()
  439. {
  440. isPlacingPlayerCharacters = false;
  441. if (currentPlacingCharacterInstance != null)
  442. {
  443. Destroy(currentPlacingCharacterInstance); // Destroy the preview instance if it wasn't placed
  444. currentPlacingCharacterInstance = null;
  445. }
  446. EndPlacementPhase();
  447. // Here you might want to trigger the next phase of your game, e.g., start the battle.
  448. GameManager.Instance.StartBattle(placedPlayerCharacters, placedEnemyCharacters);
  449. Destroy(playerSpawnArea);
  450. Destroy(enemySpawnArea);
  451. playerSpawnArea = null;
  452. enemySpawnArea = null;
  453. }
  454. private void EndPlacementPhase()
  455. {
  456. // This method can be used to clean up or finalize the placement phase.
  457. // For example, you might want to enable AI, re-enable NavMeshAgents, etc.
  458. foreach (GameObject character in placedPlayerCharacters)
  459. {
  460. NavMeshAgent agent = character.GetComponent<NavMeshAgent>();
  461. if (agent != null)
  462. {
  463. agent.enabled = true; // Re-enable NavMeshAgent
  464. }
  465. // Enable AI or other components as needed
  466. // e.g., character.GetComponent<AIController>()?.enabled = true;
  467. }
  468. foreach (GameObject character in enemyCharacters)
  469. {
  470. NavMeshAgent agent = character.GetComponent<NavMeshAgent>();
  471. if (agent != null)
  472. {
  473. agent.enabled = true; // Re-enable NavMeshAgent
  474. }
  475. // Enable AI or other components as needed
  476. // e.g., character.GetComponent<AIController>()?.enabled = true;
  477. }
  478. }
  479. private void PlaceEnemyCharacters()
  480. {
  481. Collider spawnAreaCollider = enemySpawnArea.GetComponent<Collider>();
  482. if (spawnAreaCollider == null)
  483. {
  484. Debug.LogError("Enemy spawn area does not have a collider component.");
  485. return;
  486. }
  487. Bounds spawnBounds = spawnAreaCollider.bounds;
  488. for (int i = enemySelections.Count - 1; i >= 0; i--)
  489. {
  490. var selection = enemySelections[i];
  491. float randomX = UnityEngine.Random.Range(spawnBounds.min.x, spawnBounds.max.x);
  492. float randomZ = UnityEngine.Random.Range(spawnBounds.min.z, spawnBounds.max.z);
  493. Vector3 rayOrigin = new Vector3(randomX, enemySpawnArea.transform.position.y + 10f, randomZ);
  494. Vector3 spawnPosition = new Vector3(randomX, enemySpawnArea.transform.position.y, randomZ);
  495. // Raycast to find the ground
  496. if (Physics.Raycast(rayOrigin, Vector3.down, out RaycastHit hit, 200f, groundLayerMask))
  497. {
  498. spawnPosition = hit.point;
  499. }
  500. else
  501. {
  502. Debug.LogWarning($"Raycast did not hit ground below ({randomX}, {randomZ}). Placing enemy at spawn area Y level.");
  503. }
  504. GameObject placedEnemy = Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
  505. Character character = placedEnemy.GetComponent<Character>();
  506. if (character != null)
  507. {
  508. // Try to get enhanced weapon data first
  509. WeaponItem enhancedWeapon = GetEnhancedWeaponItem(selection.characterName, false);
  510. if (enhancedWeapon != null)
  511. {
  512. EquipWeapon(character, enhancedWeapon);
  513. }
  514. else
  515. {
  516. EquipWeapon(character, selection.weaponType);
  517. }
  518. character.CharacterName = selection.characterName + "_" + (i + 1);
  519. }
  520. AdjustCharacterOnGround(placedEnemy); // Adjust the enemy to the ground
  521. placedEnemyCharacters.Add(placedEnemy);
  522. }
  523. }
  524. }