SlideShare a Scribd company logo
Orange Cube
自社フレームワーク
++C++;
Orange Cube
岩永信之
自己紹介
• C#でぐぐれ
• C#でiOS/Androidゲームを作っています
本日の話
• 自社フレームワークの話
• 今、オープンなのは IteratorTasks だけ
• できれば随時オープン化していきたい
• 要求と解決策を中心に話す
• チームが作っているゲームの性質・要求
• 要求に対する技術的な課題
• Unityという縛りの中での課題
• どうフレームワークを整備したか
• 見せれる範囲で実際のコード
• 実物デモ
背景
どういうものを作っていて、どういう要求があった
チームが作っているもの
1. ストラテジー
2. RPG、リアルタイム バトルもの
3. ストラテジー
前提: 作っているゲームの性質
• サーバーとの通信だらけ
• 非同期処理を楽にしたい
• 差分更新、更新された部分の変更通知がほしい
• アクション性は低い/結構なページ数
• ゲーム系フレームワークよりも、UI系フレームワーク使いたい
こんなフレームワークができあがりました
• IteratorTasks
• TaskInteraction
• TaskNavigation
• TypeGen
• Inventories/MasterRepository
• Binding-CodeGen
ライブコーディングでデモあり
非同期処理
IteratorTasks
System.Threading.Tasks.Task もどき
非同期処理
• スマホゲームなんて非同期処理の塊
• いろんなロジックがサーバー上で動いてる
• サーバーからもらったデータを表示
• そうでなくても、ネイティブUIには非同期処理が必要
• 参考: フリーズしないアプリケーションの作り方
エンド・ユーザーは、
0.5秒のフリーズでストレスを感じ、
3秒のフリーズはバグだと思う
例: バイト列読み込み
• 同期
static byte[] ReadBytes(Stream s, int n)
{
var buffer = new byte[n];
s.Read(buffer, 0, n);
return buffer;
}
ここでフリーズ
の可能性あり
例: バイト列読み込み
• begin/end、コールバック式
static void ReadBytes(Stream s, int n, Action<byte[]> callback)
{
var buffer = new byte[n];
s.BeginRead(buffer, 0, n, r =>
{
var result = s.EndRead(r);
callback(buffer);
}, null);
}
2個のメソッドをペアで
呼ぶ必要あり
後ろにさらに処理がつづいたり、
分岐・ループさせるとかなり面倒
例: バイト列読み込み
• ContinueWith※、コールバック式
static Task<byte[]> ReadBytes(Stream s, int n)
{
var buffer = new byte[n];
return s.ReadAsync(buffer, 0, n).ContinueWith(t => buffer);
}
※ 他のプログラミング言語だと Then という名前が多い
いわゆる継続処理(continuation)
後ろにさらに処理がつづいたり、
分岐・ループさせるとかなり面倒
例: バイト列読み込み
• await(C# 5.0※)
• C#的には5.0(2012年に正式版)で解決した問題
• “Unityでなければ”、3年前に解消されているはずの問題
static async Task<byte[]> ReadBytes(Stream s, int n)
{
var buffer = new byte[n];
await s.ReadAsync(buffer, 0, n);
return buffer;
}
同期の場合とほぼ同じ
書き方で、フリーズしない
※ UnityはC# 3.0。つらい。本気でつらい。日々ソウルジェム濁る
IteratorTasks
• しょうがないんで「もどき」を使って運用してる
• UnityがCoroutine(yield return)ベースの非同期処理なんで、同じ方針の、
Task互換ライブラリを作って使ってる
• yield return+コールバック式のメソッドを、Task互換のクラスに変換
• Coroutineと比べた利点
• MonoBehaviourに依存しない、UnityEngine.dllに依存しない
• 戻り値を返せる
IteratorTasks
https://github.com/OrangeCube/IteratorTasks
例: バイト列読み込み
• iterator → Task
• C#的には5.0(2012年に正式版)で解決した問題
• “Unityでなければ”、3年前に解消されているはずの問題
static Task<byte[]> ReadBytes(Stream s, int n)
{
return Task.Run<byte[]>(c => ReadBytesIterator(s, n, c));
}
static IEnumerator ReadBytesIterator(Stream s, int n, Action<byte[]> callback)
{
var buffer = new byte[n];
var t = s.ReadAsync(buffer, 0, n);
if (!t.IsCompleted) yield return t;
callback(t.Result);
}
await の代わりに
yield return
1段ラップ
return result の代わりに
callback(result) 作る側は相変わらず面倒だけども、
使う側は幾分かマシに
互換
• 標準TaskとIteratorTasksでコード共有
• 結構 #if 分岐でいける
• 実際、後述のTaskInteraction, TaskNavigation, 通信コード生成 は
#if で両対応してる
#if UseIteratorTasks
yield return Task.Delay(_pollingIntervalMilliseconds);
#else
await Task.Delay(_pollingIntervalMilliseconds).ConfigureAwait(false);
#endif
await のところを
yield return に
反省: Rx使わないの?
• 値1つ取るだけ(ラウンドトリップ1回)の非同期処理にRxはいまいち
• (awaitと比べるとの話。begin/endとか同期よりはだいぶいい)
• (Coroutineそのまま使うくらいならRx推奨)
• 同期の時と同じフローで書けなきゃ嫌
• if → where、var → let になるのすら嫌
• if-else で困る
• イベント ストリーム的な非同期処理には、うちでもRx的なもの使ってる
• こっちはほんとにRxの本領
参考:Reactive Extensions(Rx)入門
UniRx
反省: バッド ノウハウすぎる
• 標準ライブラリの互換ライブラリなんてものは超バッド ノウハウ
• 要らなくなるべきもの
• UnityがMono 3系になるだけで無用の長物
• 「すぐに要らなくなるはずだろう」が全然すぐじゃなかった…
• おかげ様でものすごく安定したけども、それは恥だと思ってる
• 所詮は劣化コピー
• awaitと比べると不便
• スタック トレースとか追えない
反省: 両対応は大変
• IteraterTasks(IT)/System.Threading.Tasks(TT)両対応
#if 分岐
共通コード
IT版
ライブラリA
TT版
ライブラリA
IteratorTasks 標準ライブラリライブラリA
共通コード
ライブラリA
Unity
ゲーム
編集ツール(Desktop)や
サーバー
4つ1セット
反省: 両対応は大変
• ライブラリAに依存するライブラリBがあったとして
IteratorTasks
A
A.ForIterator
A.ForThreading
A.Shared
B
B.ForIterator
B.ForThreading
B.Shared
ライブラリ1個増やすだけでも
参照設定がかなり面倒
ビューとの相互アクション
TaskInteraction
チャネルを介したゲーム ロジックとビューとの非同期やり取り
やり取りの記録、再現
ビューとの通信
• よくあるシーケンス図
ビュー ゲーム ロジック サーバー
ボタンAをタップ
アニメーション表示
アニメーション表示
ボタンBをタップ
よくあるミス:
こいつが処理の起点
本来:
こいつが処理の主体
よくあるダメな実装
• ビューのイベントが起点で、そこに多くのコードが入る
class View : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
// ここにゲーム ロジック書く
}
} ダメ!絶対!
ビューとの通信
• ロジックが主体
ビュー ゲーム ロジック
結果のアニメーション表示
ボタンAをタップ
コマンド選択して
コマンドAが選ばれた
実行結果
アニメーション再生終わった
この辺り結構複雑な処理
• コマンド再入力が必要なことも
• アニメーションないときも
ここが起点
ベタなロジック実装
public void Start()
{
// 開始処理
var d = CommandSelecting;
if (d != null) d(candidates);
}
public event Action<CommandCandidate[]> CommandSelecting;
public void SelectCommand(CommandCandidate selected)
{
// 選ばれたコマンドを実行
var d = CommandExecuted;
if (d != null) d(commandResult);
}
public event Action<CommandCandidate[]> CommandExecuted;
public void EndCommand(CommandCandidate selected)
{
// ...
}
ビュー側に「コマンド選択して」
メッセージを投げる
ビュー側から「コマンド選択結果」
を呼んでもらう
Startの続きの処理
ここでいったん処理中断
ビュー側に「コマンド実行結果」
メッセージを投げる
ビュー側から「結果アニメーション再生終わった」
を呼んでもらう
SelectCommandの続きの処理
ベタなロジック実装の問題
public void Start()
{
// 開始処理
var d = CommandSelecting;
if (d != null) d(candidates);
}
public event Action<CommandCandidate[]> CommandSelecting;
public void SelectCommand(CommandCandidate selected)
{
// 選ばれたコマンドを実行
var d = CommandExecuted;
if (d != null) d(commandResult);
}
public event Action<CommandCandidate[]> CommandExecuted;
public void EndCommand(CommandCandidate selected)
{
// ...
}
処理がとびとび
• フロー図と合わせて見ない
と何してるのかわからない
呼んでほしいタイミングでだけ呼ばれる保証が
ない
• ダメなタイミングで呼ばれた時のエラー処理
が必要
• ビューを作る人がわかるドキュメントが必須
フレームワークによっては
• イベントの送り方、結果の戻し方が違ったりはする
using GalaSoft.MvvmLight.Messaging;
using System.Windows.Input;
class BattleEngine
{
private Messenger _messenger;
public void Start()
{
// 開始処理
_messenger.Send<CommandCandidate[]>(candidates);
}
public ICommand CommandSelecting { get; private set; }
}
※ WPF, MVVM Lightの例
• ビューにメッセージを送る用のライブラリがあったり
• ビューからの応答はメソッドじゃなくて、1段階クラスを挟んだり
• フレームワークに適したクラスを挟んでるだけで、
やっぱりメッセージ送信と応答の受信がわかれてしんどい
「メッセンジャー パターン」
とか言ったりする
解決の手がかり: ビューはTask
• ロジックから見て、ビュー上の動きは非同期処理(Task)
• (コマンド選択など)ユーザーのタップを1つ待つ
• (アニメーションなど)時間経過を待つ
public static Task AwaitTap(this Button button)
public static Task PlayAsync(this Animation anim)
public static Task Delay(TimeSpan delay)
Task使ったメッセンジャー パターンで解決
Rx使えば、
button.Tap.FirstAsync().ToTask()
イベントを1つ待つ
Taskを使ったメッセンジャー
• Channelクラス
Channel _channel;
public async Task RunAsync()
{
// 開始処理
var selected = await _channel.Send<Command[], Command>(candidates);
// 選ばれたコマンドを実行
await _channel.Send<CommandResult>(commandResult);
// ...
}
CommandSelectingメッセージと
SelectCommandメソッドをペアに
CommandExecutedメッセージと
EndCommandメソッドをペアに
ビューの処理を
非同期にawait
※ IteratrTasks版だと、awaitのところがyield return
Channelの追加の役割
Channelビュー ロジック
コマンド選択して
コマンドAが選ばれた
選ばれた
結果の記録
Channel ロジック
コマンド選択して
記録した
結果の再現
Channel ロジック
コマンド選択して
サーバーと
通信
記録 再現 記録・再現ができることで
• アプリ再起動時に、続きから再開
• サーバー上でのチート検証
• 対戦履歴の再生
• オンライン対戦・協力プレイ
同じ乱数シードと、
同じユーザー入力を与えれば
実行結果は一緒
反省
• 他のフレームワークとのつなぎこみをフレームワーク化したい
• つなぎ先
• ビュー(データ バインディング)とのやり取り
• サーバーとの通信
• 今は、結構手作業
• Channelにメッセージ ハンドラーを登録して、ビューを表示して、ユーザーの選択を入れ
て返して…
• サーバーAPIたたいて、タイムアウト管理して、通信エラー時の復帰処理して…
• アプリのサスペンド時にChannelの途中記録を読みだして、ストレージに保存して、再起
動時に復元して…
ここでいったんデモ
Task, TaskInteractionの利用例
デモ内容
• ゲームのログイン時の流れ
ゲーム
ロジック
ゲーム
ロジック
ビュー
• 確認ダイアログ表示
• ユーザー名入力
• 登録状況確認
• 新規登録
• ユーザー データ取得
デモ内容
ゲーム開始
登録状況確認
サーバーと通信
登録済み
利用規約表示 同意します
いいえ
名前入力
ビュー表示、ユーザー応答待ち
登録状況確認 有効な名前
NG
はい
データ取得
まだ
済み
プレイ開始
OK
デモ
ページ遷移
TaskNavigation
ページ遷移をステート マシンとして管理
遷移トリガーをTaskで表現
• 例: 装備画面
ページ遷移
ユニット
装備
装備一覧
(空欄)
装備詳細
(装備中)
装備一覧
(変更)
装備詳細
(空欄)
比較
(変更)
装備一覧
(装備中)
比較
(装備中)
空欄選択
詳細
変更
戻る
戻る
戻る
選択
変更
選択
戻る
戻る
戻る
装備
選択
戻る
装備
装備
ユニット
グループ
装備
グループ
装備強化
グループ
ステート マシンとTask
• ページ遷移はステート マシン
• ステート
• どのページにいる
• トリガー
• どのボタンをタップした
• リストのどの要素をタップした
• タイムアウトした
ステート
A
ステート
B
トリガー1
トリガー2
Rx使えば、
button.Tap.FirstAsync().ToTask()
Rx使えば、
list.Items.FirstAsync().ToTask()
いずれにしろTaskが使える
これら複数のうちの最初の1つを待つ
Task.Any(
button.AwaitTap(),
Task.Delay(timeout));
Task.Delay(timeout)
Taskナビゲーションをフレームワーク化
• ステート マシンの設定例
AddState(S.EquipmentInventory,
new Transition
{
T.Item(ct => Cancel.AwaitTap, () => {}, TransitionKey.PageBack),
T.Item(ct => Detail.AwaitTap(ct), x => SelectedItem = x, S.EquipmentDetail),
});
AddState(S.EquipmentDetail,
…
どのステートのときに
(一覧画面にいる)
どういうトリガーで
(戻るボタンを押した)
どう遷移する
(戻る)
(詳細ボタンを押した) (詳細画面に遷移)
遷移前の処理
(選択したアイテムを記憶)
CancellationTokenを受け取って
Taskを返すメソッド
(1つ終わったら残りはキャンセルする)
※ こいつも、WPFとUnityの両方で稼働
フレームワーク化したことで
• 「戻る」(AndroidのBackボタン)対応
• ビュー内のデータ(ViewModel※をスタックで保存、pop)
• グループ
• グループ内遷移: 1つのグループViewModelを共有
• グループ間遷移: 一気に数ページ戻れる
• ページのビューはページ内のことに専念
• トリガーを起こすところまでがページの債務
• ページ遷移やViewModelの記録はナビゲーターの債務
※ ビュー内でだけ必要なデータを記録しておくモデル
独自のUnityシーン管理
• UnityのApplication.LoadLevel使ってない
• LoadLevelの問題
• 全オブジェクトの一斉破棄かけてるみたいでとにかく重たい
• リソース リーク防止の一番手っ取り早い方法ではあるけど、いくらなんでも遅い
• Application.LoadLevelAdditiveAsyncで読み込んで、自前でシーン管理
• 前のシーンを自前でDestroy
• 読み込んだシーンをルート要素につなぎなおし
というような処理を、ページ遷移管理のついでにフレームワーク化
反省: まだ結構定型コードが多い
• ステート マシンの設定コードが結構煩雑
• コード生成で対応(Unityエディター拡張)
• 結構、黒魔術的
グループ単位で設定
グループ内のページ一覧
反省: テキストで書くものじゃない
• ステート マシン設定なんて、テキスト ベースのプログラミング言語で
書くものじゃない
• ↓こういう絵で描けるVisualなDSL (と、編集用エディター拡張)が必要
• 実装も大変だし、カスタマイズ性と両立難しそう
• (Visualなエディター拡張ありのナビゲーション フレームワーク自体はUnity用のものもあ
るにはある)
装備一覧
(空欄)
装備詳細
(空欄)戻る
選択
戻る
装備
反省: ダイアログ
• 今の実装はページのみ
• ダイアログは別系統フレームワーク
• 実際の要件的には…
• UIデザイナーから上がってくるページ遷移フローはページとダイアログが同
列・混在
• ダイアログの遷移も同じナビゲーション フレームワークで動かしたいことが
多々ある
通信コード生成
TypeGen
API定義・型定義をC#で(C#→C#コード生成)
オンライン ゲーム
• サーバーとの通信は定型文が多い
• 手書きすると大量に似たようなコードを書く必要がある
• シリアライズ、デシリアライズ
• HTTP通信、エラー処理
• 多くの通信フレームワークはリフレクションで実現していて…
• iOSで死ぬ
• 性能的に、携帯端末であまり動的な処理をしたくない
コード生成
C# → C# コード生成
• 型定義、メソッド定義はstrongly-typedな言語使うのが楽
• (初代)XML、(2代目)RubyでDSL、(3代目)JSONとかで書いてた
• だんだんやりたいことが複雑に
• 配列に対応、nullableに対応、ジェネリック、型の派生に対応…
• 要するに、型に厳しい言語で書けることと要件変わらなくなった
• なら、最初からC#で書けばいい
型定義例
[Comment("装備品")]
class Equipment
{
[Comment("アイテムID")]
int Id;
[MasterForeignKey(typeof(EquipmentMaster))]
[Comment("アイテムマスターID")]
int MasterId;
[InventoryForeignKey("Enhancers")]
[Comment("装備強化アイテムのID")]
int?[] EnhancerIds;
[Required(false, true)]
[Comment("インスタンスごとの追加能力")]
AbilityIndexedValue[] InstanceAbilities;
}
[Comment("装備する")]
void AddEquipment(
[Comment("誰の(ユニットのID)")]
int unitId
,
[Comment("何番目の装備スロットに")]
int slot
,
[Comment("何を(装備品のID)")]
int equipmentId
,
[Required]
[Comment("変更結果")]
out SyncDifference<Unit>[] Units
);
型定義(C#でクラスを書く) API定義(インターフェイスのメソッドを書く)
プレーンなクラス、フィールドを書く
いくつか、属性を付けて生成結果を制御
定義C#の読み込み
• ビルドしたDLLからリフレクションで読み込み
• 普通に System.Type を読んでる
• 他の選択肢(作り始めた当時はなかったもの)
• System.Reflection.Metadata
• 依存先の解決できなくてもDLL単体で読める
• Roslyn C# Scripting API (Microsoft.CodeAnalysis.Scripting.CSharp)
• 今まだ簡単に使える段階にない
• ほんとはこれでやりたかったけども、Roslynのリリース自体が思った以上に遅く
生成物: 基本
• 型に厳しい言語で面倒なのは、シリアライズとUIバインディング
• この辺りを生成
• JSONシリアライズ/デシリアライズ
• データバインディング用(INotifyPropertyChanged)実装
• 通信処理
• メソッドと対応するURL作って
• 送りたいデータをJSON化してPOST
• 返ってきたデータをJSONデシリアライズ
生成物: 普通のクラス
public partial class Equipment
{
/// <Summary>
/// アイテムID
/// </Summary>
public int Id { get; set; }
…
public Equipment(int id, …)
{
…
Id = id;
…
}
public Equipment(Equipment x) { … }
public static Equipment Clone(Equipment x) { … }
プロパティ
コンストラクター引数
コピー コンストラクター
ディープ クローン
生成物: JSON化・JSON parse
partial class Serializer
{
private string Key(int index, Equipment _)
{
switch (index)
{
case 0: { return "id"; }
…
default: return null;
}
}
private void Serialize(int index, Equipment x)
{
switch (index)
{
case 0: { Serialize(x.Id); break; }
…
}
}
…
partial class Deserializer
{
private Equipment Deserialize(string key, Equipment x)
{
x = x ?? new Equipment();
switch (key)
{
case "id": { x.Id = Deserialize(default(int)); break; }
…
}
return x;
}
…
コード生成で静的に(ビルド時に)作ってしまえば
リフレクション要らない
生成物: データ バインディング用クラス
[Serializable]
[DataContract]
[FileExtensionsAttribute("Equipment")]
[Description("装備品")]
public partial class Equipment : BindableBase, IIdentifiable, IChild, IValidatable
{
/// <Summary>
/// アイテムID
/// </Summary>
[DataMember]
[JsonProperty(PropertyName = "id")]
public int Id { get { return _id; } set { SetProperty(ref _id, value); } }
private int _id;
…
主に編集ツール(Windowsデスクトップ、WPF)用
INotifyPropertyChanged実装
生成物: 通信コード
namespace DataModels
{
public partial class Api : IUnitApi
{
public Task<AddEquipmentResponse> AddEquipmentAsync(AddEquipmentRequest arg, …)
{
OnRequest(arg);
var t = _client.Post("AddEquipment", "/Hero/addEquipment", arg, …
t.ContinueWith(_ => OnResponse(_.Result));
return t;
}
…
HTTP Post
JSON Serialize/Deserialize 呼び出し
全API共通のイベント発火
引数・戻り値をそれぞれ1つのクラスにラップ
(モック作成でその方が都合がよかった※)
※ JSONでAPIの応答モック データを作れる
引数の追加・削除後のモック コード修正が楽だった
生成物: その他
• 型定義JSONも出力
• C#で型定義しだす前の旧型式
• (内部的には「contract JSON」と呼んでる)
• サーバー側は外注、かつ、PHP
• サーバー側のコード生成は発注先に任せてたので、C#を前提にできなかった
• プロジェクトの途中でC#定義に切り替えた
• 急に形式を変えるわけにもいかなかった
• インベントリ/マスター リポジトリ
• (次節で説明)
補足: サーバー側C#
• 複雑なロジックだけサーバーもC#
• 理由
• 2重開発がさすがに無理
• C#で書く方が楽
• 動かし方
• MonoでPHPと同一サーバー内稼働
• 合成・レベルアップ
• ダンジョン、対人バトルのチート検証
• 一部(性能を求める)機能だけWindowsサーバー/IIS
• リアルタイム バトル
反省: .NETの型システム引きずりすぎた
• 非null参照型
• void
null非許容 null許容
値型 int int?
参照型 string ない※
こいつがつらい
• nullを認めたくない場合、[Requred]属性を付けてる
• コード生成の分岐が増えて大変
• .NET経験のない人への説明が大変
※ .NET最大の後悔(million dollar mistake って言われてる)
後からの修正でフレームワークに組み込むのはものすごく大変
Task A()
Task B(T arg)
Task<U> C()
Task<U> D(T arg)
Task<void> A(void arg)
Task<void> B(T arg)
Task<U> C(void arg)
Task<U> D(T arg)
引数・戻り値の有無で4パターンの分岐
こう書けると楽だった
† どちらも今、C#チームが新機能として検討中だけど、入るとしてC# 7.0(2年くらい先?)
反省: 高機能化しすぎた
• 黒魔術度合いが半端ない
• コード生成で、ジェネリックや派生クラスに対応するの結構大変
• リポジトリ(次節で説明)対応がやりすぎ感ある
• 結構ぎりぎりのバランスで成り立ってて
• 修正入れるのそこそこ大変に
• ドキュメント整備できてないので公開してもきっと他人に使えない
反省: コード増えすぎる
• JSON化、すべて静的コード生成
• ソースコード量のうちの結構な割合がJSONがらみ
• アプリのバイナリ サイズ肥大
• 一方、利点もあって
• ソースコードが目に見えるんで、問題を見つけやすい
• JSON読み書きに問題あった時にブレイク ポイント仕掛けられる
リポジトリ
Inventories/MasterRepository
サーバーとのデータ同期、差分更新
ローカル ストレージにデータをキャッシュ
データは全部サーバー上にある
• 必要な分だけ通信でもらってる
• クライアント上でも正規化した状態で管理
• 差分更新
Unit
Id: 1
MasterId: 1
EquipmentId: 120
Equipment
Id: 120
MasterId: 39
EnhancerIds: [ 11, 15, 21 ]
Enhancer
Id: 11
MasterId: 93
Grade: 4
{
{ "action": "update", "item": { "id": 1, "master_id": 1, "equipment_id": 82 } },
{ "action": "remove", "id": 2 }
}
変化したところだけもらう
問題: インスタンスが変わる
• サーバーとの同期でインスタンスが変わる
• 漏れなく追従するの、手動では無理
UI インベントリ
Unit
Id: 1
MasterId: 1
EquipmentId: 120
参照
同期前
UI インベントリ
Unit
Id: 1
MasterId: 1
EquipmentId: 120
参照
同期後
Unit
Id: 1
MasterId: 1
EquipmentId: 82
差分更新の粒度的に
プロパティ1つだけの更新でも
インスタンス丸ごと新しくなる
古い方参照しっぱなし
UI側が更新されない
...
インベントリ内でも同様
参照先が変わる
装備
変更
2系統のデータ
• マスター
• ユニットや装備の名前、パラメーターなど、ユーザーによらないデータ
• ほとんど更新されない
• かなりデータ量が多い
• インベントリ
• ユーザーの手持ちの品
• ことあるごとに更新がかかる
デバイスのローカル ストレージに
キャッシュを保存しておきたい
マスター リポジトリ
• ライブラリを整備
• バージョンとデータをローカルに保存
• バージョンが一致していたらローカルから読む
• 不一致ならサーバーから取り直す
• ID をキーにした Dictionary 化
• コード生成を整備
• [Master]属性がついている型を束ねて MasterRepository 型を生成
• LoadAsyncメソッドで、上記ライブラリを呼ぶ
インベントリ リポジトリ
• ライブラリを整備
• Inventoriesライブラリ
• 現在のインスタンスをID検索できる
• インスタンスの更新イベントを公開
• コード生成を整備
• 通信APIをフックして、リポジトリを自動更新
• 他のインベントリ、マスターが必要なクラスに
それぞれのリポジトリを渡す
• ユニット→装備 とかのID検索プロパティを生成
インベントリ リポジトリ
• ライブラリを整備
• Inventoriesライブラリ
• 現在のインスタンスをID検索できる
• インスタンスの更新イベントを公開
• コード生成を整備
• 通信APIをフックして、リポジトリを自動更新
• 他のインベントリ、マスターが必要なクラスに
それぞれのリポジトリを渡す
• ユニット→装備 とかのID検索プロパティを生成
class DictionaryInventory<T>
{
IEnumerable<T> Items { get; }
IEvent<ChangedArg<T>> Changed { get; }
}
• IEventはIObservableと似たような機能
• つまり、IEnumerableかつIObservableな型
• 現在の値を取る → IEnumerable
• 値の変化をもらう → IObservable
• LINQ+Rx で、Where とか Select を定義可能
インベントリ リポジトリ
• ライブラリを整備
• Inventoriesライブラリ
• 現在のインスタンスをID検索できる
• インスタンスの更新イベントを公開
• コード生成を整備
• 通信APIをフックして、リポジトリを自動更新
• 他のインベントリ、マスターが必要なクラスに
それぞれのリポジトリを渡す
• ユニット→装備 とかのID検索プロパティを生成
internal IEnumerable<IDisposable> Change(SyncDifferenceItem diff)
{
switch(diff.PropertyName)
{
case "Unit": return Units.Change(diff.Difference);
case "Equipments": return Equipments.Change(diff.Difference);
case "Enhancers": return Enhancers.Change(diff.Difference);
...
インベントリ リポジトリ
• ライブラリを整備
• Inventoriesライブラリ
• 現在のインスタンスをID検索できる
• インスタンスの更新イベントを公開
• コード生成を整備
• 通信APIをフックして、リポジトリを自動更新
• 他のインベントリ、マスターが必要なクラスに
それぞれのリポジトリを渡す
• ユニット→装備 とかのID検索プロパティを生成
public partial class Equipment : IDependent<MasterRepository>
{
protected MasterRepository _masters;
void SetRepository(MasterRepository repository)
{
_masters = repository;
if (InstanceAbilities != null) InstanceAbilities.SetRepository(reposito
}
public EquipmentMaster EquipmentMaster { get { return _masters.GetEquipment(
}
通信APIをフックして、このインターフェイス
を持ったクラスにリポジトリを渡す
ID検索して所望のインスタンスを得る
反省: IObservable
• IObservableとほぼ同機能な型を作ってしまっている※
• IEvent<T> ≒ IObservable<EventPettern<T>>
• Unityがシングル スレッド動作なので、同時実行制御だけさぼってる
• IObservable<T>との差は:
• senderを取れる
• OnError/OnCompleteがない
• でも結局、senderはほとんど使ってない
• IObservableでよかった
• Rxに移行しようか悩み中
• IEventに対して、Rxと同じような、Subject, Where, Select, Subscribe実装してる
※ 時期の問題もあった。今から作るならUniRx使うと思う
データ バインディング
Binding-CodeGen
ビューには「UI上のどこにどのデータを出したい」だけを記述
データが更新されたらUIを自動更新
UIが多いゲーム
• 作ってるゲームの性質的にはUIフレームワーク中心
• 3Dとか物理エンジンとか要らない
• むしろ、XAML※的機能がほしい
• Data Binding (CommonView, DialogBase)
• ConentControl, ItemsControl
• UI仮想化
• ゲームだからって常にゲーム フレームワークが最適じゃない
• UIが得意なのは一般OS
• 一般OSのUIフレームワークの上にゲーム描写を重ねたい
• 実際、Win8アプリはXAML UIの上にDirect Xサーフェスを
重ねれる
※ WPF(Windowsデスクトップ)、Silverlight(Webプラグイン)、WinRT(Windowsストア アプリ)の系譜
データ バインディング
• データ バインディング
• UI系フレームワークの要件:
• UI上のどこにどのデータを出したい
• データが更新されたらそこだけ更新したい
<StackPanel
<TextBox Text="{Binding X}" />
<TextBox Text="{Binding Y}" />
</StackPanel>
new Point
{
X = 10,
Y = 20,
};
オブザーバー パターンで実現
※ この辺りはこれだけで1時間セッション コースになるので今回は割愛
検索すればWPF/WinRTとか、JavaScript系フレームワークの記事が出てくるはず
データ バインディング コード生成
• 自社フレームワークでは、コード生成で実現
• リフレクションが使えないので
• モデルのプロパティと、ビューのプロパティをつなぐだけの簡易なもの
[DataContextType(typeof(EquipmentContentModel))]
partial class EquipmentContent : MonoBehaviour
{
[BindingProperty("Equipment")]
public Equipment Equipment
{
set
{
SetThumbnail(value);
}
}
ビューのコード
partial class EquipmentContent
{
public EquipmentContentModel ViewModel { get …
void SourcePropertyChanged(object sender, …
{
base.SourcePropertyChanged(sender, e);
var data = DataContext as EquipmentContentModel;
if(data == null) return;
if (e.PropertyName == "Equipment")
Equipment = data.Equipment;
…
コード生成結果
コード生成
(Unityエディター拡張)
型に応じたプレハブの選択
• ContentControl, ItemsControlクラス
• たいていのUIは、
• 「このデータ型に対して、このプレハブを作りたい」みたいな要件ばっかり
• Unityインスペクターでプレハブを刺しとく
• 1要素版がContentControl、リスト版がItemsControl
UI仮想化
• VirtualizingListViewクラス
• 仮想化
• リストのうちの、画面に見えてる範囲だけ、プレハブをInstantiate
• 残りは作らない、隠れたら消す
• これがないと
• 「アイテムは100個までしか持てません」みたいなゲームになる
• 数が多いと一覧画面に入った瞬間に数秒フリーズ
• スクロールもきつい
反省: 同一プロジェクト内コード生成
• Unityエディター拡張は、コンパイル エラーがある状態で動かせない
• コード生成結果でエラーになると、コード生成し直しがままならない
• エラーがなくなるまでコードを元に戻してから生成しなおし
まとめ
まとめ (1/2)
• IteratorTasks
• System.Threading.Tasks.Task もどき
• TaskInteraction
• チャネルを介したゲーム ロジックとビューとの非同期やり取り
• やり取りの記録、再現
• TaskNavigation
• ページ遷移をステート マシンとして管理
• 遷移トリガーをTaskで表現
まとめ (2/2)
• TypeGen
• API定義・型定義をC#で(C#→C#コード生成)
• Inventories/MasterRepository
• サーバーとのデータ同期、差分更新
• ローカル ストレージにデータをキャッシュ
• Binding-CodeGen
• ビューには「UI上のどこにどのデータを出したい」だけを記述
• データが更新されたらUIを自動更新

More Related Content

What's hot

コールバックと戦う話
コールバックと戦う話コールバックと戦う話
コールバックと戦う話
torisoup
 
Unityでオニオンアーキテクチャ
UnityでオニオンアーキテクチャUnityでオニオンアーキテクチャ
Unityでオニオンアーキテクチャ
torisoup
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
torisoup
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
信之 岩永
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
Ryuji Tsutsui
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだGenya Murakami
 
UniRx完全に理解した
UniRx完全に理解したUniRx完全に理解した
UniRx完全に理解した
torisoup
 
オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫
Yuta Imai
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理
torisoup
 
未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-
torisoup
 
Unityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTips
Unity Technologies Japan K.K.
 
3週連続DDDその2 深いモデルの探求(ドメイン駆動設計 第3部)
3週連続DDDその2  深いモデルの探求(ドメイン駆動設計 第3部)3週連続DDDその2  深いモデルの探求(ドメイン駆動設計 第3部)
3週連続DDDその2 深いモデルの探求(ドメイン駆動設計 第3部)
増田 亨
 
リアルタイムコマンドバトルのゲームで PlayFab を使ってみた
リアルタイムコマンドバトルのゲームで PlayFab を使ってみたリアルタイムコマンドバトルのゲームで PlayFab を使ってみた
リアルタイムコマンドバトルのゲームで PlayFab を使ってみた
YutoNishine
 
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
UnityTechnologiesJapan002
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
信之 岩永
 
アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~
gree_tech
 
Assembly Definition あれやこれ
Assembly Definition あれやこれAssembly Definition あれやこれ
Assembly Definition あれやこれ
NakanoYosuke1
 
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
Tatsuhiko Yamamura
 
3週連続DDDその1 ドメイン駆動設計の基本を理解する
3週連続DDDその1  ドメイン駆動設計の基本を理解する3週連続DDDその1  ドメイン駆動設計の基本を理解する
3週連続DDDその1 ドメイン駆動設計の基本を理解する
増田 亨
 
UnityのMultiplayサービスの得意な事
UnityのMultiplayサービスの得意な事UnityのMultiplayサービスの得意な事
UnityのMultiplayサービスの得意な事
Unity Technologies Japan K.K.
 

What's hot (20)

コールバックと戦う話
コールバックと戦う話コールバックと戦う話
コールバックと戦う話
 
Unityでオニオンアーキテクチャ
UnityでオニオンアーキテクチャUnityでオニオンアーキテクチャ
Unityでオニオンアーキテクチャ
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
 
UniRx完全に理解した
UniRx完全に理解したUniRx完全に理解した
UniRx完全に理解した
 
オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理
 
未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-
 
Unityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTips
 
3週連続DDDその2 深いモデルの探求(ドメイン駆動設計 第3部)
3週連続DDDその2  深いモデルの探求(ドメイン駆動設計 第3部)3週連続DDDその2  深いモデルの探求(ドメイン駆動設計 第3部)
3週連続DDDその2 深いモデルの探求(ドメイン駆動設計 第3部)
 
リアルタイムコマンドバトルのゲームで PlayFab を使ってみた
リアルタイムコマンドバトルのゲームで PlayFab を使ってみたリアルタイムコマンドバトルのゲームで PlayFab を使ってみた
リアルタイムコマンドバトルのゲームで PlayFab を使ってみた
 
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
 
アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~
 
Assembly Definition あれやこれ
Assembly Definition あれやこれAssembly Definition あれやこれ
Assembly Definition あれやこれ
 
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
 
3週連続DDDその1 ドメイン駆動設計の基本を理解する
3週連続DDDその1  ドメイン駆動設計の基本を理解する3週連続DDDその1  ドメイン駆動設計の基本を理解する
3週連続DDDその1 ドメイン駆動設計の基本を理解する
 
UnityのMultiplayサービスの得意な事
UnityのMultiplayサービスの得意な事UnityのMultiplayサービスの得意な事
UnityのMultiplayサービスの得意な事
 

Similar to Orange Cube 自社フレームワーク 2015/3

Android gameprogramming
Android gameprogrammingAndroid gameprogramming
Android gameprogramming
Masahiro Hidaka
 
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 EastiOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
irgaly
 
Androidプログラミング初心者のためのゲームアプリ開発入門
Androidプログラミング初心者のためのゲームアプリ開発入門Androidプログラミング初心者のためのゲームアプリ開発入門
Androidプログラミング初心者のためのゲームアプリ開発入門
Masahiko Mizuta
 
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門Atsushi Tadokoro
 
C++11とゲーム製作
C++11とゲーム製作C++11とゲーム製作
C++11とゲーム製作
uchan_nos
 
“debug.gem”の 利用体験・開発効率の向上
“debug.gem”の 利用体験・開発効率の向上“debug.gem”の 利用体験・開発効率の向上
“debug.gem”の 利用体験・開発効率の向上
Naoto Ono
 
“debug.gem”の 利用体験・開発効率の向上.pdf
“debug.gem”の 利用体験・開発効率の向上.pdf“debug.gem”の 利用体験・開発効率の向上.pdf
“debug.gem”の 利用体験・開発効率の向上.pdf
Naoto Ono
 
Chrome DevTools.next
Chrome DevTools.nextChrome DevTools.next
Chrome DevTools.next
yoshikawa_t
 
わんくま名古屋#33(20141115) TDD道場#21
わんくま名古屋#33(20141115) TDD道場#21わんくま名古屋#33(20141115) TDD道場#21
わんくま名古屋#33(20141115) TDD道場#21
Yasuhiko Yamamoto
 
BNN CAMP vol.3  インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1
BNN CAMP vol.3  インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1BNN CAMP vol.3  インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1
BNN CAMP vol.3  インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1Atsushi Tadokoro
 
Multipeer connectivityを使った 動画のリアルタイム端末間共有
Multipeer connectivityを使った 動画のリアルタイム端末間共有Multipeer connectivityを使った 動画のリアルタイム端末間共有
Multipeer connectivityを使った 動画のリアルタイム端末間共有
Imajin Kawabe
 
メディア・アート II 第1回: ガイダンス openFrameworks入門
メディア・アート II 第1回: ガイダンス openFrameworks入門メディア・アート II 第1回: ガイダンス openFrameworks入門
メディア・アート II 第1回: ガイダンス openFrameworks入門Atsushi Tadokoro
 
Firefoxの開発プロセス
Firefoxの開発プロセスFirefoxの開発プロセス
Firefoxの開発プロセスMakoto Kato
 
Unityで本格戦国シュミレーションRPG 開発
Unityで本格戦国シュミレーションRPG 開発Unityで本格戦国シュミレーションRPG 開発
Unityで本格戦国シュミレーションRPG 開発
dena_study
 
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
Tatsuya Ishikawa
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
信之 岩永
 
Circle ci and docker+serverspec
Circle ci and docker+serverspecCircle ci and docker+serverspec
Circle ci and docker+serverspec
Tsuyoshi Yamada
 
Fabric + Amazon EC2で快適サポート生活 #PyFes
Fabric + Amazon EC2で快適サポート生活 #PyFesFabric + Amazon EC2で快適サポート生活 #PyFes
Fabric + Amazon EC2で快適サポート生活 #PyFes
Sho Shimauchi
 

Similar to Orange Cube 自社フレームワーク 2015/3 (20)

Android gameprogramming
Android gameprogrammingAndroid gameprogramming
Android gameprogramming
 
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 EastiOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
 
Androidプログラミング初心者のためのゲームアプリ開発入門
Androidプログラミング初心者のためのゲームアプリ開発入門Androidプログラミング初心者のためのゲームアプリ開発入門
Androidプログラミング初心者のためのゲームアプリ開発入門
 
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門
 
C++11とゲーム製作
C++11とゲーム製作C++11とゲーム製作
C++11とゲーム製作
 
“debug.gem”の 利用体験・開発効率の向上
“debug.gem”の 利用体験・開発効率の向上“debug.gem”の 利用体験・開発効率の向上
“debug.gem”の 利用体験・開発効率の向上
 
“debug.gem”の 利用体験・開発効率の向上.pdf
“debug.gem”の 利用体験・開発効率の向上.pdf“debug.gem”の 利用体験・開発効率の向上.pdf
“debug.gem”の 利用体験・開発効率の向上.pdf
 
Chrome DevTools.next
Chrome DevTools.nextChrome DevTools.next
Chrome DevTools.next
 
わんくま名古屋#33(20141115) TDD道場#21
わんくま名古屋#33(20141115) TDD道場#21わんくま名古屋#33(20141115) TDD道場#21
わんくま名古屋#33(20141115) TDD道場#21
 
つぶLT20121215
つぶLT20121215つぶLT20121215
つぶLT20121215
 
BNN CAMP vol.3  インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1
BNN CAMP vol.3  インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1BNN CAMP vol.3  インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1
BNN CAMP vol.3  インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1
 
Multipeer connectivityを使った 動画のリアルタイム端末間共有
Multipeer connectivityを使った 動画のリアルタイム端末間共有Multipeer connectivityを使った 動画のリアルタイム端末間共有
Multipeer connectivityを使った 動画のリアルタイム端末間共有
 
メディア・アート II 第1回: ガイダンス openFrameworks入門
メディア・アート II 第1回: ガイダンス openFrameworks入門メディア・アート II 第1回: ガイダンス openFrameworks入門
メディア・アート II 第1回: ガイダンス openFrameworks入門
 
Firefoxの開発プロセス
Firefoxの開発プロセスFirefoxの開発プロセス
Firefoxの開発プロセス
 
Unityで本格戦国シュミレーションRPG 開発
Unityで本格戦国シュミレーションRPG 開発Unityで本格戦国シュミレーションRPG 開発
Unityで本格戦国シュミレーションRPG 開発
 
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
0621 ndk game
0621 ndk game0621 ndk game
0621 ndk game
 
Circle ci and docker+serverspec
Circle ci and docker+serverspecCircle ci and docker+serverspec
Circle ci and docker+serverspec
 
Fabric + Amazon EC2で快適サポート生活 #PyFes
Fabric + Amazon EC2で快適サポート生活 #PyFesFabric + Amazon EC2で快適サポート生活 #PyFes
Fabric + Amazon EC2で快適サポート生活 #PyFes
 

More from 信之 岩永

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話
信之 岩永
 
C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
信之 岩永
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話
信之 岩永
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理
信之 岩永
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム
信之 岩永
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
信之 岩永
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)
信之 岩永
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
信之 岩永
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1
信之 岩永
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方
信之 岩永
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6
信之 岩永
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に
信之 岩永
 
Modern .NET
Modern .NETModern .NET
Modern .NET
信之 岩永
 
Deep Dive C# 6.0
Deep Dive C# 6.0Deep Dive C# 6.0
Deep Dive C# 6.0
信之 岩永
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
信之 岩永
 
C# design note sep 2014
C# design note sep 2014C# design note sep 2014
C# design note sep 2014
信之 岩永
 
.NET vNext
.NET vNext.NET vNext
.NET vNext
信之 岩永
 
C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版
信之 岩永
 

More from 信之 岩永 (20)

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話
 
C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に
 
Modern .NET
Modern .NETModern .NET
Modern .NET
 
Deep Dive C# 6.0
Deep Dive C# 6.0Deep Dive C# 6.0
Deep Dive C# 6.0
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 
C# design note sep 2014
C# design note sep 2014C# design note sep 2014
C# design note sep 2014
 
.NET vNext
.NET vNext.NET vNext
.NET vNext
 
C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版
 

Recently uploaded

MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
iPride Co., Ltd.
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
Matsushita Laboratory
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
atsushi061452
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance
 
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
harmonylab
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
Toru Tamaki
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance
 
【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow
Sony - Neural Network Libraries
 
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
yassun7010
 
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
NTT DATA Technology & Innovation
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance
 
CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料
Yuuitirou528 default
 
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
Fukuoka Institute of Technology
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance
 

Recently uploaded (16)

MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
 
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
 
【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow
 
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
 
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
 
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
 
CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料
 
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
 

Orange Cube 自社フレームワーク 2015/3

Editor's Notes

  1. 要するに、「データの更新に画面遷移(リロード)が必要とか、画面遷移するたびにロード長いとかそんなクソゲー作るな」という話
  2. MonoBehaviour は1人で債務を持ちすぎ。債務分割まったくできてないど素人設計
  3. ちなみに、C# 5.0のawaitはこれと似たようなコードに展開されてる。要は、C# 5.0と同じことを自前でやってる。
  4. つまり、UnityとっととMonoのバージョン上げろよ
  5. 命名規約的には、いまのところ await + イベント名でメソッド作ってる。いまいちかなぁと思いつつ定着。 FirstAsync 無双。
  6. Begin/End系の非同期処理と同様、行きと帰りが違う口なのが問題。ラウンドトリップをTaskで一本化してしまえば案外楽。 逆に言うと、メッセンジャー/コマンドのペアに分解する補助関数かけば、既存MVVMフレームワークにもつなげる。 この辺りは後でデモでライブコーディングします
  7. ページ遷移をステート マシンで管理しようって言うのは割かしよくある発想。 https://msdn.microsoft.com/ja-jp/magazine/dn818499.aspx
  8. インベントリは紆余曲折あった ・ 昔、要るデータだけ取ってたら更新が保守しきれなくて心折れる ・全同期やり始める ・重たすぎてサーバー側に怒られる ・差分更新をフレームワーク化、コード生成(今ここ)
  9. IteratorTasksでも言った通り、劣化コピーの実装は嫌
  10. つまるところ、「C#でクロスプラットフォーム」ってこと以外にUnity使ってる利点もない。 マップ表示だけかなぁ、ゲーム的な描画最適化頑張らないといけないの
  11. このパターン守れないとだいたいスパゲッティ コード化して大変