概要

Logic Toolkitは挙動の流れを視覚的なノードグラフ形式で構築できるVisual Scriptingカテゴリのエディタ拡張アセットです。

挙動の流れを見える化

Unityエディタ拡張ウィンドウにより、ノードグラフを視覚的に編集できます。
Unity上でのテストプレイでは、実行中ノードやデータの現在値を確認できるため、デバッグにも役立ちます。

3つの概念

Logic Toolkitでは挙動の流れを大まかに3つの概念で構成することで、再利用性の高さを実現しています。

アクション

例えば「弾丸の発射(弾丸オブジェクトの実体化)」などの一瞬で完了する処理をここではアクションと呼びます。
(プログラミング用語では同期処理とも言います)

残弾数を変数に格納や取得、残弾数があるかどうかなどの判定を行うような処理もアクションの一種と言えます。

タスク

例えば「一定時間待機」や「A地点からB地点まで直線移動し、移動完了まで待つ」など、継続的に行われる処理をここではタスクと呼びます。
(プログラミング用語では非同期処理とも言います)

イベント

例えば「キー入力が行われた時」や「オブジェクトが何かに衝突した時」などを待つ処理をここではイベントと呼びます。
(プログラミング用語でもイベントと言います)

また「イベントが来るまで待機するタスク」という考え方もできますので、タスク機能が使える箇所ではイベント機能も使用できます。

4つの流れ

Logic Toolkitでは処理の流れが4つの分類で構成されています。

実行フロー

どのような処理をどういった順番で行うかの流れをここでは実行フローと呼びます。

例えば、キャラクターに攻撃が当たった場合は以下のような流れになります。

  1. ダメージ計算
  2. ヒットエフェクトを表示
  3. 体力が0以下になったか
    1. 死亡アニメーション再生
    2. 一定時間経過を待つ
    3. オブジェクトを破棄

ステートマシン

「状態」と「状態が切り替わる条件」に着目した処理の流れをステートマシンと呼びます。

例えば、以下のようなステートマシンを組んだ敵モンスターなどがあります。

状態 説明 遷移
巡回 プレイヤーキャラを探して固定ルートを巡回する プレイヤーを発見すると「通常攻撃」ステートへ
通常攻撃 プレイヤーに近づき通常攻撃する 残り体力が半分以下で「発狂」ステートへ
発狂 攻撃力が1.5倍となり、積極的に攻撃する 残り体力が10%以下で「逃走」ステートへ
逃走 プレイヤーから遠ざかり、自身の体力自然回復を待つ 体力が残り半分以上まで回復した場合は「通常攻撃」ステートへ

ビヘイビアツリー

「優先度」と「挙動を行う条件」に着目した処理の流れをビヘイビアツリーと呼びます。

例えば、敵モンスターの挙動をビヘイビアツリーで表すと以下のようになります。

優先度 挙動 条件 説明
1 臨戦態勢 プレイヤーを見つけた 見つけたプレイヤーに対して以下の行動をとる臨戦態勢
1-1 逃走 体力が残り10%以下 プレイヤーから遠ざかり、自身の体力自然回復を待つ
1-2 発狂 体力が残り半分以下 強力な攻撃を行う
1-3 通常攻撃 無条件 プレイヤーに近づき、通常攻撃する
2 巡回 無条件 プレイヤーキャラを探して固定ルートを巡回する

(ツリー構造のため、ここでは仮に「1-1」というように子要素を表現しています)

データフロー

値の取得や演算などを行うデータの流れをここではデータフローと呼びます。

例えば、ダメージ計算などは以下のようになります。

  1. 攻撃力を取得
  2. 守備力を取得
  3. 残り体力を取得
  4. 「残り体力 - (攻撃力/2 - 守備力/4)」を計算しする
  5. 残り体力を4.の数値に設定する

ノード

Logic Toolkitでは上記「3つの概念」と「4つの流れ」を多様なノードで実現できます。

Action

単一の処理を実行するノードです。
一瞬で実行され、すぐに次のノードに遷移します。

詳細はActionを参照してください。

Task

継続的に処理を実行するノードです。
処理が完了するまで待機し、完了後に次のノードに遷移します。

詳細はTaskを参照してください。

フロー制御ノード群

ノードの実行フローを制御するノード群です。
実行するノードを分岐したり、接続先ノードを繰り返し実行させることができます。

詳細はフロー制御ノード群を参照してください。

イベントノード群

ノードの実行を開始するためのノード群です。
実行開始の条件に従い、条件に合致したら接続先ノードを実行します。

詳細はイベントノード群を参照してください。

State

ステート(状態)を扱うノードです。
実行状況をシグナルとして発信し、接続先のシグナルノードが条件判定した結果によって次のノードに遷移します。

詳細はStateを参照してください。

シグナルノード群

Stateから他のノードへ遷移する条件判定を行うノード群です。

詳細はシグナルノード群を参照してください。

BehaviorTree

ビヘイビアツリー形式で実行ノードを切り替えるノードです。
接続しているノードの優先度順に実行され、子ノードは実行した結果を親ノードに返し、親ノードは受け取った結果によって子ノードの実行を制御します。

詳細はBehaviorTreeを参照してください。

データ演算ノード群

四則演算や値の取得などを行うためのノード群です。

詳細はデータ演算ノード群を参照してください。

データ変換ノード群

データの型を変換するためのノード群です。

詳細はデータ変換ノード群を参照してください。

ノードコンポーネント

ノードコンポーネントとはどのような挙動を行うかを実装したノード用の部品です。
ノードコンポーネントをノードに設定することで、実行中のノードがどのような挙動を行うかを設定できます。

詳細はノードコンポーネントを参照してください。

C#スクリプト

各種ノードコンポーネントはC#スクリプトで追加可能です。
グラフ上では複雑になりすぎる処理はC#スクリプトを記述することで整理しやすくなります。

詳細はスクリプティングを参照してください。

Float Sub スクリプトのコード例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using UnityEngine;

namespace LogicToolkit.Builtin
{
    [System.Serializable]
    [MenuName("Float/Float Sub")]
    [MenuKeywords("-")]
    [FixedRecomputeMode(RecomputeMode.Dirty)]
    internal class FloatSubCompute : ActionComponent
    {
        [SerializeField]
        private OutputDataPort<float> _Output = new OutputDataPort<float>();

        [SerializeField]
        private InputField<float> _Value1 = new InputField<float>();

        [SerializeField]
        private InputField<float> _Value2 = new InputField<float>();

        protected override void OnAction()
        {
            _Output.SetValue(_Value1.Value - _Value2.Value);
        }
    }
}

API呼び出しスクリプトの生成

Unity本体やパッケージなどのAPIを呼び出すためのノードコンポーネント用スクリプトを生成できます。
呼び出したいメンバーを選択するだけで必要なノードコンポーネントが生成されますので、単純なスクリプトの記述作業を挟むことなくノードグラフの編集に専念できます。

詳細はスクリプト生成を参照してください。