mewlist

uGUI 描画優先度のチートシート


皆様,こんにちは!
株式会社Aiming の 土井と申します!
リードソフトウェアエンジニアをやっております!

ここ数年は,業務で Unity の uGUI を使って UI 開発をする機会が多いのですが、
Order in Layer, Sorting Layer, ヒエラルキ上の並び順……(つд⊂)ゴシゴシ
Unity では重なり順を指定する項目が多いですよね。
これらの項目間の優先度が実際にどうなっているのか理解していなかったため、調査を兼ねてチートシートを作ってみました!

描画優先度を指定するものを列挙してみた

どうやらこれらの関係を全て調べ上げれば良さそうです。

チートシート

調べました。
画像は実際に Unity の GameView で表示されたもののキャプチャです。

これで、もう UI の重なり順で悩まない!

解説

カメラ毎の優先度

  • Canvas に設定された Camera による優先度
    • ScreenSpace: Overlay 設定のものが最優先
    • 次いで Depth 値が高いものが優先

同じカメラに設定されたキャンバス同士

  • SortingLayer が高い Canvas が優先
    • 同じ SortingLayer 同士では、 Order In Layer の値が高い Canvas が優先
      • さらに同じ Order In Layer 同士では、Z 値が低い(カメラに近い) Canvas が優先

Mesh や パーティクルなど UI 以外の Renderer について

  • SortingLayer や Order In Layer の値による重なり順の制御ができる
  • ただし、SortingLayer と Order In Layer が同じ値を持つ Canvas がある場合、ヒエラルキ上の並び順による重なり順のソートは行われないので、 固有の Order In Layer 値を設定しよう

Render Queue について

  • UI の描画は、 RenderQueue = “Transparent” にて行われるため、独自のマテリアルを使用する場合は RenderQueue の値に 2501 以上を指定する必要がある

最後に

  • UI のレイヤーの間に 3D モデルを表示したりエフェクトを出したりといった要件のときには、まず全体の UI のレイヤー構成を整理して仕様化しましょう。行き当たりばったりで重なり順をいじっていると混迷を極めます
  • MeshRenderer などは標準でインスペクタ上から SortingLayer や Order In Layer が設定できません。
    • https://docs.unity3d.com/ja/current/ScriptReference/Renderer.html
    • 自前でスクリプトから設定する必要があります
      • (Order In Layer は sortingOrder というプロパティです)

おしまい。


Unity5.6.0で追加されたTest RunnerのPlayModeを使ってみた


こんにちは。大阪スタジオ エンジニアの西村です。

Unity 5.6.0からTest RunnerにPlayModeが追加されました。以前からあったEditModeのテストではカバーできなかったフレームをまたぐ非同期処理などのテストが可能になります。ざっくり試してみた結果をまとめてみました。この記事ではUnity 5.6.0f3を使用しています。

PlayModeを有効にする

初期状態ではPlayModeが無効になっているので有効にします。まずWindow – Test RunnerでTest Runnerウィンドウを開きます。

PlayModeタブを選択すると”Enable playmode tests”というボタンがあり、これを押した後でUnityを再起動する必要があります。

これでPlayModeが使えるようになりました。

PlayModeでテストを実行してみる

Create Playmode test with methodsを押すとテンプレートスクリプトが作成されます。

NewPlayModeTest.cs

using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;

public class NewPlayModeTest {

    [Test]
    public void NewPlayModeTestSimplePasses() {
        // Use the Assert class to test conditions.
    }

    // A UnityTest behaves like a coroutine in PlayMode
    // and allows you to yield null to skip a frame in EditMode
    [UnityTest]
    public IEnumerator NewPlayModeTestWithEnumeratorPasses() {
        // Use the Assert class to test conditions.
        // yield to skip a frame
        yield return null;
    }
}

スクリプトがコンパイルされるとPlayModeにテストが追加されます。

とりあえず手を加えずにRun Allしてみると。シーンがテスト用のものに入れ替わりUnityがPlay状態になります。しばらく待つとテストが実行され結果がTest Runnerウィンドウに反映されます。

当然なにもないので成功です。

次は失敗させてみましょう。適当にAssertを追加します。EditModeのテストと同じ感覚で書くことができます。

NewPlayModeTest.cs

using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;

public class NewPlayModeTest {

