-
(11) 턴제 시스템Galaxy Ball/1. 멀티플레이 - 대전모드 2024. 3. 28. 17:24
이제 정말 완성에 가까워져가고 있다. 이제 남은게 턴 변경과 아이템뿐이니
사실상 초반 구상에 없었던 아이템을 제외하고 턴변경만 구현하고 나면 게임완성이나 다름없다
이것도 한번에 끝날 단계가 아니니 한번 단계를 나누어 구현해보도록 하자
1. P2 firezone에서 P2ballPrefab도 발사되게 하기
2. 각 턴에 하나의 구체만 발사 할수 있다
3. Player1이 하나의 구체를 발사하고, 팽창하고, 구체가 고정되는 순간 턴 종료
4. 턴 종료가 되어야지만 Player2가 구체를 발사할 수 있다
5. 해당 턴 Player의 Firezone만 활성화
가장 기본적인 1번부터 시작해보자
우선 구체를 생성하고 발사를 구현하는 스크립트는 GameManager에 있고
거기서 P2firezone과 P2ballPrefab을 추가해주기만 하면된다
public class GameManager : MonoBehaviour { public GameObject P1ballPrefab; public GameObject P2ballPrefab; public GameObject P1firezone; //추가1 public GameObject P2firezone; //추가2 private Vector3 clickPosition; private bool isDragging = false; // 전역 변수 선언 public static float shotDistance; public static Vector3 shotDirection; void Update() { if (Input.GetMouseButtonDown(0)) { clickPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); clickPosition.z = 0f; Collider2D[] colliders = Physics2D.OverlapPointAll(clickPosition); foreach (Collider2D collider in colliders) { if (collider.gameObject == P1firezone) { Instantiate(P1ballPrefab, clickPosition, Quaternion.identity); isDragging = true; break; } //추가3 if (collider.gameObject == P2firezone) { Instantiate(P2ballPrefab, clickPosition, Quaternion.identity); isDragging = true; break; } } }
전역 변수에 P2firezone과 P2ballPrefab 선언뒤 똑같은 if문도 복붙하여 넣어준다
그리고 GameManager안에 올바르게 집어넣기만 하면 끝
이제 P2firezone에서도 공이 발사되고, P2firezone에서 발사된 공의 태그는 P2ball임을 확인할 수 있다
2. 각 턴에 하나의 구체만 발사 할수 있다
3. Player1이 하나의 구체를 발사하고, 팽창하고, 구체가 고정되는 순간 턴 종료
4. 턴 종료가 되어야지만 Player2가 구체를 발사할 수 있다
턴제 시스템의 핵심인 2,3,4번은 사실상 하나의 세트로 봐도 무방하기 때문에 하나씩 할게 아니라
전체적으로 다같이 하는게 좋아보인다
지금 생각난건 bool 타입으로 P1FireMode, P2FireMode를 선언해준뒤 이게 true일때만 구체를 하나씩 발사하게 하고
곧바로 false로 변경되며, P1FireMode가 false가 되면 자연스럽게 P2FireMode를 true로 만들어 구체를 발사하게 하는거다
true에서 false가 되는 기준은 3번처럼 발사,팽창,고정 이 3단계가 완벽하게 끝나야 바뀌는걸로 조건을 잡는것이다
한번 해보자. 우선 FireMode라는 변수 자체가 들어가고, 턴제 시스템이 구현될 스크립트는 아무래도
구체의 발사를 담당하고 있는 GameManager가 맞지 않을까 싶다
public class GameManager : MonoBehaviour { public GameObject P1ballPrefab; public GameObject P2ballPrefab; public GameObject P1firezone; public GameObject P2firezone; private Vector3 clickPosition; private bool isDragging = false; public static float shotDistance; public static Vector3 shotDirection; private bool P1FireMode = true; private bool P2FireMode = false;
우선 전역변수에 각자의 FireMode를 추가해준다 Player1이 무조건 선공이기에 초깃값을 P1에게 true를 부여해준다
if (Input.GetMouseButtonDown(0)) { clickPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); clickPosition.z = 0f; Collider2D[] colliders = Physics2D.OverlapPointAll(clickPosition); foreach (Collider2D collider in colliders) { if (P1FireMode && collider.gameObject == P1firezone) { Instantiate(P1ballPrefab, clickPosition, Quaternion.identity); P1FireMode = false; P2FireMode = true; isDragging = true; break; } if (P2FireMode && collider.gameObject == P2firezone) { Instantiate(P2ballPrefab, clickPosition, Quaternion.identity); P1FireMode = true; // P2FireMode가 활성화된 후에 P1FireMode를 재활성화 P2FireMode = false; isDragging = true; break; } } }
구체가 발사되는 조건에 각자의 FireMode가 true일때만 발사된다는 조건을 걸어두고
구체의 발사가 끝나면 서로의 FireMode를 변경해준다
2. 각 턴에 하나의 구체만 발사 할수 있다
3. Player1이 하나의 구체를 발사하고, 팽창하고, 구체가 고정되는 순간 턴 종료
4. 턴 종료가 되어야지만 Player2가 구체를 발사할 수 있다
이로써 2,4번이 동시에 마무리되었다. 하지만 구체가 고정되는 순간 턴 종료가 이루어져야 하지만 구체가 생성되는 즉시
P2FireMode가 true가 되기 때문에 턴제는 턴제인데 뭔가 어설픈 턴제가 되어버렸다
원래는 "구체가 고정(rigid 파괴)되는 순간 턴을 넘긴다" 가 예정이었지만 방금 생각이 든게
"본인의 턴에만 firezone 활성화/비활성화"가 더 자연스럽고 낫지 않을까라는 생각이 들었다
public class GameManager : MonoBehaviour { public GameObject P1ballPrefab; public GameObject P2ballPrefab; public GameObject P1firezone; public GameObject P2firezone; private Vector3 clickPosition; public bool isDragging = false; public static float shotDistance; public static Vector3 shotDirection; private bool P1FireMode = true; private bool P2FireMode = false; // 시작은 둘다 활성화한채로 시작 private void Start() { P1firezone.gameObject.SetActive(true); P2firezone.gameObject.SetActive(true); }
우선 맨 처음 게임을 시작할때에는 둘다 firezone을 활성화시켜주었다.
물론 Player1이 성공이기에 P2firezone을 클릭해도 아무런 변화가 일어나지 않게 했다
private void Update() { if (Input.GetMouseButtonDown(0)) { clickPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); clickPosition.z = 0f; Collider2D[] colliders = Physics2D.OverlapPointAll(clickPosition); foreach (Collider2D collider in colliders) { if (P1FireMode && collider.gameObject == P1firezone) { Instantiate(P1ballPrefab, clickPosition, Quaternion.identity); P1FireMode = false; P2FireMode = true; isDragging = true; // 클릭을 누르는 순간 본인 firezone은 비활성화 P1firezone.gameObject.SetActive(false); P2firezone.gameObject.SetActive(true); break; } if (P2FireMode && collider.gameObject == P2firezone) { Instantiate(P2ballPrefab, clickPosition, Quaternion.identity); P1FireMode = true; P2FireMode = false; isDragging = true; // 이곳 역시 반대로 변환 P1firezone.gameObject.SetActive(true); P2firezone.gameObject.SetActive(false); break; } } }
먼저 선공인 P1firezone에 클릭을 하는순간 구체가 생성되며 P1firezone은 비활성화됨과 동시에
P2firezone이 활성화 된다. 반대의 상황도 마찬가지이다
턴제 시스템 느낌도 확실히 나면서 꽤나 그럴싸해졌다. 원래 예정대로라면 위에 적은대로
3. Player1이 하나의 구체를 발사하고, 팽창하고, 구체가 고정되는 순간 턴 종료
구체가 고정되는 순간 턴 종료이기 때문에, BallController 스크립트에 있는 rigid가 파괴되었냐에 대한
유무 데이터를 bool 타입으로 가져와 이용하여 턴을 넘기려고 했었다
근데 턴제 시스템을 만드는 동시에 버그 하나를 개선하게 되었는데 이걸 고치면서 방향을 틀게 되었다
구체가 고정되어야 턴 종료를 하고 넘기는것이 아닌, 구체를 날리기만 하면 곧바로 상대가 구체를 날릴수 있는것이다
만약 날린 구체가 무조건 고정되어야만 턴을 넘길수 있다고 가정하자
상대가 공 하나 날림 -> 정지&고정 -> 내가 공 하나 날림 -> 정지&고정
선택권없이 무조건 공을 날리는 각도가 중요해지는 두뇌싸움이 될것이다.
하지만 고정되지 않아도 바로 턴이 넘어간다고 가정해보자
상대가 공 하나 날림 -> 정지&고정을 기다렸다가 상황을 보고 날리기
-> 정지&고정이 되기전에 그 공을 재빨리 받아쳐버리기
즉, 선택지가 2개가 되어 두뇌 싸움, 피지컬 싸움 둘다 가능해지는것이다
이제 이런식으로 피지컬로 날아오는 공을 쳐내며 다이나믹한 플레이도 가능해진다는 것이다
'Galaxy Ball > 1. 멀티플레이 - 대전모드' 카테고리의 다른 글
(12) Start Scene #배경화면 (2) 2024.03.29 (11.5) 버그 개선 #3 (0) 2024.03.29 (10.5) - 버그 개선#2 (0) 2024.03.28 (10) BGM & Sound Effect (2) 2024.03.28 (9) 버그 개선#1 (0) 2024.03.27