본문 바로가기
Unity

2024/04/17~ 포켓몬 게임 구현하기

by 민정e 2024. 4. 17.

스크립트 작성

간단한 포켓몬 배틀을 스크립트로 구현해 볼 것이다.

스크립트는 다음과 같이 작성하였다.

// <------------------------------2024-04-18 작성 ------------------------------>


using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEditor.UI;
using UnityEngine.UIElements;
using Unity.VisualScripting;

public class Test1 : MonoBehaviour
{
    // UI
    public TextMeshProUGUI dialog; // 메세지가 나올 부분
    public TextMeshProUGUI currentHp; // 포켓몬의 현재 체력
    public TextMeshProUGUI maxHP; // 포켓몬의 최대체력
    public TextMeshProUGUI slash; // 체력사이의 슬래쉬
    public TextMeshProUGUI pokemonName; // 포켓몬의 이름
    public TextMeshProUGUI pokemonLevel; // 포켓몬의 레벨

    // 트레이너 정보
    string trainerName = "안나";

    // 아이템 정보
    string[] allItems = { "상처약", "만병통치약" };

    // 내 포켓몬 정보
    string[] myPK = new string[3] { "피카츄", "파이리", "롱스턴"};
    int[] PKLevel = { 1, 2, 3 };
    bool[] isAlive = { true, true, true };

    float[] curHp = { 30, 40, 50 };
    float[] mHP = { 30, 40, 50 };
    float[] skillDamage = { 2.5f, 3.0f, 3.5f };
    List<string> Skill = new List<string>();

    // 메세지 번호
    int messageNumber;

    // 메세지간의 시간차이
    float timer = 2f;

    // 표시될 메세지 리스트
    List<string>dialogList = new List<string>();



    // Start is called before the first frame update
    void Start()
    {
        // 포켓몬의 스킬을 리스트에 추가해준다.
        Skill.Add("전광석화");
        Skill.Add("불꽃세례");
        Skill.Add("바위치기");
        
        // 표시될 메세지를 리스트에 추가해준다.
        DialogData();
        
        // 시작 메세지
        dialog.text = $"{trainerName}이/가 {myPK[1]}와 배틀을 시작했다!!!");

    }

    //포켓몬 선택
    void SelectPK(int a, int b, float c)
    {
        switch (myPK[a])
        {
            case "피카츄":
                dialog.text = "가라, 피카츄!";
                break;
            case "파이리":
                dialog.text = "가라, 파이리!";
                break;
            case "롱스톤":
                dialog.text = "가라, 롱스톤!";
                break;
            default:
                Debug.Log($"레벨 : {b} HP : {c}");
                break;

        }
    }

    // Update is called once per frame
    void Update()
    {
        Timer();
        Dialog(messageNumber);
        if (messageNumber == 1) // 가랏, ㅇㅇㅇ 메세지가 나올때 ㅇㅇㅇ의 정보가 같이 표시되도록 설정
        {
            slash.text = "/";
            pokemonLevel.text = $"Lv . {PKLevel[0]}"; 
            pokemonName.text = $"{myPK[0]}"; 
            currentHp.text = $"{curHp[0]}"; 
            maxHP.text = $"{mHP[0]}";
        }
    }

    // 메세지 간 시간차이를 주기 위해 만든 타이머
    void Timer()
    {
        if (timer > 0) // 2초가 지나지 않았을 때,
        {
            timer = timer - Time.deltaTime; // 시간이 흘러가도록 설정
        }

        else // 시간이 다 지나가면,
        {
            timer = 2f; // 타이머 시간을 다시 2초로 설정해준다.
            Dialog(messageNumber); // 메세지가 표시된다
            messageNumber++; // 메세지의 번호를 1 추가해준다.
        }
    }

    // 메세지를 표시하는 기능
    void Dialog(int story)
    {
        dialog.text = dialogList[story];
    }

    // 메세지 리스트에 메세지들을 저장하는 함수.
    void DialogData()
    {
        dialogList.Add($"가랏, {myPK[0]}!!!");
        dialogList.Add($"{myPK[0]}의 {Skill[0]}!!!");
        dialogList.Add($"{myPK[1]}가 {skillDamage[0]}의 데미지를 입었다!!!");
        dialogList.Add($"{myPK[1]}의 HP : {curHp[1]}");
        dialogList.Add($"{myPK[1]}의 {Skill[1]}!!!");
        dialogList.Add($"{myPK[0]}가 {skillDamage[1]}의 데미지를 입었다!!!");
        dialogList.Add($"{myPK[0]}의 HP : {curHp[0]}");
        dialogList.Add($"{trainerName}이/가 {myPK[0]}에게 {allItems[0]}을 사용했다!!!");
        dialogList.Add($"{myPK[0]}의 체력을 {10f}회복했다!!!");
        dialogList.Add($"{myPK[0]}의 HP : {curHp[0]}");
    }
}

 

 

UI

UI는 간단히 다음과 같이 만들었다. (자세한 내용은 생략)

 

한글폰트 적용하기

 

Assets > Text Mesh Pro > Resources > Fonts & Materials 에 원하는 폰트를 가지고 온다.

이후, window > TextMeshPro > Font Asset Creator에 들어간다.

