ビジュアルスクリプトによるプログラミングの基礎
Tutorial
·
Beginner
·
+10XP
·
30 mins
·
(53)
Unity Technologies

プログラミングを初めて学ぶ人にとって、ビジュアルスクリプティングは、コードを潜在的に不可解な言語ではなく、論理的なダイアグラムとして提示する有用な学習ツールになります。
このチュートリアルは、実用的なアプリケーションに進む前に、もう少しプログラミングの基礎が必要な初心者のためのものです。このチュートリアルが終了するまでに、あなたは以下のことができるようになります:
- ビジュアルスクリプトでブール (Boolean) 論理と条件分岐を適用する
- ビジュアルスクリプトで switch ステートメントを使用する
- ビジュアルスクリプトで算術計算を行う
- ビジュアルスクリプトでキーボード入力を検出する
- 一般的なオブジェクト型の使用と解釈
- 変数、メソッド、論理ステートメントなどのプログラミングに不可欠な構造を持つ簡単なコードを理解することができる。
すでにご存知の方は、次のチュートリアルにお進みください。
Languages available:
1. 概要
本チュートリアルでは、ビジュアルスクリプティングを使って、より基本的なプログラミングの概念(ブール (Boolean) 論理と分岐、データ型の理解、計算など)を学びます。また、キーボードからの簡単なユーザー入力を検出する方法についても学びます。これらの基礎知識は、このプロジェクトの最後にあるチャレンジをクリアし、「Clive the Cat's Visual Crypt」に進むために必要なものです。
注:本チュートリアルは、プログラミング初心者の方に、もう少し基礎的なことを学んでいただくためのものです。もしあなたが経験豊富なプログラマーなら、ここでこれらの基本を復習することもできますし、チャレンジまでスキップすることもできます。
2. 解決したい課題:レンダリング速度のばらつき
ハードコードされた値と変数を使って、各フレームで数度回転するようにキューブを設定しました。ただし、コンピューターによってディスプレイの更新速度が異なるため、1 フレームあたり 3 度の回転は、高速なディスプレイでは非常に速く、低速なディスプレイでは遅くなります。
どのディスプレイでも同じように見えるキューブにしたい場合はどうすればよいでしょうか。ビジュアルスクリプトでこの問題を解決してみましょう。
1 フレームあたりの回転速度を固定で設定するのではなく、1 秒あたりの回転速度で計算することにします。グラフはその値をフレームごとの度数に変換し、Transform:Rotate ユニットで使用します。他の Unity 開発者が Inspector から速度を制御できるように、Object 変数を使用することにします。
必要な計算は:
[希望する度数 / 秒]×[コンピュータの表示速度 (秒 / フレーム) ]=[度数 / フレーム]
例えば、開発者が Inspector に希望する回転速度を 1 秒間に 45 度と入力したとします。各フレームが 0.02 秒でレンダリングされる場合、キューブは 1 フレームあたり 45 * 0.02 = 0.9 度回転する必要があります。
3. 新しいグラフの追加
新しいグラフを始めてみましょう。このメソッドは、以前使った方法とは少し違います。
1. Project ウィンドウで、先ほど作成した VisualScripts フォルダに移動します。
2. 右クリックして、Create > Visual Scripting > Script Graph の順に選択します。フォルダーに新しいグラフが追加されます。
3. 新しいグラフに「RotateSpeed」という名前をつけます。
4. 以前に使用したのと同じ手順を使用して、キューブに新しい Script Machine コンポーネントを追加します。
5. 新しいスクリプトアセットを Project ウィンドウから、None (Script Graph Asset) と表示されているフィールドにドラッグします。すると、そこにスクリプトの名前が表示されます。
6. このコンポーネントの Edit Graph をクリックすると、ビジュアルスクリプトが開きます。空白(Start と Update が含まれない)になります 。
7. Rotation という名前のビジュアルスクリプトを含むもう一方の Script Machine コンポーネントの横のボックスを無効にして、そのスクリプトが実行されないようにします。
4. 回転速度の取得
他の Unity 開発者が回転速度を制御できるように、Inspector ウィンドウに表示される Object 変数を作成することにします。
1. Fuzzy Finder を使用して Update Event ユニットを追加します。

2. Blackboard で、Name RotationDegreesPerSecond という新しい Object 変数を作成します。
3. この変数の Type を Integer(整数のみ)に設定します。
4. この新しい変数には、デフォルトの Value として 45 を指定します。
5. 新しい変数を Graph にドラッグして、Get Variable ユニットを生成します。まだフローに接続されていないので、今のところグレー表示になっています。
RotateDegreesPerSecond 変数は、キューブを選択すると、Inspector の Variables セクションに表示されます。
5. Time ユニットの追加
次に、各フレームが表示される時間の長さ(秒単位)を知る必要があります。この値は、Unity API の Get Delta Time というユニットで取得できます。Fuzzy Finder でそのユニットを見つけ、Graph に追加します。

