ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (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 타입으로 가져와 이용하여 턴을 넘기려고 했었다

     

     

    (10.5) - 버그 개선

    위 영상을 보면 구체가 정지하여 고정되기 전에 추가로 firezone에서 마우스를 더 클릭하면 계속해서 힘을 받아 이동하는것을 볼수가 있다. 이렇게 된다면 계속 클릭을 멈추지 않는다는 전제하에

    sangeun00.tistory.com

     

    근데 턴제 시스템을 만드는 동시에 버그 하나를 개선하게 되었는데 이걸 고치면서 방향을 틀게 되었다

    구체가 고정되어야 턴 종료를 하고 넘기는것이 아닌, 구체를 날리기만 하면 곧바로 상대가 구체를 날릴수 있는것이다

     

    만약 날린 구체가 무조건 고정되어야만 턴을 넘길수 있다고 가정하자

     

    상대가 공 하나 날림 -> 정지&고정 -> 내가 공 하나 날림 -> 정지&고정

     

    선택권없이 무조건 공을 날리는 각도가 중요해지는 두뇌싸움이 될것이다.

    하지만 고정되지 않아도 바로 턴이 넘어간다고 가정해보자

     

    상대가 공 하나 날림 -> 정지&고정을 기다렸다가 상황을 보고 날리기

                                     -> 정지&고정이 되기전에 그 공을 재빨리 받아쳐버리기

     

    즉, 선택지가 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
Designed by Tistory.