tanaka's Programming Memo

プログラミングについてのメモ。

UnityのML-Agentsで、新しい学習環境を作成する

ML-Agentsの動作環境は整えられました。次は、新しいプロジェクトにML-Agentsを組み込む手順を確認します。以下のドキュメントを読んでいきます。

github.com

以下は、元記事から変更や補足したところです。

  • ブレインの名前の変更
  • ターゲットに近づくとリワードがもらえる機能のコードの追加
  • 学習手順と再生手順とまとめを追加

目次

動作環境

以下で確認しました。

  • Windows10
  • Unity2018.2.10
  • ML-Agents Beta 0.5.0a

ML-Agentsのリポジトリーをクローンしていなかったり、環境構築ができていない場合は、先に以下の記事を完了させてください。

am1tanaka.hatenablog.com

このチュートリアルで作るもの

ランダムな場所に登場するキューブを取るようにボールを制御するAIをトレーニングします。また、ボールが地面から落下しないようにもします。

  1. Unity上でAIをトレーニングするための環境(environment)を作ります。環境は、いくつかのオブジェクトによるシンプルな物理シミュレーションから、ゲームやエコシステム全体まで含みます
  2. Academy(アカデミー)サブクラスを実装してゲームオブジェクトにアタッチして、環境を組み込んだUnityのシーン内に配置します。このゲームオブジェクトは、シーン内の様々なブレイン(Brain=AIの脳)の親として動作します。アカデミークラスには、AIエージェントとは別にシーンを更新するいくつかのオプションのメソッドを実装できます。例えば、環境内に、AIエージェントやその他のオブジェクトを追加、移動、削除したりできます
  3. 1つ以上のAIのブレインオブジェクトを、アカデミーの子供としてシーンに追加します
  4. エージェントサブクラスを実装します。エージェントサブクラスは、環境を観察するためのコードを定義して、行動を割り当てて、強化学習のための報酬(Reward)を計算します。また、学習が終了したり、タスクが失敗した時に、エージェントをリセットするメソッドを実装します
  5. 作成したエージェントサブクラスをゲームオブジェクトにアタッチします。アタッチしたオブジェクトは、シミュレーション内のエージェントとしてシーン内で行動します。エージェントには必ずブレインオブジェクトを割り当てる必要があります
  6. Brain TypeExternalで学習させます
  7. Brain TypeInternalにして、学習してできたモデルデータを使ってUnityでAIを動かします

Unityプロジェクトの作成

まずは、新規でUnityプロジェクトを作成して、ML-Agentsを組み込みます。

  • Unity2017.4以降を起動して、RollerBallという名前で新しいプロジェクトを作成します
  • エクスプローラーで、ダウンロード(あるいはクローン)して展開したml-agentsフォルダーを開きます
  • UnitySDK/Assetsフォルダー内のML-Agentsフォルダーをドラッグして、UnityのProjectウィンドウにドロップしてインポートします

f:id:am1tanaka:20181110121550p:plain

Unityのバージョンによって表示は変わりますが、おおよそ以下のようになります。

f:id:am1tanaka:20181110121637p:plain

ML-Agentsツールキットを有効にする

公式ドキュメントだと、ML-Agentsの設定の手順が抜けているので、以下のようなエラーが発生すると思います。

f:id:am1tanaka:20181110124628p:plain

こちら「この段階ではまだエラーが発生します。設定を続けます。」という文の続きを設定します。以下、簡単な手順です。

  • Editメニューから、Project Settings > Playerを選択します

以下を、利用したいプラットフォームごとに実施します

  • Other Settingsを開きます
  • Scripting Runtime VersionExperimental、あるいは.NET 4.6 Equivalent、あるいは.NET 4.x Equivalentにします
  • Restartするかのウィンドウが表示されたら、Restartします

Unityが一度閉じて再起動するのを待ってください。これでエラーが出なくなります。

環境(Environment)を作る

ML-Agentsの環境用のシーンとして、エージェントが乗っかる床となるPlane、エージェントがゴールや目標として探索するCube、エージェントを表すSphereを作成します。

床のPlaneを作る

  • HierarchyウィンドウのCreateをクリックして、3D Object > Planeを選択します
  • 作成したPlaneの名前をFloorにします
  • 作成したFloorをクリックして選択します
  • InspectorウィンドウのTransform欄を以下の通り設定します
    • Position = 0, 0, 0
    • Rotation = 0, 0, 0
    • Scale = 1, 1, 1
  • InspectorウィンドウのMesh Renderer欄にあるMaterialsの左の三角をクリックして開いたら、Element 0の右の〇をクリックして、ウィンドウからFloorマテリアルを選択して割り当てます

f:id:am1tanaka:20181110123205p:plain

以上で床は完成です。

取るためのキューブを作る

  • HierarchyウィンドウのCreateをクリックして、3D Object > Cubeを選択します
  • 作成したCubeの名前をTargetにします
  • 作成したTargetをクリックして選択します
  • InspectorウィンドウのTransform欄を以下の通り設定します
    • Position = 3, 0.5, 3
    • Rotation = 0, 0, 0
    • Scale = 1, 1, 1
  • InspectorウィンドウのMesh Renderer欄にあるMaterialsの左の三角をクリックして開いたら、Element 0の右の〇をクリックして、ウィンドウからBlockマテリアルを選択して割り当てます

エージェントとするSphereを作る

  • HierarchyウィンドウのCreateをクリックして、3D Object > Sphereを選択します
  • 作成したSphereの名前をRollerAgentにします
  • 作成したRollerAgentをクリックして選択します
  • InspectorウィンドウのTransform欄を以下の通り設定します
    • Position = 0, 0.5, 0
    • Rotation = 0, 0, 0
    • Scale = 1, 1, 1
  • InspectorウィンドウのMesh Renderer欄にあるMaterialsの左の三角をクリックして開いたら、Element 0の右の〇をクリックして、ウィンドウからChekerGoalマテリアルを選択して割り当てます
  • Add Componentをクリックします
  • PhysicsからRigidbodyを選択してアタッチします

後程、このオブジェクトにエージェントサブクラスをアタッチします。

アカデミーとブレインを持たせる空のゲームオブジェクトを作る

  • HierarchyウィンドウのCreateをクリックして、Create Emptyを選択します
  • 作成したGameObjectの名前をAcademyにします
  • 作成したAcademyオブジェクトを右クリックして、Create Emptyを選択して、子供に空のゲームオブジェクトを作成します
  • 作成した子供のGameObjectの名前をRollerBallBrainにします(元記事では単にBrainでしたが、後の設定のため変更しました)

f:id:am1tanaka:20181113214728p:plain

以上でシーンが完成です。Main Cameraの座標や角度を調整して、Gameウィンドウで見やすくなるようにしてください。

f:id:am1tanaka:20181110125921p:plain

アカデミーの実装

アカデミーオブジェクトは、シーン内のML-Agentsを動かして、観測-意思決定-行動というシミュレーションループを制御します。ML-Agentのシーンごとに1つのアカデミーのインスタンスが必要です。アカデミークラスのベースクラスはabstractなので、メソッドを実装する必要がなくてもサブクラスを作成する必要があります。

まずは、先に作成したアカデミーオブジェクトに新しいスクリプトを追加します。

  • HierarchyウィンドウからAcademyオブジェクトをクリックして選択します
  • Inspectorウィンドウで、Add Componentをクリックします
  • New Scriptを選択して、RollerAcademyという名前で作成します
  • 作成したRollerAcademyスクリプトをダブルクリックして、エディターで開きます
  • MLAgentsの機能を使うために、using MLAgents;を定義します
  • クラスの継承元をMonoBehaviourからAcademyに変更します
  • Start()Update()メソッドを削除します

基本的な機能はベースクラスのAcademyが持っているので、実装は不要です。以下の通りにしたら、上書き保存をしてUnityに切り替えます。

using MLAgents;

public class RollerAcademy : Academy { }

デフォルトの設定のまま使います。Inspectorウィンドウで変更する項目はありません。

f:id:am1tanaka:20181111010139p:plain

ブレイン(Brain)を作る

ブレインオブジェクトは、行動を決める処理を担当します。エージェントは自らが観測した情報をブレインに送ります。ブレインは送られてきた観測情報を元に行動を決定してエージェントに伝えます。エージェントは、ブレインから受け取ったデータに従って行動します。Brain Type設定で、ブレインがどのように意思決定を行うかを選択することができます。アカデミーやエージェントクラスと違い、ブレインは既存のスクリプトをそのまま利用します。

  • Hierarchyウィンドウから、Academyの子供のRollerBallBrainオブジェクトを選択します
  • Inspectorウィンドウで、Add Componentをクリックします
  • Scripts > MLAgents > Brainを選択して、コンポーネントをアタッチします

f:id:am1tanaka:20181113214956p:plain

設定は改めて行います。現時点ではBrain TypePlayerのままにしておきます。

エージェントの実装

エージェントを作成します。

  • Hierarchyウィンドウから、RollerAgentオブジェクトをクリックして選択します
  • Inspectorウィンドウで、Add Componentをクリックします
  • New Scriptを選択して、RollerAgentという名前で作成します
  • 作成したRollerAgentスクリプトをダブルクリックして、エディターで開きます
  • Academyの時と同じように、usingを設定して、ベースクラスをMonoBehaviourからAgentに変更します

以下のようなコードになります。

using MLAgents;

public class RollerAgent : Agent { }

上書き保存をして、Unityに戻ります。

ここまでの手順は、あらゆるUnityのプロジェクトにML-Agentsを加える基本的な手順です。次に、強化学習を使ってSphereのエージェントがキューブを取るように動かすためのロジックを加えていきます。

今回のシンプルなシナリオでは、アカデミーオブジェクトに環境の変更は実装しませんが、シミュレーション前やシミュレーション中に、床の大きさを変えたり、エージェントやその他のオブジェクトを追加したり削除したりしたい場合は、アカデミーにメソッドを自由に追加して実装することができます。ここでは、エージェントが成功したり失敗した時に、エージェントや目標物をリセットすることだけを行います。

エージェントの初期化とリセット

