見出し画像

[Unity] Listを使ってInputFieldで入力された文字列をウィンドウ画像と一緒に出す(非エンジニア)

Unity version 2021.3.10f1

1、Sprite 2Dをインストール

  1. メニューのWindow >> PackageManagerからPackageManagerを開く

  2. Pacakages:のプルダウンからUnity Registryを選択する

  3. 2D Spriteを検索してインストール

2D Sprite Package

2、InputFieldを作成

Hierarchyウィンドウで右クリックから
UI >> Legacy >> Input Field

TextMeshProのInputFieldもあるが、勉強不足のためここではLegacyを使う

3、Window用の画像を作成

  1. ウィンドウに使う画像をProjectウィンドウにドラッグ&ドロップしてインポートする

  2. インポートした画像を選択しInspectorウィンドウのTextureTypeをSprite(2D and UI)にする

  3. InspectorウィンドウのSpriteModeをSingleにする

  4. InspectorウィンドウのPixelsPerUnitを1にする

  5. InspectorウィンドウのMeshTypeをFullRectにする

  6. InspectorウィンドウのPivotをCustomにしてXを0にする

  7. InspectorウィンドウのApplyを押す

  8. InspectorウィンドウのSpriteEditorを押す
    ※2D Sprite PackageをインストールしてもSpriteEditorを開けない時はプロジェクトを再起動してみてください

  9. SpriteEditorでBorderに任意の値を入れてウィンドウ右上にあるApplyを押してウィンドウを閉じる
    ※四隅の形状を維持しながらウィンドウサイズを変更できるようにする

Sprite Editor

4、Windowをプレファブ化

  1. Hierarchyウィンドウで右クリックからCameraを作成
    ※新しく作成せずにMainCameraを使っても良い
    ここではUI用のCameraとして追加している

  2. 作成したCameraのRenderTypeをOverlayにする

  3. MainCameraのInspectorウィンドウのStackの+から作成したCameraを追加する

  4. InputFieldの親オブジェクトのCanvasのRenderModeをScreenSpace - Cameraにする

  5. CanvasのInspectorウィンドウのRenderCameraを作成したCameraにする

  6. Window画像をHierarchyウィンドウにあるCanvasにドラッグ&ドロップする
    ※Canvasにドラッグ&ドロップをすることでCanvasを親にできる

  7. ドラッグ&ドロップした画像を選択しInspectorウィンドウのDrawModeをSlicedにする

  8. InspectorウィンドウのWidthとHeightでサイズを調整する

  9. InspectorウィンドウのLayerをUIにする

  10. InspectorウィンドウのOrder in Layerを-1にする

  11. HierarchyのWindow画像を右クリックしてUI >> Legacy >> Textでテキストフィールドを作成
    ※テキストフィールドがWindow画像の子として作成される

  12. WidthとHeightでフィールドのサイズ、FontSizeで文字サイズを調整

  13. PivotのXを0にしてPosX,PosYで位置調整

  14. Projectウィンドウで右クリックからCreate >> Folder でフォルダを作成フォルダ名をResourcesにする
    ※このフォルダ名は変更してはいけない

  15. Resourcesフォルダの中にフォルダを作成しフォルダ名をPrefabとする
    ※このフォルダ名は変更可能、Scriptで記述している箇所があるので変更の際はそちらも変更

  16. そのフォルダにHierarchyウィンドウのWindow画像をドラッグ&ドロップしてプレファブ化する

  17. Hierarchy上のWindow画像を削除する

  18. Hierarchyウィンドウで右クリックからCreateEmptyを作成して名前をTextLogにする Canvasを親にする
    ※このオブジェクトがWindowの座標の基準になる
    ※名前は変更できるがScriptで記述している箇所があるので変更の際はそちらを変更する

WindowのPrefab


5、Scriptを作成する

  1. Projectウィンドウで右クリックからCreate >> C# ScriptでScriptを作成し以下を記述
    ※ファイル名は任意だがファイル名とクラス名は同じにしなくてはならない

  2. Hierarchyウィンドウで右クリックからCreateEmptyでからのGameObjectを作成

  3. 作成したからのGameObjectに以下のScriptをAddComponentする

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // これ必要

public class TextWindowScript : MonoBehaviour // クラス名はファイル名と同じにする
{
    // 変数の宣言
    private List<GameObject> List_TextLog = new List<GameObject>(); // List
    private InputField InputF; // InputField用の変数
    private GameObject TextWindow; // Windowプレファブ用の変数
    private GameObject TextLog; // Windowプレファブを入れる空のオブジェクト用の変数

    void Start()
    {
        // Input FieldオブジェクトのInputField Componentを取得して代入
        InputF = GameObject.Find("InputField (Legacy)").GetComponent<InputField>();
        // ResourcesフォルダのWindowのプレファブを取得して代入
        TextWindow = Resources.Load<GameObject>("Prefab/Window");
        // TextLogオブジェクトを取得して代入
        TextLog = GameObject.Find("TextLog");
    }

    void Update()
    {
        INPUT_TEXT();
    }

