• 케릭터의 선택 및 게임상의 케릭터를 재할당하여 상태를 변하게 하는 기능의 구현

UGUI 구성

케릭터 선택 버튼 UI

  • 먼저 케릭터를 선택후 선택 된 케릭터를 랜더링할 오브젝트를 생성합니다.
  • 그리고 나서 해당 오브젝트에 Button 컴포넌트를 추가하여 버튼을 눌렀을 때 케릭터 선택 창이 나올 수 있도록 합니다.
  • 그리고 버튼 컴포넌트 위에 케릭터를 표시할 이미지 컴포넌트를 하나 추가 합니다.

  • 버튼 UI의 Sprite를 선택하고 이미지는 별도로 랜더링할 예정이므로 위치만 설정합니다.

  • 해당 이미지에 Sprite만 너으면 아래 그림처럼 표시가 나오게 됩니다.

케릭터 리스트 패널

  • 케릭터 선택 버튼을 눌렀을 때 활성화 될 선택패널을 생성합니다.

  • 해당 패널에는 케릭터의 숫자 만큼 케릭터가 정령되어야 하므로 Grid 또는 Horizontal Layout Group 컴포넌트를 추가 합니다 (여기서는 Grid Layout Group을 사용)
  • 해당 레이아웃에서 표시될 자녀 오브젝트의 사이즈를 맞추고 Padding 값을 조절하여 정렬 합니다.

  • Layout Group을 사용하면 해당 설정에 맞게 오브젝트가 추가 될 때마다 알아서 정렬을 해줍니다.

선택 실행 버튼 Script (LoginPanel)

  • 이제 해당 오브젝트를 실행 시킬 Script를 작성합니다.
#region Selected Button Variables  
[SerializeField] private Button characterSelectBtn; // 케릭터 선택 패널 실행 버튼 오브젝트  
[SerializeField] private Image characterSelectPanel; // 케릭터 선택 패널 오브젝트  
[SerializeField] private Image characterThumbnail; // 케릭터 선택 버튼 위에 보여줄 케릭터 이미지  
#endregion

#region Initialize Default Value  
/// <summary>  
/// LoginPanel 초기화 메서드  
/// 인풋 필드 및 로그인 화면 케릭터 기본 값 세팅  
/// </summary>  
private void Start()  
{  
	InitializedInPutField(); // 인풋 필드 초기화  
	InitializedDefaultCharacter(); // 케릭터 세팅 초기화 (FROG)  
  
	// 케릭터가 선택 되면 해당 케릭터 Sprite를 바꿔주는 이벤트  
	GameManager.Instance.OnCharacterThumbnailChanged += CharacterSelectPanelClose;  
}  
#endregion

#region Character Select Method Group  
private void InitializedDefaultCharacter()  
{  
	// 케릭터 선택 버튼을 클릭하면 케릭터 선택 패널이 열리도록 이벤트 구독  
	characterSelectBtn.onClick.AddListener(CharacterSelectPanelOpen);  
	// 케릭터 기본 이미지 설정  
	characterThumbnail.sprite = GameManager.Instance.CharacterThumbnail;  
}  
  
/// <summary>  
/// 케릭터 선택 패널 오픈 메서드  
/// </summary>  
private void CharacterSelectPanelOpen()  
{  
	// 케릭터 선택 패널 오브젝트 활성화  
	characterSelectPanel.gameObject.SetActive(true);  
}  
  
/// <summary>  
/// 선택된 케릭터 Sprite를 받아 선택된 케릭터를 랜더링 후 케릭터 선택 패널 비활성화  
/// </summary>  
/// <param name="sprite">선택한 케릭터 Sprite</param>  
private void CharacterSelectPanelClose(Sprite sprite)  
{  
	characterThumbnail.sprite = sprite; // 케릭터 이미지 교체  
	characterSelectPanel.gameObject.SetActive(false); // 케릭터 선택화면 비활성화  
}  
#endregion
  • 버튼 타입의 경우 onClick AddListner 이벤트를 사용하여 클릭시 작동할 이벤트를 구성합니다.
  • 추가적으로 GameManager에서 Thumbnail이 바뀔 때 마다 이벤트로 Login Panel의 Thumbnail 을 바꿔 줍니다.