RollerBallのエージェントは、Targetに触れたら自分自身でそのことを記録して、Targetをランダムな座標に配置し直すリセット関数を呼び出します。また、RollerBallが地面から落下したら、リセット関数によって地面に戻します。

Targetを追うためには、エージェントはTargetTransformを知っている必要があります。そのために、RollerAgentクラスにpublicTransformを定義します。これにより、Inspectorウィンドウで、ターゲットを設定できるようになります。エージェントの速度をリセットしたり、エージェントを動かすための力を与えるために、Rigidbodyコンポーネントの参照が必要です。Rigidbodyは、Unityで物理シミュレーションをするための基本的なエレメントです。スクリプトのゲームオブジェクトにアタッチされているRigidbodyへの参照は、Start()メソッド内で、GameObject.GetComponent<T>()を使って取得します。

RollerAgent.csは以下のようになります。

using System.Collections.Generic;
using UnityEngine;
using MLAgents;

public class RollerAgent : Agent {
    Rigidbody rBody;
    private void Start()
    {
        rBody = GetComponent<Rigidbody>();
    }

    public Transform Target;
    private float previousDistance = float.MaxValue;
    public override void AgentReset()
    {
        // 前回の距離をリセット
        previousDistance = float.MaxValue;

        if (this.transform.position.y < -1.0)
        {
            // エージェントが落ちた
            this.transform.position = Vector3.zero;
            this.rBody.angularVelocity = Vector3.zero;
            this.rBody.velocity = Vector3.zero;
        }
        else
        {
            // ターゲットを新しい場所へ移動させる
            Target.position = new Vector3(
                Random.value*8-4,
                0.5f,
                Random.value*8-4
            );
        }
    }
}

次は、Agent.CollectObservations()関数(情報を収集する関数)を実装します。

環境を観測する(Observing the Environment)

エージェントは、収集した環境の情報をブレインに送ります。ブレインは送られてきた情報を使って行動を決めます。エージェントをトレーニングする時、あるいは、トレーニングされたモデルを利用する時に、観測したデータをfeature vector(観測結果を表すベクトルデータ)としてニューラルネットワークに与えます。エージェントの学習を成功させるためには、正しい情報を与えなくてはなりません。どの情報を与えるのが正しいかを決めるよい指標は、問題を解決するために何が必要かを分析して考えることです。

今回の場合、エージェントは以下の情報を集めます。

  • ターゲットの座標。一般的に、絶対的な座標よりも、エージェントから見た相対的な座標を使う方がよいでしょう。今回は、Plane上を移動するだけでY座標は変化しないので、X-Z座標のみ利用します
// エージェントからターゲットへの相対座標を計算する(Calculate relative position)
Vector3 relativePosition = Target.position - this.transform.position;

// 相対座標(Relative position)
AddVectorObs(relativePosition.x / 5);
AddVectorObs(relativePosition.z / 5);
  • 床の四隅からのエージェントの距離。エージェントを床に留まらせるための情報です
// 床の角までの距離 (Distance to edges of platform)
AddVectorObs((this.transform.position.x + 5) / 5);
AddVectorObs((this.transform.position.x - 5) / 5);
AddVectorObs((this.transform.position.z + 5) / 5);
AddVectorObs((this.transform.position.z - 5) / 5);
  • エージェントの速度。ターゲットを通り過ぎたり、床から転落しないように速度を学習させるための情報です
// Agent velocity
AddVectorObs(rBody.velocity.x / 5);
AddVectorObs(rBody.velocity.z / 5);

全ての値は5で割って、正規化をしています。これは、ニューラルネットワークが受け取る値が-11の範囲だからです。何故5かというと、今回の床のサイズが10なので、-55でどこにいるかが表されるからです。

(補足) この処理では1を越えることがあるため、正規化としては不十分です。後程、正規化フラグを設定します。 (補足ここまで)

観測した状態(state observation)の数は8つです。それをAddVectorObs()関数でブレインに渡します。

以上をまとめると以下のようになります。RollerAgent.csに加えてください。

public override void CollectObservations()
{
    // 相対座標を計算(Calculate relative position)
    Vector3 relativePosition = Target.position - this.transform.position;

    // 相対座標を正規化して設定(Relative position)
    AddVectorObs(relativePosition.x/5);
    AddVectorObs(relativePosition.z/5);

    // 床の隅からの距離を正規化した値を設定(Distance to edges of platform)
    AddVectorObs((this.transform.position.x + 5)/5);
    AddVectorObs((this.transform.position.x - 5)/5);
    AddVectorObs((this.transform.position.z + 5)/5);
    AddVectorObs((this.transform.position.z - 5)/5);

    // エージェントの速度(Agent velocity)
    AddVectorObs(rBody.velocity.x/5);
    AddVectorObs(rBody.velocity.z/5);
}

エージェントコードの最後は、Agent.AgentAction()関数です。ブレインが決定した行動を受け取ります。

Actions

ブレインが決めた行動は、アクションの配列としてAgentAction()関数に渡されます。この配列の要素数は、エージェントのブレインの設定であるVector Action Space TypeVector Action Space Sizeによって決まります。RollerAgentでは、Continuous Vector Action Space(連続的な行動空間)で、ブレインから2つのcontinuous control signals(連続的な制御信号)を必要とします。よって、Brain Vector Action Sizeには2を設定します。最初のエレメントであるaction[0]X軸方向に加える力で、2つ目のaction[1]Z軸方向に加える力とします(もし、Y方向の移動もあった場合は、Vector Action Size3になります)。ニューラルネットワークから返される値は、-11の間の値になります。ブレインは、これらの値がどのようなものなのかは把握しません。トレーニングは、観測した入力に対して返す値を調整した結果、どのようなリワード(報酬)が得られるかということだけに注目して行われます。

RollerAgentaction[]配列の値をRigidbodyコンポーネントであるrBodyAddForce()で反映させます。

Vector3 controlSignal = Vector3.zero;
controlSignal.x = action[0];
controlSignal.z = action[1];
rBody.AddForce(controlSignal * speed);

実際のコードは後述します。

Rewards(リワード=報酬)

強化学習ではリワードの設定が必要です。リワードはAgentAction()関数内で割り当てます。学習アルゴリズムは、シミュレーションのステップごとにエージェントにリワードを与えて、エージェントにとって最適な行動が何かを学習するのに利用します。エージェントが目的のタスクを達成したら(今回ならTargetオブジェクトに辿り着いたら)報酬を与えて、望まない行動をしたら(今回なら床から転落したら)報酬を取り上げます。

レーニングを短縮するために、エージェントが最終的なタスクを達成するのを助けるための補助的なリワード(sub-rewards)を設定する方法があります。例えば、Targetとの距離が前回より近づていたらリワードを少し与えつつ、毎ステップごとに少しリワードを減らすような設定を加えることで、エージェントはTargetに近づくことが有利だと学習でき、Targetに到着しやすくなります。

RollerAgentは、Targetに辿り着いたかを検出するために距離を計算します。算出した距離が到達したと判断する値以下になっていたら、エージェントに1.0のリワードを与えて、完了したことを報告するためにDone()を呼び出します。

float distanceToTarget = Vector3.Distance(this.transform.position,
                                          Target.position);
// Reached target
if (distanceToTarget < 1.42f)
{
    AddReward(1.0f);
    Done();
}

メモ: Done()を呼び出してエージェントが完了したことを知らせると、リセットするまで動作が停止します。Agent.ResetOnDoneプロパティーをインスペクター上でTrueに設定しておくことで、完了したらすぐに自動的にエージェントをリセットすることもできますし、アカデミーがMaxStepに到達して、環境をリセットするのを待つこともできます。今回はResetOnDoneプロパティーTrueに設定してリセットします。MaxStep0のままにして、アカデミーが環境をリセットしないようにします。

(補足)

Targetへの距離が縮まったら少しリワードを与えて、学習効果を高めるためのコードです。元記事には変数は定義されていたものの、リワードを与えるコードがなかったので補足します。

        // 近づいたサブリワード
        if (distanceToTarget < previousDistance)
        {
            previousDistance = distanceToTarget;
            AddReward(0.03f);
        }

(補足ここまで)

以下は、ステップごとにリワードを少し減らすことで、タスクをより手早く完了できるようにするための工夫です。

// タイムペナルティ
AddReward(-0.05f);

最後に、プラットフォームから転落した時にリワードを大きく減らす処理と、Doneを呼び出して次のステップで自分自身をリセットさせる処理です。

// プラットフォームからの転落
if (this.transform.position.y < -1.0)
{
    AddReward(-1.0f);
    Done();
}

AgentAction()

行動とリワードの考え方は以上の通りです。AgentAction()関数の完成形は以下のようになります。RollerAgent.csに加えてください。

    public float speed = 10;

    public override void AgentAction(float[] vectorAction, string textAction)
    {
        // Targetとの距離
        float distanceToTarget = Vector3.Distance(
            this.transform.position,
            Target.position);

        // Targetに接触したか
        if (distanceToTarget < 1.42f)
        {
            AddReward(1);
            Done();
        }

        // 近づいたサブリワード
        if (distanceToTarget < previousDistance)
        {
            previousDistance = distanceToTarget;
            AddReward(0.03f);
        }

        // 近づかなかったペナルティ
        AddReward(-0.05f);

        // プラットフォームから転落
        if (this.transform.position.y < -1.0)
        {
            AddReward(-1);
            Done();
        }

        // 動作の設定。sizeが2なのでvectorActionは2つ
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = vectorAction[0];
        controlSignal.z = vectorAction[1];
        rBody.AddForce(controlSignal * speed);
    }

仕上げのエディター設定

全てのゲームオブジェクトとML-Agentコンポーネントの設定が完了したので、データを接続していきます。

  • HierarchyウィンドウのAcademyオブジェクトの左の三角をクリックして開いて、子供のRollerBallBrainオブジェクトを表示します
  • HierarchyウィンドウのRollerAgentゲームオブジェクトをクリックして選択します
  • Hierarchyウィンドウから、RollerBallBrainオブジェクトをドラッグして、InspectorウィンドウのBrainフィールドにドロップします
  • Inspectorウィンドウで、Dicision Frequency1から5に変更します
    • エージェントは、この設定のステップ数ごとにブレインへ観測データを送信して意思決定を要求します。行動(Action)は1ステップごとに行われます(バランスボールのサンプルもこの値は5でした)