    private void INPUT_TEXT ()
    {
        // リターンキーを押した時かつ入力した文字が1文字以上の時
        if(Input.GetKeyDown(KeyCode.Return) && InputF.text.Length > 0)
        {
            // ListにTextWindowをインスタンス化して追加する
            List_TextLog.Add(Instantiate<GameObject>(TextWindow));
            // Listに追加されたTextWindowのテキストフィールドにInputFieldに入力された文字列を代入
            List_TextLog[List_TextLog.Count - 1].transform.Find("Text").gameObject.GetComponent<Text>().text = InputF.text;

            // InputFieldの文字列の長さを代入
            int text_count = InputF.text.Length;
            // 文字列が1文字の時
            if(text_count == 1){
                // 1文字の時のウィンドウの横幅
                List_TextLog[List_TextLog.Count - 1].GetComponent<SpriteRenderer>().size = new Vector2(80, 112);
            }
            // 文字列が1文字以外の時
            else{
                // 1文字以上の時のウィンドウの横幅を文字数に合わせて可変
                List_TextLog[List_TextLog.Count - 1].GetComponent<SpriteRenderer>().size = new Vector2((text_count) * 30.0f + 36, 112);
            }
            // 追加されたTextWindowの親をTextLogオブジェクトにする
            List_TextLog[List_TextLog.Count - 1].transform.SetParent(TextLog.transform);
            // 追加されたTextWindowのローカル座標を(0,0,0)にする
            List_TextLog[List_TextLog.Count - 1].transform.localRotation = Quaternion.Euler(0,0,0);
            // 追加されたTextWindowのローカルスケールを(1,1,1)にする
            List_TextLog[List_TextLog.Count - 1].transform.localScale = Vector3.one;
            // 追加されたTextWindowの座標が一番下に追加してそれ以外を全て上にずらす
            for (int i = 0; i < List_TextLog.Count; i++){
                List_TextLog[i].transform.localPosition = new Vector3(0, (List_TextLog.Count - 1 - i) * 120, 0);
            }
            // InputFieldの文字列を消す
            InputF.text = "";
        }
    }
}

Scriptの補足

private List<GameObject> List_TextLog = new List<GameObject>();
GameObject型のListをList_TextLogという名前で宣言

private InputField InputF;
InputField型の変数をInputFという名前で宣言

private GameObject TextWindow;
private GameObject TextLog;
GameObject型の変数をそれぞれ宣言

InputF = GameObject.Find("InputField (Legacy)").GetComponent<InputField>();
HierarchyウィンドウにあるInputField (Legacy)という名前のオブジェクトのComponentのInputFieldをInputFという変数に代入

TextWindow = Resources.Load<GameObject>("Prefab/Window");
ResourcesフォルダにあるGameObject型のファイルを読み込んで変数に代入
<>内で型を指定している
"Prefab/Window"はResourcesフォルダ以下の場所とファイル名を指定している
ここではPrefabフォルダにあるWindowというファイルの指定

TextLog = GameObject.Find("TextLog");
HierarchyウィンドウにあるTextLogという名前のオブジェクトをTextLogという変数に代入
※オブジェクト名と変数名を同じにする必要性はない
後で見た時にわかりやすくしているだけです

INPUT_TEXT();
INPUT_TEXT(){ 処理 }内の処理を実行

if(Input.GetKeyDown(KeyCode.Return) && InputF.text.Length > 0)
Input.GetKeyDown(KeyCode.Return)はリターンキーの押した時にtrueを取得
InputF.text.LengthでInputField内の文字列の長さを取得し条件値として使っている

Instantiate<GameObject>(TextWindow)
TextWindowに代入されているGameObjectをインスタンス化(実体化)する

List_TextLog.Add();
List_TextLogにデータを追加
List_TextLog[数字]で呼び出しできる
数字は追加された順に0から連番になっている

List_TextLog.Count - 1
List_TextLog.CountはList_TextLogに入っているデータの数を取得している
List_TextLog[連番]で何番目のデータに対して処理行うか指定している
連番は0からなので-1している

List_TextLog[連番].transform.Find("Text").gameObject.GetComponent<Text>().text = InputF.text;
List_TextLogに入っているGameObjectの中にあるTextオブジェクトのComponentのTextを取得してそこにInput Fieldの文字列を代入

List_TextLog[連番].GetComponent<SpriteRenderer>().size = new Vector2((text_count) * 30.0f + 36, 112);
List_TextLogに入っているGameObjectのComponentのSpriteRendererのSizeの項目を更新している
new Vector2( x, y ) でXとYの値を代入している
数字は文字数に応じて長さが変わるように計算している
文字の大きさなどで数字を調整する必要があるここではFontSize36で調整している

List_TextLog[連番].transform.SetParent(TextLog.transform);
List_TextLogに入っているGameObjectの親をTextLogオブジェクトにする

List_TextLog[連番].transform.localRotation = Quaternion.Euler(0,0,0);
List_TextLogに入っているGameObjectのローカル角度を(0,0,0)にする

List_TextLog[連番].transform.localScale = Vector3.one;
List_TextLogに入っているGameObjectのローカルスケールを(1,1,1)にする
Vector3.one は new Vector3(1,1,1) と同義

for (int i = 0; i < List_TextLog.Count; i++){ 処理 }
for文で処理をList_TextLog.Countの数だけ行う

List_TextLog[i].transform.localPosition = new Vector3(0, (List_TextLog.Count - 1 - i) * 120, 0);
List_TextLogに入っているGameObjectのローカル座標への代入
(List_TextLog.Count - 1 - i) * 120はfor文で回した時にY座標が120ずつ上にずれていくようにしている

参考元

勉強中ですので説明が間違っている可能性があります自分でも調べて確認してみてください

この記事が気に入ったらサポートをしてみませんか?