TopDown Engine + Rewired で NPC に話しかけたり扉を開けたりができない問題

「Interact」アクション

TopDown Engine に Rewired を導入したところ、移動やジャンプはできるのに、話しかけたり扉を開けたりといった操作ができないという問題が発生しました。

f:id:Gigacee:20200716093830p:plain
この状態で A ボタンを押しても何も起こらない

コードを見てみると、話しかけるや扉を開けるといった操作は「Interact」ボタンを使用するようですが、Rewired の設定を見ると「Interact」ボタンが存在していません。

f:id:Gigacee:20200716093844p:plain
コード中の「Interact」ボタンについて書かれている箇所

f:id:Gigacee:20200716094313p:plain
Rewired の設定には「Interact」が無い

なので、新規で「Interact」アクションを追加し、任意のボタンを割り当てることで、正しく動作するようになります。

f:id:Gigacee:20200716094345p:plain
Interact アクションを追加

f:id:Gigacee:20200716094441p:plain
任意のボタンに Interact アクションを割り当て

Esc キーに Pause を割り当てる

また、初期状態ではキーボードに Pause がアサインされていないので、これも設定します。Rewired Editor を開いて、以下の手順で設定することができます。

  1. 上部メニューから「Keyboard Maps」をクリックする。
  2. 左下の「Layout」の中から「Player1」を選択する。
  3. 「Element」下部のメニューから「New」をクリックする。新しい Element が生成される。
  4. 生成された Element が選択されている状態で、右上の「Key」の中から「ESC」を選択する。
  5. 右下の「Action」の中から「Pause」を選択する。

f:id:Gigacee:20200719122548p:plain

これで、ESC キーに Pause を割り当てることができました。

補遺

なお、Corgi Engine も同様の手順でボタンのアクションを設定することができます。

TopDown Engine 入門 Part 12 ~ダイアログ編~

ダイアログ(会話テキスト)を表示させる

TopDown Engine には、シンプルなダイアログシステムが備わっています。今回はこれを利用して、NPC に話しかけるとメッセージが表示されるようにしてみましょう。

ダイアログゾーン

キャラクターに話しかけられるようにするには、そのキャラクターに【ダイアログゾーン】を設定する必要があります。キャラクターの子に空の GameObject を作成して「DialogueZone」とリネームし、Add Component から Box Collider 2D と Dialogue Zone をアタッチしましょう。Box Collider 2D は、「Is Triggger」にチェックを入れておきます。

f:id:Gigacee:20200714215221p:plain

この Box Collider 2D が、ダイアログゾーンの範囲になります。Offset や Size を適宜調整してください。また、Dialogue Zone の一番下の「Dialogue Line」に、話す内容となるメッセージを入力しておきます。

f:id:Gigacee:20200714215230p:plain

これで最低限の設定ができました。シーンを再生し、NPC の近くで決定ボタン(デフォルトではスペースキー)を押し、メッセージが表示されるかどうか確かめてください。位置や大きさは、「Prompt Relative Position」「Offset」の数値を調整したり、「Button Prompt Prefab」「Dialogue Box Prefab」に設定されている Prefab の Scale を調整してください。

f:id:Gigacee:20200714215242p:plain


NEXTTopDown Engine 入門 Part 13 ~アニメーション編~

PREVTopDown Engine 入門 Part 11 ~ルーム編~


TopDown Engine のキャラクターを、アナログスティックと十字キーの両方で動かせるようにする

CharacterMovement の代わりに、以下のスクリプトをアタッチします。

using System;
using MoreMountains.TopDownEngine;
using UnityEngine;

public class CharacterMovementCustom : CharacterMovement
{
    float secondaryHorizontalInput;
    float secondaryVerticalInput;

    protected override void InternalHandleInput()
    {
        base.InternalHandleInput();

        secondaryHorizontalInput = _inputManager.SecondaryMovement.x;
        secondaryVerticalInput = _inputManager.SecondaryMovement.y;
    }

    protected override void HandleInput()
    {
        if (InputAuthorized)
        {
            _horizontalMovement = Math.Abs(secondaryHorizontalInput) > Mathf.Epsilon
                ? secondaryHorizontalInput
                : _horizontalInput;

            _verticalMovement = Math.Abs(secondaryVerticalInput) > Mathf.Epsilon
                ? secondaryVerticalInput
                : _verticalInput;
        }
        else
        {
            _horizontalMovement = 0f;
            _verticalMovement = 0f;
        }
    }

    public override void ResetInput()
    {
        base.ResetInput();

        secondaryHorizontalInput = 0f;
        secondaryVerticalInput = 0f;
    }
}

TopDown Engine で、Composite Collider 2D の Hole に入っても落ちれない問題

TopDown Engine では、CharacterFallDownHoles2D コンポーネントを持ったキャラクターが「Hole」レイヤーに設定されたコライダーを通ると落ちることができるのですが、Hole のコライダーが Tilemap Collider 2D + Composite Collider 2D だった場合、初期状態では落ちることができません。

デモを見ると、Tilemap で作られた Hole があるものの、よく見ると「Used By Composite」にチェックが入っていません。