また、HierarchyウィンドウからTargetオブジェクトをドラッグして、RollerAgentTargetフィールドにドロップします。

f:id:am1tanaka:20181113220102p:plain

最後に、RollerBallBrainゲームオブジェクトをクリックして選択したら、Inspectorウィンドウで以下を設定します。

  • Vector Observation Space Size = 8
    • ブレインに送る観測データベクトルの次元数(要素数)
  • Stacked Vectors = 1
  • Visual Observation = 0
    • 観測データとして利用するグラフィックの数。今回は未使用なので0
  • Vector Action Space Type = Continuous
    • 行動結果を表すベクトルを、整数(Discrete)で返すか、小数(Continuous)で返すか
  • Vector Action Space Size = 2
    • 行動結果として返すベクトルの次元数(要素数)
  • Action Descriptions = 2
    • Vector Actionの各要素の説明
  • Brain Type = Player
    • 意思決定の種類
      • Player = 人が操作する
      • Heuristic = 行動決定のためのアルゴリズムDecitionインターフェースを実装したクラスを作成して、自前で実装する
      • External = Pythonと通信して、TensorFlowなどに意思決定させる
      • Internal = TensorFlowを使って学習済みのモデルで意思決定する

f:id:am1tanaka:20181113134844p:plain

以上で、トレーニングを開始する前に、環境を試す準備ができました。

環境を試す

実際にトレーニングを開始する前に、手動で環境を試すのはよい手順です。Brain TypePlayerのままにしてあるので、キー入力でエージェントを動かすことができます。前後左右の4方向に4つのキーを割り当てます。

  • HierarchyウィンドウでRollerBallBrainオブジェクトをクリックして選びます
  • InspectorウィンドウのKey Continuous Player Actions欄を開きます(この設定は、Brain TypePlayerの時のみ表示されます)
  • Size4にします
  • 以下の通り、設定します
Element Key Index Value
Element 0 D 0 1
Element 1 A 0 -1
Element 2 W 1 1
Element 3 S 1 -1

Indexの値は、AgentAction()関数に渡す配列のインデックスを表します。Valueの値は、Keyが押された時にvectorAction[Index]に渡される値です。

Playすると、[W][A][S][D]キーで、Agentを操作することができます。エラーが発生しないことと、Targetに触ったり床から落ちたらエージェントがリセットされることを確認してください。ML-Agents SDKには、ゲームウィンドウにエージェントの状態を簡単に表示させることができるMonitorクラスが用意されています。より詳細な状態が見たい場合は利用するとよいでしょう。

(ここではやりませんが)作成した環境とPython APIが想定通りに動くかどうかを、Jupyter notebookを使って試しておくことができます。確認のためには、notebooks/getting-started.ipynbを利用します。ノートブックのenv_nameに、この環境をビルドして生成した実行ファイル名を設定します。

学習の準備が整ったら、ブレインのBrain TypePlayerからExternalに変更します。ここから先の手順は、Training ML-Agentsと同じです。

シーンレイアウトを振り返る

最後に、作成した環境でエージェントがどのように動作するかを振り返っておきましょう。

今回のトレーニングをUnity ML-Agentsで実行するために、3つのゲームオブジェクトを作成しました。

  • Academy
  • Brain
  • Agents

約束事です。

  • 1つのシーンには、Academyゲームオブジェクトを1つだけ配置できます
  • Brainは1つのシーンに複数配置できますが、それらはすべてAcademyゲームオブジェクトの子にする必要があります

以下、シーンのHierarchyの見え方の例です。

example hierarchy

(https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Learning-Environment-Create-New.md より)


元記事には学習手順と学習結果を利用する手順が省略されているので、以下に補足します。

学習手順

前提

Unity ML-AgentsをWindows10で使う 2018年11月版 - tanaka's Programming Memoが完了していることを前提にします。

準備

まずはブレインを外部に変更します。

  • HierarchyウィンドウでRollerBallBrainをクリックして選択します
  • Inspectorウィンドウで、Brain TypePlayerからExternalに変更します

学習の設定をします。デフォルトの5万ステップだと、あまり学習の成果が見られません。3D Ballのサンプルは12個のエージェントを同時にトレーニングしていたので2万ステップ程度で効果が表れましたが、こちらは同時に1つのエージェントしかトレーニングしないので、その10倍の20万ステップは最低でも学習させたいところです。余裕をもって、50万ステップに設定します。

また、ニューラルネットワーク-11の範囲のデータを受け取る仕様になっています。ところが、今回のサンプルでは状況に応じてこの範囲を超えてしまうことがあり、学習の妨げになります。そこで、正規化フラグを有効にすることで範囲外の数値が来たら-11の範囲に収めるように設定します。

  • ML-Agentsのリポジトリーからダウンロードしたml-agents-masterフォルダー内のconifg/trainer_config.yamlを何らかのテキストエディターで開きます
  • 22行目のcuriosity_enc_size: 128という行と、24行目のBananaBrain:の間に、以下を追加します
24:
RollerBallBrain:
    normalize: true
    max_steps: 5.0e5
  • 上書き保存します

これで、UnityのRollerBallBrainという名前のブレインをトレーニングする場合、以下が有効になります(このためにBrainの名前をRollerBallBrainに変更しました)。

  • 入力データを正規化(normalize)する
  • ステップ数を50万回(5.0e5は、5x10^5の意味)

学習させる

Pythonを使って学習を開始します。

  • Windowsの検索バーにanaと入力して、Anaconda Promptを起動します
  • cdコマンドで、ml-agents-masterのフォルダーに移動します。作成したUnityProjectではなく、ML-AgentsのGitHubリポジトリーをダウンロードして展開したフォルダーの方です
  • 以下を入力します
mlagents-learn config/trainer_config.yaml --run-id=RollerBall --train
  • Unityのアスキーアートが表示されて、INFO:mlagents.envs:Start training by pressing the Play button in the Unity Editor.という表示が出たら、Unityに切り替えて、Playすれば、学習が始まります。

f:id:am1tanaka:20181113224106p:plain

ログの見方

コンソール画面に謎の文字が表示されますが、ここから学習がどのように進んでいるかを読み取ることができます。このログは、設定した回数ごとの集計になっています。デフォルトでは千回に1回、集計されて以下のように表示されます。

f:id:am1tanaka:20181114172135p:plain

Step以降を見ていきます。上の例ではStep: 360000.になっています。359001回~360000回のステップのトレーニングが完了した時の情報ということです。

大切なのは、それに続くMean RewardStd of Rewardの2つの数値です。

Mean Reward

リワードの平均値です。今回の例なら、36万ステップまで千ステップの平均リワードが1.149だったということです。この値は、最初は-15ぐらいでしたので、かなりの学習成果が上がっているということになります。

この値は、上がったり下がったりを繰り返しつつ、徐々に大きくなっていくはずです。5万~10万ステップぐらいまでは変化しているように見えない場合もありますので、慌てずじっくりと眺めてください。

20万ステップしても変化がないようなら、学習効果が得られない設定になっている可能性があります。プログラムや考え方を見直してみてください。

Std of Reward

リワードの標準偏差です。標準偏差とは、データのバラつきを表す値です。全てのリワードが同じ値ならこの値は0になり、バラけているほど大きな値になります。

AIがめちゃくちゃに動いている最初の方はリワードがバラバラになるので、大きな値になりがちです。頭が良くなるにつれて行動が似てくるのでリワードのバラつきが減り、この値は小さくなっていくのが一般的です。

いきなりこの値が小さい場合、めちゃくちゃに動いてもリワードが変わらないということなので、エージェントの設定を失敗している可能性があります。

条件によっては学習が進むほどこの値が大きくなることもあります。この値が小さくなれば十分に学習できた、と単純には言えないということです。バラつきを表す値ということを考えて、値を読み取ってください。

学習は何ステップがよいか

条件によって結構変化しますが、とりあえず2Dのものなら50万ステップ程度が目安のように感じています。学習をさせすぎると成績が悪化する過学習という現象が起きる場合があります。学習後にMean Rewardを確認して、スコアが悪化していくようなら、丁度良さそうなステップ数を確認して、その回数で学習し直すとよいでしょう。

まだスコアが伸びそうな場合は、trainer_config.yamlmax_stepsの値を増やして上書き保存をしてから、Anaconda Promptで以下を実行すれば、先ほどのデータの続きから学習を再開できます(すでに学習ステップ数がmax_stepsに達していたら、学習を再開させてもすぐに終わってしまいます。学習回数を増やす場合は、trainer_config.yamlmax_stepsも増やしてください)。

mlagents-learn config/trainer_config.yaml --run-id=RollerBall --train --load

今回のプロジェクトだと、30万ステップぐらいでほぼ安定して、50万ステップまで少しずつ精度が上がっていった(Std of Rewardが小さくなっていった)感じでした。

考察(おまけ)

前よりターゲットに近づいた時に与えるリワードを0.1にして、毎回の減点より大きい数値にして試すと、100万ステップ学習させてもスコアが伸び続けました。面白いのが、標準偏差も大きくなっていったことです。近寄るごとにリワードがもらえる設定だと、Targetをすぐに取るよりも、ゆっくり近づいて取った方がリワードが多く得られるようでした。そうなると、どこにTargetが出るかによって点数に差が出るようになります。リワードが出現位置の乱数に影響を受けるようになるため、標準偏差の値が大きくなっていたものと思われます。

なるべく早くTargetを取るAIにしたかったので、リワードを見直して今回のパラメーターにしました。

再生手順

最後に、学習したモデルデータをUnityのプロジェクトに組み込んで再生してみましょう。

TensorFlowSharpプラグインをプロジェクトにインポートします。ダウンロードしていない場合は、こちらからダウンロードして、インポートしてください。PC上で試すだけなら、AndroidiOSプラグインは不要なので、チェックを外した方が容量やインポート時間を節約できます。

f:id:am1tanaka:20181114001257p:plain

インポートが完了したら、TensorFlowを有効にするための設定をします。

  • Editメニューから、Project Settings > Playerを選択します

