LoginSignup
10
11

More than 3 years have passed since last update.

【この有料アセットがすごい!】UnityでScratch - Likeなブロックプログラミングを実現「Play Mode Blocks Engine」

Last updated at Posted at 2021-02-20

初めに

先輩に面白いアセットを教えていただいたので実際に買って遊んでみた。
そのレビューとして、ざっくり理解した使い方を書いていこうと思う

基本的な機能の説明

UnityでScratch-Likeな機能が実装できる有料アセット
値段は25ドルなので2600円くらい?(2021/02/20現在)
Play Mode Blocks Engine

大部分はScratchと同じ。
Blockを組んで何らかの実行イベントを起こすと組んだブロックに応じて処理が走る。

全体

外観はこんな感じ。(いくつか自分で適当にボタンやテキスト追加してます)
スクリーンショット 2021-02-20 17.30.55.png

ブロックは2種類ある

  1. Function Block:targetObjectやBlockのカタマリに作用。上下に凹凸のあるもの
    スクリーンショット 2021-02-19 22.58.21.png

  2. Operation Block:Function Blockの入力値として用いる。上下に凹凸がない。
    スクリーンショット 2021-02-19 22.59.12.png

ブロックの分類は7種類ある

  1. Event:イベントリスナーとして動く
    スクリーンショット 2021-02-19 22.32.23.png

  2. Motion:targetObjectの動きや位置、方向に関連するブロック
    スクリーンショット 2021-02-19 22.34.39.png

  3. Control:Blockのカタマリに作用。条件分岐や繰り返し、待機処理など
    スクリーンショット 2021-02-19 22.35.11.png

  4. Looks:targetObjectの見た目を変える
    スクリーンショット 2021-02-19 22.36.41.png

  5. Sounds:音を鳴らす
    スクリーンショット 2021-02-19 22.36.55.png

  6. Operators:論理演算子。Function Blockに用いる
    スクリーンショット 2021-02-19 22.36.21.png

  7. Variable:変数に関する操作ブロック。新しい変数を作成するためのボタンがあり、新しい変数名を挿入して作成を確認するためのパネルが開く。
    スクリーンショット 2021-02-19 22.42.16.png
    スクリーンショット 2021-02-19 23.01.55.png

各targetObjectがそれぞれ独自のPG環境を持つ

  • シーン上に複数のtargetObjectがあり、それぞれにCode Blockのセットがある時もある。抽象化の目的で、各targetObjectはそれぞれ独自のCanvasを持つ。
  • ブロックをプログラミング環境にドロップできる
  • 目的のブロックを押したまま/右クリックすることで、アクションを含むメニューパネルを開くことができる。(コピーと削除)
  • コードは保存及びロードができる

Codeの保存機能の仕組み

  • 現在のキャンバスブロックを単純なテキストベースのファイル(.BE)に変換し保存する。
  • 任意のテキストエディタで開くことができ、データの操作が容易である。
  • 逆に、ブロックのテキストへの変換をするカスタム関数がある。
  • 保存したコードは、Application.persistentDataPathからUnityによって提供される永続データディレクトリの「SavedCodes」というフォルダに保存される。
  • [保存]ボタンをクリックするとポップアップメニューが開く
    • 保存したコードのリストが見れる
    • 新規保存、上書き保存、ファイルの削除ができる。 スクリーンショット 2021-02-19 23.06.31.png

Codeのロード機能の仕組み

  • .BEファイルに書かれたブロック配置をプログラミング環境に再現する。
  • [コードのロード]ボタンをクリックするとメニューが開く
    • ロードおよび削除するファイルが選択できる。 スクリーンショット 2021-02-19 23.07.30.png

Joy Stickについて

  • 4つの方向ボタン(↑→↓←)と2つのアクションボタン(A,B)がある
  • Eventsブロックに対応するイベントを発生させられる。(Aボタンが押されたら…など) スクリーンショット 2021-02-19 23.11.25.png

Model Class

BE TargetObject

ScratchでいうSpriteみたいなもの。再生ボタンや他のトリガーを介して自身のトリガーがActiveになった時に処理が走る

