読者です 読者をやめる 読者になる 読者になる

ほげほげー

C#メインで困ったことや面白く感じたことをメモしていきます。

Unity での開発でも async/await を使おう

C# Unity

いつも通り久しぶりに記事を書きます。

Unity で async/await を使うようになってから大変捗っているので覚書。

async/await 以前の非同期

従来の C# では非同期を取り扱うためには色々面倒な事をする必要がありました。

例えば delegateBeginInvoke, EndInvoke を使う。

例えば System.Threading.Thread を使う。

例えば System.Threading.ThreadPool を使う。

などなど。まぁ歴史的経緯もあってほんとに色々あります。

どれでやるにしても本当に簡単な処理を非同期にする時以外は、
メインスレッドに返したり、非同期の連鎖があったりと、
大抵の場合非常にコードが汚くなりがちです。

Unity ではもちろん UI に触るときはメインスレッドからしか受け付けていないので、
別スレッドで処理した場合はメインスレッドに何らかの方法でディスパッチする必要があります。*1*2

async/await 以後の非同期

async/await は C# 5.0(.NET Framework 4.5) から導入された演算子です。

戻り値を void, Task, Task<T> にして、async キーワードを付ける事で、
Task, Task<T> を戻り値にしているメソッドを await 演算子で待機できるようになります。*3

普通のメソッド呼び出しと同じように書けるようになるので非常に読みやすい。

await NanikaOmotaiAsync();
var result = await NanikaOmotaiGetAsync();
await NanikaOmotaiSetAsync(result);

適切に Task で処理されていれば、await で待機した場合、非同期処理後は元のスレッドで処理を再開するので、
重たい処理の間だけ別スレッドで処理して、それ以外の処理は呼び出し元のスレッドで処理する形になります。

f:id:tyhe:20160404220239p:plain

重い処理が MainThread を専有しなくなるので UI が固まることはありません。

Unity で非同期をするには

  • 昔ながらの手段を使う
  • コルーチンを使う(後述)
  • UniRx を使う
  • MinimumAsyncBridge を使う(本記事で紹介)

Unity のコルーチンは非同期なのか

非同期だけどシングルスレッドなので注意しないとUIが固まります。

f:id:tyhe:20160404220034p:plain

StartCoroutine で登録された IEnumerator 全てに対して1フレーム毎に MoveNext を呼び出します。
また、全てのMoveNext の処理が終わるまでの間1フレームが終わりません。
そのため、30fpsのゲームの場合は30ms、60fpsのゲームの場合は15ms超える処理となってしまうとFPSが落ちてしまいます。

コルーチンは基本的に重たい処理を複数フレームに小分けにして処理をするもの、
と考えておくと良いですね。

コルーチンで目にする yield が何なのかについては以下の記事を読んでいただくと比較的分かりやすいと思います。

tyheeeee.hateblo.jp

Unity で async/await を使って開発する

やっと本題。

Unity Script では使えません。残念でした。

しかしながら、Assets/Dlls 以下に設置する dll については別。

dll の作成時には async/await を使おうと思えば使えるのです。
ただし、Unity で使える .NET Framework は 3.5 Subset 相当なので当然 Task クラスやら何やらはありません。

ではどうするか?

自前で Awaiter パターン を実装した Task クラスを実装すれば良いのです。

Awaiter パターンについて詳しくは他の方の記事を見ていただくとして、
ここでは簡単に。

class Hoge
{
    public HogeAwaiter GetAwaiter();
}

class HogeAwaiter
{
    public bool IsCompleted { get; }
    public void OnCompleted(Action continuation) { }
    public T GetResult() { }
}

これらのメソッドを持っているオブジェクトなら実は何でも await 出来ます。
そして拡張メソッドでも OK なので、本当になんでも。

しかしながら、イチから実装するのは大変なので、ここでは株式会社オレンジキューブが公開している
MinimumAsyncBridge を使います。

github.com

NuGet Package も公開されているのでパッケージマネージャコンソールからインストールできます。

Install-Package MinimumAsyncBridge

では早速。

プロジェクトを作成して、対象のフレームワーク .NET Framework 3.5 にする

f:id:tyhe:20160405004041p:plain

参照を右クリックして NuGet パッケージの管理を開く

f:id:tyhe:20160405002422p:plain

MinimumAsyncBridge の最新版をインストールする

f:id:tyhe:20160405002534p:plain