以下を、利用したいプラットフォームごとに実施します

  • Other Settingsを開きます
  • Scripting Defined Symbols欄に、ENABLE_TENSORFLOWを入力して、[Enter]キーを押します
  • [Ctrl]+[S]キーを押して保存します

以上で、Brain ModeInternalが利用できるようになります。

学習したモデルデータをプロジェクトに読み込みます。モデルデータはml-agents-masgterフォルダーの中に、models > run-idで設定した名前のフォルダーの中に入っています。

  • エクスプローラーなどでml-agents-masterフォルダー内の、models/RollerBallフォルダーを開きます
  • .bytesファイルをドラッグして、UnityのProjectウィンドウにドロップします

f:id:am1tanaka:20181114010242p:plain

最後に、ブレインの設定を切り替えて、モデルデータを設定します。

  • Hierarchyウィンドウで、RollerBallBrainをクリックして選択します
  • Inspectorウィンドウで、Brain TypeInternalに変更します
  • Projectウィンドウからモデルデータをドラッグして、InspectorウィンドウのGraph Model欄にドロップします

f:id:am1tanaka:20181114010533p:plain

以上で完了です。Playをすれば、学習させたAIがRollerAgentを操作してTargetを取っていくのが確認できます。

f:id:am1tanaka:20181114011102g:plain

まとめ

新規プロジェクトから学習用の環境を構築して、学習、結果の利用ができました。入力や出力を当てはめられるものであれば、自前のプロジェクトに組み込めそうです。

学習させる上で、以下の知見が得られました。

  • 学習は50万ステップ程度は見込んでおく
  • 同時に複数のエージェントを学習できるように、3DBallのように親オブジェクトからの相対座標で動く環境を作るとよい(この記事の作り方だと、同時に学習できないのでステップ数が多くなるので)
  • サブリワードの設定は、学習の回数を減らしたりイメージに近い行動をさせるのに大いに有効
  • 正規化も重要。コード側で正規化をしていない場合は、設定のnormalizeフラグを利用する

一年前はこの辺りで他のことを初めてしまってとん挫したので、今回は自分で作った環境でAIを鍛えたいです。

参考URL

Unity ML-AgentsをWindows10で使う 2018年11月版

f:id:am1tanaka:20181107163745g:plain

Unityで機械学習(Machine Learning)が使えるML-Agentsについて、1年前に導入の記事を書きました。あれから大幅に変更されて、動作環境やセットアップ手順が変わったので、2018年11版としてまとめ直します。

  • レーニング時に、待ちすぎると待機が終わる注意を追記(2018/11/9)
  • TFSharpのインポート時に、必要がなければAndroidiOSのチェックを外すとよいというコメントを追記(2018/11/8)

目次

Unity ML-Agents Toolkit (Beta)について

https://github.com/Unity-Technologies/ml-agents よりざっくりと。

Unity Machine Learning Agents Toolkit(ML-Agents)は、AIで動くエージェントをゲームやシミュレーションでトレーニングするための環境を提供します。エージェントは、強化学習(Reinforcement learing)、模倣学習(Imitation learning)、遺伝的アルゴリズム学習(Nueroevolution)、その他の機械学習を簡潔に使えるPython APIを通して学習させることができます。また、TensorFlowで構築された最新鋭のAIエージェントを2D、3D、VR/ARゲームなどでトレーニングして使う機能も提供します。これらのトレーニングされたエージェントは、NPMの振る舞いを制御することを含めて、ゲームの自動テストや、リリース前に異なったゲームのデザインを評価するなど様々な目的で利用できます。

機能

  • PythonからUnityの環境を操作
  • 10以上のUnity用のサンプル
  • 複数の環境設定や、トレーニングシナリオに対応
  • ディープラーニングを使ってメモリーを強化したエージェントのトレーニン
  • 分かりやすい学習シナリオのカリキュラム定義
  • 教師あり学習(supervised learning)のためのエージェントの振る舞いのブロードキャスティング
  • 模倣学習のための組み込みに対応
  • On Demand Decision Making(要求された時に意思決定をする)による自由度の高いエージェント制御
  • 環境内でのネットワークの視覚化
  • Dockerによる環境構築
  • ジム(gym)として学習環境をラッピングする機能

インストール手順

ml-agents/Installation.md at master · Unity-Technologies/ml-agents · GitHubを参考に、Windows10で環境を構築する手順です。簡単にするために、ドキュメント通りではない部分があります。

インストール手順概要

ML-Agentsの環境は以下の通り。

なお、このブログでは以下の環境で確認しました。

  • Windows10
  • Unity2018.2.10とUnity2017.3.0(推奨環境ではありませんが、3DBallは動きました)
  • Anaconda5.1 + Python3.6
  • TensorFlow1.7.1

Unity2017.4以降のインストール

Unity2017.4以降がインストールされていればOKです。Dockerを利用する場合は、Linuxビルドが必要ですが、今回は利用しないので、Linuxビルドは不要です。

ML-Agentsツールキットリポジトリーのダウンロード

gitが利用できる環境であれば、コマンドラインを開いて、リポジトリーをダウンロードしたいフォルダー(ドキュメント -> Unity Projectsフォルダーなど)に移動してから、以下を実行します。

git clone https://github.com/Unity-Technologies/ml-agents.git

Gitの利用が不安な場合は、こちらのページを開いて、以下を実行します。

  • Webページ右の緑色のClone or Downloadボタンをクリックします
  • Download ZIPを選択して、ZIPファイルをダウンロードします
  • ml-agents-master.zipのダウンロードが完了したら、プロジェクトを保存したいフォルダー(ドキュメント -> Unity Projectsフォルダーなど)に全て展開します

以上でml-agents-masterフォルダーに以下のファイルが展開されます。

UnitySDKフォルダー

ML-Agentsを利用したいプロジェクトに追加が必要なUnityアセットが入っています。このフォルダー内には、UnityでML-Agentsを使い慣れるのに便利な多くのサンプル環境も入っています。

ml-agentsフォルダー

AIをトレーニングしたり、UnityとPythonを連携させるためのPython APIなどのPythonパッケージが入っています。

gym-unityフォルダー

ブロック崩しピンボールなどのゲーム向けAIなどを強化学習で教育するためのツールキットであるOpen AI GymをUnityで使うためのインターフェースが入っています。

Pythonとmlagentsパッケージのインストール

以下をインストールしていきます。

注意!

  • 現在、Python3.5や3.7はサポートしていません

インストール手順

ml-agents/Installation-Windows.md at master · Unity-Technologies/ml-agents · GitHubを参考にインストールをします。

ML-AgentsはWindows10のみでテストされています。他のWindowsやBootcampやParallelsのような仮想マシンでも動く可能性はありますが、動作テストはされていません。

Step 1: Anacondaを使ってPythonをインストール する

Windows用のAnacondaをダウンロードしてインストールします。Anacondaは、Pythonの科学計算向けパッケージです。Python自体を含み、複数の独立したPython環境の構築ができます。

ML-Agentsでは、少し古いAnaconda5.1を利用します。Anacondaのサイトからだと、古いバージョンのダウンロードリンクが動いていないようなので、64-bitならこちら32-bitならこちらからダウンロードしてください(ビット数が分からない場合は、とりあえず64ビットのものを使ってみてください)。

オプションはそのままで構わないので、インストールを進めます。

  • VSCodeは不要なので、以下はSkipします

f:id:am1tanaka:20181106162826p:plain

  • 完了したら、特に何も開く必要はないので、チェックを外してFinishをクリックします

f:id:am1tanaka:20181106162911p:plain

インストールが完了したら、仕上げのためにAnaconda Navigationを起動して設定をします。

  • 検索バーに(検索バーが表示されていなければスタートボタンをクリックしてから)anaと入力すると、Anaconda Navigationが検索で表示されるのでクリックします

f:id:am1tanaka:20181106163055p:plain

  • 設定が完了したらアプリが起動するので、OK, and don't show ageinをクリックします

f:id:am1tanaka:20181106163619p:plain

  • 以上が完了したら、アプリを閉じます

f:id:am1tanaka:20181106163626p:plain

コマンドラインからAnacondaを使えるようにするために、環境設定を実行します。

  • 検索バーに環境と入力するなどして、環境変数を編集を開きます

f:id:am1tanaka:20181106165350p:plain

  • Path欄をダブルクリックします

f:id:am1tanaka:20181106165504p:plain

  • 新規ボタンをクリックして、以下の2つのパスを追加して、OKをクリックします
%UserProfile%\Anaconda3\Scripts
%UserProfile%\Anaconda3

以上で、コマンドラインからAnaconda用のコマンドであるcondaが呼び出せるようになりました。

Step 2: 新規にCondaの環境(Conda environment)を設定する

ML-Agentsツールキット用のCondaの環境を作成します。Condaの環境を利用することで、ML-Agentsの動作に必要なパッケージをインストールする影響を限定して、システム全体や他のPython環境に影響を与えるのを防ぎます。Conda環境は、ML-Agentsを実行したい時に必要に応じて有効にすることができます。

Anaconda Promptを使って環境設定をします。

  • 検索バーにanaと入力して、リストアップされるAnaconda Promptをクリックして起動します

f:id:am1tanaka:20181106172435p:plain

  • 以下のコマンドを実行して、Python3.6の環境を、ml-agentsという名前で新規に作成します
conda create -n ml-agents python=3.6

f:id:am1tanaka:20181106172653p:plain

  • yを入力して[Enter]キーを押して、設定を完了させます

f:id:am1tanaka:20181106172839p:plain

Anaconda環境の有効化

ML-Agentsでこの環境を利用する場合は、Anaconda Promptから以下のコマンドを実行します。

activate ml-agents

これで、作成したml-agents環境が有効になり、以下のようにプロンプトが変更されます。

f:id:am1tanaka:20181106173153p:plain

TensorFlow1.7.1のインストール

機械学習ライブラリであるTensorFlowを、作成したConda環境にインストールします。先に開いたAnaconda Promptで、ml-agentsを有効にしたら、以下を実行します。

pip install tensorflow==1.7.1

f:id:am1tanaka:20181106173407p:plain

注意!! ML-Agentsは、TensorFlowの最新版はサポートしません。必ず、指定のバージョン(1.7.1)をインストールしてください。

Step 3: 必要なPythonパッケージのインストール

