SlideShare a Scribd company logo
1 of 35
UnityでもTaskが使いたい!
~MinimumAsyncBridgeの紹介~
安井彰一
@Shaula0x0400
自己紹介
Facebook:安井彰一
Twitter:@Shaula0x0400
Github:the9ball
株式会社オレンジキューブ所属
Taskとは
Taskとは
● async/await で記述できる非同期処理機構
async Task 時間のかかる処理()
{
...処理...
}
await 時間のかかる処理();
● 参考 : 非同期メソッド
(http://ufcpp.net/study/csharp/sp5_async.html)
Taskとは
● Coroutineじゃだめなの?
○ CoroutineはMainThreadで動作するため、
CPU時間を専有してGUI等の処理に影響が出てしまう。
○ yield return 毎での処理分割になるため、
適切に分割しないとパフォーマンスを活かせない。
● ただし
○ UnityにはMainThreadからでないと操作できないオブジェクトが多い。
そのため、Unityのオブジェクトを操作する際には
動作しているスレッドに気をつけないといけない。
他の候補
● JobSystem
○ 安全に使用できるような様々な制限がかかっている。
○ 専用の記述が多数ある。
○ とはいえ、まだ未知数
他の候補
● UniRx ( https://github.com/neuecc/UniRx )
○ ReactiveExtensions(System.Reactive)をUnityで動かせるようにした実装。
○ 基本はイベント(メッセージ)処理。
○ Unity独自の拡張も多い。
○ シーケンシャルな処理を記述するには
Coroutineと組み合わせる必要がある。
UnityでTask
UnityでTask
● 初期状態では記述できない。
● Unity2017ではScripting Runtime Versionを
.NET4.6に切り替えればコンパイル/動作に問題はない。
○ ただし、Editor(とPC)上ではな!!!
○ どうもAndroid/iOS上ではまだうまく動かないらしく、
標準的な機能としては使用できない模様。。。
UnityでTask
そこでオススメしたいのが
MinimumAsyncBridge
(https://github.com/OrangeCube/MinimumAsyncBridge)
MinimumAsyncBridge
MinimumAsyncBridge
● 弊社開発のTaskをUnityで動作できるようにした実装。
● .NET4.5以上の場合は自動的に
通常のSystem.ThreadingTasksを参照してくれる。
● Nugetで配布されているので導入も簡単。
● つまり、Unity以外とのコード共有が可能!!!
MinimumAsyncBridge
すごい!!!
だが話は簡単ではなかった。
MinimumAsyncBridge
● 前述した通り、Unityでコンパイルすることはできない。
(してもスマホで動作しない)
● つまり、Unityプロジェクト内に
DLLを置いたところで意味がない。
MinimumAsyncBridge
● 前述した通り、Unityでコンパイルすることはできない。
(してもスマホで動作しない)
● つまり、Unityプロジェクト内に
DLLを置いたところで意味がない。
Unityプロジェクト内に置かなければいいんじゃね?
MinimumAsyncBridge
つまり
1. Unityとは別にC#プロジェクトを作成
2. Unityプロジェクト内にDLLを配置
3. Unity内から呼び出し
4. 非同期処理が実現可能!
別プロジェクトでDLLを作成する利点
● Unityのビルドが早くなる。
(DLL内のソースコードについてコンパイルが不要なので)
● MVC系設計のようにModelを分離させやすい。
● ツールやサーバーなどとコード共有できる。
● UnityがなくてもUnitTestができる。
導入方法
導入方法(ただしWindows/VisualStudio)
1. C#3.5クラスライブラリプロジェクトを作成
2. MinimumAsyncBridgeをNugetで追加
3. LayoutAutoToSequencialをcloneしてslnに追加
4. IteratorTaskBridgeをcloneしてslnに追加
5. Unityプロジェクト内にコピーするためのプロジェクトを作成
6. CopyDllsAfterBuildをNugetで追加
7. LayoutAutoToSequencialを使用するようPostBuildを修正
8. Unity内から呼び出し
導入方法(C#3.5クラスライブラリプロジェクトを作成)
1. プロジェクト作成でClass Library(.NET Core) を選択
2. 作成したプロジェクトをUnloadしてEditProject
(テキストエディタでも可)
3. TargetFrameworkをnet35に書き換え
(複数ターゲットの場合はFrameworksで;区切り)
4. Reload Project
導入方法(MinimumAsyncBridgeをNugetで追加)
1. ライブラリプロジェクト右クリックして
Manage Nuget Packages を選択
2. BrowseからMinimumAsyncBridgeを検索して追加
3. using System.Threading.Tasks;してコードを記述
導入方法(LayoutAutoToSequencialをcloneしてslnに追加)
スマホでのビルドをしない場合は不要です。
また、最適化(Releaseビルド)をしていない場合も不要です。
1. MinimumAsyncBridgeをcloneしてslnに追加
(https://github.com/OrangeCube/MinimumAsyncBridge)
導入方法(IteratorTaskBridgeをcloneしてslnに追加)
1. IteratorTasksをcloneしてslnに追加
(https://github.com/OrangeCube/IteratorTasks)
導入方法(Unityプロジェクト内にコピーするためのプロジェクトを作成)
1. プロジェクト作成でConsoleApp(.NET Core) を選択
2. 作成したプロジェクトをUnloadしてEdit Project
(テキストエディタでも可)
3. TargetFrameworkをnet35に書き換える
(複数ターゲットの場合はFrameworksで;区切り)
4. Reload Project
5. Add Referenceでクラスライブラリプロジェクトと
導入方法(CopyDllsAfterBuildをNugetで追加)
1. 先ほどと同じ方法でCopyDllsAfterBuildをNugetで追加
2. CopySettings.jsonをプロジェクトのルートに作成
○ 配置先パスを設定
○ コピー用プロジェクト名をexcludesに追加
{
"destination": "../../project/Assets/Dlls",
"pattern": "*",
"excludes": [ "UnityEngine", "UnityEditor", "CopyDll" ]
導入方法(LayoutAutoToSequencialを使用するようPostBuildを修正)
スマホでのビルドをしない場合は不要です。
また、最適化(Releaseビルド)をしていない場合も不要です。
1. PostBuildイベントの処理においてCopyの前に
LayoutAutoToSequencialを実行するよう修正
$(SolutionDir)..¥..¥MinimumAsyncBridge¥tools¥LayoutAutoToSequencial¥bin¥Rel
ease¥LayoutAutoToSequencial.exe" "$(TargetDir)"
pushd "$(NuGetPackageRoot)CopyDllsAfterBuild¥2.1.1¥tools¥" & postbuild
"$(ProjectDir)" "$(TargetDir)" & popd
導入方法(Unity内から呼び出し)
1. IteratorTasks.Task.DefaultScheduler.Update();を呼ぶ
○ Unity独自の事情で毎フレーム呼び出す
○ DontDestroyOnLoadなオブジェクトで行うのが良い
2. 呼び出す
導入方法
そうしてできあがったのがこちらです。
https://github.com/the9ball/BridgeTest
注意点
● Taskはどのスレッドで実行されるかわからないため
MainThreadでしか操作できないオブジェクトを
操作してしまうとエラーになってしまうので注意。
まとめ
まとめ
みんなでTaskを使いこなして
Unityが正式にasync/await対応するよう
プレッシャーをかけていきましょう!
付録
Task初学者へのアドバイス
● Task.IsCompleted はタスクが終わったことのみを通知します。
つまり、完了/キャンセル/例外の何れの状態でもIsCompletedです。
成功を判定したい場合はTask.Status==TaskStatus.RanToCompletionです。
● 同時並列を行いたい場合は、Task.WhenAll/WhenAnyを使用しましょう。
● 途中キャンセルが必要な場合はCancellationTokenを引数にしましょう。
呼び出す側はCancellationTokenSourceを使用してください。
ただし、CancellationTokenSource.Dispose()をしても
IsCancellationRequestedにならないという点に注意が必要です。
● Coroutineとの連携などにはTaskCompletionSource<T>が有用でしょう。
最後に
オレンジキューブでは、一緒に
ゲームを作ってくれる仲間を募集しています。
以下のどれか1つでも当てはまる場合はおすすめです。
是非一度お話をしましょう。
・C# が好き
・ワンソースマルチプラットフォームで海外展開しているクリユニに興味がある
・短時間で決着する対戦ゲームに興味がある
・リッチなドット絵のゲームに興味がある
・ローグライクゲームが好き
・さらなるストラテジーの進化に挑戦してみたい
・ゲーム作るのも好きだが、プレイするのも大好き
もしご興味があればお気軽にご連絡ください。
https://www.wantedly.com/projects/114864

More Related Content

Viewers also liked

マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD
マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DDマジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD
マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DDエピック・ゲームズ・ジャパン Epic Games Japan
 
AssetBundle (もどき) の作り方
AssetBundle (もどき) の作り方AssetBundle (もどき) の作り方
AssetBundle (もどき) の作り方Mori Tetsuya
 
なぜなにリアルタイムレンダリング
なぜなにリアルタイムレンダリングなぜなにリアルタイムレンダリング
なぜなにリアルタイムレンダリングSatoshi Kodaira
 
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DDマテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DDエピック・ゲームズ・ジャパン Epic Games Japan
 
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術Unity Technologies Japan K.K.
 

Viewers also liked (6)

マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD
マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DDマジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD
マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD
 
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
 
AssetBundle (もどき) の作り方
AssetBundle (もどき) の作り方AssetBundle (もどき) の作り方
AssetBundle (もどき) の作り方
 
なぜなにリアルタイムレンダリング
なぜなにリアルタイムレンダリングなぜなにリアルタイムレンダリング
なぜなにリアルタイムレンダリング
 
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DDマテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD
 
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
 

UnityでもTaskが使いたい!~MinimumAsyncBridgeの紹介~

Editor's Notes

  1. Unityというか.NET3.5
  2. クラスライブラリ
  3. 先程MinimumAsyncBridgeをNugetで追加したのはコード共有等をする場合はこのLATSが不要であるため
  4. UnityでTaskの制御をするためのライブラリ 別途DLLをUnityプロジェクト内に置いても良い
  5. これを作成するのは手動コピーの手間を省くため 先程作成したクラスライブラリを始めとして出力先をUnityProject内に指定してもいいが、 依存関係によってはDLLが競合するなどの問題があるため、この方法をおすすめする
  6. 下のものに似たコードは既に設定されているはず TargetDirとProjectDirが何故か空文字になってしまっており、調査中なのでパスが少し違ったりするかも?