MinimumThreadingBridge も一緒にインストールされるのでインストールする

f:id:tyhe:20160405002629p:plain

これでできました。

あとは何も意識すること無く普通に async/await が使えます。

f:id:tyhe:20160405004242p:plain

さて、何で使えるのかというと、

  • async/await をコンパイルした時に吐かれる IL 自体には何の拡張も無い
  • GetAwaiter 関連さえ実装されていれば async/await は使える

ということは、Unity でも Dlls に入れる分には特に問題なく使えるのです。

その辺の軽い説明はこちらを参照。

[http://tyheeeee.hateblo.jp/entry/2015/06/12/Visual_Studio_2015%E3%81%A8_Unity%E3%81%A8:embed:cite]

特に問題なく使えると言ったな。あれは嘘だ。

async/await 対応は実は完璧ではなくて、
Release ビルドをすると IL2CPP でのビルドに失敗します。

Release ビルド時に特定の最適化がされる事に起因するっぽいのですが、
IL2CPP そのものに修正が入らないとどうにもならないので、まぁ Debug ビルドで我慢。

バグとしては挙げているので、まぁそのうち・・・きっと直らないと思います。

とはいえ、最適化入っても入らなくてもそんな致命的な程には変わらないので、 async/await の利便性を享受するために甘んじて受け入れましょう。

2016/12/27 追記

Release ビルド時に [StructLayout(LayoutKind.Sequential)] 属性が付与される事に起因しているっぽい。 https://unity3d.com/jp/unity/whats-new/unity-5.3.5 の Fixes に書かれている IL2CPP: 基本クラスが StructLayout 属性を持たないときに、StructLayout 属性を持つC# クラスのための適切なC++コードを生成(767367) で直ってるかもしれません(未確認)

これが原因だと分かっていれば無理矢理やってやれない事も無くて、
Mono.Cecil あたりを使って dll 読み込んで属性をちょちょいと外して書き戻してあげれば良かったりします。

実際現在開発中のゲームではそれで動作しています。

Unity の今後について

先日 Xamarin が Microsoft に買収されて、ARM 版の Mono がオープンソース化されたことで、
Unity の C# 最新仕様への対応が飛躍的に進むんでないかと期待していたりします。

そして .NET Foundation への加入も表明し、これから加速していきそうな予感がします。

blogs.unity3d.com

これからの Unity に期待ですね。

C# 6.0 対応はやく

*1:UI をメインスレッドからしかさわれないのは他のフレームワークでもでも大体同様です。WPF や WinForms でもそう。

*2:UI ではない WWW クラスも AssetBundle をダウンロードする機能を積んでいるからか、メインスレッドで触らないといけないのはホントひどい話

*3:厳密には GetAwaiter が使えるクラスなら何でも

PowerShell の自動変数とその落とし穴

本記事は PowerShell Advent Calendar 22日目の記事です。

atnd.org

はじめに

先日書捨てのコード書いててこいつにやられた*1ので忘れないように。

なお、本記事は時間が無さ過ぎて相当圧縮された模様なのであしからず。

自動変数とは

PowerShell が自動的に生成、代入する変数のことです。

$_$Error などがよく使われていると思います。

一覧は以下のリンクから確認して下さい。

about_Automatic_Variables

今回のおはなし

自動変数には割と一般名が使われているため、注意しないと出くわしてしまう問題があります。

というか、割と出くわして、毎回忘れてしまう類のもの。

知っている人に取っては今更感溢れる内容にはなるのでそっ閉じ推奨。

関数の引数に型付きで $Input って名前を付けるとい動かない事がある

事がある、と言ったものの、大抵の場合動かない。

理由は単純で、$INPUT が関数に渡された全ての入力を列挙する自動変数だから。

実際に以下の関数を定義して呼び出すとエラーが発生します。

function TestSample([int]$Input)
{
    Write-Host $Input
}

呼び出した時のエラーはこんな感じ。

TestSample -Input 123

TestSample : "System.Collections.ArrayList+ArrayListEnumeratorSimple" の値を "System.Collections.ArrayList+ArrayListEnumeratorSimple" 型から "System.Int32" 型に変換できません。
発生場所 行:1 文字:1
+ TestSample -Input 123
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [TestSample]、PSInvalidCastException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException,TestSample

このエラーから自動変数であることを知らずに原因にたどり着くのはわりと時間かかるので困り者です。

が、知ってさえいれば未然に防ぐことも可能ですし、万一で遭遇しても比較的早く原因にたどり着くことができるはず。

というわけで、備忘録がてらアドベントカレンダーに参加したものの自動変数の説明入れつつ最後に落とし穴的にまとめようと思ったら時間がなくて落とし穴だけになってしまったという超縮小版記事でしたごめんなさいごめんなさい。

次は @oota_ken さんの「知っているかもなtype裏技」です。

*1:注意参照

Windows Phone についてふたことみこと。

Windows Phone iPhone Android Windows

はじめに

これらは私個人としての意見であって Windows Phone を使っている人が全てこのような感想を得るわけではないことを予めご了承ください。

また、Windows Phone を愛する方の気分を害する恐れがあります。ご留意ください。

それでは。

続きを読む

MADOSMA が壊れたので修理に出しました

Windows Phone MADOSMA

先日購入した MADOSMA ですが、実は先々月あたりに壊れてました。

何がどう壊れたのかですが、何故か音量ボタン(下)が押しっぱなしな状態になり、
再起動しても「!」と表示されてそのまま終了する、という現象に苛まれていました。

長期間(1週間とか)放っておいてから再起動すると普通に起動するのですが、
その状態で音量ボタンに触ると再び音量ボタン(下)が押しっぱなしになり、
OS ごと落ちて再起動ループです。

そんなこんなで修理に出して修理が完了するまでの一連の流れを適当にまとめておきます。

MADOSMA が壊れたら

慌てず騒がず修理に出しましょう。

修理に出す

実は MADOSMA 専用の修理申し込みの窓口があります。

www2.mouse-jp.co.jp

まだ発売してから1年経っていないので余裕で無償修理期間ですね。

手順

詳しくは上記のサイトを診てもらうことにして、実際に出した時の手順を簡単にまとめておきます。
この程度でいいのよ?と。

  • ヨドバシオンラインの注文履歴のキャプチャ画像を印刷。
    プリンタ無いのでネットプリントを利用。便利。

  • 以下のページから修理依頼。バッテリー裏にあるシリアルコードが必要。
    修理依頼シート入力後の控え番号を適当な紙に書いておく。
    自分の場合はキャプチャ取ってネットプリントした。

www2.mouse-jp.co.jp

  • MADOSMA に挿してる SIM と Micro SD を外して保管。

  • 買った時の箱にバッテリーと本体詰めて、更に郵便局でダンボールに詰めてもらって送付。 箱がなかったら適当にクッション材にくるむだけでもOK。
    ここにプリントアウトしたものも詰めてる。

届いたら

マウスコンピュータのサポートセンターからメールが来るので配達証明とかあまりいらないかも。*1

修理

経過報告

○○したら再現しました。

○○しても再現しませんでした。

って連絡くれて、修理が必要なら修理して送ってくれます。

で、実は自分の場合、送ったら直ってしまったらしく、再現しなかったのですが、
万一のために交換対応していただきました。

感謝感謝です。

出荷

というわけで 10/2 に出荷の連絡がありました。

到着

そしたら 10/3 のお昼に届きました。早い。

お帰り MADOSMA ちゃん。

f:id:tyhe:20151003121000j:plain f:id:tyhe:20151003121316j:plain

まとめ

非常に丁寧にやり取りをしていただき、更に交換までして頂きました。

今後万一壊れたとしても心置きなく修理に出せるという安心感を得られたので個人的にはかなり満足です。

ただ、キャリアで買った場合と比較して、修理時の代替品が無かったりするので、SIMを挿して使える端末を2台以上持っていないと厳しいよなーとは思いました。

Apple みたく即日交換、即日修理、というわけにもいかないので、最低でも2週間弱は手元に無くても大丈夫な状態である必要があります。

これは MVNO で運用する場合避けて通れない点かなとは思うので、これから MVNO で運用をしようと検討されている方はよくよく考えて行動に移してください。

*1:シルバーウィーク前に送ったので届くまでにだいぶかかってしまったので実はちょっと心配してた

iPhone 6s Plus を買ったので雑感と TIPS

iPhone iOS iOS9

iPhone 5s を使っていて、割と満足はしていたのですがディスプレイが剥がれて来たので思い切って 6s Plus に機種変更してみました。

もちろんニコニコ現金一括払い。

そんな感じで買ってセットアップして諸々終わったので感想とか iPhone 6s(& Plus) 絡みの TIPS とかを書いていきます。

購入

ソフトバンクショップで購入してきました。

登録してあるクレジットカードの期限がギリギリだったせいかカードの審査通らなかったので別のクレジットカードを登録して購入。

割とめんどくさかったのでクレジットカードの期限にはご注意を。

それはさておき。

無事 iPhone 6s Plus 128GB Space Gray を購入できました。

f:id:tyhe:20150925222305j:plain f:id:tyhe:20150925222359j:plain

開封の儀は適当に済ませて。

バックアップからの復元

購入した状態からすぐに復元して操作を進めていくと
スライドでアップグレード って出たところで固まる現象に苛まれます。

コレ、iOS 9.0.1 にアップデートしないと無限ループします。

なので、一旦電源を落としてパソコンに繋いで、iOS のアップデートします。*1

次に、iCloud設定をアップデート中…って出たまま進まないかもしれません。

その時はしばらく待ってから電源落として再起動すると何事もなかったかのように進みます。

これでようやくバックアップからの復元が出来ました。

その他購入物

今回は6ヶ月使ったあとにSIMロック解除して長く使う予定なのでガラスフィルムを買いました。
傷がついたら張り替えればいいってステキです。

で、迷いに迷った挙句実際買ったのはこれ。(アフィリエイトリンク注意)

高いですが指の滑りが何も貼ってない時とほぼ変わりなく、なめらかでいい感じです。

あとは適当な安いケースとバンカーリングを買いました。

バンカーリング、今のところ違和感のほうが大きくて、ヘタしたら無い方が良いんじゃないか?
って思ってしまうくらいなのですが、コレはきっと慣れなので慣れていきます。
片手での操作が楽になっていることは間違いないので。

梨地仕上げなバンカーリングなんでなくなってしまったんだろう。
あったらそっちにしたのに。

適当な購入記はここまで。

感想

デカイ。

けど、なんとか片手で操作できるのは意外だった。

ちゃんとフリック入力用テンキーの高さが低めになってくれるからか、
心配していたほど文字入力が大変ではなくてよかった。

サードパーティ製のキーボードも視野に入れてみようかな、とは思ったけど、無くてもなんとかなりそう。

ゲームのパフォーマンスがだいぶ上がったのがやはり嬉しい。
最近のゲームは 3D でエフェクトゴリゴリだったりするので 5s だと少しだけつらい場面があったので。

Android は Nexus 5 を持ってるけども、ゲームのパフォーマンスだけで言えば iPhone 5s よりも若干低い感じ。
なので、6s Plus のおかげでスマホゲームの環境は相当改善された。 *2

3D Touch はちょっと期待はずれだった。

MacBook の感圧タッチパネルもいまいちだと思ったけど、その劣化版。
これを使った操作の主な役割がパソコンで例えると右クリックなのはちょっと。

Peek, Pop でプレビュー, オープンはちょっとだけ面白いけど、
面白いだけで実用性を問われるとうーん。

ですが、ちょっとだけ便利な使い方はあったので、それはTIPSへ。

3D Touch TIPS

リンク

リンクを開くときにちょっと強く押し続けると(以下、Peek)プレビュー。 そのまま更に強く押すと(以下、Pop)開く。 Peek の状態から上にドラッグでリンクに対する操作を選択。

f:id:tyhe:20150926010429p:plainf:id:tyhe:20150926010431p:plain

メール

一覧の状態から Peek でプレビュー。
Peek の状態から左にドラッグでゴミ箱(OR アーカイブ)。
Peek の状態から右にドラッグで既読。
Peek の状態から上にドラッグで操作を選択。

f:id:tyhe:20150926010400p:plainf:id:tyhe:20150926010404p:plainf:id:tyhe:20150926010406p:plainf:id:tyhe:20150926010408p:plain

アプリケーションアイコン

Pop でコンテキストメニューが開く。

f:id:tyhe:20150926010330p:plain

タスク一覧

ディスプレイ左端を Peek した状態で右にドラッグするとタスク一覧表示。

カーソル移動

文字入力時にキーボード上で Peek。
キーボードの表示が消えるので、その状態で上下左右にドラッグするとカーソル移動。

f:id:tyhe:20150926010143p:plain

カーソル移動は画期的、とまでは言わないけれども、妥協点としては良さそう。
今までカーソル移動は非常に不満だったのでコレが唯一便利に感じる。

3D Touch でできる他の動作は全部別にそれで無くても良い。
リンクはそもそも開いてしまえばいいし、操作の選択もホールドで良い。
メールも同じくそもそも開けばいいし、操作の選択はフリックで良い。
それぞれ一手間増えるだけで大して便利にはならない。

アプリケーションのコンテキストメニューはこれからの発展に期待。
だけど、自分はほとんどゲームしかやらないので実はあんまり期待してなかったり。

まとめ

いろいろ発展途上だけど、とりあえずパフォーマンスが上がっただけで自分は満足です。

自分が買う iPhone は、これからの AndroidWindows Phone 次第ではありますが、
これで最後にする予定。少なくともハイエンドのものを買うのはきっとこれで最後。

早く Windows Phone のハイエンド端末が出ないかな。と、言ったところでお開きです。

*1:リリース前に気付けよって強く思います

*2:Windows Phone はゲームが無いので比較できません。かなしみ。

【かんたん】 Windows 10 への無償アップグレードを抑止する

Windows10 Windows 10 Windows Microsoft

にわかに盛り上がりを見せている Windows 10 強制アップグレード騒動ですが、
デマも甚だしいので一般ユーザー向けの手順をご紹介します。

はじめに

以下の画面からアップグレードを予約をしていない方へ。

f:id:tyhe:20150724112533p:plain

何もする必要はありません。

何もしなくてもアップグレードは適用されませんのでご安心下さい。

本記事の対象者は上記の画面からアップグレードを 誤って予約してしまった一般ユーザー が対象です。

アップグレードの予約をキャンセルする

タスクバーから Windows のマークをクリック。

f:id:tyhe:20150724113401p:plain

表示されたウィンドウ左上のハンバーガーメニューをクリック。

f:id:tyhe:20150724113421p:plain

左からメニューが現れるので、「確認の表示」をクリック。

f:id:tyhe:20150724113457p:plain

「予約の取り消し」リンクが現れるのでクリック。

f:id:tyhe:20150724113549p:plain

続いて「予約の取り消し」をクリック。

f:id:tyhe:20150724113607p:plain

無事予約が取り消されました。

f:id:tyhe:20150724113712p:plain

ね?簡単でしょ?

合法 Windows Phone こと MADOSMA 買ったった

Windows Phone MADOSMA

はい。

どう見てもティッシュ。

f:id:tyhe:20150618210936j:plain

開封。

f:id:tyhe:20150618211006j:plain

中身。

f:id:tyhe:20150618211102j:plain

内蓋の中。

f:id:tyhe:20150618211154j:plain

解体。燦然と輝く技適。

f:id:tyhe:20150618211259j:plain

SIM買ったった。

f:id:tyhe:20150618211513j:plain

SIMとSDカード挿入。

f:id:tyhe:20150618211754j:plain

〆。

f:id:tyhe:20150618211835j:plain

初回起動時の設定。

f:id:tyhe:20150618223130p:plain

始めましょう

f:id:tyhe:20150618223157p:plain

途中でロックしてから復帰したら。ただいま。

f:id:tyhe:20150618223231p:plain

国産だ・・・。

f:id:tyhe:20150618224645p:plain

Windows Phone が始まりました。

f:id:tyhe:20150618223248p:plain

いっぱいアップデート。

f:id:tyhe:20150618223312p:plain

こっそり Aristea インストール。

f:id:tyhe:20150618223324p:plain

電話の更新。

f:id:tyhe:20150618223352p:plain

長い。

f:id:tyhe:20150618224754p:plain

やっと準備が終わった。

f:id:tyhe:20150618231340p:plain

詳細は・・・アッハイ

f:id:tyhe:20150618231439p:plain

更新。

f:id:tyhe:20150618231510p:plain

更新しました。

f:id:tyhe:20150618231522p:plain

詳しくはこちら?

f:id:tyhe:20150618231531p:plain

えーごだった。

f:id:tyhe:20150618231721p:plain

やっぱりメモリ1GBの恩恵は大きいですね。非常に快適です。

普段は NEXUS5 と iPhone 5s を使っていますが、これからはMADOSMAがここに加わる事になりますね。

アプリが充実してくれるといいんですが。

特にスマホゲーと呼ばれる分野。各社の対応に期待。