    [Test]
    public void NewPlayModeTestSimplePasses() {
        // Use the Assert class to test conditions.
        Assert.IsTrue(false, "失敗させてみる");
    }

    // A UnityTest behaves like a coroutine in PlayMode
    // and allows you to yield null to skip a frame in EditMode
    [UnityTest]
    public IEnumerator NewPlayModeTestWithEnumeratorPasses() {
        // Use the Assert class to test conditions.
        // yield to skip a frame
        Assert.IsTrue(false, "失敗させてみる");
        yield return null;
    }
}

はい、失敗しました。

PlayModeらしいテスト

ここまではEditModeでも実行できる内容です。次にEditModeでは出来なかったフレームの更新がある状態になっているか試してみます。

NewPlayModeTest.cs

using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;

public class NewPlayModeTest {

    [Test]
    public void NewPlayModeTestSimplePasses() {
        // Use the Assert class to test conditions.
    }

    // A UnityTest behaves like a coroutine in PlayMode
    // and allows you to yield null to skip a frame in EditMode
    [UnityTest]
    public IEnumerator NewPlayModeTestWithEnumeratorPasses() {
        // Use the Assert class to test conditions.
        // yield to skip a frame
        yield return null;
    }

    [UnityTest]
    public IEnumerator 複数フレームに渡ってテストできる() {
        // Time.timeは同一フレーム中は同じ値を返す
        var startTime = Time.time;
        System.Threading.Thread.Sleep(1000);
        Assert.AreEqual(startTime, Time.time);

        yield return new WaitForSeconds(1f);
 
        // フレームが変わっていればTime.timeの値が変わっているはず
        Assert.AreNotEqual(startTime, Time.time);
        yield return null;
    }
}

複数フレームに渡ってテストできることがわかります。

MonoBehaviourTest

MonoBehaviourTestと言うものがありますが詳しい使い方がわかりませんでした。動作テストに使用したコードは以下の通り。

ExampleBehaviour.cs

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

public class ExampleBehaviour : MonoBehaviour {
    protected int counter = 0;

    // Use this for initialization
    void Start () {
 
    }
 
    // Update is called once per frame
    protected void Update () {
        counter++;
    }
}

ExampleBehaviourTest.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.TestTools;

public class ExampleBehaviourTest : ExampleBehaviour, IMonoBehaviourTest {
    public bool IsTestFinished { get; private set; }

    // Update is called once per frame
    new void Update () {
        base.Update();
        Debug.Log(counter);
        if (counter > 10)
        {
            // ここで止めておかないと他のテストの裏でも動き続ける
            gameObject.SetActive(false);
            IsTestFinished = true;
        }
    }
}

NewPlayModeTest.cs

using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;

public class NewPlayModeTest {

    [Test]
    public void NewPlayModeTestSimplePasses() {
        // Use the Assert class to test conditions.
    }

    // A UnityTest behaves like a coroutine in PlayMode
    // and allows you to yield null to skip a frame in EditMode
    [UnityTest]
    public IEnumerator NewPlayModeTestWithEnumeratorPasses() {
        // Use the Assert class to test conditions.
        // yield to skip a frame
        yield return null;
    }

    [UnityTest]
    public IEnumerator 複数フレームに渡ってテストできる() {
        // Time.timeは同一フレーム中は同じ値を返す
        var startTime = Time.time;
        System.Threading.Thread.Sleep(1000);
        Assert.AreEqual(startTime, Time.time);

        yield return new WaitForSeconds(1f);
 
        // フレームが変わっていればTime.timeの値が変わっているはず
        Assert.AreNotEqual(startTime, Time.time);
        yield return null;
    }

    [UnityTest]
    public IEnumerator MonoBehaviourのテスト() {
        yield return new MonoBehaviourTest<ExampleBehaviourTest>();
    }
}

MonoBehaviourTestを利用してMonoBehaviourを実行することも可能です。IMonoBehaviourTestを実装したMonoBehaviourがIsTestFinishedがtrueを返すことでテストが完了します。IsTestFinishedがfalseのまま30秒経過するとタイムアウトしますが、タイムアウトしても完了として扱われてしまいます。

MonoBehaviourTest実行中にAssertを呼び出してしまうと以後のテストが失敗してしまうため、Assertを呼び出すことでテスト単体を失敗させる事ができません。MonoBehaviourTestについてはそもそも使い方を間違えている可能性もあるので深追いしないことにしました。

