using System; using Cinemachine; using Sirenix.OdinInspector; using Unity.VisualScripting; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using Random = UnityEngine.Random; // ReSharper disable once CheckNamespace namespace BlueWaterProject { public class SpawnController : MonoBehaviour { [SerializeField] private float instantiationDistance = 3f; [SerializeField] private float checkRadius = 1f; [SerializeField] private LayerMask checkLayer; [SerializeField] private LayerMask groundLayer; [Title("Crewmate 생성")] [InfoBox("$CrewmateIndexInfoMessage")] [SerializeField] private int crewmatePrefabIndex; private Collider[] colliders = new Collider[MAX_COLLIDER]; private GameObject spawnPositionObj; private CinemachineVirtualCamera cinemachineVirtualCamera; private Transform spawnLocation; private string CrewmateIndexInfoMessage => $"0 ~ {GameManager.Inst.CrewmatePrefabList.Count - 1} 숫자를 입력해주세요."; private const string PLAYER_NAME = "Player"; private const string IN_ISLAND_PLAYER_NAME = "InIslandPlayer"; private const int MAX_COLLIDER = 10; private void Start() { groundLayer = LayerMask.GetMask("Ground"); spawnPositionObj = GameObject.Find("StageMap/SpawnPosition"); if (spawnPositionObj == null) { print("StageMap 또는 SpawnPosition 오브젝트를 찾을 수 없습니다."); return; } cinemachineVirtualCamera = GameObject.Find("Virtual Camera")?.GetComponent(); if (cinemachineVirtualCamera == null) { print("Virtual Camera 오브젝트를 찾을 수 없습니다."); return; } spawnLocation = GameObject.Find("Characters")?.transform; if (spawnLocation == null) { spawnLocation = new GameObject("Characters").transform; } var currentSceneName = SceneManager.GetActiveScene().name; if (currentSceneName != "02.Main") { SpawnInIslandPlayer(spawnPositionObj.transform.position, GameManager.Inst.InIslandPlayerPrefab.transform.rotation); } } private void SpawnInIslandPlayer(Vector3 spawnPos, Quaternion spawnRotation) { // if (Physics.Raycast(spawnPos, Vector3.down, out var hit, 10f, groundLayer)) // { // print(hit.point.y); // spawnPos.y = hit.point.y; // } var islandPlayer = Instantiate(GameManager.Inst.InIslandPlayerPrefab, spawnPos, spawnRotation, spawnLocation); islandPlayer.name = IN_ISLAND_PLAYER_NAME; islandPlayer.gameObject.SetActive(true); var playerInput = islandPlayer.GetComponent(); if (playerInput == null) { playerInput = islandPlayer.transform.AddComponent(); } var desiredActionMap = playerInput.actions.FindActionMap(PLAYER_NAME); if (desiredActionMap == null) { print($"Action map named '{PLAYER_NAME}' not found in player actions!"); return; } playerInput.defaultActionMap = PLAYER_NAME; // if (GameManager.Inst.ShipPlayer != null) // { // GameManager.Inst.ShipPlayer.GetComponent().enabled = false; // } playerInput.enabled = true; var inIslandPlayer = islandPlayer.GetComponent(); if (inIslandPlayer == null) { inIslandPlayer = islandPlayer.AddComponent(); } InIslandCamera.Inst.SetTarget(islandPlayer.transform); GameManager.Inst.SetCurrentInIslandPlayer(inIslandPlayer); } [DisableIf("@crewmatePrefabIndex >= GameManager.Inst.CrewmatePrefabList.Count || crewmatePrefabIndex < 0")] [Button("Crewmate 추가")] public void AddCrewmate() { if (!GameManager.Inst.CurrentInIslandPlayer.GameObject) return; if (crewmatePrefabIndex >= GameManager.Inst.CrewmatePrefabList.Count || crewmatePrefabIndex < 0) { print("존재하지 않는 인덱스입니다."); return; } for (var i = 0; i < 50; i++) { var randomDirection = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f)).normalized; var spawnPos = GameManager.Inst.CurrentInIslandPlayer.Transform.position + (randomDirection * instantiationDistance); Array.Clear(colliders, 0, MAX_COLLIDER); var size = Physics.OverlapSphereNonAlloc(spawnPos, checkRadius, colliders, checkLayer); if (size != 0) continue; var crewmate = Instantiate(GameManager.Inst.CrewmatePrefabList[crewmatePrefabIndex], spawnPos, GameManager.Inst.CrewmatePrefabList[crewmatePrefabIndex].transform.rotation, spawnLocation); crewmate.CrewmatePrefabIndex = crewmatePrefabIndex; crewmate.gameObject.SetActive(true); GameManager.Inst.CurrentCrewmateList.Add(crewmate); return; } print("소환할 수 있는 자리가 없습니다."); } public void SetCrewmatePrefabIndex(int value) => crewmatePrefabIndex = value; } }