케릭터 선택 Script (CharacterCard)

  • 케릭터선택 패널이 실행되면 케릭터의 수만큼 케릭터를 선택 패널에 랜더링할 기능을 구현
  • 필요한 케릭터의 정보
    • 케릭터의 타입 (선택된 케릭터 구분용)
    • 케릭터의 선택 후 보여질 기본 이미지
    • 인게임에서 적용될 Animator Controller
  • 기본적으로 아무것도 선택되지 않은 기본값을 설정할 수 있어야 합니다. 그렇지 않으면 케릭터 창이 빈 값으로 나오기 때문입니다.
  • 케릭터 정보를 받아서 이것을 인스턴스화 하여 랜더링한 Instantiate 기능

케릭터 정보 세팅

  • 직렬화 된 케릭터 정보를 클래스로 만들어 해당 객체를 리스트로 관리
#region Character InformationList  
/// <summary>  
/// Character Class 로 케릭터의 타입(enum), 이미지 (Sprite), 인게임에서 사용할 컨트롤러(AnimatorController) 설정,  
/// 인스펙터 상에서 characters 리스트 형태로 할당하여 정보를 저장  
/// </summary>  
[Serializable] public class Character  
{  
	public enum CharacterTypes { FROG, PINKYMAN } // 케릭터의 유니크 타입 목록  
	public CharacterTypes characterType; // 케릭터의 유니크 타입값  
	public Sprite characterImage; // 케릭터의 기본 Sprite  
	public AnimatorController animator; // 인게임에서 사용할 케릭터 컨트롤러  
}  
  
[SerializeField] private List<Character> characters; // Character Class를 리스트 형태로 관리  
#endregion

인스턴스화 할 케릭터 프리팹

  • 인스턴스화 할 프리팹 및 인스턴스화 될 부모 오브젝트의 Transform 변수
#region Character Select Variables  
[SerializeField] private Transform selectPanelTransform; // 케릭터 카드를 랜더링할 부모 오브젝트의 위치  
[SerializeField] private SelectCard selectCardPrefab; // 인스턴스화 할 케릭터 프리팹  
#endregion

초기화

  • 케릭터의 기본 값을 세팅
  • 케릭터 선택창에 랜더링 프리팹 인스턴스화
#region Default Character Initilaze  
/// <summary>  
/// 기본 InputField 화면의 기본 케릭터 설정  
/// </summary>  
private void Start()  
{  
	Character defaultCharacter = characters[0];  
	GameManager.Instance.CharacterController = defaultCharacter.animator; // 기본 케릭터 Controller GameManager로 할당  
	GameManager.Instance.CharacterType = defaultCharacter.characterType; // 기본 케릭터 타입 GameManager로 할당  
	GameManager.Instance.CharacterThumbnail = defaultCharacter.characterImage; // 기본 케릭터 이미지 GameManager 할당  
	InstantiateSelectCard(); // 선택화면의 케릭터 오브젝트를 인스턴스화  
}  
  
private void InstantiateSelectCard()  
{  
	foreach (var character in characters)  
	{  
		SelectCard cardInstance = Instantiate(selectCardPrefab, selectPanelTransform);  
		cardInstance.CharacterType = character.characterType;  
		cardInstance.CharacterSprite = character.characterImage;  
		cardInstance.Controller = character.animator;  
	}  
}  
#endregion

GameManager

  • GameManger는 Singleton으로 인스턴스를 만들고 전역으로 접근 가능하도록 합니다.
  • 각 변수는 케릭터의 정보를 담으며, 변수가 변경 되면 해당 이벤트를 발생시켜 Callback으로 해당 데이터를 넘겨 줍니다.