先にダウンロードしていた、ML-AgentsのGitリポジトリーフォルダーに移動して、インストールコマンドを実行します。Step 2に続けて、Anaconda Promptで作業します。

  • cdコマンドで、先ほどダウンロードして展開したML-Agentsのフォルダー内のml-agentsフォルダーを開きます
    • 展開したのがユーザーのドキュメントフォルダー内のUnity Projectsフォルダーだった場合は、以下のようになります。違うフォルダーに展開した場合は、そのフォルダー内のml-agentsフォルダーを開いて下さい
cd %USERPROFILE%\Documents\UnityProjects\ml-agents-master\ml-agents
pip install .

Step 4のGPUレーニングは使わなくてもよいのでとりあえず飛ばします

以上でインストール完了です。

最初の手引き

以下の内容に沿って、インストールした教育済みモデルの例をUnityで動作させる手順と、どのようにモデルをトレーニングするかの手順を示します。

github.com

UnityでML-Agentsツールキットを準備する

まずは、ML-Agentsツールキットを利用するための設定をして、TensorFlowSharpプラグインを組み込みます。

  • 2017.4以降のUnityを起動します
  • Openをクリックして、ダウンロードして展開したml-agents-masterフォルダー内のUnitySDKフォルダーを開きます

f:id:am1tanaka:20181107145656p:plain

  • バージョン違い確認のダイアログが表示されたら、Continueをクリックして、読み込みを進めます

この段階ではまだエラーが発生します。設定を続けます。

  • プロジェクトが起動したら、Editメニューから、Project Settings > Playerを選択します
  • 以下を、利用したいプラットフォームごとに実施します
    • Other Settingsを開きます
    • Scripting Runtime VersionExperimental、あるいは.NET 4.6 Equivalent、あるいは.NET 4.x Equivalentにします

f:id:am1tanaka:20181107150052p:plain

  • Scripting Defined Symbols欄に、ENABLE_TENSORFLOWを入力して、[Enter]キーを押します

f:id:am1tanaka:20181107150241p:plain

  • FileメニューからSave Projectを選択します

TensorFlowSharpプラグインのインストール

こちらからTensorFlowSharpプラグインをダウンロードします。

ダウンロードが完了したら、ダウンロードしたファイルをダブルクリックするか、UnityのProjectタブにドラッグ&ドロップして、プロジェクトにインポートします。AndroidiOSでの利用の予定がない場合は、インポートするパッケージからチェックを外しておくとよいです(ご指摘下さったHayatoさん、ありがとうございます!)

インポートが成功したら、Assets > ML-Agents > Plugins > Computerフォルダー内に、TensorFlow関連のファイルが確認できます。

f:id:am1tanaka:20181107152720p:plain

以上で、エラーがなくなります。

レーニング済みのモデルを動作確認

3DBallを実行してみましょう。

  • ProejctタブでAssets/ML-Agents/Examples/3DBallフォルダーを開いて、3DBallシーンをダブルクリックして開きます

f:id:am1tanaka:20181107152947p:plain

  • Hierarchyタブで、Ball3DAcademyゲームオブジェクトの子供のBall3DBrainオブジェクトを選択します

f:id:am1tanaka:20181107153107p:plain

f:id:am1tanaka:20181107153220p:plain

  • Projectタブで、Assets/ML-Agents/Examples/3DBall/TFModelsフォルダーを開きます

f:id:am1tanaka:20181107153355p:plain

  • 3DBallモデルをドラッグして、InspectorタブのGraph Model欄にドロップします

f:id:am1tanaka:20181107153526p:plain

以上で設定完了です。Playすると、板の上でボールのバランスをとる様子が確認できます。

f:id:am1tanaka:20181107153610p:plain

強化学習(Reinforcement Learning)のトレーニン

Brainを外部(External)に設定

学習はUnityとPythonを連携させて行うので、Brainを外部にあるPythonとつなげるためにExternalにします。

  • Hierarchyタブで、Ball3DAcademyオブジェクトの子供のBall3DBrainオブジェクトを選択します
  • InspectorタブのBrain Type欄をExternalに変更します

f:id:am1tanaka:20181107155442p:plain

学習の開始

学習は、Anaconda Promptから行います。Anaconda Promptが閉じている状態から開く手順を示します。

  • 検索ボックスにanaと入力して、Anaconda Promptが表示されたらクリックして開きます

f:id:am1tanaka:20181106172435p:plain

  • 以下を実行して、ML-Agents環境に切り替えます
activate ml-agents
  • cdコマンドで、ml-agents-masterフォルダーに切り替えます
  • 以下を入力して、トレーニングの開始を準備します
mlagents-learn config/trainer_config.yaml --run-id=firstRun --train

ツールが起動すると、以下のような画面が表示されて待機状態になります。

f:id:am1tanaka:20181107160032p:plain

  • UnityでPlayします

f:id:am1tanaka:20181107160314p:plain

Unityでボールのバランスを取るトレーニングがはじまります。最初は下手ですが、徐々に上手になっていくのが確認できます。Anaconda Promptの方では、学習の様子が表示されます。

f:id:am1tanaka:20181107160714p:plain

実行が始まらない場合

実行が始まらない場合は、開始するフォルダーを間違えている可能性があります。ML-Agentsのリポジトリーを展開したml-agents-masterフォルダーにいることを確認してください。

また、Anaconda Promptでmlagents-learn config/trainer_config.yaml --run-id=firstRun --trainコマンドを実行したあと、UnityでPlayしないまま1分程度放置すると待機が終わってUnity側でエラーが発生します。Anaconda Promptを実行してUnityでPlayするようメッセージが表示されたら、速やかにUnityの方もPlayしてください(2018/11/9追記)

レーニングを終了する

レーニングは、5万ステップに達したら自動的に終了するような設定になっています。

f:id:am1tanaka:20181107161155p:plain

AIでは過学習といって、学習させすぎるとかえって精度が落ちる場合があります。学習の途中でも十分な成果が出ていると感じたら、[Ctrl]+[C]キーを押して停止することができます。

レーニングしたモデルは、models/<run-identifire>/editor_<academy_name>_<run-identifier>.bytesというファイルに保存されます。

f:id:am1tanaka:20181107161607p:plain

<academy_name>は、現在のUnityシーンでのAcademyゲームオブジェクト名です。このファイルに、最後のチェックポイントの状態のモデルが記録されています。以下の手順で、学習させたモデルをプロジェクト内部に組み込むことができます。

  • 保存された上記の.bytesファイルを、UnitySDK/Assets/ML-Agents/Examples/3DBall/TFModels/フォルダーにコピーします
  • Unityに切り替えて、3DBallシーンが開いていることを確認します
  • Hierarchyタブから、Ball3DBrainオブジェクトを選択します

f:id:am1tanaka:20181107162002p:plain

  • Inspectorタブで、Brain TypeInternalに切り替えて、読み込んだ学習ファイルをGraph Model欄にドラッグ&ドロップします

f:id:am1tanaka:20181107162242p:plain

以上で設定完了です。UnityでPlayすると、先ほど学習したモデルでの実行を試せます。

本当に学習したモデルなのか?

学習を完全にやると、最初の時と同じなので自分で学習させたのか良く分かりません。そこで、不完全な学習状態のデータを作って、それを設定してみましょう。以下は概略なので、分からない部分があったら、これまでの説明に戻ってください。

  • Brain TypeExternalに切り替えます
  • Anaconda Promptで上カーソルキーを押すと、学習させる時に入力したコマンドを呼び出せるので、[Enter]キーを押します
  • 学習の待機状態になったら、Unityに切り替えてPlayします
  • Anaconda Promptで経過を見て、Stepが5000になったら、[Ctrl]+[C]キーを押して、学習を停止します

f:id:am1tanaka:20181107162651p:plain

  • Unityに切り替えて、Projectタブで先ほど読み込んだ学習ファイルeditor_Ball3DAcademy_firstRun-0.bytesを削除します
  • 学習させなおしたeditor_Ball3DAcademy_firstRun-0.bytesを、ProjectタブのUnitySDK/Assets/ML-Agents/Examples/3DBall/TFModels/にドラッグ&ドロップし直します
  • Brain TypeInternalに切り替えます
  • Inspectorタブで、Brain TypeInternalに切り替えて、読み込んだ学習ファイルをGraph Model欄にドラッグ&ドロップします

以上で、今度は全然バランスが取れない状態が確認できます。これで、自分が学習させたファイルだったことが確認できるでしょう。

f:id:am1tanaka:20181107163745g:plain

このあと

このブログでは、以下のドキュメントのInstallation & Set-upの内容を紹介しました。

ml-agents/docs at master · Unity-Technologies/ml-agents · GitHub

新規のUnityプロジェクトにML-Agentsの環境を作って、学習、再生する記事であるml-agents/Learning-Environment-Create-New.md at master · Unity-Technologies/ml-agents · GitHubについて以下にまとめました。続きに是非どうぞ。

am1tanaka.hatenablog.com

あるいは以下のような場合はそれぞれのものを読み進めるとよいでしょう。

www.youtube.com

最後に

1年が経過して、インストール手順も学習方法もシンプルになりました。Jupyter Notebookを使わずにコマンドラインで学習できるようになったのはいいですね。Jupyterも引き続き使えるので、必要になったら使えます。

このブログの内容で、Examplesの中のプロジェクトを一通り試すことはできると思います。サンプルプロジェクトのBrain Typeは、最初はプレイヤーが自分で操作するPlayerモードになっているので、それをInternalに変更すれば学習済みのAIの動きを見ることができます。

自分でモデルを作って学習させる方法は分からないので、引き続きドキュメントを読んでまとめていきます。

参考URL

Unity Hubで、最新じゃないバージョンをインストールする

Unity Hub、便利なんだけど少し前のバージョンがインストールできないんだよな...と思っていたのですが、インストール方法がありました!

Unity Hubからは、各マイナーバージョンの最新版のみですが、Unity公式の過去のバージョンがダウンロードできるダウンロードアーカイブページに、Unity Hubのボタンがあって、これをクリックすればUnity Hubでインストールできました!

f:id:am1tanaka:20181106210016p:plain

これで晴れて、Unity Hubを激押しできる!!