Source Font File에 폰트파일을 드래그해서 넣어주고, Atlas Reolution을 4096 4096으로 설정, Character Sequence에  다음과 같이 적어준다.

 => 32-126,44032-55203,12593-12643,8200-9900 (한글 유니코드)

그 다음, Generate Font Atlas를 눌러주고, Save버튼을 눌러 저장을 해주면 된다. 이후 Text에 폰트를 적용시켜주면 한글이 잘 나오는 것을 알 수 있다.

결과물

슬라이더

Slider는 다음과 같이 구성되어있다.

Background, Fill Area, Handle Slide Area.

Background는 말 그대로 기본 바탕을 말을하고, Fill Area는 채워지는 부분, Handle Slide Area는 슬라이드할수있는 핸들을 뜻한다.

※주의※ Slider의 Handle을 절대 건드리지 말아라. 건드렸다 ctrl + z를 하면 핸들이 사라지는 버그가 있다.

 

 

 

 

채팅창처럼 앞의 내용을 남겨두고 아래에 문자열을 추가하고싶다면 다음과 같이 코드를 작성하면 된다.

 

 

클릭을 했을 때 메세지가 나오도록 스크립트 변경

진짜 포켓몬 게임처럼, 메세지가 나오는 박스를 클릭을 했을 때, 다음 메세지가 나오도록 해줄 것이다.

코드는 다음과 같이 변경해주었다. 타이머를 아예 삭제를 하고, 업데이트 문의 내용도 삭제해 주었다.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEditor.UI;
using UnityEngine.UIElements;
using Unity.VisualScripting;

public class Test1 : MonoBehaviour
{
    // UI
    public TextMeshProUGUI dialog; // 메세지가 나올 부분
    public TextMeshProUGUI currentHp; // 포켓몬의 현재 체력
    public TextMeshProUGUI maxHP; // 포켓몬의 최대체력
    public TextMeshProUGUI slash; // 체력사이의 슬래쉬
    public TextMeshProUGUI pokemonName; // 포켓몬의 이름
    public TextMeshProUGUI pokemonLevel; // 포켓몬의 레벨

    // 트레이너 정보
    string trainerName = "안나";

    // 아이템 정보
    string[] allItems = { "상처약", "만병통치약" };

    // 내 포켓몬 정보
    string[] myPK = new string[3] { "피카츄", "파이리", "롱스턴"};
    int[] PKLevel = { 1, 2, 3 };
    bool[] isAlive = { true, true, true };

    float[] curHp = { 30, 40, 50 };
    float[] mHP = { 30, 40, 50 };
    float[] skillDamage = { 2.5f, 3.0f, 3.5f };
    List<string> Skill = new List<string>();

    // 메세지 번호
    int messageNumber;

    // 메세지간의 시간차이
    float timer = 2f;

    // 표시될 메세지 리스트
    List<string>dialogList = new List<string>();



    // Start is called before the first frame update
    void Start()
    {
        // 포켓몬의 스킬을 리스트에 추가해준다.
        Skill.Add("전광석화");
        Skill.Add("불꽃세례");
        Skill.Add("바위치기");
        
        // 표시될 메세지를 리스트에 추가해준다.
        DialogData();

        dialog.text = $"{trainerName}이/가 {myPK[1]}와 배틀을 시작했다!!!"; // 시작 메세지

    }

    //포켓몬 선택
    void SelectPK(int a, int b, float c)
    {
        switch (myPK[a])
        {
            case "피카츄":
                dialog.text = "가라, 피카츄!";
                break;
            case "파이리":
                dialog.text = "가라, 파이리!";
                break;
            case "롱스톤":
                dialog.text = "가라, 롱스톤!";
                break;
            default:
                Debug.Log($"레벨 : {b} HP : {c}");
                break;

        }
    }

    // Update is called once per frame
    void Update()
    {

    }


    // 메세지를 표시하는 기능
    public void Message()
    {
        dialog.text = dialogList[messageNumber];
        messageNumber++;
    }

    // 메세지 리스트에 메세지들을 저장하는 함수.
    void DialogData()
    {
        dialogList.Add($"가랏, {myPK[0]}!!!");
        dialogList.Add($"{myPK[0]}의 {Skill[0]}!!!");
        dialogList.Add($"{myPK[1]}가 {skillDamage[0]}의 데미지를 입었다!!!");
        dialogList.Add($"{myPK[1]}의 HP : {curHp[1]}");
        dialogList.Add($"{myPK[1]}의 {Skill[1]}!!!");
        dialogList.Add($"{myPK[0]}가 {skillDamage[1]}의 데미지를 입었다!!!");
        dialogList.Add($"{myPK[0]}의 HP : {curHp[0]}");
        dialogList.Add($"{trainerName}이/가 {myPK[0]}에게 {allItems[0]}을 사용했다!!!");
        dialogList.Add($"{myPK[0]}의 체력을 {10f}회복했다!!!");
        dialogList.Add($"{myPK[0]}의 HP : {curHp[0]}");
    }

 

 

textbox를 선택하고, On Click 에 +를 해준 다음, 스크립트를 넣어준 GameObject를 넣어준다. 이후 Function을 Text1의 Message로 설정해준다.

 

 

다음과 같이 잘 작동하는 것을 볼 수 있다.