TIL
[멋쟁이사자처럼 부트캠프 TIL 회고] 유니티 게임개발 3기 47일차 TICTACTOE제작3
HYttt
2025. 2. 5. 17:40
TICTACTOE 제작
블록의 색상 변경
- 같은 모양 3개가 완성된 줄에 색상표시하기
- 블록의 색상을 변경하는 함수는 Block 클래스에 있음
- BlockController는 GameManager로부터 플레이어 타입과 완성된 줄의 인덱스 튜플 배열을 받아 O 승리 이면 파란색, X 승리 이면 빨간색으로 변경
using System;
using UnityEngine;
[RequireComponent(typeof(SpriteRenderer))]
public class Block : MonoBehaviour
{
[SerializeField] private Sprite oSprite;
[SerializeField] private Sprite xSprite;
[SerializeField] private SpriteRenderer markerSpriteRenderer;
public enum MarkerType{None, O, X}
public delegate void OnBlockClicked(int index);
private OnBlockClicked _onBlockClicked;
private int _blockIndex;
private SpriteRenderer _spriteRenderer;
private Color _defaultColor;
private void Awake()
{
_spriteRenderer = GetComponent<SpriteRenderer>();
_defaultColor = _spriteRenderer.color;
}
/// <summary>
/// 블럭의 색상을 변경하는 함수
/// </summary>
/// <param name="color">색상</param>
public void SetColor(Color color)
{
_spriteRenderer.color = color;
}
public void InitMarker(int blockIndex, OnBlockClicked onBlockClicked)
{
_blockIndex = blockIndex;
SetMarker(MarkerType.None);
this._onBlockClicked = onBlockClicked;
SetColor(_defaultColor);
}
public void SetMarker(MarkerType markerType)
{
// 생략
}
private void OnMouseUpAsButton()
{
_onBlockClicked?.Invoke(_blockIndex);
}
}
using UnityEngine;
public class BlockController : MonoBehaviour
{
[SerializeField] private Block[] blocks;
public delegate void OnBlockClickedDelegate(int row, int col);
public OnBlockClickedDelegate onBlockClickedDelegate;
public void InitBlocks()
{
for (int i = 0; i < blocks.Length; i++)
{
blocks[i].InitMarker(i, blockIndex =>
{
var clickedRow = blockIndex / 3;
var clickedCol = blockIndex % 3;
onBlockClickedDelegate?.Invoke(clickedRow, clickedCol);
});
}
}
public void PlaceMarker(Block.MarkerType markerType, int row, int col)
{
// row, col를 index로 변환
var markerIndex = row * 3 + col;
// Block에게 마커 표시
blocks[markerIndex].SetMarker(markerType);
}
public void SetBlockColor(GameManager.PlayerType playerType, (int row, int col)[] blockPositions)
{
if(playerType == GameManager.PlayerType.None) return;
foreach (var blockPosition in blockPositions)
{
var blockIndex = blockPosition.row * 3 + blockPosition.col;
Color markerColor;
if(playerType == GameManager.PlayerType.PlayerA)
markerColor = new Color32(0, 166, 255, 255);
else if (playerType == GameManager.PlayerType.PlayerB)
{
markerColor = new Color32(255, 0, 94, 255);
}
else
{
markerColor = Color.black;
}
blocks[blockIndex].SetColor(markerColor);
}
}
}
플레이어의 턴을 표시하는 UI
- 현재 차례의 플레이어의 마커가 더 밝게 표시되도록 구현
- Canvas Group의 Alpha값을 조절
- 게임이 종료되면 게임종료 버튼 표시
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameUIController : MonoBehaviour
{
[SerializeField] private CanvasGroup canvasGroupA;
[SerializeField] private CanvasGroup canvasGroupB;
[SerializeField] private Button gameOverButton;
public enum GameUIMode
{
Init,
TurnA,
TurnB,
GameOver
}
private const float DisableAlpha = 0.5f;
private const float EnableAlpha = 1f;
public void SetGameUIMode(GameUIMode mode)
{
switch (mode)
{
case GameUIMode.Init:
canvasGroupA.gameObject.SetActive(true);
canvasGroupB.gameObject.SetActive(true);
gameOverButton.gameObject.SetActive(false);
canvasGroupA.alpha = DisableAlpha;
canvasGroupB.alpha = DisableAlpha;
break;
case GameUIMode.TurnA:
canvasGroupA.gameObject.SetActive(true);
canvasGroupB.gameObject.SetActive(true);
gameOverButton.gameObject.SetActive(false);
canvasGroupA.alpha = EnableAlpha;
canvasGroupB.alpha = DisableAlpha;
break;
case GameUIMode.TurnB:
canvasGroupA.gameObject.SetActive(true);
canvasGroupB.gameObject.SetActive(true);
gameOverButton.gameObject.SetActive(false);
canvasGroupA.alpha = DisableAlpha;
canvasGroupB.alpha = EnableAlpha;
break;
case GameUIMode.GameOver:
canvasGroupA.gameObject.SetActive(false);
canvasGroupB.gameObject.SetActive(false);
gameOverButton.gameObject.SetActive(true);
break;
}
}
public void OnClickGameOverButton()
{
// TODO : 구현해야 함..
}
}
Main Scene 분리
- Main Scene 과 Game Scene을 분리
- 플레이 버튼 클릭시 GameScene 로드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainPanelController : MonoBehaviour
{
public void OnClickSinglePlayButton()
{
SceneManager.LoadScene("GameScene");
}
public void OnClickDualPlayButton()
{
SceneManager.LoadScene("GameScene");
}
public void OnClickSettingsButton()
{
}
}