デジゲー博に出展してきました!

f:id:am1tanaka:20181104212822j:plain

2018/11/4 秋葉原UDX2階 アキバ・スクエアと4階 UDXギャラリーNextで開催されたデジゲー博に、開発中のスマホ用パズルゲームVoxelorer Bird(ボクセローラーバード)を展示してきました!同時に、非常勤講師を勤めています池袋にある専門学校デジタルアーツ東京のゲームプログラマーコースの学生さん作品を展示しました。

目次

今回の目的

出展すること!

今回の目的はとにかくこれでした。申し込み時のトレイラー画像がこちら。

f:id:am1tanaka:20181104214149p:plain

キャラクターがちょっと違うしジャンプしてるし・・・。当初は何を出すか決めておらず、専門学校の体験授業で使ってる素材のデモ展示でもしようと考えていました。9月になって、Unity1週間ゲームジャムで公開した溶岩番にたくさんいいねをいただきまして、自分自身でも改良案が沢山浮かんできます。これならスマホアプリ化できるのでは?と思い立って、溶岩番を元にしたスマホアプリを開発して展示することにしました。それが今回のVoxelorerBirdでした。

学生さん作品

展示の左半分は学生さん作品。今回の展示で素晴らしい活躍をしてくれたるな氏はただの重力球 (@runa_rockmoon) | Twitter君が開発している神経衰弱バトルもりのひの試遊展示と、中央のタブレットでは1年生の皆さんの作品の動画を流しました。

f:id:am1tanaka:20181105234048p:plain

神経衰弱バトル【もりのひ】

f:id:am1tanaka:20181105234448p:plain

タワーディフェンスゲーム【スバコ・ディフェンス】

f:id:am1tanaka:20181105234830p:plain

対戦ゲーム【エアホッケー

f:id:am1tanaka:20181105234732p:plain

ノベルゲーム【イスポール戦記】

お時間を割いて遊んでいただき、沢山のご意見をいただきました。本当にありがとうございました。これ以上ない糧になったはずです。さっそく月曜日にいただいたご意見をもとに改良に取り組んでいました!

配布物と遊んでいただいた回数など

配布物がどれぐらい必要かが分からなかったので、何となくシールを50枚作成しました。結果、配布できたのは40枚ほどだったので、少なすぎず、多すぎず、ちょうどよい数でした。展示が11時から16時の5時間。シールは試遊していただいた方に差し上げたので、試遊回数と配布枚数は同じです。おおよそ7~8分にお一人が試遊されたということで、今後の展示の時の基準にできそうです。他のいくつかの出展された方のブログでも、おおよそ30~40枚と拝見しました。

二人体制で回したので、2ゲーム合わせると70名ほどの方に遊んでいただきました。試遊の回転を上げたり、配布枚数を増やしたい場合は、単純に売り子を増やすのがよさそうです。

また、こちらからお声掛けしないと遊んでいただくのは難しかったです。どのようなゲームか遠目でも分かるようにした上で、ちょっと目線が来ていると思ったら「試遊できます」とお声掛けすることで遊んでいただけました。

ブースの材料

まずは今回の目玉のポスター。

B3というちょっとイレギュラーなサイズにしましたが、1ブースの机の上に立てておくにはちょうど良いサイズだったと思います。スタンドとかあればもっと大きいのを背後に飾るのもいいなと思いましたが、机の上の方がインパクトがあった気がしますし、目線が分かりやすくて声掛けがしやすかったので、これは今後もやろうと思います。ブースが大きければもう1サイズ大きくてもよさそうでした。

作成は、お店とか知らないので、なんとなく知ってたアスクルさんで発注しました。

画像データはUnityで作りました。ポスター用の解像度で出力するカメラを作って、テクスチャーにレンダリングしたものをスクリプトPNGに保存。ポストプロセスとかフォントとか、レイアウトや効果を使ってデザインするのに一番慣れているのがUnityという事実。解像度はカメラの設定で自由ですし、今後もこの手法でいこうと思いました。作成したPNGアスクルさんのオンラインの入稿データ作成サービスにアップロードして、余白とか調整して発注しました。

仕上がったポスターは、ハンズで購入したB3用のパネルに両面テープで貼り付けました。それを、段ボールで作ったイーゼルもどきに立てかけて展示しました。

シールも同じくアスクルさんのシール・ステッカー・ラベル作成/印刷|1000円以上送料無料!| パプリby ASKULで。こちらも文字も含めてUnityで画像データを作りました。入稿方法もポスターとほぼ一緒。

危うく失敗しそうだったのがシールの納品期間でした。営業日だから土日は日数から外さないといけなかったのに、そのままの日数で考えてしまって到着がギリギリになりました。クロネコさんが発送日のうちに運んでくれたことで前日には余裕で受け取れて事なきを得ましたが、シールなしを覚悟していました。

テーブルクロスは東急ハンズさんで。今後も使うことがあるだろうしと、ちょっと高かったですが、手触りがよくて皺になりにくそうな素材のやつを選びました。とてもきれいな感じになったので満足です^^

底上げの台は100均の折り畳みできる物入れ2つ。その上にハンズで買ったパネルを並べて、そこに布をかけて机の出来上がり。スマホのスタンドは140円の黒い厚紙を切って自作しました。

数年前に某地理系のイベントに出展した時は、自宅のプリンターで印刷したA4の紙を貼り合わせてポスターを作りましたが、クオリティが低くて大失敗でした。その反省から、目に見える場所はお金をかけるというのが今回の裏テーマでした。その甲斐あって、良い感じのブースにできました。届いたポスターのクオリティは感動もの!シールもいい感じで仕上がっていて、グッズ作り、これはハマります。

会場で他の出展者さんのところにあった、後ろに立てて大きいポスター貼れるスタンドもいいなーと思いました。今後も展示を続けるなら、いずれゲットしたいです。A0のでかいポスター作りたい。

次回に向けて

試遊時間をちゃんと考えていなかったのは失敗でした。デジゲー博専用のステージを用意したものの、ほとんど出番なしorz クリアされたのはYさんおひとりでした(完全クリア、おめでとうございます!)

ゲームの説明用のステージ1つ、ちょっと応用ステージ2つ、最後にチャレンジステージで終わり。というぐらいで次は準備しようと考えています。

展示については以下の通り。

  • ベルトポーチを持って行って、道具はそれにまとめて入れる
  • スマホの落下防止はフックなどで簡単に付けられるものにする
  • 充電ケーブルは長さが十分で取り回しやすいやつを用意

ノベルティについて。細かいものを手に持っておられたのが邪魔そうだったので、A4サイズの紙が入る手提げ袋とかクリアフォルダーなどを用意するとお役に立つかなと感じました。

今回は自分が不慣れなので、無理に学校からブースは出さず自分のブースに詰め込みましたが、さすがに手狭でした。グッズとか作っても広げられないし、次回はLooking Glassでの展示もできるはず。出展の要領は分かったので、次は学生さんと共同で2ブース構成にしたいなと考えています。

DATフェスタについて

学生さん作品の本番は、一週間後の11/9(金)、10(土)に池袋の専門学校デジタルアーツ東京で開催されるDATフェスタです。今回から一週間でどのように改良されるか、私も楽しみにしております(学園祭前の一週間は準備のため講義がなくなるため、非常勤講師の私は出講しないので、本番当日までどうなるか分からないのです^^;)

会場はこちら。よろしければお運びください!私は金曜日に少し顔を出すだけなのでほぼ不在だと思いますが、学生さんと直にがっちりコミュニケーション取れるはずです!

最後に

人混み&情報量が多いのが苦手ということで、物凄く疲れました。自分は他のブースを回るだけの気力&体力がなかったので、るな氏はただの重力球君に会場周りはお願いしました。

激疲れしましたが、目の前で操作を拝見したり、ご意見をいただくことで多くの改良のヒントを得られて収穫も大漁でした!「面白い!」とのめり込んで遊んでくださる方がいらっしゃったことは、頑張って準備した甲斐があったと実感できました。るな氏はただの重力球くんも同様だったと思います。1年生のT君が遊びに来てくれたのも嬉しかったですし、多くの凄いゲームを体験して大いに得るものがあったと思います。これを機に、出展できそうなところには今後も出ていこうと思いました。頑張って完成させるぞ!

ブースにご挨拶にきてくださった皆様、立ち止まって時間を割いて遊んでくださった皆様、貴重なご意見を下さった皆様、状況を察して遠くから見るに留めて下さった皆様、本当にありがとうございました。個人名を出すことは控えますが、お一人お一人に深く感謝しております。

最後にの最後になりますが、素晴らしい展示会を運営して下さりました、デジゲー博準備会の皆様、お疲れ様でした。そして、ありがとうございました!

関連URL

UnityのプロジェクトをiPhoneSE実機で動かした時にハマったポイント

ようやくスマホで公開してみようという作品が出来たので、Unityプロジェクトを手元のiPhone実機で動かしてみました。動かすまでにあちこちハマったので忘れないうちに備忘録を。

f:id:am1tanaka:20181007135314p:plain

目次

必要なもの

以上です。アプリを配布したり、iCloudを利用したりせず、実機で動作テストがしたいだけなら年間1万円ちょっとのAppleデベロッパーアカウントは必要ありません

バイス向けにビルドするために Apple Developer アカウントは必要ありません。テストの目的であなた自身のデバイスだけにビルドするには、どんな種類の Apple ID でも十分です。(Unity公式マニュアルより)

開発者の登録

開発用にApple IDを作成しておくとよいようです。そのIDに開発者設定を加えます。以下のサイトが参考になると思います。

Appleの開発者登録をする, iOSアプリ作成準備

You’ve already agreed to the Apple Developer Agreement.

みたいなメッセージが表示されればこの手続きは完了しています。

環境構築

  • macXcodeをインストール(Mac App Storeからインストールできます)
  • UnityにiOSビルドパッケージが入っていなかったら、追加でインストール

Unityプロジェクト側でやっておくとよいこと

実機での動作テストの際にやっておくとよさそうな設定や確認事項です。

ターゲットデバイスiOSにする

