Simple_Vocabulary_Application Wiki - UAVisonline/Portfolio GitHub Wiki

게임요소를 결합한 간단한 영어 단어장 프로젝트

해당 프로젝트는 간단한 게임적 요소 (플레이어 커스텀 및 스킬 시각 효과, 사용자 맞춤형 선택)를 영어 단어장에 결합한 프로그램을 만드는 것을 목표로 진행되었다. 실제 프로그램 내에서 사용자는 단어 입력 및 삭제, 상점기능을 통한 스킨 및 스킬 구매, 시각효과가 결합된 단어 테스트를 진행할 수 있다.

해당 프로젝트는 2022년 5월 HCI를 수강하면서 ClueBall Game에 이어 주제를 직접 선정해 진행한 프로젝트이며, '게임적요소를 활용하는 것이 사용자에게 흥미, 효율면에서 도움이 되는가?'라는 주제를 선정해 개발, 완료한 프로젝트이다.

해당 프로젝트는 진행할 때 이전에 구매한 아래 Unity Asset들을 활용했으며, 유저 스터디를 위해 단톡방에 배포를 진행하였다.

  • All in 1 Sprite Shader (플레이어 스킨 구현에서 사용)
  • Easy Save (데이터 저장을 위해 사용)
  • GUI Pro Kit - Fantasy, Sci-Fi (UI 요소에서 활용)
  • 118 Sprite effect bundle, Epic Toon FX, Hero Knighe-Pixel Art (스킬 시각 효과 및 플레이어 기본 스킨으로 활용)

해당 위키에서는 프로젝트에 대해 아래 항목들에 관해 설명하고자 한다.

  • 단어장 및 Test 관련으로 어떤 부분을 구현했는가?
  • 상점 시스템 및 플레이어 스킨, 상점 스킨의 구분을 어떻게 하였는가?
  • 프로젝트에서 아쉬었던 점은 무엇인가?

단어장 및 Test 관련으로 어떤 부분을 구현했는가?

1.단어장 구현(VocaMaster Script 및 단어관련 Script)

프로젝트 내 VocaMaster Script는 기본적으로 사용자가 입력한 단어를 관리한다. 이 때 단어는 List형태의 영어스펠링과 이를 Key로 삼아서 상세한 정보를 반환하는 Dictionary<string,ScriptableObject>를 사용하고 있다. 또한 해당 Script는 EasySave Asset을 이용해 가동되는 즉시 위 단어 정보(List 및 Dictionary<string,ScriptableObject>)를 불러온다.

또한 VocaMaster에는 단어를 Load하는 기능 외에도 아래와 같은 기능을 제공하고 있다.

  • 데이터 저장 기능 (Save, body_Save function)
  • 내부용 변수를 반환하는 기능(get_index, get_count, get_detail_index)
  • 단어 스펠링 및 단어 뜻을 반환하는 함수 (get_list_content(int index), get_dictionary_body(string value))
  • 단어 추가, 단어 삭제 함수 (insert_voca(string hd, string bd), delete_voca(string hd))
  • 그 외 Test 및 기타 사항을 위한 기능 함수 (get_level_index_list(float min_value, float max_value),.....)

이를 통해 단어장과 관련된 Script들은 VocaMaster와 상호작용 하는 것으로 사용자가 저장한 단어를 불러오거나 새로운 단어를 입력, 기존 단어를 삭제하는 것이 가능하며 이를 그림으로 표현하면 아래와 같이 나타낼 수 있다.

BGM Game


2.Test 구현 및 절차적 문제 선정(TestMaster Script)

프로그램은 사용자가 입력한 단어가 20개 이상일 때, 테스트를 통해 단어암기를 도모할 수 있다. 이 때 테스트에 낼 단어를 사용자에게 있어서 도움이 되는 방향으로 선정하고자 했으며 이를 위해 간단한 선택 알고리즘을 TestMaster Script에 적용, 이는 init_test 함수 형태로 아래와 같이 구현되어 있다.

BGM Game

이렇게 생성된 Test 문제를 전부 풀면, TestMaster Script에서 아래 reflect_test function이 실행된다.

326 public void reflect_test() // 테스트 결과를 Data에 대하여 반영 (단어 Level 값 변동 및 Coin 증가)
    {
        int coin_plus = 0;
329     for(int i =0;i< answer_result.Count;i++)
        {
            if(answer_result[i]==true)
            {
                VocaMaster.vocaMaster.set_dictionary_level(answer[i], -1.0f); // 문제를 맞춘 경우 -> level - 1
                coin_plus += 50;
            }
            else
            {
                VocaMaster.vocaMaster.set_dictionary_level(answer[i], +1.0f); // 문제를 틀린 경우 -> level + 1
            }
340     }
......
347     VocaMaster.vocaMaster.Save();
        ShopManager.shopmanager.plus_coin(coin_plus); // 상점 관련 플레이어 화폐를 관리하는 Script
349 }

