ドラゴンクエスト1の名前の入力画面を作成する【Unity】

RPGの原点ともいわれるドラゴンクエストを作ってみたいと思い入力画面を作ってみました

デモ

f:id:ayousanz:20201006062740g:plain

実装内容

  • 矢印キーでの文字を指し示す矢印の移動
  • Zキーを押すことで,文字の入力(名前の書き換え)
  • 「もどる」での文字の削除

実装方法

先に書いておきますが,この方法は最適の実装ではありません(今後修正予定) 特に矢印の移動の部分においては処理が重くなることが分かっています

文字と矢印の準備

本来は文字もscriptから描写,矢印は一つだけ使用して動かすという方向性で考えていたのですがうまくいかなかったために以下の方法で実装しています

すべての文字に対して,Textとその子供に矢印を設置しました f:id:ayousanz:20201006063240p:plain

矢印の見掛け上の移動

テキストのcolor のalpha値を0と255を切り替えることで,任意の文字に矢印が動いているように見せています

f:id:ayousanz:20201006063401p:plain

private void ChangeArrowAlpha(int _row, int _column, bool isView)
    {
        valueListList[_row].GetObject(_column).GetComponent<Transform>().GetChild(0).GetComponent<Text>().color = isView ? new Color(255f,255f,255f,255f) : new Color(255f,255f,255f,0f);
    }

文字の書き換え方法

Zキーを任意の文字の上で押したときに名前にその文字に書き換える方法は以下で実装しています

private static string ChangeCharAt(string tStr, int index, string newStr)
    {
        return tStr.Remove(index, 1).Insert(index,newStr);
    }

InsertとRemoveの詳しい説明は公式をご覧ください

docs.microsoft.com

docs.microsoft.com

空白の文字を飛ばして,矢印の移動をする

空白であるかどうかを確認し,その後空白の場合は移動する配列に+,-を追加して調節しています

private bool IsEmptyString(int row,int column)
    {
        // TODO:進む先の文字が空白かどうかを判断する
        var temp = valueListList[row].GetValue(column);
        return temp.Trim().Length == 0 || string.IsNullOrEmpty(temp);
    }

文字の管理について

上記の文字は独自のクラスを用いてリスト化しています. 画像はOdinを導入しているためリストの見た目はデフォルトと異なります

f:id:ayousanz:20201006064144p:plain

また,独自リストは以下

//Inspectorに複数データを表示するためのクラス
[System.SerializableAttribute]
public class ValueList{
    public List<GameObject>  list = new List<GameObject>();

    public ValueList(List<GameObject>  list){
        this.list = list;
    }

    public GameObject GetObject(int index)
    {
        return list[index];
    }

    public int GetLength()
    {
        return list.Count;
    }

    public void Clear()
    {
        list.Clear();
    }

    public void PrintInList()
    {
        
        StringBuilder str = new StringBuilder();
        for (int index = 0; index < list.Count; index++)
        {
            string text = list[index].GetComponent<Text>().text.ToString();
            str.Append(text);
        }
        Debug.Log(str.ToString());
    }

    public string GetValue(int index)
    {
        return list[index].GetComponent<Text>().text;
    }
}

ayousanz.hatenadiary.jp