Playerでテスト

左上のRun AllではUnity Editor上のPlayモードで実行されますが実際のPlayer上でも実行することが出来ます。

Build SettingsのSwitch PlatformでAndroidに切り替えてみると、右上のボタンがRun all in player(Android)に変わります。

実行してみるとビルドが走りAndroid端末でテストが実行されます。実行結果がUnity上のTestRunnerにフィードバックされないのは残念ですが手軽に実行することが出来ます。

まとめ

今回調べた中で分からなかった事

  1. UnityEngine.TestTools.MonoBehaviourTestの扱い方
  2. コマンドラインからPlayModeのテストを実行する方法

MonoBehaviourTestの扱い方が分からなかったため不完全燃焼ではありますが、PlayModeを利用することで今まで出来なかった非同期処理のテストも書くことが出来るようになりました。また、コマンドラインからの実行が出来ないのでCIに組み込む事が出来ませんが、コードレビュー時など手元でサクッと実行できるのは便利です。

今後もPlayModeテストをCIに組み込むことを視野に入れてウォッチを続けていきます。


Unity3DのDIフレームワーク、Zenjectの紹介


はじめまして。エンジニアの石井と申します。

今回は現在担当プロジェクトで使用しているUnity(ゲームエンジン)用DIフレームワーク、Zenjectを紹介させていただきます。

Zenjectとは

https://github.com/modesttree/Zenject

ZenjectはUnity3D向けに作成された、DI(依存性の注入)フレームワークです。
Zenjectを使うことでオブジェクト間の依存関係を外部から解決することができます。
簡単になにが良いかを説明しますと、
依存オブジェクトを別の入れ物(コンテナ)に格納しておきコンテナ経由で使うことで、
コンストラクタやメソッドの引数で渡していたり、自身でnewしていたり、FindObjectしていた部分をなくすことができます。

Zenjectサンプル

Zenjectを使ってのUIイベント処理の簡単なサンプルを作っていきます。
今回はボタンが押された時のイベントを処理するサンプルです。

1.インストール

AssetStoreからか、
https://github.com/modesttree/Zenject/releases
からダウンロードしてUnityのプロジェクトにインポートしてください。

2.Contextの作成

シーン上にContextを作成します。
右クリックからScene Contextを選んでください。
Zenject_context

3.Installerの作成

コンテナへの格納(Bind)にZenjectはInstallerというスクリプトを使用します。
今回はSingletonとしてオブジェクトをBindしていきます。

シーン上にGameObjectを作成して、
下記スクリプトをAdd Componentしてください。
※直接SceneContextでも問題ありません。
Zenject_Installer

using System;
using Zenject;

public class InstallerSample : MonoInstaller<InstallerSample>
{
    public override void InstallBindings()
    {
        Container.Bind<ZenjectSample>().AsSingle();
        Container.Bind<IInitializable>().To<ZenjectSample>().AsSingle();
        Container.Bind<IDisposable>().To<ZenjectSample>().AsSingle();
    }
}

4.ContextにInstallerをアタッチ

ContextにInstallerをアタッチすることでInstallerが機能します。
SceneContextのInstallersに、作成したInstallerSampleをアタッチしてください。

Zenject_Context_Installer0

5.UIの作成

UIを作成していきます。
下記のようにボタンを2つ作成し、
Zenject_UI_hierarchyZenject_UI

それぞれ下記のようにスクリプトをAdd Componentします。
Zenject Bindingスクリプトにより、Installerに定義しなくてもBindすることができます。
Identifierを使うことで、個別にInjectすることもできます。

Zenject_UI_Parts

using UnityEngine;
using UnityEngine.UI;
using UniRx;

public class UIView : MonoBehaviour
{
    [SerializeField]
    Button button;

    [SerializeField]
    Text text;

    public IObservable<string> OnClickObservable()
    {
        return button.OnClickAsObservable().Select(_ => text.text);
    }
}

イベントの変換はUniRxを使い、Textをstringで送出します。

6.サンプルクラスの作成

サンプルクラスを作成します。
[Inject]アトリビュートにより先ほど作成したUIViewが注入されます。
IInitializable.Initializeメソッドにより初期化され、
各ボタンのClickイベント購読し、押されたらOnClickメソッドが呼ばれるようになっています。
Sceneの切り替えやゲームの終了などでContextが破棄されるタイミングでIDisposable.Disposeメソッドが呼ばれ、
購読を停止しています。