BE Block

動かすコードブロックのこと。大きく次の5つに大別される

  1. Trigger
    1. ブロックの塊の上に配置。
    2. イベントリスナーとして動作
    3. ブロックの塊をActiveにするのに必要なFunction Block

この形の
スクリーンショット 2021-02-19 23.12.37.png

  1. Simple
    1. サイクルごとに1回実行される
    2. 子ブロックをラップしないFunction Block

この形の
スクリーンショット 2021-02-19 23.13.23.png

  1. Loop
    1. ループ命令を実行するFunction Block
    2. ループ条件が満たされている場合に、実行される子ブロックをラップ

この形の
スクリーンショット 2021-02-19 23.20.10.png

  1. Conditional
    1. 条件付き命令を実行
    2. 条件が満たされた場合に実行される子ブロックをラップ

この形の
スクリーンショット 2021-02-19 23.20.10.png

  1. Operation
    1. Function Blockのヘッダーに配置される
    2. 真偽値を文字列で返す

この形の
スクリーンショット 2021-02-19 23.24.59.png

BE Inputs

各ブロックのヘッダーには入力値を入力/選択する箇所がある。
スクリーンショット 2021-02-19 23.32.15.png
これらの値は、BEInputと呼ばれる型で、BEBlockオブジェクトに格納されている。
BEInputには、文字列および浮動小数点値としての入力のマップがある。

  1. string[ ]型のstringValues
  2. float[ ]型のnumberValues

これらはフラグisStringを持つ。(少なくとも1つの入力値を数値に変換できない場合にtrueになる)

【2つの入力を持つBE BlockオブジェクトbeBlockの例】

最初の入力値はbeBlock.BeInputs.stringValues [0]またはbeBlock.BeInputs.numberValues [0]で呼び出す。
2番目の入力値は、beBlock.BeInputs.stringValues [1]またはbeBlock.BeInputs.numberValues [1]で呼び出す。

すでに実装されているブロックでは文字列と数値の両方の入力を考慮しているため、プレーヤーは特に型を気にせずにブロックを使用できる。

BE CONTROLLER

プログラミング環境に配置され、ターゲットオブジェクトに関連付けられたすべてのActiveなブロック処理を実行。
大きく次の役割を持つ。
1. トリガーブロックを開始
2. すべてのブロックグループを停止
3. 対応するブロックグループシーケンスの次のブロックをアクティブ化
4. その他のメソッド

BE Instruction

BE Instructionは、コントローラーによって呼び出されるメソッド定義するコントローラークラス
BEFunctionメソッドとBEOperationメソッドの一方または両方が含まれる。

BE Variables

実際のコーディング手法にできるだけ近くするため、Function Blockとして使用したり、Function Blockの入力値として設定したりする変数のこと。
BE変数には、変数の名前と値を格納するBEVariableと呼ばれるカスタムタイプのリストからアクセスする。
BE CONTROLLERには、SetVariable(string、string)とGetVariable(string)がすでにある。
ColorとSoundに対応するBE変数Listもある

Play Next Method

名前の通り、次の命令処理に移行することを通知するメソッド。
BEFunctionメソッドの中には次のどちらかは必須

  1. PLAY NEXT OUTSIDE:Simpleの最後やLoopの最後、Conditionalで条件を満たさない場合などに呼ばれる
  2. PLAY NEXT INSIDE:Trigger、Loop、Conditionalで条件を満たす場合などに呼ばれる

スクリーンショット 2021-02-20 0.05.08.png

プログラミング環境に組んだブロックが実行される仕組み

PlayNextMethodによって再帰的な構造になっている

  • 何らかのトリガーで各BlockのisActiveがtrueになったら処理が動く。
  • 処理が終わったらPlayNextOutsideが呼ばれ、次のBlockに入っていく
  • その際に次のBlockのisActiveが変わる処理が走る(多分)

Scene

