[오류]


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" 라는 오브젝트 안에 여러 스크립트가 할당돼있고 프리팹스도 할당 돼있습니다.


7cf3c028e2f206a26d81f6e04e827269


7ff3c028e2f206a26d81f6e14e85756b

아직 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가 생성되는 것입니다.

고수님들 도움 부탁드립니다 ㅠㅠ