UnityNovelProj Unity で VisualNovel を作成する

url: https://www.youtube.com/watch?v=QsFnsbAxrMg&list=PLGSox0FgA5B58Ki4t4VqAPDycEpmkBd0i&index=59
title: "Make a Visual Novel in Unity 2023 - Episode 18 (part1) New Input System"
description: "Let's move from the legacy input system to the new input systemOther Links: - Discord Server   - https://discord.gg/xVTZSgV   - Discord members get to engage..."
host: www.youtube.com
favicon: https://www.youtube.com/s/desktop/6f111fa1/img/favicon_32x32.png
image: https://i.ytimg.com/vi/QsFnsbAxrMg/maxresdefault.jpg

Input System

Input System は Unity が公式で提供している入力を抽象化するためのパッケージです。 #UnrealEngine の Enhanced Input System とほぼ同じです。

url: https://docs.unity3d.com/Packages/[email protected]/manual/index.html
title: "Input System | Input System | 1.14.2"
host: docs.unity3d.com

https://nekojara.city/unity-input-system-intro https://nekojara.city/unity-input-system-actions

ログ

18-1: インストールとセットアップ

Imgur

Legacy Input System と併用して利用するため、 No を選択してインストールします。

Project Settings > Player から Legacy & New 両方を利用するように変更して Apply します。

Imgur

Keyboard Input Manager に Player Input を Attach します。

Imgur

VisualNovelInput という Input Action Asset を作成します。 これは Key と Action の Binding を行う Map を複数設定できるアセットです。

  • Player
  • UIMenu など、複数用途の Map を同時に設定できます。

Imgur

VisualNovelInput Action Asset を設定し、かつ Action が発火したときの挙動を UnityEvent にします。

Imgur

18-2: キー入力を受け取れるようにする

url: https://www.youtube.com/watch?v=98wxRRcTa7g&list=PLGSox0FgA5B58Ki4t4VqAPDycEpmkBd0i&index=61
title: "Make a Visual Novel in Unity 2023 - Episode 18 (part2) Input Manager"
description: "Let's re-craft our input manager to be more expandable and cross platform compatibleOther Links: - Discord Server   - https://discord.gg/xVTZSgV   - Discord ..."
host: www.youtube.com
favicon: https://www.youtube.com/s/desktop/c90d512c/img/favicon_32x32.png
image: https://i.ytimg.com/vi/98wxRRcTa7g/maxresdefault.jpg

PlayerInputManager を旧 InputSystem から新しい InputSystem に変更します。 ここで UnityEngine.InputSystem が見つからない問題が発生しました。 こちらの解決方法については Assembly Definition Asset を使っているときに UnityEngine.InputSystem が見つからない を参照ください。

キー入力を受け取るためには PlayerInput というコンポーネントを GameObject に付与しておきます。 そして、ビヘイビアを Unity Events の Invoke とし、かつ PlayerInput コンポーネントを参照する別途 C# Script (Player Input Manager) をアタッチします。

Imgur

今回は Invoke C Sharp Scripts でキー入力を受け取るようにします。

url: https://nekojara.city/unity-input-system-player-input#Invoke%20C%20Sharp%20Events%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%A6%E9%80%9A%E7%9F%A5%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8B
title: "【Unity】Player InputでInput Systemの入力を取得する"
description: "Input Systemで提供されているPlayer Inputの使い方の解説です。 Player Inputは、Input Systemの入力を仲介するコンポーネントで、Input Actionの入力をスクリプト側に通 ..."
host: nekojara.city
favicon: https://nekojara.city/wp-content/uploads/2021/01/cropped-favicon-32x32.png
image: https://nekojara.city/wp-content/uploads/2021/12/unity-input-system-player-input-1024x576.png

Invoke C Sharp Events に変更します。

Imgur

Awake メソッド (ライフサイクルにおいて初めて実行されるとき) に以下を行います。

  • PlayerInput Component を取得する
  • Next アクションと、それに紐づけたい関数の参照をリストとして保持する

そして、 OnEnable , OnDisable という GameObject として有効・無効それぞれのときに、該当の Action が performed = 完全に trigger されたときに、コールバック関数を実行します。

どのような値が入力されたかについては InputAction.CallbackContext で取得します。 今回はクリックのみなので取得した値は利用していませんが、 アナログスティックの十字ボタンなどは Context から値を取得して利用します。

using System;
using System.Collections.Generic;
using Core.DisplayDialogue;
using UnityEngine;
using UnityEngine.InputSystem;
 
namespace Core.UserIO
{
    public class PlayerInputManager : MonoBehaviour
    {
        private PlayerInput playerInput;
        private List<(InputAction action, Action<InputAction.CallbackContext> callback)> actions = new();
 
        public void Awake()
        {
            playerInput = GetComponent<PlayerInput>();
            BindActions();
        }
 
        private void BindActions()
        {
            actions.Add((playerInput.actions["Next"], OnNext));
        }
 
        private void OnEnable()
        {
            foreach (var tuple in actions)
                // action が完全に trigger されたら callback を実行する
                tuple.action.performed += tuple.callback;
        }
 
        private void OnDisable()
        {
            foreach (var tuple in actions)
                tuple.action.performed -= tuple.callback;
        }
 
        /// <summary>
        /// なにか入力があったら dialogueSystem のイベント発火を実行する
        /// </summary>
        private void OnNext(InputAction.CallbackContext context)
        {
            DialogueSystemController.instance.OnUserPromptNextEvent();
        }
    }
}