BE Con​​trollerインスペクターの下部には、Sceneと呼ばれるセクションがある。
シーンで現在アクティブなすべてのターゲットオブジェクトを識別し、そのプログラミング環境のActivationを決定する。
次節のWorkshopを用いて複数のTargetObjectを用いる場合は、BE Controllerの持つ「Scene」からSingleSelectionを選択しておけば、一度に表示されるプログラミング環境を1つに制限できる。
スクリーンショット 2021-02-20 0.18.56.png

Workshop

BE Controllerのインスペクターの下部には、Workshopと呼ばれるセクションがある。
いくつかの変数を設定するだけで新しいTargetObjectやBlockを作成できるスクリーンショット 2021-02-20 0.20.21.png

オリジナルのブロックを作る方法

BE Controllerのインスペクターの下部のWorkshopから、いくつかの変数を設定するだけで新しいターゲットオブジェクトとブロックを作ることができる。まずはBlockタイプと動作ルールを設計する。

今回は例として、入力値を受け取って指定回数あいさつをConsole表示するようなBlockを作ってみる

以下の処理はWorkshopセクションで行う

  • Blockの表示名とタイプを決める。(今回は名前はFuga、ブロックタイプはSimple)
  • Blockヘッダー作成する。表示するテキストと入力タイプを正しい位置に配置してHeaderGuidelineを設定する

HeaderGuideline記入例は以下の通り

[inputfield = 1]
回あいさつする

スクリーンショット 2021-02-20 0.33.20.png

色々この辺を設定したら「ビルドブロック」ボタンを押すと、「ブロックと命令が作成されました」というメッセージが表示される。
スタックに命令をインポートしようとしています...」、メッセージが消えるまで待てば完了。

結果として、以下が作成される

  • スクロールビューに表示される新しいブロック(名前はFuga)
  • BE Instruction Script フォルダ内に新しいスクリプト(Fuga.cs)
  • Instruction Stackにコンポーネントとして追加されたInstruction
  • 新しいプレハブ(resources/prefabs/Blocks/Fuga.prefab)

スクロールビューでは一番上に生成されるので適当な場所に置き直すことスクリーンショット 2021-02-20 0.35.50.png
スクリーンショット 2021-02-20 0.36.13.png

スクリーンショット 2021-02-20 0.38.54.png

ここまででプログラミング環境にD&Dできるブロックは完成したので、次はオブジェクトとスクリプトを対応させていく
新しく作成されたスクリプトには、命令動作のコーディングをするために必要なテンプレートがすでに含まれている
以下は作成されたばかりのスクリプト(コメントは適宜加えた)

Fuga.cs
using UnityEngine;
using System.Collections;
using System;

public class Fuga : BEInstruction
{
    // Use this for Operations
    public override string BEOperation(BETargetObject targetObject, BEBlock beBlock)
    {
        string result = "0";

        //入力値に関してここで色々いじったり判定したりして結果を0か1の文字列で返す(なんでboolじゃないのかな?)

        return result;
    }

    // Use this for Functions
    public override void BEFunction(BETargetObject targetObject, BEBlock beBlock)
    {
        // 入力値を受け取るときはこんな感じ
        string option = beBlock.BeInputs.stringValues[0];

        // 子要素のBlockに進むときはPlayNextInside(beBlock)、それ以外はPlayNextOutside(beBlock)を用いる。BEFunctionメソッド内に必須
        BeController.PlayNextOutside(beBlock);
    }
}

今回はコンソール表示をしたいので、BEFunctionの処理を次のように記述

Fuga.cs
public override void BEFunction(BETargetObject targetObject, BEBlock beBlock)
    {
        int option = int.Parse(beBlock.BeInputs.stringValues[0]);
        for (int i = 0; i < option; i++)
        {
            Debug.Log("おはよう");
        }
        BeController.PlayNextOutside(beBlock);
    }

結果はこんな感じ。下にBlockを繋げても問題なく動く
画面収録-2021-02-20-0.49.29.gif

最後に

25ドルでここまで遊べるのはなかなか強い。
一点気になるとすればブロックを繋げるのが少々難しい…
その辺の判定とかUIを修正すれば面白いものが作れそうな有料アセットだと思った。

ここまで読んでいただきありがとうございました。
この記事が何かのお役に立てたなら幸いです。

10
11
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
10
11