-
(21) 클리어한 스테이지만 활성화★Galaxy Ball/2. 싱글플레이 - 스토리모드 2024. 6. 3. 17:55
이번건 굉장히 중요한 기능임과 동시에 내가 연출 다음으로 어려워하고 있는 부분이기도 하다
사실 아직 저장, 불러오기, 싱글톤에 대한 지식이 완벽하지 않기에 어려워하고 있는것이다
이번글에서는 클리어한 스테이지 & 클리어할 차례가 된 스테이지는 활성화 시키고,
클리어하지 못한 스테이지는 비활성화하도록 하겠다
그리고 클리어 여부에 따라 구체의 색상도 바꿔보도록 하겠다
지금은 튜토리얼 씬에 적용하는것이지만 한번 구현을 성공하게 되면 메인씬에 구현시키는것은 똑같은 원리이기에
이번에 성공해보는것이 굉장히 중요하다
우선 머릿속에 떠오르는걸 먼저 적어두고 구현을 시작해보겠다
1. StageGameManager에 식별을 위한 StageClearID 만든뒤 1로 초기화
(StageClearID는 싱글톤으로 씬을 변환해도 그 값이 초기화되지 않음)
2. 모든 스테이지 구체에 StageState 스크립트 제작 후 부착
(* StageState : 본인 스테이지보다 StageClearID가 낮다면 구체가 검정색이 된뒤 플레이버튼 비활성화)
(만약 StageClearID가 높다면 색상을 파란색으로 변경, 같다면 빨간색으로 변경. 이 둘은 플레이버튼 활성화)
3. 플레이어 공에 부착된 플레이 UI 띄우기 기능을 이제 스테이지 구체에 기능 옮겨주기
자 그럼 한번 순서대로 구현해보자
1. StageGameManager에 식별을 위한 StageClearID 만든뒤 1로 초기화
(StageClearID는 싱글톤으로 씬을 변환해도 그 값이 초기화되지 않음)
우선 싱글톤으로 StageClearID라는 변수를 StageGameManager에 추가해보자
혹시라도 헷갈린다면 기본적인 싱글톤에 관한 정리글을 보고 참고하자
public class StageGameManager : MonoBehaviour { public static StageGameManager instance = null; public int StageClearID; private Vector3 clickPosition; public bool isDragging = false; public static float shotDistance; public static Vector3 shotDirection; private void Awake() { if (instance == null) //instance가 null. 즉, 시스템상에 존재하고 있지 않을때 { instance = this; //내자신을 instance로 넣어줍니다. DontDestroyOnLoad(gameObject); //OnLoad(씬이 로드 되었을때) 자신을 파괴하지 않고 유지 } else { if (instance != this) //instance가 내가 아니라면 이미 instance가 하나 존재하고 있다는 의미 Destroy(this.gameObject); //둘 이상 존재하면 안되는 객체이니 방금 AWake된 자신을 삭제 } }
딱 int타입 변수 하나 추가하는것이기 때문에 별다른 특이사항은 없다
2. 모든 스테이지 구체에 StageState 스크립트 제작 후 부착
(* StageState : 본인 스테이지보다 StageClearID가 낮다면 구체가 검정색이 된뒤 플레이버튼 비활성화)
(만약 StageClearID가 높다면 색상을 파란색으로 변경, 같다면 빨간색으로 변경. 이 둘은 플레이버튼 활성화)
사실상 가장 중요한 단계.
이번에는 조건이 좀 까다롭기에 단계를 정하고, 그 단계에 따라 코드를 작성해보겠다
1. 해당 스크립트가 부착된 오브젝트의 6번째 문자를 가져오기 ex) Stage'6' => 6
2. StageClearID와 비교하여 6번째 문자가 크면 "Big", 같으면 "Same", 작으면 "Small" 출력
3. 이제 그 문자출력에서 해당 오브젝트의 색상변경으로 기능을 변경
4. 플레이 박스를 띄워주는 기능을 PlayerControl에서 Stage로 옮김
5. 문자가 StageClearID보다 작거나 같으면 플레이버튼 활성화, 크면 비활성화
1. 해당 스크립트가 부착된 오브젝트의 6번째 문자를 가져오기 ex) Stage'6' => 6
using UnityEngine; public class StageState : MonoBehaviour { void Start() { char sixthChar = gameObject.name[5]; Debug.Log("6번째 글자: " + sixthChar); } }
2. StageClearID와 비교하여 6번째 문자가 크면 "Big", 같으면 "Same", 작으면 "Small" 출력
public class StageState : MonoBehaviour { private StageGameManager gameManager; void Start() { int stagenum = int.Parse(gameObject.name[5].ToString()); gameManager = StageGameManager.instance; int stageClearID = gameManager.StageClearID; if(stageClearID < stagenum) { Debug.Log("big"); } if (stageClearID == stagenum) { Debug.Log("same"); } if (stageClearID > stagenum) { Debug.Log("small"); } } }
3. 이제 그 문자출력에서 해당 오브젝트의 색상변경으로 기능을 변경
public class StageState : MonoBehaviour { private StageGameManager gameManager; private SpriteRenderer spriteRenderer; void Start() { int stagenum = int.Parse(gameObject.name[5].ToString()); gameManager = StageGameManager.instance; int stageClearID = gameManager.StageClearID; spriteRenderer = GetComponent<SpriteRenderer>(); if (stageClearID < stagenum) { Debug.Log("big"); spriteRenderer.color = new Color32(73, 73, 73, 255); } else if (stageClearID == stagenum) { Debug.Log("same"); spriteRenderer.color = new Color32(255, 61, 61, 255); } else { Debug.Log("small"); spriteRenderer.color = new Color32(69, 155, 255, 255); } } }
4. 플레이 박스를 띄워주는 기능을 PlayerControl에서 Stage로 옮김
using UnityEngine; public class StageState : MonoBehaviour { public GameObject StageStart; public int stagenum; public static int chooseStage; private StageGameManager gameManager; private SpriteRenderer spriteRenderer; void Start() { this.stagenum = int.Parse(gameObject.name[5].ToString()); gameManager = StageGameManager.instance; int stageClearID = gameManager.StageClearID; spriteRenderer = GetComponent<SpriteRenderer>(); if (stageClearID < this.stagenum) { Debug.Log("big"); spriteRenderer.color = new Color32(73, 73, 73, 255); } else if (stageClearID == this.stagenum) { Debug.Log("same"); spriteRenderer.color = new Color32(255, 61, 61, 255); } else { Debug.Log("small"); spriteRenderer.color = new Color32(69, 155, 255, 255); } } private void OnTriggerStay2D(Collider2D collision) { if (collision.gameObject.tag == "StageBall") { StageStart.gameObject.SetActive(true); } chooseStage = stagenum; Debug.Log(chooseStage); FindObjectOfType<ShowStageBox>().UpdateStageInfo(chooseStage); } private void OnTriggerExit2D(Collider2D collision) { if (collision.gameObject.tag == "StageBall") StageStart.gameObject.SetActive(false); } }
using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class StageGoBtn : MonoBehaviour { public Button GoBtn; private void Start() { this.GoBtn.onClick.AddListener(() => { // 씬을 로드하기 전에 chooseStage 값을 저장 GlobalData.SelectedStage = StageState.chooseStage; // 수정!!! SceneManager.LoadScene("Story-InGame"); }); } } public static class GlobalData { public static int SelectedStage; }
추가로 플레이 버튼에 들어갈 StageGoBtn도 수정해줘야 한다
내가 이걸 발견 못해서 하루종일...
5. 문자가 StageClearID보다 작거나 같으면 플레이버튼 활성화, 크면 비활성화
using UnityEngine; public class StageState : MonoBehaviour { public GameObject StageStart; public GameObject StartButton; //통제할 버튼 추가 public int stagenum; public static int chooseStage; private bool isclear; //활성화/비활성화할 조건 추가 private StageGameManager gameManager; private SpriteRenderer spriteRenderer; void Start() { this.stagenum = int.Parse(gameObject.name[5].ToString()); gameManager = StageGameManager.instance; int stageClearID = gameManager.StageClearID; spriteRenderer = GetComponent<SpriteRenderer>(); if (stageClearID < this.stagenum) { isclear = false; // 클리어한 스테이지보다 높은 경우 spriteRenderer.color = new Color32(73, 73, 73, 255); } else if (stageClearID == this.stagenum) { isclear = true; // 나머지는 true spriteRenderer.color = new Color32(255, 61, 61, 255); } else { isclear = true; spriteRenderer.color = new Color32(69, 155, 255, 255); } } private void OnTriggerStay2D(Collider2D collision) { if (collision.gameObject.tag == "StageBall") { StageStart.gameObject.SetActive(true); if(!isclear) { StartButton.gameObject.SetActive(false); // 버튼을 통제할 새로운 조건 추가 } } chooseStage = stagenum; Debug.Log(chooseStage); FindObjectOfType<ShowStageBox>().UpdateStageInfo(chooseStage); } private void OnTriggerExit2D(Collider2D collision) { if (collision.gameObject.tag == "StageBall") StageStart.gameObject.SetActive(false); } }
추가한 내용은 주석에 달아두었다
하...드디어 끝났다.
1. StageGameManager에 식별을 위한 StageClearID 만든뒤 1로 초기화
(StageClearID는 싱글톤으로 씬을 변환해도 그 값이 초기화되지 않음)
2. 모든 스테이지 구체에 StageState 스크립트 제작 후 부착
(* StageState : 본인 스테이지보다 StageClearID가 낮다면 구체가 검정색이 된뒤 플레이버튼 비활성화)
(만약 StageClearID가 높다면 색상을 파란색으로 변경, 같다면 빨간색으로 변경. 이 둘은 플레이버튼 활성화)
3. 플레이어 공에 부착된 플레이 UI 띄우기 기능을 이제 스테이지 구체에 기능 옮겨주기
이 모든게 전부 성공적으로 구현되는것을 확인할 수 있다
이제 남은건 스테이지 클리어 조건과 스테이지 클리어씬을 만들고
하나하나 클리어할때마다 StageClearID에 1씩 더해주기만 하면 된다
그리고 그거까지 마무리 된다면 이제 정말 스테이지만 열심히 Json으로 만들어주기만 하면 된다
'Galaxy Ball > 2. 싱글플레이 - 스토리모드' 카테고리의 다른 글
#오류수정 (2) 2024.06.05 (22) 스테이지 클리어 조건 & 클리어 씬 제작 (2) 2024.06.04 (20) 아이템 오류 해결 & 스테이지 맵 카메라 축소 기능 (0) 2024.06.03 (19) 싱글플레이용 아이템 추가 제작 (0) 2024.06.01 (18) 프롤로그 영상 제작 & 유니티 영상 삽입 & 스테이지 맵 정지 버튼 만들기 (0) 2024.05.31