using System;
using System.Collections.Generic;
using UniRx;
using Zenject;

public class ZenjectSample : IInitializable, IDisposable
{
    [Inject]
    List<UIView> buttons;

    List<IDisposable> subscriptions = new List<IDisposable>();

    void IInitializable.Initialize()
    {
        UnityEngine.Debug.Log("Initialize");

        buttons.ForEach(button =>
        {
            subscriptions.Add(button.OnClickObservable().Subscribe(text => OnClick(text)));
        });
    }

    void OnClick(string buttonText)
    {
        UnityEngine.Debug.Log(buttonText);
    }

    public void Dispose()
    {
        subscriptions.ForEach(subscription => subscription.Dispose());
        subscriptions.Clear();

        UnityEngine.Debug.Log("Dispose");
    }
}

7.動作確認

Sceneが読み込まれる際に、Initializeメソッドが呼ばれ、
ボタンが押されるたびにボタンのTextがログに表示され、
最後にDisposeが呼ばれていることがわかります。

Zenject_log

おわりに

簡単に紹介させていただきましたが、
他にもZenjectには様々なContext、Installerが用意されていますので、
依存関係の解決でお困りの方はぜひ一度試してみてください。


Unityのmetaファイルについての勉強会を行いました


こんにちは、エンジニアの堀尾です。

今回の開発者ブログは以前プロジェクト内で行ったUnityのmetaファイルについての勉強会のお話です。

勉強会を行った経緯

Unityを使用する上でmetaファイルは非常に重要です。しかし、エンジニア以外の人たちにとっては謎のファイルという認識になっておりたびたび問題が発生していました。

  • 問題の例
    • metaファイルのコミットを忘れたことでAssetの関係を保持できなくなる
    • GUIDが競合してしまい、エフェクトやモデルが正しく表示されなくなる

そこで、metaファイルとは何なのかどういった働きをしているのかを資料としてまとめ、勉強会を行いました。


プロジェクトのプランナーさんとデザイナーさん向けに発表を行ったのですが、内容が難しかったのか後半になるにつれ眠そうな人がちらほらと…。しかし、「今までただ謎のファイルとしか認識していなかったけど何となくわかった気がする」と言ってくれる人もいたので勉強会自体は開いてよかったなと感じています!

おわりに

勉強会を行っただけで全ての人がmetaファイルについて正しく理解できた訳では無いと思いますが、理解するまでの第一歩は踏み出せたのではないかなと思っております。


Unite 2016 Tokyoに参加してきました


はじめまして!エンジニアの鈴木聡です!

04/04-05の2日間開催された、Unite 2016 Tokyoに参加しましたので、その記事を書かせていただこうと思います!

Unityの中の人がたくさん!

Unity公式のカンファレンスということもあり、Unityの中の人の生の声が聞けるのが大きな特徴だと思います!開発の方も来日されますので、結果として講演は英語が多めに…でも大丈夫です!同時通訳が完備されていますので!(でも本当は英語で直接理解した方がいいと思います…)
unite2016_room1_m

Unity新機能

すでによく知られているものからあまり知られていないものまで、多くの新機能が発表されていました。アセットバンドルに関しては、Manifest や LZ4 圧縮や UnityWebRequest など、多くの利便性の向上が図られていて、すぐにでも活用していきたいと思いました!

リリースはまだ先になりそうですが、タイムラインエディター(Sequence Tools)がかなり将来性を感じる内容で、力を入れて開発を進めるという意思を感じましたので、実用化に向けて今から楽しみな感じです!

高速化まわり

モバイルにも3Dレンダリングの波は確実に押し寄せてきていて、コンソールやPCで実現できている表現が徐々に入ってきていて、なかなか苦労が絶えない今日この頃だと思います。その実現のために高速化や最適化についても、実際の開発例からUnityの内部構造に至るまでの様々な講義が行われ、今後の開発に役立てられそうな情報が少なからず入手できたのではないかと思います!日々精進ですね!

まとめ

今回、初めて参加させていただいたのですが、他のカンファレンスとはまた違った空気があり、なかなかよかったのではないかと思います!ここで得た知見を今後の開発に生かしていきたいと思います!
unite2016_booth_m

以下CM