Singleton

  • GameManager는 오직 하나만 존재하므로 Singleton으로 정적으로 접근 가능하도록 합니다.
#region Singleton to GameManager  
public static GameManager Instance { get; private set; }  
  
/// <summary>  
/// GameManager 싱글턴 인스턴스 화  
/// </summary>  
private void Awake()  
{  
	if (Instance == null)  
	{  
		Instance = this;  
	}  
	else  
	{  
		Destroy(gameObject);  
	}  
	DontDestroyOnLoad(gameObject);  
}  
#endregion

케릭터 정보 및 프로퍼티 이벤트 Invoke

  • 이벤트의 경우 프로퍼티를 사용하여 설정 시에 자동적으로 해당 이벤트를 실행할 수 있도록 Set을 합니다.
#region Character Information Variable  
private Sprite _characterThumbnail; // 이미지 변수  
public event Action<Sprite> OnCharacterThumbnailChanged; // 이미지 변경 이벤트  
private AnimatorController _characterController; // 컨트롤러  
public event Action<AnimatorController> OnCharacterControllerChanged; // 컨트롤러 변경 이벤트  
public CharacterTypes CharacterType { get; set; } // 케릭터 타입  
#endregion  
  
#region Changed Character Information Event Method  
/// <summary>  
/// Thumbnail 변경시 이벤트 변경  
/// </summary>  
public Sprite CharacterThumbnail // 케릭터 선택 패널에서 보여 줄 케릭터 스프라이트  
{  
	get => _characterThumbnail;  
	set  
	{  
		_characterThumbnail = value;  
		OnCharacterThumbnailChanged?.Invoke(_characterThumbnail);  
	}  
}  
  
/// <summary>  
/// Controller 변경 시 이벤트 변경  
/// </summary>  
public AnimatorController CharacterController  
{  
	get => _characterController;  
	set  
	{  
		_characterController = value;  
		OnCharacterControllerChanged?.Invoke(_characterController);
	}  
}  
#endregion

Select Card

  • 선택창에 인스턴스화 되어 Group Layout 에 생성되는 카드 인스턴스 입니다.
  • 해당 스크립트는 SelectCard 프리팹에 컴포넌트 할당합니다.
  • 케릭터의 버튼을 선택하면 해당 인스턴스에 할당 된 정보를 GameManager 에 할당하여 변경 합니다.

#region Character Card Variables  
// 해당 케릭터가 인스턴화 될 때 설정되는 케릭터 정보  
public CharacterTypes CharacterType { get; set; }  
public Sprite CharacterSprite { get; set; }  
public AnimatorController Controller { get; set; }  
#endregion  
  
#region Object Variables  
private Button _selectBtn;  
private Image _characterImage;  
#endregion  
  
#region Initliaze Component  
/// <summary>  
/// 각 컴포넌트 및 이벤트 초기화  
/// </summary>  
private void Awake()  
{  
	_selectBtn = GetComponent<Button>(); // 버튼 컴포넌트 할당  
	_selectBtn.onClick.AddListener(Selected); // 버튼 클릭 이벤트 준비 (Callback => Selected)  
	_characterImage = GetComponent<Image>(); // 케릭터 컴포넌트 할당  
}  
  
/// <summary>  
/// 기본 인스턴스의 케릭터 이미지 세팅  
/// </summary>  
private void Start()  
{  
	_characterImage.sprite = CharacterSprite;  
}  
#endregion  
  
#region Callback Event  
/// <summary>  
/// 버튼 클릭 이벤트 발생시 Callback으로 실행되는 메서드  
/// GameManager에 해당 케릭터 정보를 전달 합니다.  
/// </summary>  
private void Selected()  
{  
	GameManager.Instance.CharacterType = CharacterType;  
	GameManager.Instance.CharacterController = Controller;  
	GameManager.Instance.CharacterThumbnail = CharacterSprite;  
}  
#endregion