最初にやっておくとよいです。

  • UnityのFileメニューから、Build Settingsを開きます
  • プロジェクトに必要なシーンをScenes In Build欄にドラッグ&ドロップで加えます
    • 最初に起動したいシーンを先頭にしておきます
  • Platform欄でiOSを選択して、Switch Platformをクリックして切り替えます

実機を接続

これも最初にやっておくとよいです。

  • テストで使いたいiPhoneiPadをUSBケーブルでmacに接続します
  • UnityのEditメニューからProject Settings -> Editorを選択します
  • InspectorビューのDevice欄をクリックすると、接続した端末が列挙されるので選択しておきます

最低限やっておくPlayer Settings

UnityのBuild SettingsPlayer Settingsで呼び出すか、EditメニューからProject Settings -> Playerを選択して呼び出せるプレイヤー設定です。本番用ではもっと必要ですが、とりあえず実機で動かすだけなら以下でいけました。

  • Company Name(会社やチーム、制作者名)
  • Product Name(作品名)
  • Other SettingsBundle Identifierに、半角英数とハイフンとドットでアプリを識別する文字列を設定
    • jp.組織名.作品名という並び
    • 例) jp.yourname.oragasakuhin

あとは自分は縦画面専用なのでResolusion and PresentationDefault OrientationPartraitに変更したぐらいです。

BITCODEをOFF

8425:        [xcode] clang: error: linker command failed with exit code 1 (use -v to see invocation)

とかいうエラーがXcodeで出た時の原因No1だと思います。Xcode側で対応もできるのですが、naichiさんがUnity側で対応するスクリプトを用意してくださっているので、こちらを最初からプロジェクトに組み込んでいくとよいです。

このままだと他の環境でビルドする時に怒られるので、コードの最初の行に#if UNITY_IPHONE、最後の行に#endifを加えておくとよいです。

ビルド時だけメソッドやプロパティが見つからないと怒られる

Unityで実行できるのに、ビルドの時に以下のようなエラーを食らいました。