f:id:Gigacee:20200706211224p:plain

デモのように Composite Collider 2D を使わないようにすれば落ちれますが、パフォーマンス的にはあまり良くないので、どうしたものか……と考えていたのですが、「Geometry Type」を「Polygons」にしたら落ちれるようになりました。

f:id:Gigacee:20200706211801p:plain

原因

キャラクターが Hole に入っているかどうかはPhysics2D.OverlapPointで判定しているのですが、「Geometry Type」が「Outlines」(Edge Collider 2D と同じ扱い)だと常に false になるからのようです。輪郭だけで中身が無いからオーバーラップしてるかどうか判らないということなんでしょうかね?

TopDown Engine 入門 Extra ~Rewired 編~

TopDown Engine で Rewired を使うには

Rewired」という、様々な種類のコントローラーやキーボード、マウス、画面のタッチイベントといったあらゆる入力を簡単に管理できる、人気のアセットがあります。他の有名なアセットとの連携も多数サポートしているのも特徴で、その中に TopDown Engine の姉妹アセットである Corgi Engine も存在しているのですが、TopDown Engine は残念ながらありません。

ですが、TopDown Engine の入力システムは Corgi Engine と同じバックエンドで動いているはず。ということは、そのまま流用できるのではないか? と考え、パッケージをインポートして多少手を加えてみたら、あっさり動作するようになりました! 今回は、その方法の紹介をします。

導入手順

  1. TopDown Engine がインストールされている状態で、Rewired をインポートする。
  2. Unity の上部メニューバーから Window > Rewired > Integration > Corgi Engine > Install Integration Pack をクリックし、Corgi Engine 用の統合パッケージをインポートする。
  3. インポートされたスクリプトのusing MoreMountains.CorgiEngine;using MoreMountains.TopDownEngine;に一括置換する。
    1. これでコンパイルエラーが発生しなくなります。
  4. Unity 上部のメニューバーから Window > Rewired > Integration > Corgi Engine > Create > Rewired Input Manager をクリックする。現在のシーンに Rewired Input Manager が生成される。
    1. ソロプレイ用とマルチプレイ用のものがあります。ここではソロプレイ用を使っています。
  5. 生成された Rewired Input Manager の Add Component から Component > Corgi Engine > Manager > Rewired Input Manager をアタッチする。
  6. TopDown Engine の標準の Input Manager を削除する(使用していた場合)。

f:id:Gigacee:20200705143143p:plain
Rewired Input Manager

これでもう、TopDown Engine の操作を Rewired ベースで行えるようになりました! 初期設定ですでに TopDown Engine のキャラクターを動かせるようになっているので、お好きなコントローラーを繋いで動作確認をしてみてください😉

Hierarchy 上の特定のコンポーネントを持つ GameObject のフォントカラーを変更するエディター拡張

using UnityEditor;
using UnityEngine;

public static class HierarchyFontColoring
{
    static readonly Vector2 offset = new Vector2(18f, 0);

    // どんなフォントカラーに変更するか
    static readonly Color separatorColor = new Color(1f, 0f, 0f);

    [InitializeOnLoadMethod]
    static void AddHierarchyItemOnGUI()
    {
        EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
    }

    static void HierarchyWindowItemOnGUI(int instanceId, Rect selectionRect)
    {
        var gameObject = EditorUtility.InstanceIDToObject(instanceId) as GameObject;

        if (gameObject == null)
        {
            return;
        }

        // フォントカラーを変更したいコンポーネント
        var target = gameObject.GetComponent<Camera>();

        if (target == null)
        {
            return;
        }

        var offsetRect = new Rect(selectionRect.position + offset, selectionRect.size);

        EditorGUI.LabelField(offsetRect, gameObject.name, new GUIStyle
        {
            normal = new GUIStyleState
            {
                textColor = separatorColor
            }
        });
    }
}

コメントの箇所を適宜書き換えてください。

TopDown Engine 入門 Part 11 ~ルーム編~

ルームによってレベルを分ける

Part 6 にて、レベル 1 を拡張し、2 つ目の部屋を作りました。その際、カメラの撮影範囲も広げたわけですが、現状だと片方の部屋からもう片方の部屋が見えてしまいます。

f:id:Gigacee:20200703214156p:plain

隣の部屋が見えないようにするには、スクリプトを書いて部屋を移動する際にコンファイナを動的に変化させるなどといった対策が考えられますが、少々面倒です。また、例えば「初めて部屋に入ったときのみ、会話イベントを発生させる」といったようなことをやりたい場合もあるでしょう。そんな時に役立つのが、TopDown Engine の【ルーム】システムです。

ルームを準備する

ルームの作り方は簡単です。まずはセクション 1 のルームから作っていきます。

空の GameObject を作成して「Room1」とリネームし、Add Component から「Room」と「Box Collider 2D」をアタッチします。

f:id:Gigacee:20200703214215p:plain