実は、弊社はUnite 2016 Tokyoのブロンズ協賛をさせていただいてました!Uniteに参加された方は、入場の時に袋を手渡されていると思いますが、その中にひっそりと入っていたKitKatは、弊社「剣と魔法のログレス」のマンドラというキャラの絵が入った特注品だったんですよ!unite2016_kitkat_mはい、チョコレート。

このKitKatについては後日談がありまして、とある事情で会場で配る予定よりも大量に上回る個数を作られることになったのですが、ご厚意によりUnity Technology様より弊社に余剰分を無償提供していただけることになりました!unite2016_kitkatbox_mどどーん!

機会がある度に配布させていただこうと思っておりますので、気になる方は会場などで弊社社員にお声掛けいただければ幸いです!


ヴァリアントレギオンでUnity4からUnity5へバージョンアップした時に発生した問題


エンジニアの山内です。

絶賛サービス中のタイトル ヴァリアントレギオン のアプリ開発ではUnityを利用しており、開発開始時のUnityのバージョンは3.5で、現在は5.0.4と2回のメジャーバージョンアップを行っています。
Unity4 から Unity5 へバージョンアップした時に、こんな問題がありました、という紹介です。

特定の端末で文字が表示されない

特定GPUの端末で文字列が塗りつぶされて長方形になる問題が発生しました。文字の描画には unity-sysfont を使用していたのですが、5.x向けにはサポートされていないためと推測し、テクスチャ生成部分とレンダリング部分を改修して対処しました。

ビルド時間が2倍に

IL2CPPの影響でアプリのビルド時間が2倍になりました。対応として開発時はIL2CPPを切る方法が検討されましたが、その違いで不具合が発見されない方が怖いのでそのままにしています。

バイナリが制限サイズを越えた

IL2CPPの影響でアプリのサイズが大きくなり、ipaの制限である100MBを超えてしまいました。対応としてはチュートリアルで使用するデータをアプリから削って、追加ダウンロードするようにしました。
Androidでも制限を越えてしまいましたが、これはコンテンツ追加の影響だったので組み込みのテクスチャを減色・整頓しました。

Animation解放時にアプリがクラッシュする

ヴァリアントレギオンではUnity3の頃から開発していた名残でレガシーなAnimationを利用しています。Animationがついたモデルを解放するとき、アニメーションクリップをRemoveしなければクラッシュするというバグを踏みました。この問題は解放処理の前に停止処理を必ず行うようにして回避しました(Unityの不具合で現在もfixされていないようです)。
レガシーアニメーション関連の不具合は他にも余波があり、開発ツール側での問題解決ができておらず、一部の作業はUnity4で行うという事態になっています。さらにUnity5.1以上にバージョンアップした際にもAnimationで問題が出るため、現在5.0.4で足踏み中です。
現在これらを解消するべくAnimationからAnimatorに一括変換中です。

ほかにも

  • エネミーがバックステップする時にノーモーションでスッと下がる
  • メインメニュー上のアイコンの並びがガタガタになる
  • ガチャ演出で宝箱を空ける瞬間に宝箱が吹っ飛ぶ

など、見た目に楽しい(楽しくない)問題がありました。


syoshino

第5回DeNAゲーム開発勉強会×Aimingで発表を行いました


こんにちは。 リードエンジニアの吉野です。

先日、株式会社ディー・エヌ・エー(DeNA)様 主催の、「第5回DeNAゲーム開発勉強会×Aiming」にて発表を行わせていただきました。

DeNA 様は『パズル戦隊デナレンジャー』について発表されました。

弊社からは、以下の内容を発表いたしました。

Unity物理におまかせゴルフ ~ぐるぐるイーグル

OLYMPUS DIGITAL CAMERA
Aimingエンジニアの西尾です。
Unityの物理エンジンを使って、ゴルフゲームをリリースするまでにやったことの紹介です。
もしかしたら、こういう情報が他のゲームを作っている人の参考になるかもしれないと思い資料を作成しました。

ゲームデータDLとの戦い 〜幻塔戦記グリフォン

OLYMPUS DIGITAL CAMERA

Aimingエンジニアの吉野です。
幻塔戦記グリフォンにおける、ダウンロードデータの扱いの改定の歴史を発表させていただきました。