Assets/Scripts/Player/PlayerMouse.cs(83,31): error CS1061: Type `RouteManager' does not contain a definition for `WalkDistance' and no extension method `WalkDistance' of type `RouteManager' could be found. Are you missing an assembly reference?

エラーを出しているやつ(この例の場合はWalkDistanceメソッド)が、#if UNITY_EDITOR#endifの中に書かれていて、ビルド時に削除されてました^^; なかなか気付かずにかなりの時間をロスしました。regionを使ってちゃんとブロック分けしないと駄目ですね...

ビルド

以上の対応ができたら、とりあえずビルドしちゃいましょう。あとはエラーが出たら対応ということで。FileメニューからBuild & Runを選択すると、Unityでのビルド、Xcodeを起動してビルド、ビルド成功したら実機へインストールして起動、という一連の動作をしてくれます。

Xcode

Unity側で問題がなくなったら、Xcodeが起動して、最終的なビルドが実施されます。その際に食らったあれこれです。

ライセンスの設定

まずこのSigning for ...というエラーが出るはずです。

f:id:am1tanaka:20181007125556p:plain

先に登録したAppleIDを登録します。以下のサイトが参考になると思います。

実機でアプリを確認する, iOSアプリ作成準備

このサイトでいうコーディングが終わっていれば、三角マークをクリック実機でアプリが実行されますという箇所は、すでにUnityでコーディングが終わっているので、指示通り三角マークをクリックして進めて構いません。

問題なくビルドが成功したら、USBで接続している実機に実行ファイルが転送されて、実機での動作が確認できます!

しかし、自分はもう少しエラーを食らいました。

非対応命令の利用

BITCODEOFFにしたのに、以下のエラーがまた出ました。

f:id:am1tanaka:20181007132855p:plain

エラーがどこで発生したのかを確認しないと解決のしようがありません。

  • エラーの場所を右クリック(ダブルタップ)して、Reveal in Logを選択します

f:id:am1tanaka:20181007132928p:plain

  • 詳細が表示されるので、どこでエラーが発生しているかを確認します

f:id:am1tanaka:20181007133137p:plain

スクリーンショットの撮り方が悪くて原因箇所が隠れてしまってますが、_OpenWindowUndefined symbols(定義されていない)ということと、それが_UnityRoomTweetであるということが読み取れます。

そういえば、UnityRoom用のツイートアセットを組み込んだままでした。それが使っているOpenWindowメソッドがiOSでは使えないということですね。

ツイート機能は他のアセットで行う予定なのでこれは不要でした。Unityでアセットを削除するとか、iOSビルド時にはビルド対象から外すなどの処置をして解決できました。

その他

メインの開発やAndroid用ビルドはWin10マシンでやっていて、iPhoneだけmac book airでビルドするという体制でやっています。プロジェクトはGitHubでやり取りしてるのですが、その際にアセットストアのアセットをインポートし忘れてエラーが出ていたというのもやらかしました。

アセットストアのアセットもPackage Managerで管理したい...

まとめ

大体こんなところでした。Appleの公式マニュアルを中心に進めたのですが、要領を得ない説明が多くて難儀しました。実機テストするまでの手順は、素直に書籍やブログをあたった方がよさそうです。

Xcodeを全く使い慣れていないので、アカウントをどうやってプロジェクトに設定するかや、エラーの確認方法を調べるのに時間を食いました。

iPhoneSE買ったものの全然開発に使ってないじゃん、という状況でしたが、ようやく動かせました。よかったよかった。

参考URL

裸眼立体視ディスプレイLooking Glassを発注しました!

f:id:am1tanaka:20180922201438j:plain

以前から気になっていた裸眼立体視ディスプレイLooking Glassのデモが吉祥寺のPico Pico Cafeさんで開催されたので見に行きました。その時の感想と、発注しちゃったので発注方法についてです。

目次

経緯と感想

当初は行く予定はなかったのですが、先に入っていた予定が1件キャンセルになり、代官山につのだゆきさんのガラス昆虫を見に行った帰りに寄れるなと思って急遽行くことに決めました。少し前にGateb〇xの実物を見て、立体視ではなくガッカリ感がありました。それもあって期待度はそれほどでもなく、買わないことを決断する材料にというつもりでした。しかし、実物は衝撃的でした。写真では立体感は伝わりませんが、立体感なしでも驚きの機能がありました。

f:id:am1tanaka:20180925190139g:plain

モニターを見る角度を変えているだけで、アプリの操作はしていません。どこから見るかで画像の角度が変わって見えるのです。左右方向のみですが、45°の範囲でこのように見ることができます。この機能があれば直感的な動きで奥行きを感じることができます。

技術的にはレンチキュラーレンズを使った古典的手法とのことです。ディスプレイの厚さは、技術的な理由というより、厚みの部分に立体像があるように感じさせる効果っぽいです。LEDライトが仕込まれていて明るく見せることもできています。

技術的なところは以下の記事に詳しいです。画面の解像度が上がったことで、情報量を増やせたことで古典的な手法でも表現力を強化できたということのようです。

[TGS 2018]ガラスの中に浮かぶ映像? 完成度の高い立体ディスプレイLookng Glass - GamesIndustry.biz Japan Edition

デモは、VoxatronをLookingGlassに対応させたもの。初めて遊びましたが、カメラがめり込んだ部分は中身が見えるようになっていたり、Voxelの魅力が詰まった作品でした。

その他には、リープモーションで踊っている3Dモデルの邪魔をするやつ。

f:id:am1tanaka:20180927212403g:plain

リープモーションで手の動きを取ってメタボールをいじれるやつ。

f:id:am1tanaka:20180922195945j:plainf:id:am1tanaka:20180922195946j:plain

Unity in the Sky!のモデルをおっさんに差し替えたものなどがありました。

f:id:am1tanaka:20180922201103j:plain

どのようなものが動かせるか

45°の範囲で、1°ずつ違う画像を用意する仕組みになっています。Looking Glassを通さないとこんなです。

f:id:am1tanaka:20180922202405j:plain

これだけの画像をレンダリングする訳なので、モデルやエフェクトはそれなりに制限されることが予想されます。自分でやりたいことがどの程度動くかは、実際に触ってみてのお楽しみです。

購入方法

すでにKickstarterでの募集は終わっているので、公式サイトから注文しました。9/24現在は前売り価格なので$100ぐらい安いです。

送料がかかります(僕の場合は$80でした)。最初は製品の価格しか表示されず、確定時に追加されるので予算に注意してください!

大きいスクリーンは魅力でしたが、お値段が結構なもんで、置き場所もあれだしということで8.9インチの通常版にしました。Leap Motionも欲しかったのでInteraction Accessory Pack を付けました。

海外の発注なので、住所が海外仕様です。〒999-9999 東京都立野川市横町1-1-1なら、以下のような感じです。

  • Street address
    • 1-1-1 Yokocho
  • Country
    • Japan
  • Postcode / ZIP
    • 999-9999
  • Prefecture
    • Tokyo
  • Town / City
    • Tatenokawa-shi

あとは電話番号やらカードやらを入力します。支払いは手数料が安いっぽいのでクレジットカードにしました。

先にも書きましたが送料がかかるので注意してください。さらに注意なのがLocal Pickupの選択肢です。$0+税金$20ちょっとで安いじゃん!と迂闊に選んではいけません。自分で受け取りに行くというオプションです。取りに行くのはおそらく香港です。うっかり選ぶところだった。危なかった。。。

僕の注文内訳です。

  • Standard Looking Glass ($499)
  • Interaction Accessory Pack ($99)
  • 送料 $80

合計$678

日本円だと8万円弱ぐらい?Oculus Questより高いですがiPhoneよりは安い。Leap Motionも入手できるし、届くまでのわくわく感だけで個人的にはすでに元は取れちゃってる気がしてます。

おまけ

似たような製品でVoxon Photonics社のVoxon VX1というのもあります。こちらは投影先のスクリーンが物理的に動いてそこの画像を投影するという力技をしています。お値段100万円オーバー!手が出ません...

[TGS 2018]空間に本物の立体映像を描くVoxon Photonicsのテクノロジー - GamesIndustry.biz Japan Edition

まとめ

立体視は好きで、昔からちょくちょく手は出していましたが成果を出せない鬼門でした。今回も同様になるのではないかという心配はありますが、作りたいものが具体的にいくつか浮かんでいて、開発中のVoxelorerBirdはすぐに対応できるはずなので、ジンクスを打ち破れるのではという期待が大きいです。そして、操作方法を色々と工夫すると面白いものが作れそうに感じています。自作の入力デバイスを昔から作りたいと思い続けてきましたが、その夢も叶えられるかも知れません。

オーダー番号を見ると1,500台はすでに注文されているようです。Kickstarterだけで1,200台を越えていました。千人ぐらい僕より先に突っ込んだ先生方が世界中にいるということで心強いです!

発送は年末で告知されていますが、到着は来年の1月過ぎかなと予想しています。それまでに色々と片付けて、万全の体制で待ちたいと思います。

参考URL

Unity1週間ゲームジャム「あつい」に参加しました

Unity 1週間ゲームジャム | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

今回のテーマは「あつい」。公開した作品はこちらからどうぞ。

ログインすると評価できます。面白かったら評価いただければ嬉しいです!

溶岩番

溶岩番 | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

目次

開発の流れ

ツイートを交えつつ、一週間を振り返ります。

準備会

今回も前回に続き、秋葉原コワーキングスペースWeeybleさんにて、ニムさん主催の準備会のLT枠に参加することにしました。

準備会では、前回と同様にnaichiさんのネットランキングとツイートの実装方法と、TextMesh Proのフォントアセットの作り方をご紹介しました。発表資料はこちら。

docs.google.com

LT後は、参加者の皆さんの作業にお邪魔しつつ、Voxelゲームプロジェクトのボクセルの影の研究をもくもくしてました。

9/3(月)

お題発表。

0:26にTrelloにボードを作成して作業開始!前回参加した直後は「ランダム要素でスコアが左右されるネットランキングがアツい短時間で終わるゲーム」というメモを残していました。しかし、その後の活動で方針が変わって「Voxelを使ったタッチ操作で遊べるようなパズル的なゲーム」という頭になってました。

まず考えたのが溶岩の上を岩が流れてくるので、それをタイミングよくジャンプして進んでいくフロッガー的なゲーム「ボルケーノジャンプ」でした。岩の上に乗っていると徐々に岩が沈んでいくので、なるべく早く次にジャンプするゲームです。ワンキーゲームで簡単に作れそうだけど、ゲーム性が大味になりそうに感じたので保留にしました。

昔からゲーム中にジャンプするのが大好きだったのですが(メルヘンメイズとかジオグラフシール、ジェノサイドなどなど)、最近はジャンプが出来ない方がゲーム性は出しやすいのではないかと考えるようになっていました。ゼルダキノピオ隊長の影響です。そして、昔ながらのマス目ごとにきっちり動くようなものを作ってみたいという気持ちが出てきて、「溶岩の上にうまく岩を置いてゴールを目指すゲーム」→「岩を押して、溶岩に落とすゲーム」という感じで、1時半頃、企画がまとまりました。

タイトルに表れている通り、ネタ元は「倉庫番」です。そこにペンゴを少々。

TLで肉を焼く系のアイディアや奇抜なネタで盛り上がっている中、あまりにど直球なパズルゲームの企画。今回も埋もれる...と腹をくくりました。企画がまとまったところで就寝。日野方面の大学の後期が始まる日だったので、手一杯で開発には入りませんでした。

9/4(火)

日曜日に「今週は月曜日以外は休みなんですよ」とか言ってましたが、水曜日から専門学校でした^^; この日はその準備でほぼ終わり。せめてもということでUnityのプロジェクトを作成して、Unity Collaborateにプッシュだけはしました。

短期勝負だしGitHub使うまでもないかと思って、Unity Collaborateでバージョン管理しました。Gitを使う自信がない...という場合もUnity Collaborateがおススメです。ちょっと設定するだけなので楽ちんです。Unity Collaborateに小まめにPushしておけば、アセットの設定が壊れるなどの事故があっても、以前の状態に戻すことができます。一人で開発する場合でも何らかのバージョン管理サービスは使った方が安心安全です!

9/5(水)

朝一から専門学校の講義。夕方に講義を終えてから、画面を整えるためにモデルやテクスチャ探しをはじめました。3D Cartoon Box Mapのブロックを配置してみたり、CC0のテクスチャーを配布している3D TEXTURESの溶岩をダウンロードして背景に置いたりしてみましたが、しっくりきません。

この日はそれで終わり。成果なし!

9/6(木)

丸1日開発に使える貴重な日。まずは画面続きの続き。思い切って素のCubeにエッジを描いただけのテクスチャーを貼って、あとはマテリアルとライトだけで仕上げたところ、良い雰囲気の画面になりました。

そこからは以下のような作業を黙々と。

  • 沈むブロックや、押すときの矢印、階段などをMagicaVoxelでモデリング
  • 画面レイアウトを調整
  • 溶岩のアニメーション作成
  • 動作確認用のステージの作成
  • プレイヤーが歩ける範囲をマッピングする処理

まだゲームに動きはついていませんが、画面は整いました。

9/7(金)

この日は講義&人に会っていたので帰宅は23時頃。

表示されている数字はプレイヤーからの歩数です。これを使ってプレイヤーが移動できるかや、どこを通るかを計算することができます。つまり、まだこの時点でプレイヤーは動いていません^^; こんな状態から完成したんだっけ。

9/8(土)

まるまる時間が使える最後の日です。といいつつ、ニュース見たりしててお昼過ぎから作業をはじめましたf^^;

  • クリックしたら場所へ歩く処理
  • 歩ける場所や押せるカーソルアイコンの作成
  • ノーマルブロックの動きを実装
  • 氷ブロックの動きを実装
  • プレイヤーをカメラが追う処理
  • プレイヤーを移動に応じて回転させたり、歩かせるアニメ処理
  • フォントを組み込んで、タイトル作成

目の前の作業を次々に撃破していって、なんとかゲームっぽく動き始めました!

まだ沈むブロックが入っていませんが、ギリギリ間に合うかも。間に合わないかも。な状態まで辿り着きました。

9/9 最終日

ついに最終日。家事をやってから11時ぐらいから開発スタート。

  • 沈むブロックを実装
  • ライトや背景色の仕上げ
  • ステージクリアの実装
  • ブロックが沈まなくなったり、氷が滑らなくなったバグを修正
  • 「タイトルへ」ボタンと「やり直し」ボタンの実装
  • ツイート内容の設定

あとはWeeybleさんに移動して最後の仕上げ。

  • エンディング実装
  • ステージ2つ追加

残り30分の時点で、なんとか最低限のゲーム要素が揃いました。2つステージを作って、ほぼ20時ちょうどに公開することができました!

ハッシュタグなどつけ忘れていたので、改めて正式にリリースのツイート。

これにて1週間終わり!20時以降はWeeybleに集まった皆さんのゲームを遊んだり、お互いのおすすめゲームを紹介したり、打ち上げ会を楽しみました!

嬉しい誤算

この企画を考えた時は、地味すぎてあまり遊んでもらえないだろうなと覚悟してました。公開前のTLはほぼ無風でしたし。しかし、1日経ってからunityroomを覗いてみたら人気TOP3に入っているではありませんか!!

1週間ゲームジャムにちゃんと参加した作品はこれが6回目です。これまでは真ん中より少し上が定位置でした。TOP6は果てしなく遠いと感じていたので本当に嬉しい予想外の結果でした。その後、おすすめアプリや週間ランキングにも入ることができました。一度ここに載ると、その後は実況で取り上げていただけたりするので順調にプレイ回数や評価が増えるのを実感しました。公開からすぐに遊んでご評価してくださった皆様、ありがとうございました!

実況

実況プレイしていただいた動画です。ぱふもどきさん( @PafuOfDuck )のチャンネルはこちら。

youtu.be

溶岩番の実況中は帰宅していなかったので生では見られませんでしたが、時間が合う時に遊びながら拝見してました^^

そしてntnyさん( @nD_ntny )と椿さん( @tsubaki_t1 )という豪華布陣による実況。

www.twitch.tv

こちらも帰宅した時には終わっていたのでアーカイブで拝見しました。

どちらの動画も何かやらかしていないかドキドキしながらの視聴でしたが、楽しんでいただけていたようでホッとしました。また、僕が考えた解法と違うクリア方法が示されたり、気になっていた説明方法や操作性の確認ができて大変有意義でした。ありがとうございました!

次回に向けて

次回は、専門学校の作品展が終わって1年生の皆さんが個人作品を持つべき時期です。主テーマは学生さんのゲーム作りの援護射撃です。それと同時に、伴走のために自分でも何か作る予定です。

画面作りはローポリ&Voxelの方向性でしっくりきたので、次回もこの路線で表現を磨くのがテーマの一つです。あとは機械学習、Photon、Firebaseのいずれかを使った超ミニゲームとかを出たとこ勝負で。次回も楽しみです!

最後に

人気TOP3に入ることができたのは嬉しい成果でした。狙って出した結果ではありません。狙わずに力を抜いて出したジャブが急所に当たってKO勝ちしたような、そんな感覚です。続けるのは大変ですが、実感しているメリットは多いです。

  • コンパクトに完成させるノウハウが身につく
  • 同じ条件で作られたゲームと自作品を比較することで次のテーマが見つかる
  • 軽いアイディアを試せる
  • ゲームジャムに参加している作者さんと交流が持てる
  • 講義で利用できるゲームのひな形が増える
  • 今回のような成果が出ることもある New!!

今後も基本は埋もれる方向だと思いますが、目立てなくても心がけ次第で得るものは沢山あります。参加を検討している方は是非参加してみてください!遊ばれた数やいいね数が少ないと落ち込みますが、本当に大切なのは完成させて発表することで得られる経験や発見です。そこから課題を見つけて次に繋げて、積み上げていけばレベルアップできます!運がよければいきなりヒットすることも有り得るでしょう。それも発表してこそです。

今回の作品は手応えがあったのでアプリ化に取り組もうと考えています。タイミングよくデジゲー博に当選したので参考展示を目指します。自然と新しい目的が見えてくる好循環になったので、積み上げていこうと思います!

利用アセット

利用アセットなどは以下の作品ページからご覧ください。いつも素晴らしいツールをありがとうございます。

溶岩番 | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

関連・参考URL