ルームには、ルーム用のバーチャルカメラとコンファイナが必要です。まず、Part 5 で行ったのと同じように、メニューバーの Cinemachineから「Create 2D Camera」をクリックし、バーチャルカメラを生成します*1。生成されたバーチャルカメラに「Cinemachine Camera Controller」をアタッチし、さらに CinemachineVirtualCamera の「Add Extension」から「CinemachineConfiner」を選択して Cinemachine Confiner をアタッチします。

次はコンファイナです。空の GameObject を作成し、「Confiner」とリネーム、そして Box Collider をアタッチしましょう。*2

最後に、VirtualCamera と Confiner を Room1 の子にします。

f:id:Gigacee:20200703214224p:plain

これで、ルームの準備ができました。

ルームの設定をする

次に、ルームの設定をしていきます。以下の手順に従ってください。

Room1

  1. Room の「Camera」グループにある各項目を、以下のように設定する。
    1. 「Virtual Camera」に、子の VirtualCamera を設定する。
    2. 「Confiner」に、子の Confiner を設定する。
    3. 「Cinemachine Camera Confiner」に、子の VirtualCamera を設定する。
  2. Box Collider 2D の「Is Trigger」にチェックを入れる。
  3. Box Collider 2D の「Size」が部屋の範囲になるように調整する。

VirtualCamera

  1. Cinemachine Camera Controller の「Confine Camera To Level Bounds」のチェックを外す。
  2. Cinemachine Confiner の「Confine Mode」を「Confine 3D」に設定する。
  3. Cinemachine Confiner の「Bounding Volume」に、同階層の Confiner を設定する。

Confiner

  1. Box Collider の「Is Trigger」にチェックを入れる。*3
  2. Box Collider の「Size」がカメラの映せる範囲になるように調整する。

以上で設定は完了です。

2 つ目のルームを作る

2 つ目以降は、Room1 を複製して作成すると楽です。Room1 を複製して「Room2」とリネームし、位置と範囲を 2 部屋目に合わせましょう。

ルーム間の移動

さて、これでそれぞれのルームが作成できたわけですが、まだルーム間の移動を実装できていません。と言っても、すでに Part 6 でテレポーターを作成していますので、これに少々設定を加えるだけで OK です。以下の手順で行ってください。

  1. 各テレポーターを、該当の Room の子にする。
    1. 「Room1」の子が「TeleporterToSection2」、「Room2」の子が「TeleporterToSection1」です。逆にしないよう注意してください。
  2. TeleporterToSection2 にアタッチされた Teleporter コンポーネントの「Rooms」グループ内にある「Camera Mode」を「Ciniemachine Priority」に設定する。
  3. 同じく「Rooms」グループ内にある「Target Room」に Room2 を設定する。*4
  4. 同様に、TeleporterToSection1 の「Camera Mode」を「Ciniemachine Priority」に、「Target Room」に Room1 を、それぞれ設定する。

これで、テレポーターによって移動した時に、各ルームにそれが伝わるようになりました。

その他の手順

各ルームにバーチャルカメラとコンファイナを設定したので、今まで使用していたバーチャルカメラとコンファイナは使用しなくなります。古い方のバーチャルカメラ(CM vcam1)は削除し、Level Manager の「Use Level Bounds」のチェックを外しておきましょう(Box Collider も削除してしまって大丈夫です)。

動作確認

ここまでできたら、シーンを再生し、隣の部屋が見えなくなっていることを確認しましょう。

f:id:Gigacee:20200703214236p:plain

ルーム移動に掛かる時間

ルームを移動する際に掛かる時間は、各テレポーターにアタッチされている Teleporter コンポーネントの「Teleport Sequence」グループで設定します。

f:id:Gigacee:20200703214246p:plain

一方、カメラの移動に掛かる時間は、Main Camera にアタッチされている CinemachineBrain コンポーネントの「Default Blend」に設定された秒数になります。

f:id:Gigacee:20200703214256p:plain

初期状態だとカメラの移動に 2 秒も掛かってしまうため、「Default Blend」の数字を低くしたくなりますが、ここでは代わりに Main Camera に「Chinemachine Brain Controller」をアタッチしましょう。こうすることで、移動時に自動で Teleport Sequence と同じ値を設定してくれるようになります。

コールバック

Room コンポーネントの「Actions」グループで、ルームに入った時や出た時に実行されるコールバック関数を設定できます。なお、同様のものがテレポーターや GoToLevelEntryPoint にもあります。


NEXTTopDown Engine 入門 Part 12 ~ダイアログ編~

PREVTopDown Engine 入門 Part 10 ~初期位置編~


*1:「CM vcam{数字}」という名称になっていると思いますが、「VirtualCamera」などにリネームしておくと良いでしょう。数字はあとで邪魔になります。

*2:Part 5 と同様、Box Collider "2D" ではないことに注意してください。

*3:Part 5 同様、入れなくても構いません。

*4:Current Room には Room1 が入りますが、ゲーム実行時に親の Room が自動で設定されるため、手動で設定する必要がありません。

The coloring of this site is Dracula PRO🧛🏻‍♂️
This website uses the FontAwesome icons licensed under CC BY 4.0.

2020 GIGA CREATION