329~340 Line을 통해 사용자가 푼 단어 결과를 순회하여 맞춘 문제에 대해서는 level 데이터를 1 감소, 틀린 문제에 대해서는 level 데이터를 1 증가하도록 한다. 그리고 이러한 변경사항을 실제로 데이터 상 저장하기 위해 347 Line, Save function을 실행한다.

그 뒤 사용자는 다시 테스트를 진행할 때 위 문제 선택 알고리즘을 통해 자신이 틀린 단어(level data가 높음)를 더 많이 풀 수 있다. 이러한 테스트를 반복할수록 더 취약한 단어에 대해 집중 공부하는 것이 가능해지면서 사용자의 영어 실력 증진에 도움을 주고자 했다.

상점 시스템 및 플레이어 스킨, 상점 스킨의 구분을 어떻게 하였는가?

1.상점 시스템, 상점 스킨과 플레이어 스킨의 구분(ShopManager Script)

스킨 시스템은 All in 1 Shader를 통해 기본적인 틀을 전부 받아왔으며, 프로젝트에서는 해당 에셋이 제공하는 material shader의 변수를 바꾸는 식으로 구현하였다.

상점에서 사용자는 플레이어 스킨과 Test를 진행할 때 사용할 연출을 선택 및 구매할 수 있다. 이 때 연출 부분은 관련 Template Script(TestDirector)을 작성, 이를 사용하는 GameObject를 연출별로 제작하였고, Test를 진행할 때 사용자가 장착한 연출 오브젝트를 시스템이 생성해서 Test용 다양한 연출을 적용하는 방식을 구현하였다.

이러한 부분에 있어서 ShopManager Script가 핵심적인 역할을 담당하고 있으며, Test 연출 외 플레이어 스킨 및 상점 스킨 시스템도 해당 Script를 이용해 처리하고 있다.

우선 ShopManager Script는 프로그램이 실행되면 Awake() 함수 내 내용을 실행해 현재 사용가능한 스킨, 연출에 대해 플레이어의 구매, 장착 여부를 불러온다. 그 뒤 장착한 스킨을 시스템은 플레이어 Material에 적용하는데 이를 Script 내 applied_shader(Line 297) 함수로 처리한다. 그 후 상점에 입장하면 현재 상점 material을 플레이어 material로 바꾸는 작업이 진행, 그 후 상점에서 스킨을 클릭하면 시착이 가능하도록 해야하는데 이를 Script 내 아래 함수들을 이용해서 처리한다.

198 public void purchased_color(int index) // index에 해당하는 Color Skin 구매
    {
        ......... (새로운 Color를 구매 및 장착, 기존 Color를 해제하며 이를 Data 상 저장하는 작업을 진행)
        equipment_index = index;

        shop_shader(equipment_index); // 상점 내 Player Material 설정
        applied_shader(); // Player Material 설정
    }

226 public void equipment_color(int index) // index에 해당하는 Color Skin 장착 (위에서 구매 기능만 제거)
    {
        ....... (이전에 구매했던 Color를 장착, 기존 Color를 해제하며 이를 Data 상 저장하는 작업을 진행)
        equipment_index = index;

        shop_shader(equipment_index);
        applied_shader();
    }
.......
286 public void enter_btn() // 상점 돌입 시 (현재 장착중인 index Color로 Shop Shader 설정)
    {
        shop_shader(equipment_index);
    }

291 public void shop_shader(int index)
    {
        shop_material.SetColor("_ColorChangeNewCol", colors[index].cape_color);
        shop_material.SetColor("_ColorChangeNewCol2", colors[index].body_color);
    }
  • enter_btn 함수를 상점에 진입하는 Button 기능에 집어넣어 상점 material을 플레이어 material로 변환하도록 한다.
  • 구매 및 장착 버튼을 이용해 현재 장착한 Color의 index를 변경, 그 후 Shop_shader와 applied_shader 함수를 통해 플레이어, 상점 material 색상을 변경한다.
  • ShopColorPalate Script를 통해 상점 내 스킨 UI가 존재하며 이를 클릭하는 것으로 ShopManager의 shop_shader를 실행, 상점 material 색상을 변경할 수 있다. BGM Game

프로젝트에서 아쉬었던 점은 무엇인가?

1.데이터 저장 효율성에 관하여

해당 프로젝트는 데이터를 Easy Save Asset을 통해 저장하며, 이 Asset은 Dictionary, List형태의 데이터 및 ScriptableObject 같은 유니티 전용 데이터를 쉽게 저장할 수 있다.

여기에서 필자는 단순히 영단어 데이터를 Dictionary에 저장하는 방식을 사용했는데, 내부 영단어 데이터를 1개만 삭제하거나 추가해도 전체 데이터에 대해 저장하는 작업을 거치기 때문에 데이터 숫자가 많아질수록 훨씬 부하가 커지게 된다.

이러한 부분을 HashTable을 이용, 여러개의 Dictionary를 만든다면 영단어 1개가 추가되어도 그 Dictionary에 대해 데이터를 저장하는 작업을 거치면 되고 부하를 줄일 수 있을 것이다.

⚠️ **GitHub.com Fallback** ⚠️