1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unity+WebGL向けに開発したタイピングゲームを「かな入力」に対応させる

Last updated at Posted at 2025-06-24

想定読者

  • Web向けにかな入力にも対応したタイピングゲームをUnityを用いて開発している方
  • ローマ字入力のタイピングゲームを開発できる方

当記事ではタイピングゲームの基本的な作り方については紹介しません。

はじめに

 この記事の実装手法には、WebページのJavaScriptを編集し、unityInstance.SendMessage()を用います。

 そのため、unityroom など、WebページのJavaScriptを編集できない公開プラットフォームなどでは、実装が困難になるかもしれません。

ちょっとした技術解説

 Unityでタイピングゲームを作る際にはMonoBehaviourのイベント関数であるOnGUI()と、Eventクラスを用いてキーの押下処理を実行する手法がよく用いられます。

using UnityEngine;

public class Something : MonoBehaviour

    private void OnGUI()
    {
        if(Event.current.type == EventType.KeyDown)
        {
            Process(Event.current.keyCode);
        }
    }
}

しかし、この手法ではUnity Editor上とブラウザ上で実行した場合において返されるKeyCodeが異なり、キーの位置が英字配列に対応したKeyCodeが返されてしまいます。

以下のテーブルは、筆者の手元環境であるmacOSとChromeにて行った際の実例です。

入力キー 入力キー(かな) 出力(Unity Editor) 出力(Chrome、macOS)
@ KeyCode.At KeyCode.LeftBracket
{ KeyCode.LeftBracket KeyCode.RightBracket
_ KeyCode.Underscore KeyCode.None

そのため、この手法では英字配列にはない「ろ」を安定して取得するのが困難です。

また、InputSystem.KeyBoardのイベントonTextInputからcharacterを取得する手法があります。

using UnityEngine;
using UnityEngine.InputSystem;

public class Something : MonoBehaviour
{

    private void Awake()
    {
        if (Keyboard.current is { } keyboard)
        {
            keyboard.onTextInput += character => {
                Process(character);
            };
        }
    }
}

しかし、この手法では「Shift+0」にあたる「を」を安定して取得できません。

 ローマ字入力では、この技術仕様を意識する必要はございません。しかし、かな入力に対応させるには何かしらの解決手法を用いる必要があります。そして次節にて解決手法の一例を紹介します。

解決手法

 JavaScriptのキー押下イベントkeydownから取得できるstring値e.codeunityInstance.SendMessage()を用いてUnity+WebGL側で処理させます。
 e.codeは最新のブラウザなら共通であり、安定して「ろ」や「を」を取得することができます。

実装方法

Unity側

まず、OnGUIの部分はWebGLビルドでは無効になるようにプリプロセッサを入力します。

+ #if UNITY_EDITOR
private void OnGUI()
{
    if(Event.current.type == EventType.KeyDown)
    {
        Process(Event.current.keyCode);
    }
}
+ #endif

そしてKeyCodeDetector.csというMonoBehaviour継承クラスを生成します。

KeyCodeDetector.cs
using System.Collections.Generic;
using UnityEngine;

public class KeyCodeDetector : MonoBehaviour
{
    private readonly Dictionary<string, KeyCode> _externalKeyCodes = new() {
        { "Digit0", KeyCode.Alpha0 },
        { "Digit1", KeyCode.Alpha1 },
        { "Digit2", KeyCode.Alpha2 },
        { "Digit3", KeyCode.Alpha3 },
        { "Digit4", KeyCode.Alpha4 },
        { "Digit5", KeyCode.Alpha5 },
        { "Digit6", KeyCode.Alpha6 },
        { "Digit7", KeyCode.Alpha7 },
        { "Digit8", KeyCode.Alpha8 },
        { "Digit9", KeyCode.Alpha9 },
        { "KeyA", KeyCode.A },
        { "KeyB", KeyCode.B },
        { "KeyC", KeyCode.C },
        { "KeyD", KeyCode.D },
        { "KeyE", KeyCode.E },
        { "KeyF", KeyCode.F },
        { "KeyG", KeyCode.G },
        { "KeyH", KeyCode.H },
        { "KeyI", KeyCode.I },
        { "KeyJ", KeyCode.J },
        { "KeyK", KeyCode.K },
        { "KeyL", KeyCode.L },
        { "KeyM", KeyCode.M },
        { "KeyN", KeyCode.N },
        { "KeyO", KeyCode.O },
        { "KeyP", KeyCode.P },
        { "KeyQ", KeyCode.Q },
        { "KeyR", KeyCode.R },
        { "KeyS", KeyCode.S },
        { "KeyT", KeyCode.T },
        { "KeyU", KeyCode.U },
        { "KeyV", KeyCode.V },
        { "KeyW", KeyCode.W },
        { "KeyX", KeyCode.X },
        { "KeyY", KeyCode.Y },
        { "KeyZ", KeyCode.Z },
        { "Minus", KeyCode.Minus },
        { "Equal", KeyCode.Caret },
        { "IntlYen", KeyCode.Backslash },
        { "BracketLeft", KeyCode.At },
        { "BracketRight", KeyCode.LeftBracket },
        { "Semicolon", KeyCode.Semicolon },
        { "Quote", KeyCode.Colon },
        { "Backslash", KeyCode.RightBracket },
        { "Comma", KeyCode.Comma },
        { "Period", KeyCode.Period },
        { "Slash", KeyCode.Slash },
        { "IntlRo", KeyCode.Underscore }
    };

    public void ExternalInput(string input)
    {
        if(_externalKeyCodes.TryGetValue(input, out var keyCode))
        {
            Process(keyCode);
        }
    }
}

このファイルを作り終えたら、GameObjectにアタッチしをScene上に置きます。

Shift押下処理につきましては省略します。

Web側

Unity+WebGLを実行するためのJavaScriptから以下の文を探し、window.addEventLister("keydown")を追加します。

// ----------省略----------

    const script = document.createElement("script");
    script.src = loaderUrl;
    script.onload = () => {
        createUnityInstance(canvas, config, () => {
    }).then((unityInstance) => {
        document.querySelector("#unity-fullscreen-button").onclick = () => {
            unityInstance.SelFullscreen(1);
        }

+       window.addEventListener("keydown", (e) => {
+            unityInstance.SendMessage("KeyCodeDetector", "ExternalInput", e.code);
+       });

    }).catch((message) => {
        alert(message);
    });
    
// ----------省略----------

これにて、かな入力にも対応したUnity+WebGLタイピングゲームを作ることができます。

さいごに

記事内のソースコードは自由に利用、改変しても大丈夫です。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?