김조성준 2024. 9. 9. 23:54

1. Link


깃허브 링크 : https://github.com/kimchosungjun/MyProject_PlatformerGame.git

플레이 영상 : https://youtu.be/x59CBxRP5gE

 

 

2. 구현한 기능


1) 음향 조절 기능

아래는 구현한 Audio Mixer를 이용하여 구현한 음향 조절 기능입니다. 

사운드의 종류마다 다르게 조절이 가능하게 만들었습니다. 오디오 아이콘을 누르면 음소거를 시킬 수 있습니다.

 

2) Video Player를 이용한 튜토리얼 기능 구현

 

아래는 구현한 Video Player를 이용하여 구현한 튜토리얼입니다.  

영상 자료를 활용하여 게임에 대한 이해를 쉽게 할 수 있도록 도왔습니다.

 

3) FSM을 이용한 플레이어 조작

 

 플레이어의 상태들을 정의하고 상태가 변화했음을 알려주고 현재 상태의 행동을 유지하는 StateMachine을 사용하여

플레이어의 조작을 구현했습니다.

 

아래는 정의된 상태머신을 사용한 코드의 예시 입니다.

    public override void Init(PlayerController _playerController) // = Awake
    {
        if (soundPlayer == null)
            soundPlayer = GetComponentInChildren<SFXSoundPlayer>();
        controller = _playerController;
        stateMachine = new PlayerStateMachine();
        playerStates = new PlayerState[(int)PlayerActionType.Roll + 1];
        playerStates[(int)PlayerActionType.Idle] = new NormalIdle(this);
        playerStates[(int)PlayerActionType.Move] = new NormalMove(this);
        playerStates[(int)PlayerActionType.Jump] = new NormalJump(this);
        playerStates[(int)PlayerActionType.Fall] = new NormalFall(this);
        playerStates[(int)PlayerActionType.Roll] = new NormalRoll(this);
        attackTransform = controller.AttackTransform;
        stateMachine.ChangeState(playerStates[(int)currentActionType]);
    }

    public override void Execute() // = Update
    {
        if (canControll)
        {
            stateMachine.Execute();
            Flip();
            Attack();
            BuffSkill();
            AttackSkill();
        }
        else
        {
            horizontal = 0;
            rigid.velocity = new Vector2(0, rigid.velocity.y);
            if (!IsGround)
            {
                if (rigid.velocity.y == 0)
                    anim.SetBool("Fall", false);
                if (rigid.velocity.y < 0)
                    anim.SetBool("Jump", false);
            }
            anim.SetBool("Move", false);
            anim.SetBool("Roll", false);
            anim.SetBool("Idle", true);

        }
        CoolTimerChecker();
    }

 

플레이어의 상태를 나타내는 코드는 아래의 형태를 받아와 구현됩니다.

public abstract class PlayerState
{
    public PlayerState(Player _player) { }

    public abstract void Enter();
    public abstract void Execute();
    public abstract void Exit();
}

 

 

4) 데이터 저장 시스템

 

 

플레이어의 강화정보, NPC와의 대화와 튜토리얼을 봤는지 여부를 저장하는 기능을 구현했습니다.

 

대화 데이터가 있다면 해당 데이터를 불러와 사용하고 데이터가 없다면 저장해야 하는 대화 정보의 틀을 가져와 새로 작성합니다. 

    public void StartNew()
    {
        string newData = File.ReadAllText(newDataPath);
        talkList = JsonUtility.FromJson<TalkList>(newData);
        foreach (var talkVal in talkList.talks)
        {
            if (!talkDictionary.ContainsKey(talkVal.talkerName))
            {
                talkDictionary.Add(talkVal.talkerName, talkVal);
            }
        }
        // 기존 데이터 초기화
        string modifyString = JsonUtility.ToJson(talkList);
        File.WriteAllText(useDataPath, modifyString);
    }

 

그리고 정보를 저장할 때는 새로 작성하여 덮어쓰면서 저장합니다. 

    public void SaveJson()
    {
        string modifyString = JsonUtility.ToJson(talkList);
        File.WriteAllText(useDataPath, modifyString);
    }

 

5) 대화 시스템

대화에서 강조하고 싶은 단어가 있을 때 글자색 바꾸기, 글자 굵기 키우기, 글씨체 바꾸기 등 여러 방법을 사용합니다.

Textmesh-Pro에서는 리치 텍스트가 지원되어 아래와 같이 단어를 강조할 수 있습니다.

리치 텍스트

6) 피스켈을 사용하여 만든 픽셀 이미지

 

 게임을 만들다가 필요한 몇몇 이미지는 직접 만들어서 사용했습니다.

 

 

튜토리얼을 진행시키는 매개체 빛 

 

 플레이어

 

 

상호작용을 알려주는 UI

 

키를 알려주는 UI