〰️

指定座標を巡回する実装でUnityのVisualScriptingと仲良くしてみる

2023/07/07に公開

食わず嫌いはよくない

なんか線とか繋げて動かすヤツは信用できねェ……!
ということでこれまでVisual Scriptingは敬遠していたのですが、Unityがなんか最近推しているっぽいので、まあ推しているなら悪いものではないのだろう……たぶん……ということで触ってみることにしました。

ちょっと別件で最近必要だったので、このようなものを作ります。
指定された位置をGameObjectに巡回させるだけの単純な処理です。座標の指定はCreate Emptyで作ったGameObjectで行います。その方がやりやすいので。

VisualScripting

全体像

graph value

グラフ内でだけ使われる変数の定義です。リストのインデックスに使います。

object value

オブジェクトのInspectorから設定する変数の定義です。

  • Active
    移動するかどうかのフラグ
  • Speed
    移動するスピード
  • Distance
    どれだけ近づけば目的地点についたか判定する
  • Points
    巡回する座標を指定するGameObject

active

全体の起点であるUpdateをActiveでフィルタすることで動きを止めることができます。

compare

このオブジェクトがPoints内のindexで指定されたGameObjectとどれだけ離れているか、その距離がDistanceより遠いか近いかを判定します。

index

compareによる判定で距離が十分に近づいていた場合は次の目標に移動するためにindexを1足します。その際にリストから溢れないように剰余を使います。

move

現在のオブジェクトの座標と目標のオブジェクトの座標をVector3.MoveTowardsに入れて出てきた座標を設定します。

Inspector

Inspectorの設定はこんな感じです。

C#

C#でも作ってみます。

コード

なるべく同じロジックになるようにしましたがほんとならもっとオシャレな書き方があります。

using Cysharp.Threading.Tasks;
using UnityEngine;

public class Patrol : MonoBehaviour
{
    [SerializeField]
    private bool active = true;

    [SerializeField]
    private float distance = 0.2f;

    [SerializeField]
    private float speed = 10f;

    [SerializeField]
    private Transform[] points;

    private void Start()
    {
        Move().Forget();
    }

    private async UniTaskVoid Move()
    {
        var ts = this.transform;
        var index = 0;

        while (true)
        {
            if (destroyCancellationToken.IsCancellationRequested)
            {
                break;
            }

            await UniTask.Yield(destroyCancellationToken);
            if (!active)
            {
                continue;
            }

            var current = ts.position;
            var toward = points[index].position;
            var moveTowards = Vector3.MoveTowards(
                current, toward, speed * Time.deltaTime
            );
            ts.position = moveTowards;

            if (Vector3.SqrMagnitude(current - toward) >= Mathf.Pow(distance, 2))
            {
                continue;
            }

            index++;
            index %= points.Length;
        }
    }
}

Inspector

思うこと

この動かすやつの他にも10個ほど作っての感想です。

  • こんな単純な処理ですら人間の処理限界を超えて線が多い
  • これ人と協業は無茶では
  • Listになんでも放り込めるのやめて……!
  • 参考記事を見つけてもコピペできないからひたすらスクリーンショットを真似して作るしかないのか?
  • 処理の本体はjsonだがminifyされているのでgitでdiffがまったく見えない
  • これのレビューってどうするの……? 目diff……?
  • せめてjsonではなくYAMLに書き直してdiffが見える形にしてほしい
  • 「VisualScriptingが他を使う」ことは想定されているが「他がVisualScriptingを使う」口がおざなりなのが連携できなくてつらい
  • ビルド時間えらい延長される
  • たまに壊れてない?
  • バグったらどうするんだこれ
  • 性能面でのチューニングができなさそう
  • .assetなのでビルドなしにいろいろ追加できるのは大きなアドバンテージなのはわかる

まとめ

なんか線とか繋げて動かすヤツは信用できねェ……!

おしまい。

参考

https://qiita.com/yusuga/items/ba7b5c2cac3f2928f040

Discussion