オンラインゲームでは避けて通れないゲームデータのダウンロードについて、誰かの助けになれば幸いです。
なるべく一般的な内容にしようと思い、ゲーム仕様に依存するデータ部分や、Unityの仕様に依存するダウンロードデータの取り扱いなどは概要にとどめてあります。

また別の機会があれば詳しく解説できればと思います。

発表会の後に懇親会も行われました!
IMG_9585

当日の動画はこちらです。

DeNA 様の発表につきまして
ブログへのリンクを貼らせていただきましたのでぜひご覧ください。
DeNA Engineers’ Blog | 第5回 DeNAゲーム開発勉強会xAiming レポート

最後に、発表の機会を与えていただいた、DeNA 様、ありがとうございました。


sindharta

幻塔戦記グリフォンの AI で使っている Behaviour Tree


こんにちは、クライアントエンジニアの Sindharta Tanuwijaya(シンダルタ タヌイジャヤ)です。

今更ですが、1月の社内の勉強会で、 Behaviour Tree という AI の手法を発表させて頂きました。当時は幻塔戦記グリフォンを開発するのにあたって、1つのフィーチャーを完成させるためにこの機能を作っていましたが、今はいろいろなフィーチャーで使われています。

Behaviour Tree とは思考 AI のアルゴリズムの1つで、比較的に良く知られているステートマシンと目的が似ています。それはゲーム内のオブジェクトをどう考えさせて、行動させることです。ステートマシンも良い手法ですが、 AI が複雑になってくるのにつれて、管理の難しさが倍に増えるデメリットがあります。そこで、 Behaviour Tree を導入してみたわけです。

当日発表したスライドは以下です。

また、自分の発表をさらに分かりやすくするために、動画も作りました。

折角ですので、私が参考にしたリソースも伝えたいと思います。すべて英語ですが。

  1. Introduction to Behavior Trees
  2. Unity 4.x Game AI Programming

ちなみに、 Behave という Behaviour Tree をデザインするための Unity のプラグインはあります。とても良いプラグインですが、様々な面を検討した結果、今回私たちは独自のものを作ることになりました。Behave が持っているエディター機能をはやく見習わないといけないですね。

Behaviour Tree という手法はコンシューマーゲームでは約10年前に導入されていたと思いますが、いよいよ今になってスマートデバイスのゲームに導入してもおかしくはない時代になってきています。スマートデバイスがリッチになってきた証拠です。Aiming でこれからもどんどんリッチなゲームを開発していきたいと思います!

最後にちょっとしたネタがあります。Behaviour も、u なしの Behavior も両方見かけたことがありませんか?実はu なしの Behavior はよく米国で使われているらしく、イギリスなどといった他のところでは Behaviour は正しいそうです。個人的にはu ありの Behaviour が格好よく見えるので、それを選ばせていただきました。


ppc(細田幸治)

Unityで使える非同期処理のクラスライブラリ(iterator-tasks)を公開しました


こんにちは。Aiming 東京開発グループの細田です。
私たちのチームで開発したロードオブナイツで使っている非同期処理ライブラリを公開しました!!

github のアドレスはこちら
https://github.com/aiming/iterator-tasks

サンプルとテストコード付いてます。

設計者は ++C++; の中の人こと岩永信之さんです。ネットでC#について検索したことがある方なら一度はサイトを見たことあると思います。

公開したクラスをどんな用途で使っているか、どんな設計で出来ているかについては以下のスライドをご参照ください。

.NET 4.0 の Task のような機能を Unity でも使えるようになります。
一般的なゲームで実装されるタスクとはちょっと意味合いが異なり、非同期で動き、必ず終了する処理について使いやすくするためのライブラリです。
WWW での異常系実装やシーケンシャルな非同期処理の実装が簡単に出来るので是非使ってみてください。

 


komaba

Aiming Study 7 「ロードオブナイツ UnityからHTML化する際のアプリの設計とアジャイル的開発管理の話」


初めまして、ソフトウェアエンジニアの駒場です。
11月6日、Aiming Study 7 「ロードオブナイツ UnityからHTML化する際のアプリの設計とアジャイル的開発管理の話」が渋谷で行われました。
当日の様子は以下からご覧になれます。

Video streaming by Ustream

※小林の発表は 40:40 辺りから、質疑応答は 1:14:35 辺りから始まります。

会場はGMOインターネット株式会社さんにGMO Yours をご提供頂き、60名以上の方々にご参加頂けました。ありがとうございました!

続きを読む