6. Multiply ユニットの追加
これで、グラフには計算に必要な数値が揃いました。これらを Multiply という名前のユニットで乗算を行います。
1. Multiply ユニットを追加します。いくつかのオーバーロードがあります。Math / Generic にある、2つの数値を乗算するものを選択してください。
Multiply ユニットのオブジェクト型インジケーターが緑色であることに注目してください。これは、このユニットがさまざまなオブジェクトタイプを受け入れることができることを示しています。ここでは、 整数 (int) 型と float 型の乗算を行います。
2. Multiply ユニットの出力を Transform:Rotate ユニットの X Angle 入力に接続します。
3. Multiply ユニットがオレンジ色になることに注意してください - これはエラーを警告するためのものです。Multiply ユニットを選択して、Graph Inspector を参照してください。Multiply への入力が欠落していることがわかります。オレンジ色のユニットは入力が欠けていることを示すと知っておくと便利です。
4. Get Delta Time ユニットの出力を Multiply の A または B の入力に接続します。
5. Get Variable ユニットの出力を Multiply のもう一方の入力に接続します。オレンジ色の警告が消えます。
7. 算出した値を適用する
計算は完了しました。あとはその値を使って何かする必要があります。
1. Fuzzy Finder で「rotate」を検索して、Transform:Rotate (X Angle, Y Angle, Z Angle) ユニットを見つけ、Graph に追加します。
2. Transform:Rotate に 2つの接続を行う:
- フロー矢印で Update ユニットから Transform:Rotate に流れます。
- Multiply ユニットの計算値を Transform:Rotate につなげます。回転させる軸 (X, Y, Z) を選びます。
3. 作業を保存します。
4. ビジュアルスクリプトをテストするために Play モードに入ります。Script Graph ウィンドウの Values ボタンを有効にすると、目の前で計算される値が表示されます。
8. フローを分岐させる
プログラミングで強力かつ一般的な構造は、「if」という条件文です。この構造は、ブール (Boolean) 型 (True / False) をテストし、それが True の場合はあるフローを、False の場合は別のフローをたどり、ビジュアルスクリプトのフローを分岐させるものです。
If ユニットと、キーボード入力を検出する Get Key ユニットを使って、エンドユーザーにキューブを制御させることができます。ユーザーがフレーム中に Space バーを選択すると、キューブが回転します。ユーザーが Space バーを押したり離したりすることで、効果的に起動と停止が行われます。
1. Update イベントユニットと Transform:Rotate ユニットとの接続を解除します (間に新しいユニットを入れる)。コネクターの始点で右クリックすると、接続を解除することができます。
2. 「Input: Get Key (Key)」というタイトルのユニットを追加します(Fuzzy Finder で「get key」を検索)。
3. Get Key ユニットには非常に長いドロップダウンがあります。Space(上部付近)を選択します。
4. Graph に If ユニット(Fuzzy Finder で「if」を検索)を追加します。
5. Get Key ユニットは、Boolean の値を出力します:指定されたキーが押されている間は True、押されていないときは False となります。Graph はこの値に従って分岐します。Get Key から If に Boolean を接続(ピンクのインジケーターで)します。
6. また、Update から Get Key、Get Key から If への Graph のフローも繋げます。
7. If ユニットには、True と False の 2つの出力があることに注意してください。Get Key が True を送るとキューブが回転するようにしたいので、True フローを Transform:Rotate ユニットに接続します。
8. Get Key が False を送ると、Graph は何もしないので、False にあるフロー矢印は未接続のままにしておきます。
グラフは以下のように表示されるはずです。

作業内容を保存して、Play モードに入ります。Script Graph ウィンドウの Values ボタンを有効にし、ユニットからユニットへの値のフローをリアルタイムで見ることができるようにしてください。
9. Vector3 を用いた位置変更
Vector3 は、3つの浮動小数点数 (X, Y, Z) で構成される構造体です。3D 空間では、ゲームオブジェクトや空間内のその他の点の位置を変更または指定するために Vector3 が使用されます。
ここでは、Vector3 構造体と、Vector3 を操作するのに便利ないくつかのユニットを使って、キューブの位置を変更してみましょう。ユーザーが W キー(WASD キーボード入力の「up」キー)を長押しすると、キューブが上に移動するようにします。
1. まず、既存のグラフ上に Get Key と If ユニットを複製します。それらを選択し、右クリックして Duplicate Selection を選択します。
2. 新しい Get Key ユニットで、Key として W を選択します。
3. 元の If ユニットの False 出力からのフローを、新しい Get Key(W) のフロー入力に接続します。ユーザーがスペースを押していない場合は、W を押しているかどうかを確認するフローに進みます。

