[오류]
RedBlockManager is not assigned!
0x00007ff9106a4a3d (Unity) StackWalker::ShowCallstack
0x00007ff9106ac2d9 (Unity) GetStacktrace
0x00007ff911e284d9 (Unity) DebugStringToFile
0x00007ff90f80e12c (Unity) DebugLogHandler_CUSTOM_Internal_Log
0x0000017ba6bd59fd (Mono JIT Code) (wrapper managed-to-native) UnityEngine.DebugLogHandler:Internal_Log_Injected (UnityEngine.LogType,UnityEngine.LogOption,UnityEngine.Bindings.ManagedSpanWrapper&,intptr)
0x0000017ba6bd58c3 (Mono JIT Code) UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
0x0000017ba6bd54fb (Mono JIT Code) UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
0x0000017ba6bd5280 (Mono JIT Code) UnityEngine.Logger:Log (UnityEngine.LogType,object)
0x0000017bb1cec3f5 (Mono JIT Code) UnityEngine.Debug:LogError (object)
0x0000017bb1ce8123 (Mono JIT Code) ClickableBlock:HandleRedBlockClick () (at C:/Users/Administrator/My project/Assets/Script/ClickableBlock.cs:111)
0x0000017bb1ce79cb (Mono JIT Code) ClickableBlock:OnMouseDown () (at C:/Users/Administrator/My project/Assets/Script/ClickableBlock.cs:81)
0x0000017c52d16528 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
0x00007ff93664697e (mono-2.0-bdwgc) mono_jit_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/mini/mini-runtime.c:3445)
0x00007ff936588444 (mono-2.0-bdwgc) do_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3068)
0x00007ff936588530 (mono-2.0-bdwgc) mono_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3115)
0x00007ff9105ce154 (Unity) scripting_method_invoke
0x00007ff9105a8cf3 (Unity) ScriptingInvocation::Invoke
0x00007ff910599c70 (Unity) MonoBehaviour::InvokeMethodOrCoroutineChecked
0x00007ff910599d7f (Unity) MonoBehaviour::InvokeMethodOrCoroutineChecked
0x00007ff9105ab217 (Unity) Scripting::SendScriptingMessage
0x00007ff9105aaf4e (Unity) Scripting::SendScriptingMessage
0x00007ff90f80dcf1 (Unity) GameObject_CUSTOM_SendMessage
0x0000017bb1ccdf8d (Mono JIT Code) (wrapper managed-to-native) UnityEngine.GameObject:SendMessage_Injected (intptr,UnityEngine.Bindings.ManagedSpanWrapper&,object,UnityEngine.SendMessageOptions)
0x0000017bb1ccde5b (Mono JIT Code) UnityEngine.GameObject:SendMessage (string,object,UnityEngine.SendMessageOptions)
0x0000017bb1ccdb2b (Mono JIT Code) UnityEngine.SendMouseEvents/HitInfo:SendMessage (string)
0x0000017ba6bf846b (Mono JIT Code) UnityEngine.SendMouseEvents:SendEvents (int,UnityEngine.SendMouseEvents/HitInfo)
0x0000017ba6bf54ab (Mono JIT Code) UnityEngine.SendMouseEvents:DoSendMouseEvents (int)
0x0000017ba6bf578b (Mono JIT Code) (wrapper runtime-invoke) <Module>:runtime_invoke_void_int (object,intptr,intptr,intptr)
0x00007ff93664697e (mono-2.0-bdwgc) mono_jit_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/mini/mini-runtime.c:3445)
0x00007ff936588444 (mono-2.0-bdwgc) do_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3068)
0x00007ff936588530 (mono-2.0-bdwgc) mono_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3115)
0x00007ff9105ce154 (Unity) scripting_method_invoke
0x00007ff9105a8cf3 (Unity) ScriptingInvocation::Invoke
0x00007ff9105a3f85 (Unity) ScriptingInvocation::Invoke<void>
0x00007ff9106db59d (Unity) Scripting::UnityEngine::SendMouseEventsProxy::DoSendMouseEvents
0x00007ff9109e16d9 (Unity) `InternalInitializeModule_InputLegacy'::`2'::PreUpdateSendMouseEventsRegistrator::Forward
0x00007ff91021e75b (Unity) ExecutePlayerLoop
0x00007ff91021e8b7 (Unity) ExecutePlayerLoop
0x00007ff9102249ed (Unity) PlayerLoop
0x00007ff91129b30a (Unity) EditorPlayerLoop::Execute
0x00007ff9112b0cf7 (Unity) PlayerLoopController::InternalUpdateScene
0x00007ff9112b2a9d (Unity) PlayerLoopController::UpdateSceneIfNeededFromMainLoop
0x00007ff9112acb51 (Unity) Application::TickTimer
0x00007ff9116e96fa (Unity) MainMessageLoop
0x00007ff9116eeefd (Unity) UnityMain
0x00007ff734a52cda (Unity) __scrt_common_main_seh
0x00007ff98cf37344 (KERNEL32) BaseThreadInitThunk
0x00007ff98d3426b1 (ntdll) RtlUserThreadStart
현재 "BlockSpawner" 라는 오브젝트 안에 여러 스크립트가 할당돼있고 프리팹스도 할당 돼있습니다.
아직 YellowBlock은 구현도 못하고 현재 RedBlock, 2, 3 과 GreenBlock , 2 이렇게 구현하고 있습니다.
처음 블록을 랜덤으로 16개 씬에 배치하는 스크립트 코드
[ BlockSpawner ]
using UnityEngine;
using System.Collections.Generic;
public class BlockSpawner : MonoBehaviour
{
public GameObject[] blockPrefabs; // 블록 프리팹 배열
public int rows = 4; // 행 수
public int cols = 4; // 열 수
private GameObject[,] grid; // 블록 배치 그리드
private RedBlockManager redBlockManager; // RedBlockManager 참조
private RedBlock2Manager redBlock2Manager; // RedBlock2Manager 참조
private GreenBlockManager greenBlockManager; // GreenBlockManager 참조
private GreenBlock2Manager greenBlock2Manager; // GreenBlock2Manager 참조
void Start()
{
grid = new GameObject[rows, cols]; // 그리드 생성
// RedBlockManager 생성
redBlockManager = gameObject.AddComponent<RedBlockManager>();
redBlockManager.blockPrefabs = blockPrefabs; // 프리팹 배열 할당
// RedBlockManager 유효성 검사
if (redBlockManager == null)
{
Debug.LogError("RedBlockManager is not assigned after creation!");
return; // 초기화 중단
}
else
{
Debug.Log("RedBlockManager is successfully initialized!");
}
redBlock2Manager = gameObject.AddComponent<RedBlock2Manager>();
redBlock2Manager.blockPrefabs = blockPrefabs; // 필요에 따라 설정
// GreenBlockManager 추가 및 프리팹 배열 할당
greenBlockManager = gameObject.AddComponent<GreenBlockManager>();
greenBlockManager.blockPrefabs = blockPrefabs; // GreenBlockManager에 프리팹 배열 할당
// GreenBlock2Manager 추가 (프리팹 배열 할당 제거)
greenBlock2Manager = gameObject.AddComponent<GreenBlock2Manager>();
// 블록 생성
SpawnBlocks(); // 블록 생성 메서드 호출
}
void SpawnBlocks()
{
int totalBlocks = 16; // 총 블록 수 (4x4 그리드이므로 16개)
int[] blockCounts = new int[3] { 4, 4, 8 }; // 각 색상별 블록 수 조정
// 블록 크기 및 간격 설정
float blockSize = 1.4f; // 블록 크기 (스케일에 따라 조정)
// 랜덤 배치
for (int i = 0; i < totalBlocks; i++)
{
int blockIndex = GetRandomBlockIndex(blockCounts); // 랜덤 블록 인덱스 얻기
if (blockIndex >= 0 && blockIndex < blockPrefabs.Length) // 인덱스 유효성 검사
{
// 중앙 기준으로 블록의 위치를 설정
int j = i % cols; // 열
int k = i / cols; // 행
// 중앙 기준으로 위치 조정
Vector3 position = new Vector3(j * blockSize - (blockSize * (cols - 1) / 2),
k * blockSize - (blockSize * (rows - 1) / 2),
-4); // Z 축을 -4로 설정
GameObject block = Instantiate(blockPrefabs[blockIndex], position, Quaternion.identity);
block.transform.localScale = new Vector3(0.34f, 0.34f, 1); // 블록 스케일 설정
grid[k, j] = block; // 그리드에 블록 저장
blockCounts[blockIndex]--; // 블록 수 감소
// 블록에 클릭 이벤트 추가
block.AddComponent<BoxCollider2D>(); // 2D 충돌체 추가
ClickableBlock clickableBlock = block.AddComponent<ClickableBlock>();
clickableBlock.Initialize(GetComponent<BlockSpawner>(), redBlockManager, redBlock2Manager, greenBlockManager, greenBlock2Manager); // ClickableBlock 추가
// 로그 추가
Debug.Log($"Block spawned at: {position}, Block Index: {blockIndex}");
}
else
{
Debug.Log("No available blocks to spawn.");
}
}
}
int GetRandomBlockIndex(int[] blockCounts)
{
// 사용 가능한 블록 인덱스를 찾기
List<int> availableBlocks = new List<int>();
for (int i = 0; i < blockCounts.Length; i++)
{
if (blockCounts[i] > 0)
{
availableBlocks.Add(i); // 사용 가능한 블록 추가
}
}
// 사용 가능한 블록이 없으면 -1 반환
if (availableBlocks.Count == 0)
return -1;
// 랜덤 인덱스 선택
int randomIndex = Random.Range(0, availableBlocks.Count);
return availableBlocks[randomIndex]; // 랜덤 블록 인덱스 반환
}
}
오브젝트들의 클릭 이벤트를 관리하는 스크립트 코드
[ ClickableBlock ]
using UnityEngine;
public class ClickableBlock : MonoBehaviour
{
private BlockSpawner blockSpawner; // BlockSpawner 참조
private RedBlockManager redBlockManager; // RedBlockManager 참조
private RedBlock2Manager redBlock2Manager; // RedBlock2Manager 참조
private GreenBlockManager greenBlockManager; // GreenBlockManager 참조
private GreenBlock2Manager greenBlock2Manager; // GreenBlock2Manager 참조
// Initialize 메서드
public void Initialize(BlockSpawner spawner, RedBlockManager redManager, RedBlock2Manager red2Manager, GreenBlockManager greenManager, GreenBlock2Manager green2Manager)
{
blockSpawner = spawner;
redBlockManager = redManager;
redBlock2Manager = red2Manager;
greenBlockManager = greenManager;
greenBlock2Manager = green2Manager;
// 유효성 검사
ValidateManagers();
// 추가 로그
Debug.Log($"Initialized ClickableBlock with RedBlockManager: {redBlockManager}, RedBlock2Manager: {redBlock2Manager}, GreenBlockManager: {greenBlockManager}, GreenBlock2Manager: {greenBlock2Manager}");
// 각 매니저의 초기화 로그
LogManagerInitialization();
}
// 매니저 유효성 검사
private void ValidateManagers()
{
if (redBlockManager == null)
{
Debug.LogError("RedBlockManager is not assigned in ClickableBlock!");
}
if (redBlock2Manager == null)
{
Debug.LogError("RedBlock2Manager is not assigned in ClickableBlock!");
}
if (greenBlockManager == null)
{
Debug.LogError("GreenBlockManager is not assigned in ClickableBlock!");
}
if (greenBlock2Manager == null)
{
Debug.LogError("GreenBlock2Manager is not assigned in ClickableBlock!");
}
}
// 각 매니저의 초기화 상태 로그
private void LogManagerInitialization()
{
if (greenBlock2Manager != null)
{
Debug.Log("GreenBlock2Manager initialized successfully!");
}
else
{
Debug.LogError("GreenBlock2Manager is not assigned!");
}
if (redBlockManager != null)
{
Debug.Log("RedBlockManager initialized successfully!");
}
if (redBlock2Manager != null)
{
Debug.Log("RedBlock2Manager initialized successfully!");
}
if (greenBlockManager != null)
{
Debug.Log("GreenBlockManager initialized successfully!");
}
}
void OnMouseDown()
{
if (gameObject.CompareTag("RedBlock"))
{
HandleRedBlockClick();
}
else if (gameObject.CompareTag("RedBlock2"))
{
HandleRedBlock2Click();
}
else if (gameObject.CompareTag("GreenBlock"))
{
HandleGreenBlockClick();
}
else if (gameObject.CompareTag("GreenBlock2"))
{
HandleGreenBlock2Click();
}
else
{
Debug.Log($"Non-RedBlock or Non-GreenBlock clicked: {gameObject.name}. No action taken.");
}
}
private void HandleRedBlockClick()
{
if (redBlockManager != null)
{
redBlockManager.OnRedBlockClick(gameObject);
}
else
{
Debug.LogError("RedBlockManager is not assigned!");
}
}
private void HandleRedBlock2Click()
{
if (redBlock2Manager != null)
{
redBlock2Manager.OnRedBlock2Click(gameObject);
}
else
{
Debug.LogError("RedBlock2Manager is not assigned!");
}
}
private void HandleGreenBlockClick()
{
if (greenBlockManager != null)
{
greenBlockManager.OnGreenBlockClick(gameObject);
}
else
{
Debug.LogError("GreenBlockManager is not assigned!");
}
}
private void HandleGreenBlock2Click()
{
if (greenBlock2Manager != null)
{
greenBlock2Manager.OnGreenBlock2Click(gameObject);
}
else
{
Debug.LogError("GreenBlock2Manager is not assigned!");
}
}
}
[ RedBlockManager ]
using UnityEngine;
public class RedBlockManager : MonoBehaviour
{
private GameObject firstRedBlock; // 첫 번째 선택된 RedBlock
private Vector3 firstRedBlockPosition; // 첫 번째 RedBlock의 위치
public GameObject[] blockPrefabs; // 블록 프리팹 배열
private RedBlock2Manager redBlock2Manager; // RedBlock2Manager 참조
void Start()
{
redBlock2Manager = GetComponent<RedBlock2Manager>(); // RedBlock2Manager 컴포넌트 가져오기
Debug.Log("RedBlockManager initialized successfully!");
}
// RedBlock 클릭 처리 메서드
public void OnRedBlockClick(GameObject redBlock)
{
Debug.Log($"OnRedBlockClick called with: {redBlock.name}");
if (!redBlock.CompareTag("RedBlock"))
{
Debug.Log($"Clicked block is not a RedBlock: {redBlock.name}. No action taken.");
return;
}
// 동일한 인스턴스 클릭 방지
if (firstRedBlock != null && redBlock == firstRedBlock)
{
Debug.Log("Same RedBlock clicked. No action taken.");
return;
}
// 첫 번째 RedBlock이 선택되지 않은 경우
if (firstRedBlock == null)
{
firstRedBlock = redBlock; // 첫 번째 RedBlock 선택
firstRedBlockPosition = redBlock.transform.position; // 위치 저장
Debug.Log($"First RedBlock selected: {firstRedBlock.name} at {firstRedBlockPosition}");
}
else
{
// 두 번째 RedBlock 클릭 처리
ProcessRedBlockSelection(redBlock);
}
}
private void ProcessRedBlockSelection(GameObject secondRedBlock)
{
Debug.Log($"ProcessRedBlockSelection called with: {secondRedBlock.name}");
if (firstRedBlock == null || secondRedBlock == null)
{
Debug.LogError("One of the blocks is null.");
return;
}
// 두 RedBlock의 위치 비교
if (Vector3.Distance(firstRedBlockPosition, secondRedBlock.transform.position) < 0.01f)
{
Debug.Log("Same position selected. No action taken.");
return; // 아무 작업도 수행하지 않음
}
// 두 RedBlock 제거
Debug.Log($"Destroying firstRedBlock: {firstRedBlock.name} and secondRedBlock: {secondRedBlock.name}");
Destroy(firstRedBlock); // 첫 번째 RedBlock 제거
Destroy(secondRedBlock); // 두 번째 RedBlock 제거
// 첫 번째 RedBlock 자리에는 RedBlock, YellowBlock, GreenBlock 중 랜덤으로 하나 생성
CreateNewBlock(firstRedBlockPosition); // 첫 번째 RedBlock의 위치에 새로운 블록 생성
redBlock2Manager.CreateRedBlock2(secondRedBlock.transform.position); // 두 번째 RedBlock 자리에는 RedBlock2 생성
// 선택 상태 초기화
ResetSelection();
}
private void CreateNewBlock(Vector3 position)
{
int[] blockIndices = { 0, 1, 2 }; // RedBlock, YellowBlock, GreenBlock 인덱스
int randomBlockIndex = Random.Range(0, blockIndices.Length); // 랜덤 인덱스 선택
GameObject newBlock = Instantiate(blockPrefabs[blockIndices[randomBlockIndex]], position, Quaternion.identity);
newBlock.transform.localScale = new Vector3(0.34f, 0.34f, 1); // 새로운 블록 스케일 설정
newBlock.name = StripClone(blockPrefabs[blockIndices[randomBlockIndex]].name); // 이름 설정
newBlock.tag = "RedBlock"; // 태그 설정
// 디버깅 정보 추가
Debug.Log($"Created block: {newBlock.name} at {position}, Scale: {newBlock.transform.localScale}");
// 클릭 이벤트 추가: 새로 생성된 블록에 ClickableBlock 추가
AddClickableBlock(newBlock);
}
private void AddClickableBlock(GameObject block)
{
// BoxCollider2D 추가
BoxCollider2D collider = block.AddComponent<BoxCollider2D>();
collider.size = new Vector2(0.34f, 0.34f); // 크기 설정
ClickableBlock clickable = block.AddComponent<ClickableBlock>();
clickable.Initialize(GetComponent<BlockSpawner>(), this, redBlock2Manager, GetComponent<GreenBlockManager>(), GetComponent<GreenBlock2Manager>());
// 디버깅 로그 추가
Debug.Log($"BoxCollider2D added to block: {block.name}");
}
private void ResetSelection()
{
firstRedBlock = null; // 선택 초기화
firstRedBlockPosition = Vector3.zero; // 위치 초기화
Debug.Log("Selection reset.");
}
// 이름에서 "(Clone)"을 제거하는 메서드
private string StripClone(string name)
{
return name.Replace("(Clone)", "").Trim();
}
}
[ RedBlock2Manager ]
using UnityEngine;
public class RedBlock2Manager : MonoBehaviour
{
private GameObject firstRedBlock2; // 첫 번째 선택된 RedBlock2
private Vector3 firstRedBlock2Position; // 첫 번째 RedBlock2의 위치
public GameObject[] blockPrefabs; // 블록 프리팹 배열
private bool isRedBlock2Selected = false; // RedBlock2 선택 상태
private bool isRedBlockSelected = false; // RedBlock 선택 상태
public void CreateRedBlock2(Vector3 position) // RedBlock2 생성 메서드 추가
{
int redBlock2Index = 3; // RedBlock2의 인덱스
// 배열 길이 확인
if (blockPrefabs.Length <= redBlock2Index)
{
Debug.LogError("RedBlock2 index is out of bounds of blockPrefabs array!");
return; // 메서드 종료
}
GameObject redBlock2 = Instantiate(blockPrefabs[redBlock2Index],
position, Quaternion.identity);
redBlock2.transform.localScale = new Vector3(0.34f, 0.34f, 1); // RedBlock2의 스케일 설정
redBlock2.name = "RedBlock2"; // RedBlock2의 이름 설정
// 클릭 이벤트 추가: 새로 생성된 RedBlock2에 ClickableBlock 추가
AddClickableBlock(redBlock2);
}
private void AddClickableBlock(GameObject block)
{
ClickableBlock clickable = block.AddComponent<ClickableBlock>();
clickable.Initialize(GetComponent<BlockSpawner>(), GetComponent<RedBlockManager>(), this, GetComponent<GreenBlockManager>(), null); // 모든 매니저 전달
}
// RedBlock 클릭 처리
public void OnRedBlockClick(GameObject redBlock)
{
isRedBlockSelected = true; // RedBlock이 선택되었음을 표시
Debug.Log($"RedBlock clicked: {redBlock.name}. No action can be taken on RedBlock2.");
}
// RedBlock2 클릭 처리
public void OnRedBlock2Click(GameObject redBlock2)
{
// RedBlock이 이미 선택된 경우, 아무 작업도 하지 않음
if (isRedBlockSelected)
{
Debug.Log($"RedBlock is already selected. No action can be taken on {redBlock2.name}.");
return;
}
// 클릭된 객체가 RedBlock2가 아닐 경우, 아무 작업도 하지 않음
if (!redBlock2.CompareTag("RedBlock2"))
{
Debug.Log($"Clicked block is not a RedBlock2: {redBlock2.name}. No action taken.");
return;
}
// RedBlock2가 선택되지 않은 경우
if (firstRedBlock2 == null)
{
firstRedBlock2 = redBlock2; // 첫 번째 RedBlock2 선택
firstRedBlock2Position = redBlock2.transform.position; // 위치 저장
isRedBlock2Selected = true; // 선택 상태 변경
Debug.Log($"First RedBlock2 Selected: {redBlock2.name} at {firstRedBlock2Position}");
}
else
{
ProcessRedBlock2Selection(redBlock2);
}
}
private void ProcessRedBlock2Selection(GameObject secondRedBlock2)
{
// 두 RedBlock2의 위치 비교
if (firstRedBlock2Position == secondRedBlock2.transform.position)
{
// 같은 위치일 경우 아무 작업도 하지 않고 선택 초기화
Debug.Log("Same position selected. No action taken, resetting selection.");
firstRedBlock2 = null; // 선택 초기화
isRedBlock2Selected = false; // 선택 상태 초기화
return;
}
// 이름에서 "(Clone)"을 제거한 후 비교
if (StripClone(firstRedBlock2.name) == StripClone(secondRedBlock2.name))
{
Debug.Log("Same block type selected. Removing both RedBlock2s.");
Destroy(firstRedBlock2); // 첫 번째 RedBlock2 제거
Destroy(secondRedBlock2); // 두 번째 RedBlock2 제거
// 새로운 블록 생성
CreateNewBlock(firstRedBlock2Position); // 첫 번째 RedBlock2의 위치에 랜덤한 블록 생성
CreateRedBlock3(secondRedBlock2.transform.position); // 두 번째 RedBlock2의 위치에 RedBlock3 생성
// 선택 상태 초기화
firstRedBlock2 = null; // 선택 초기화
isRedBlock2Selected = false; // 선택 상태 초기화
}
else
{
Debug.Log("Different block types selected. No action taken.");
// 선택 상태 초기화 (서로 다른 경우)
firstRedBlock2 = null; // 선택 초기화
isRedBlock2Selected = false; // 선택 상태 초기화
}
}
private void CreateNewBlock(Vector3 position)
{
// RedBlock, GreenBlock, YellowBlock 중 랜덤으로 하나 생성
int[] blockIndices = { 0, 1, 2 }; // RedBlock, YellowBlock, GreenBlock 인덱스
int randomBlockIndex = Random.Range(0, blockIndices.Length); // 랜덤 인덱스 선택
GameObject newBlock = Instantiate(blockPrefabs[blockIndices[randomBlockIndex]],
position, Quaternion.identity);
newBlock.transform.localScale = new Vector3(0.34f, 0.34f, 1); // 새로운 블록 스케일 설정
newBlock.name = StripClone(blockPrefabs[blockIndices[randomBlockIndex]].name); // 이름 설정
// 클릭 이벤트 추가: 새로 생성된 블록에 ClickableBlock 추가
AddClickableBlock(newBlock);
}
private void CreateRedBlock3(Vector3 position)
{
int redBlock3Index = 4; // RedBlock3의 인덱스 (인덱스가 맞는지 확인)
// 배열 길이 확인
if (blockPrefabs.Length <= redBlock3Index)
{
Debug.LogError("RedBlock3 index is out of bounds of blockPrefabs array!");
return; // 메서드 종료
}
GameObject redBlock3 = Instantiate(blockPrefabs[redBlock3Index],
position, Quaternion.identity);
redBlock3.transform.localScale = new Vector3(0.34f, 0.34f, 1); // RedBlock3의 스케일 설정
redBlock3.name = "RedBlock3"; // RedBlock3의 이름 설정
// 클릭 이벤트 추가: 새로 생성된 RedBlock3에 ClickableBlock 추가
AddClickableBlock(redBlock3);
}
// 이름에서 "(Clone)"을 제거하는 메서드
private string StripClone(string name)
{
return name.Replace("(Clone)", "").Trim();
}
}
[ GreenBlockManager ]
using UnityEngine;
public class GreenBlockManager : MonoBehaviour
{
private GameObject firstGreenBlock; // 첫 번째 선택된 GreenBlock
private Vector3 firstGreenBlockPosition; // 첫 번째 GreenBlock의 위치
public GameObject[] blockPrefabs; // 블록 프리팹 배열
private GreenBlock2Manager greenBlock2Manager; // GreenBlock2Manager 참조
void Start()
{
Debug.Log("GreenBlockManager initialized successfully!");
greenBlock2Manager = GetComponent<GreenBlock2Manager>();
if (greenBlock2Manager == null)
{
Debug.LogError("GreenBlock2Manager not found!"); // 오류 메시지
}
// blockPrefabs 배열이 null인지 확인
if (blockPrefabs == null)
{
Debug.LogError("Block prefabs array is null!");
}
else if (blockPrefabs.Length == 0)
{
Debug.LogError("Block prefabs array is empty!");
}
else
{
Debug.Log($"Block prefabs array initialized with {blockPrefabs.Length} elements.");
}
}
public void OnGreenBlockClick(GameObject greenBlock)
{
if (!greenBlock.CompareTag("GreenBlock"))
{
Debug.Log($"Clicked block is not a GreenBlock: {greenBlock.name}. No action taken.");
return;
}
if (firstGreenBlock != null && greenBlock.transform.position == firstGreenBlockPosition)
{
Debug.Log("Same GreenBlock clicked. Resetting selection.");
ResetSelection(); // 선택 상태 초기화
return;
}
if (firstGreenBlock == null)
{
firstGreenBlock = greenBlock; // 첫 번째 GreenBlock 선택
firstGreenBlockPosition = greenBlock.transform.position; // 위치 저장
Debug.Log($"First GreenBlock selected: {firstGreenBlock.name}");
}
else
{
ProcessGreenBlockSelection(greenBlock);
}
}
private void ProcessGreenBlockSelection(GameObject secondGreenBlock)
{
Debug.Log($"Processing selection for blocks: {firstGreenBlock.name} and {secondGreenBlock.name}");
if (firstGreenBlock == null || secondGreenBlock == null)
{
Debug.LogError("One of the blocks is null.");
return;
}
// 첫 번째 GreenBlock 자리에는 RedBlock, YellowBlock, GreenBlock 중 랜덤한 블록 생성
Debug.Log($"Creating random block at {firstGreenBlockPosition}");
CreateRandomBlock(firstGreenBlockPosition); // 첫 번째 GreenBlock의 위치에 새로운 블록 생성
// 두 GreenBlock 제거
Debug.Log($"Removing blocks: {firstGreenBlock.name} and {secondGreenBlock.name}");
Destroy(firstGreenBlock); // 첫 번째 GreenBlock 제거
Destroy(secondGreenBlock); // 두 번째 GreenBlock 제거
// 두 번째 GreenBlock 자리에는 GreenBlock2 생성
greenBlock2Manager.CreateGreenBlock2(secondGreenBlock.transform.position); // GreenBlock2 생성
// 선택 상태 초기화
ResetSelection();
}
private void CreateRandomBlock(Vector3 position)
{
// blockPrefabs 배열의 유효성 검사
if (blockPrefabs == null || blockPrefabs.Length == 0)
{
Debug.LogError("Block prefabs array is null or empty!");
return; // 배열이 null 또는 비어있으면 메서드 종료
}
// RedBlock, YellowBlock, GreenBlock 중 랜덤으로 하나 선택
int[] validBlockIndices = { 0, 1, 2 }; // RedBlock, YellowBlock, GreenBlock 인덱스
int randomIndex = Random.Range(0, validBlockIndices.Length); // 랜덤 인덱스 선택
// 선택한 프리팹이 null인지 확인
if (blockPrefabs[validBlockIndices[randomIndex]] == null)
{
Debug.LogError($"Block prefab at index {validBlockIndices[randomIndex]} is null!");
return; // 프리팹이 null이면 메서드 종료
}
// 프리팹을 인스턴스화
GameObject newBlock = Instantiate(blockPrefabs[validBlockIndices[randomIndex]], position, Quaternion.identity);
newBlock.transform.localScale = new Vector3(0.34f, 0.34f, 1); // 새로운 블록 스케일 설정
newBlock.name = StripClone(blockPrefabs[validBlockIndices[randomIndex]].name); // 이름 설정
newBlock.tag = "RedBlock"; // 랜덤으로 생성된 블록의 태그를 RedBlock으로 설정
Debug.Log($"Created block: {newBlock.name} with tag: {newBlock.tag} at {position}"); // 생성된 블록 정보 로그
// 클릭 이벤트 추가 및 BoxCollider2D 추가
AddClickableBlock(newBlock);
}
private void ResetSelection()
{
firstGreenBlock = null; // 선택 초기화
firstGreenBlockPosition = Vector3.zero; // 위치 초기화
}
private void AddClickableBlock(GameObject block)
{
// BoxCollider2D 추가
BoxCollider2D collider = block.AddComponent<BoxCollider2D>();
collider.size = new Vector2(0.34f, 0.34f); // 크기 설정
ClickableBlock clickable = block.AddComponent<ClickableBlock>();
BlockSpawner spawner = GetComponent<BlockSpawner>();
if (spawner == null)
{
Debug.LogError("BlockSpawner reference is null!");
return; // BlockSpawner가 null이면 메서드 종료
}
clickable.Initialize(spawner, null, null, this, greenBlock2Manager); // 필요한 매니저 전달
// 디버깅 로그 추가
Debug.Log($"BoxCollider2D added to block: {block.name}");
}
private string StripClone(string name)
{
return name.Replace("(Clone)", "").Trim();
}
}
[ GreenBlock2Manager ]
using UnityEngine;
public class GreenBlock2Manager : MonoBehaviour
{
public GameObject greenBlock2Prefab; // GreenBlock2 프리팹
// Start 메서드 추가
void Start()
{
Debug.Log("GreenBlock2Manager initialized successfully!");
}
public void CreateGreenBlock2(Vector3 position)
{
// GreenBlock2 프리팹이 null인지 확인
if (greenBlock2Prefab == null)
{
Debug.LogError("GreenBlock2 prefab is null! Cannot create GreenBlock2.");
return; // 프리팹이 null일 경우 메서드 종료
}
// GreenBlock2 생성
GameObject newGreenBlock2 = Instantiate(greenBlock2Prefab, position, Quaternion.identity);
newGreenBlock2.transform.localScale = new Vector3(0.34f, 0.34f, 1); // GreenBlock2 스케일 설정
newGreenBlock2.name = StripClone(greenBlock2Prefab.name); // 이름 설정
// 클릭 이벤트 추가
AddClickableBlock(newGreenBlock2);
}
public void OnGreenBlock2Click(GameObject greenBlock2) // 클릭 처리 메서드
{
Debug.Log($"GreenBlock2 clicked: {greenBlock2.name}");
// GreenBlock2에 대한 추가 클릭 처리 로직 추가
}
private void AddClickableBlock(GameObject block)
{
ClickableBlock clickable = block.AddComponent<ClickableBlock>();
clickable.Initialize(GetComponent<BlockSpawner>(), null, null, null, this); // 필요한 매니저 전달
}
private string StripClone(string name)
{
return name.Replace("(Clone)", "").Trim();
}
}
제가 원하고자 하는 게임은 두개의 같은 오브젝트를 클릭하면 두번째로 클릭한 자리에 한단계 업그레이드가 된 블록2가 생성되는 것입니다.
고수님들 도움 부탁드립니다 ㅠㅠ
GPT한테 해달라하셈
GPT한테 질문하면서 만들고 있어요 GPT도 같은 말만 반복하길래 여기로 왔습니다 ㅜ
플레이어 인풋을 처리하는 객체를 하나 만들고 현재클릭한 블록, 이전에 클릭했던 블록 저장하고 비교하면서 처리하면되는데 이렇게 코드 통으로 올려놓고 해줘 하면 누가 하겠어? 보기라도 편하면 한번 훑어보겠는데 그냥 성의없이 복붙하면 그냥 드르륵 스킵하게됨
죄송합니다 정리해서 다시 올릴게요