Unity勉強中!あこがれだったプログラマーに今からなろう!

昔あこがれだったプログラマー。今からでもUnityを勉強してみようと思い立ち、チャレンジ開始! Unity勉強メモや、悪戦苦闘な日々の記録です。

ゲームの顔になるタイトル画面をつくろう(1):3Dアクションゲームを作ろう(14)

3Dアクションゲームのゲーム本体は概ね完成してきたので、次はこのゲームの顔になるべきタイトル画面を作ろう。

しまづさんのオンラインサロンの日曜には、じょにさんの講座があり、
14日にUI、特にタイトル画面についての説明があった。
色々なゲームのUIが見れるデーターベースも教えてもらえたので、
gameuidatabase.com
そこで、色々なゲームのUIを見ることができた。
見ていて閃くものがあったので、ちょっと凝ったものを作ろうと思う。

まずは、タイトル画面でユーザーに何を伝えたいのかを決める。

このゲームの場合は、やっぱり作り込んだ世界観だろうか🧐

それならば、ゲーム舞台の世界観をデモシーンのように流して、そこでオープニングストーリーも再生する。
それをメインにして、タイトルロゴとメニューはちょっと控えめに、サイドに配置する様にしてみよう🧐

タイトルロゴはInkScapeで作った。

タイトルはいつも通り悩んだけれど、
結局はゲームのコンセプト通り、宝石を捜索するという事で、石の探求。つまり、Jewel Quest。
ところが、これでググってみたら、他ゲームがあっさりヒットしてしまったので、ちょこっとモジって、Quest for Jewel of Peaceに決めた。
英語は苦手なので、意味が合っているのか不安😅
日本語の「の」って、結構万能な言葉で、英語の、of、by、for、全て、翻訳サイトでは「の」となってしまう。
ちなみに翻訳サイトで訳すと、平和の宝石の探求。
Jewel of Peace のofの「の」は平和の宝石、平和を司る宝石って意味で良いと思うけど、
Quest forのfor「の」が、「平和の宝石」を探索するって意味になっていれば良いのだけど。。。😅

さて、主題は決まったけど、これだけでは、このゲームのコンセプトが伝わらない。
どこかでゲームのタイトルは、最近のライトノベルの表題にみたいに、タイトルだけで内容を説明できる方がより良い。という記事をみた覚えがある。
だから、ゲームの目的をズバリと添えることにした。

で、完成したのが、これ

Inkscapeもまだ勉強中なので、そこまで綺麗なものが作れなかったのが残念。

タイトルロゴができたので、次はメニュー表示。
これは次の習作予定のドラクエRPGのため、通勤時にyoutubeで学んだことを参考にする事にした。

【Unity】ドラクエ風シンプル2DRPGの作り方! #15 キーボード入力によるアクションの選択【シーズン2】

完成形はこんな感じ

youtu.be

ほぼほぼ、しまづさんの丸コピー🤪
変えているのは「Text」ではなく「ボタン-TextMeshPro」にした事と、
文字の色だけでなく、大きさも変えるようにした事。
ボタンに変えたのは、キーボードだけでなく、マウスやスマホでのクリック操作用だ。

ボタンの子要素のTextMeshProにアタッチするSelectableTextも、TextMeshPro用に変更する。

using UnityEngine;
using TMPro;

public class SelectableText : MonoBehaviour
{
    [SerializeField] private TMP_Text tmpText;

    public void SetSelectedTexe(bool selected)
    {
        if(selected)
        {
            tmpText.color=Color.yellow;
            tmpText.fontSize=28; //文字を大きくする
        }
        else
        {
            tmpText.color=Color.white;
            tmpText.fontSize=24; //文字を小さくする
        }
    }
}


メニュー選択するスクリプトはMenuSelectionという名前にして、InputSystem対応仕様に変更する。
GetKeyDownがないので、連続反応防止でタイマー制御もつけることにした。

using UnityEngine;
using UnityEngine.Playables;

public class MenuSelection : MonoBehaviour
{
    
  [SerializeField] SelectableText[] selectableTexts;
  int selectedIndex;
  [SerializeField] private AudioSource audioSource;
  [SerializeField] private AudioClip MoveSE;
  private InputSystemSC inputSystemSC;
  float inputTimer=0;   //連打防止タイマー

private void Start() 
{
    inputSystemSC=new InputSystemSC();
    inputSystemSC.Enable();
    Init();
 }    

public void Init()
{
    selectableTexts=GetComponentsInChildren<SelectableText>();
}

private void Update() 
{
    inputTimer+=Time.deltaTime;

    //InputSystemからMoveに設定されている要素をVector2で受け取る。
    Vector2 LeftDirction=inputSystemSC.SelectedMenu.Move.ReadValue<Vector2>();

    //そこからy軸、縦方向だけの要素を抜き出す。
    var LeftDirction2 =LeftDirction.y;

    if(LeftDirction2<0 && inputTimer>0.5f)
    {
        audioSource.PlayOneShot(MoveSE);
        selectedIndex++;
        inputTimer=0;

    }

    if(LeftDirction2>0 && inputTimer>0.5f)
    {
        audioSource.PlayOneShot(MoveSE);
        selectedIndex--;
        inputTimer=0;
    }
    selectedIndex=Mathf.Clamp(selectedIndex,0,selectableTexts.Length-1);

    for (int i = 0; i < selectableTexts.Length; i++)
    {
        if(selectedIndex==i)
        {
            selectableTexts[i].SetSelectedTexe(true);
        }
        else
        {
            selectableTexts[i].SetSelectedTexe(false);
        }
    }
}
}

これで、ロゴとメニューが完成したので、次はオープニングストーリーをTimelineで作ってみよう。