4. ChangePos という名前の新しい Graph 変数を、Type を Vector3 にして作成します。Values は 0, 0, 0 のままにしておきます。ChangePos には、キューブを現在の位置から移動させる距離を表す Vector3 が格納されます。
5. ChangePos を計算してみましょう。Unity には便利な Vector3 の「shorthand」ユニットが用意されています。これは方向などの操作を示すシンプルな Vector3 の値です。その一つが Vector 3: Get Up です。このユニットを追加し Graph Inspector で調べて、どんなものか確認しましょう (注:Vector3 の値は X,Y,Z で、Y は上下です)。
6. Get Up Vector3 の Y 値は 1 ですが、1 フレームに 1 Unity ユニット (meter) というのは、キューブを動かすには非常に速いスピードです。これに 0.01 をかけてみましょう。インライン (inline) 値が 0.01 の Float Literal ユニットを作成します。
7. Multiply ユニットにはいくつかのオーバーロードがあり、その中には Vector3 用のものもあります。ただし、今回必要なのは、1 つの浮動小数点数に Vector3 の 3つの値をすべて乗算することだけです。この場合、Multiply (Math/Generic) を使うとうまくいきます。そのユニットを追加し、Get Up に 0.01 を掛けるように接続を行います。

8. Graph 変数 ChangePos の値を Multiply の出力に設定する et Variable ユニットを追加します。
9. If ユニットの True 出力から Set Variable ユニットにフロー矢印を接続します。
10. Transform: Translate (Translation, Relative To) ユニットを追加します。このユニットは、Self (the cube) を Translation と呼ばれる量だけ変換します。ChangePos の出力値を Translation に接続します。Relative To の設定は Self のままで。
11. Set Variable から Transform:Translate へのフローを繋ぎます。
最終的には以下のようになります:

作業内容を保存し、Play モードに入ります。Script Graph
ウィンドウの Values ボタンを必ず有効にして、ユニットからユニットへの値のフローをリアルタイムで確認できるようにしてください。
ヒント:なぜ ChangePos という変数を導入したのか疑問に思われるかもしれません。Multiply から Transform: Translate に直接つなげればいいのでは?そのようにしてもよかったのですが…、次のステップで ChangePos を使うことにします。
10. Switch
キューブを一方向にしか動かさないのはあまり意味がないので、S キーを加えて下に動かしてみましょう。先ほど追加したユニットを複製して、Get Key ユニットの W を S に置き換え、Vector 3: Get Up を Vector 3: Get Down に置き換えることも簡単にできます。ただし、後になって(お願いすることになるかもしれない)左右の動きが加わったとしましょう。このグラフは大きくて扱いにくいものになります。
Switch ユニットは、2 つ以上の選択肢がある場合に、長い If ユニットの連鎖に代わる強力な分岐方法です。Switch ユニットを使って、このグラフを整理してみましょう:
1. Space をチェックする Input Get Key ユニットを削除します。その代わりに Input: Get Input String を追加します。これは、押されたキーをチェックして、そのキーストロークの文字列を出力します。
2. 最初の If ユニットを削除し、代わりに Switch On String を追加すると、その文字列が入力され、その文字列に応じて Graph のフローが分岐します。
3. Input: Get Input String ユニットには入力がないことに注意してください。Get Input String ユニットには入力がありません。Graph Inspector で見てみましょう。Update ユニットを使わずに、各フレームのキーボード入力を返しています。Update から Switch にフロー矢印を直接接続し、Get Input String から Switch の文字列入力に値のコネクターを接続します。
4. Graph Inspector の Switch On String ユニットを以下のように設定します:
- Ignore Case を有効にします。
- Options で、+ アイコンを選択します。
- スペースを入力します。Graph のユニットに追加されているのがわかります。
- さらに + アイコンを 2回選択すると、W と S のオプションが追加されます。
できあがった Switch ユニットは以下のようになります:

5. Switch ユニットから、Space 文字列の出力を Transform: Rotate ユニットに接続します。
6. 同様に、W 文字列の出力を ChangePos を更新する Set Variable ユニットに接続します。
7. W キーの Float、Multiply、Set Variable の各ユニットを複製し、S キーにはこれらのユニットを新たに追加しています:
- W キーで Vector 3: Get Up を使用していた場所に、Vector 3: Get Down ユニットを追加する
- 新しい Set Variable ユニットのフロー矢印を Transform: Translate に接続します。
8. Set Variable ユニットの両方から Transform: Translateユニットの Translation 入力への複数の入力を作成することはできません。代わりに、Get Variable: ChangePos ユニットを追加し、これを Translation の入力とします。
9. 使われなくなった Input: Get Key (W) とその If ユニットを削除します。
作成した最終的なグラフはこのようになります:

作業内容を保存し、Play モードに入ります。Script Graph ウィンドウの Values ボタンを必ず有効にして、ユニットからユニットへの値のフローをリアルタイムで確認できるようにしてください。
11. 次は何をするの?
今までに様々な Visual Scripting ユニットを使用し、分岐、計算、時間、Vector3 などを応用してきました。これらの新しいスキルを自分のプロジェクトで活用できるようなチャレンジをする準備ができましたね。