目次
正直なところ、それぞれのセッションのまとめだけ書いておわり~としたいです。 ですが、まあ、なんといいますか、自分用のメモとしてもちゃんと残しておきたいのでちゃんと書いてあります。
◆ Mecanim徹底解説 & 最新機能アップデート
Mecanimとは? => Unity4から搭載された新しいアニメーションシステム(http://docs.unity3d.com/Documentation/Manual/MecanimAnimationSystem.html) Humanoidであれば腕や足、胴体、頭などがあり、それぞれに該当するオブジェクトを設定することで、Humanoid向けに作られたアニメーションがなんでも使える。 (例えば、テストはわかりやすい様な人型モデルで、本番は着ぐるみだったりヒラヒラしてるようなモデルだったり) アニメーションのステート制御ができる。などなど、続きは公式で。
このセッションは始めにちょこっとだけ説明があって、あとはデモベースで進んで行きました。
プロジェクトウィンドウでアニメーションを選択すると、プレビューウインドウから動きを確認できます。 そのとき、0.3秒~1秒までの間をほげほげアニメーションとしてインポートというように範囲を選ぶことができます。 インポートはAnimatorウィンドウにドラッグアンドドロップでできます。
デモでは既にアイドル、走るのステートが登録されていました。 ここに"スライディングでフェンスの下をくぐるアクション"を追加をしていきます。
1.走るアニメーション時にキー押下でスライディングフラグを立てる 2.スライディングアニメーション時に特定パラメータがしきい値を超えた時にColliderを無効にする 3.Animatorウィンドウにアニメーションを放り込む 4.スライディングフラグがON(事前に自前のスクリプトで定義していた模様)なら遷移するように設定 5.Inspectorウィンドウからブレンド具合を確認 6.ブレンドに不満があったら自分で調整をする 7.特定のパラメータのカーブをアニメーションに合わせて調整する
という流れです。
Inspectorで確認したときに、足付近にIKピボットが表示されます。 これはUnityが内部で自動で計算し、アニメーションが不自然に見えないように調整してくれています。 しかし、アニメーションによってはそのミスマッチが発生することがあるので、その場合はブレンド具合を調整して直します。
さらに"フェンスに手をついて飛び越えるアクション"を追加していきます。 ターゲットマッチングを使うことで実現ができます
1.先ほどと同様にアニメーションを追加する 2.RayCastを行い、フェンスと一定の距離でのみアニメーションをする 3.その時のRayCastのデータを利用して、フェンスに対しての手とターゲットのマッチングを行う (animator.MatchTarget(ターゲット位置、ターゲット回転、部位、MatchTargetWeightMask, 開始時間, 終了時間))
これはドアの開け閉めや武器を取り出す時のモーションなど、なんか色々使えそうです。 (武器の場合は後述するIKリグの方がよさそう)
新機能として、2Dブレンドツリーがあります。 これは向きと速度のブレンドをスマートに行うときなどに使えるようです。
そして、アニメーションのレイヤを追加して"ダメージを受けて倒れる"動きをつけていきます。
1.Animatorウィンドウから新規アニメーションレイヤーを作成する 2.Maskオプションに、足、胴体、頭のマスクを設定 2.Syncオプションの有効
Maskオプションは、アニメーションの適用されるオブジェクトを指定します。 Syncオプションは、別のレイヤーとアニメーションの同期をすることができます。 要するに別レイヤーのステートマシンをまるまるコピーされてくるような具合です。 これら2つを組み合わせることで、走りながら倒れていく、というような表現が簡単にできるようです。
最後にIKリグを使った武器の装備を行います。
1.武器をプレイヤーオブジェクト内に内包する 2.アニメーションレイヤーを増やして、IKpassをONに 3.AnimatorIKメソッドを定義して、そのなかでIKのポジションを設定する
なお、このデモで使用したファイル一式はアセットストアよりDLできるようです。 が!どれだか分らなかったので、それっぽそうな公式ファイルを列挙しました。 http://u3d.as/content/unity-technologies/mecanim-locomotion-starter-kit/4jU http://u3d.as/content/unity-technologies/mecanim-example-scenes/3Bs
◆ Unityでのメモリープロファイリング
Pro限定の機能ですが、UnityにはCPU時間やメモリ使用を確認できるツールが付属しています。 これを正しく使うことで、どんなオブジェクトまたはどんな処理に対してCPUやメモリが割かれているのか、 また、メモリリークなども分かり、どこがネックなのかというのがすぐにわかります。
この講演では、タイトルにあるようにメモリの使い方について焦点があてられていました。
まず、マネージドとネイティブがあります。 マネージド:Mono、GCあり、アセットやゲームオブジェクト、スクリプトなど ネイティブ:Unity、GCなし、メッシュだとかエンジンの中身にかかってくるあたり。
マネージドはヒープ領域が使われ、いっぱいになるまでもぐもぐしていきます。 いっぱいになった所でGCが走り、解放されていきます。 その際、フラグメントなどが発生し、その後のパフォーマンスに影響を及ぼす可能性があります。 そのためプロファイル機能で確認できる"メモリアクティビティ"を低く保つことが重要だと言っていました。
では、メモリアクティビティを低く保つにはどうするか。 ・メソッド内で大きな領域を使う一次変数をクラス変数にする ・クラスではなく構造体を使う ・弾丸などたくさん使うものはオブジェクトを生成し、非アクティブを活用し使いまわす => オブジェクトプール ・“OnGUI"は定義すら許されない ・IDisposableが付いたものは自主的にDisposeメソッドを呼び出す ・参照が残るようなことがないようにする => メモリリークに繋がる ・Resources.UnloadUnusedAssets()を使用する
例えば、WWWクラスを例にあげると、これは確実にDisposeを呼ぶ必要があります。 何故ならば、マネージド部分はシンプルですが、内部のネイティブ部分ではあれこれとしているので、インスタンスを作るとググっとメモリアクティビティが増えます。 Disposeを呼ばずに、nullを代入や放っておくのもよいですが、いつ解放されるかわかりません。
AssetBundleで考えてみます。 WWWから読み込み -> AssetBundle(非圧縮/圧縮,ファイル/データ) -> GameObject化 これをプロファイラで確認すると、 WWWインスタンス、AssetBundleインスタンス、内部のWebStreamインスタンス、テクスチャ等データ という4つのものが発生します。
そのためAssetBundle.Unload(false)およびWWW.Disposeを確実に呼び出す必要があります。 また、テクスチャ等のデータが不要になった際には、UnloadUnusedAssets()を用いて排除する必要があります。
以降は質疑応答で出たものですが、
・モバイルでのメモリープロファイリング Unityエディタではモバイル端末実機におけるメモリの状態を知ることができない。 Unity側ではさっくりとプロファイリングし調整、実機を使ってより詳細なプロファイリングを行なう必要があります。
・アセットストアにある"AsttroDude” オブジェクトプールを上手くつかっているので、ぜひ見てください => http://u3d.as/content/unity-technologies/astro-dude/24Y
・使っていないスクリプトがメモリに影響するか スクリプトに限らず、アセットで不要なものは除くのがオススメ。 もしかしたらUnity側にバグがあるかもしれないので、再現性や情報があればバグレポートを出してください。
・なぜ"OnGUI"がダメか OnGUIが定義されているだけで、GUI関連の様々なクラスがロードされてメモリもぐもぐしてしまう。 それも毎フレーム実行されてしまうので、メモリだけでなくCPUももぐもぐされます。 仮に空っぽのOnGUIでも、ifで処理をしないようにしたOnGUIでもダメです。 どうしてもOnGUIが必要な場合はプリプロセッサを上手く使って有効/無効を切り替えてください。
◆ 2Dコンテンツのためのワークフロー
・2Dアートツールとして、あなたにとって最高に使いやすいツールを使ってください ・メタデータを上手く使用し、Unity側であれこれ度々追記することが少なくなるようにするといいでしょう ・2Dのためにぜひともエディタスクリプティングをしてみてください。
ということでした。 えっと、お昼直後で眠たかった、というわけではなく、最前列近辺だったので首がいたかったのです(白目
◆ iPhoneでリアルタイムマルチプレイを実現!
マルチプレイには「リアルタイム」と「非同期」の2種類があります。 「非同期」 ソシャゲや将棋など、リアルタイム性の少ないもの。 Web技術の応用でできるので、オープンソースのライブラリなども多く扱いやすい。 コストは少なめ。
「リアルタイム」 FPSや格闘ゲーム、今ここでオンラインの人がいるんだ!というもの。 TCP/UDPの様に低レイヤの話であったりNAT貫通とかとか小難しい話が出てくる。 遅延が許されない(=> クソゲー化、波動拳が入力後1秒で出て勝てるか) オープンソースは少なく、費用がかかってしまいがち。
Unity標準のNetwork機能は
- ・クライアントがホストになる必要がある ≠Dedicatedサーバー
- ・便利な機能がたくさんあり、未経験でもデモはすぐに出来た
モバイル端末がホストになることは帯域や安定性からして非常に難しいようです。 そこでゲームサーバを外部に用意して行う方法が求められ、条件に合うのがPhotonだったようです。
PhotonはUnityとほぼ同じNetwork郡の命令を持っており、また料金もさほど高くないとのこと。 Photonの構成はこうなっているようです。
- Windowsサーバ:.NET -> C/C++コア -> ReliableUDP/TCP
- クライアント:PhotonSDKライブラリ
ライセンス形態はこうなっています。 PhotonCloud:同時接続人数や転送速度に応じて金額が変わる。サーバの用意が不要。無料枠あり。 PhotonServer:サーバ用のプログラムの販売。Windowsサーバが必要。 サーバ側のプログラムをちょっといじりたい、という場合にはPhotonServerでないと出来ないとのこと。 ただし、Windowsサーバが必要ということに加え、情報がそんなに多くなく英語ばかりということなので、構築は"イバラの道"
Photonクライアントを利用して同期を取るには、“StateSync"と"RPC"の2つが用意されています。 “StateSync"はそのとおり同期してくれ、“RPC"はメソッド呼び出しの同期が取れます。
PhotonNetwork.offlinemode = true; とすることで、オフライン状態への以降も特に障害なく行なってくれるようです。
手間を考えると常に複数端末でオンラインでテストをするわけにもいかないので、Unityエディタの拡張を上手く使って、オフラインからテストできる仕組みを用意するとよさそうです。 また、Macがメインの会社なのでMac版Unityならでは?の複数起動の裏ワザも使っていたとのこと。
◆ Unity Hacks
そういう使い方があったか!とか、データの使い回しやあまり知られてなさそうな事など、生産性を挙げるアイデアの生まれる種になれば。 というような趣旨の講演でした。
・AnimationCurve 入力の向きに応じた速度変化やカメラの移動量など、"2D的に変化のあるデータ"を表現するのに使えます。 アニメーション用途以外にも活用できるので、いまの開発現場に活かせる箇所があるかもしれません。 また、ビジュアル的に見えるので、キーフレームを打ちつつデータを取る、といったデバッグ用途でも使えます。
・データの使い回し 例えばステルスゲーム、ライトの当たらない暗闇に入るとキャラが影にかかって薄くなる、みたいなものですね。 その場合は LightmapSettings.lightProbes.GetInterpolatedLightProbe(とrender.transform.positionなど)を使うとライティング情報が取得できるようです。 つまり、ライトが気に食わなかったら移動してベイクして、それだけでスクリプトの編集は不要になります。
・ReflectedState enumとAction、Dictionaryを使ってステートマシンを作る、というテクニックです。 enumは列挙型、Actionは.NET frameworkにあるメソッド参照、デリゲートです。Dictionaryはkey-valueペアが作れるリストです。
enumで定義して、StartメソッドでDictionaryに放り込む。 呼び出したいところでUtillity.Get~~~(メモ書きがここで途切れている)
でこうなんかうまいことつくるとちょっと便利になる、ということだそうです。
・WebPlayer これは過去に闇鍋プログラミング勉強会#2で話してきたのでめっちゃ理解してます(多分) -> http://stersblog.blog15.fc2.com/blog-entry-427.html スライドの37-45あたり。
Unity → WebBrowser Application.ExternalCall(func_name, data) Application.ExternalEval(js_string)
WebBrowser -> Unity Unityオブジェクトに対して SendMessage(game_object_name, func_name, data)
・Rapid Game Devlopment ゲーム開発の高速化、みたいな話かな? 昨年のUnite2012で話していた内容なので録画した動画をみてくれ、とのこと。 -> http://angryant.com/videos/
・Importer/Exporter プログラマーとデザイナー、企画管理などいろんな人がゲーム開発に参加して、それぞれで共有しておきたいデータがあるはず。 例えばプロジェクトファイルそのものだったり、テクスチャ・モデルなどのアセット、オブジェクトの設定などを共有する必要がある。 そこで、インポータ・エクスポータの拡張などをしたほうがよい場合がある。
ScriptableObjectを継承してシリアライズ~なんてのをうまく使えばできるはず。
・ワークフローの自動化 なぜ? -> 生産性の向上
例えば、Androidのネイティブコードを追加したい。 でもJavaコードの編集して、コンパイルして、Unityに追加して、バグがあれば編集して、コンパイルして、Unityに~~~と毎回繰り返すのはつらい。 そこで、javaコードをUnityでコンパイルできるようにしてしまおう、というもの。 コンパイルできればADKだって不要だし、煩わしいコマンドを叩く必要もないし、なによりUnityに統合できるのがつよい。 (コンパイルだったかEvalだったか少し怪しいですが…)
やり方としては、CodeProviderとか?Microsoft.JScriptとか使うんですかね(よくわからなかった..
・マニフェストファイル アップデート(?)の時に厄介なことになるらしい。 なのでアセットとして放り込んでおきたいよな、ということ。 バンドルしてプレファブを生成するとで可能になるらしい
・プレファブバンドル データをシリアライズすることで可能になる。ScriptableObjectの有効利用とのこと。 これをすると、独自のエディタ拡張で設定した値やら何やら、はたまたGameObjectのプロパティなんかをプレファブとしてどんどん保存できる。 ただ、もちろんのことだけども、ゲーム中に読み込むならそれを読むプログラムを書く必要がある。 ・・・でもシリアライズの逆をするだけなのでそんなに難しいこともない…?
・スクリプトバンドル 外部のエディタであれこれ書いてビルドし、~~.dllに相当するものを生成。 これをUnityスクリプトからAssembly.Loadなんかを使うといい感じに使える。 Day1の暗号化の話でも触れていたはず。
このように色々なTipsがある。 これらを利用して、みなさんのゲーム開発現場に置いてなにか改善できるひらめきが生まれるといいでしょう。
今年は昨年の講演に比べて、より実践的なことを話しました。 ではでは、みなさんはどのようにして生産性をあげていきますか?
◆ AssetStoreマニアクス2nd
・iOS/Android Etcetera Plugin モバイル端末を扱う基本的なスクリプト集 わかっている人なら不要では?
・CutScene Creator - uSequencer 高機能なカットシーンエディタ つまりはオブジェクトアニメーションをシーン全体でやるようなもの?
・Play Maker ステート制御により、スクリプト不要でゲームが作れる。 状態遷移やパラメータ変更などができる。 SendMessageを利用することでスクリプトと連絡が取れるが、やりすぎると複雑化してダメ
・Rage Spline スプライン曲線が書けるやつ。 横スクロール型2Dゲームでの曲線なマップを視覚的につくることができる。
・Smooth Moves 2Dスプライトのボーンアニメーションを簡単にできるやつ。 1枚の画像から切り出したり、タイムラインがあったり高機能。
・Pool Manager4 プレファブの事前生成やプリロードの仕組みを提供する。 「メモリープロファイリング」の時に聞いた話を簡単に実装できる。
・FxMaker エフェクトツール。 ゲームビューでコントロールできるという(いい意味で)わけの分からないプラグイン エフェクトを作ったりプリセットを利用したり、コピペできたりなんかもうすごい。
・結論 エディタ拡張すごい。ここまで出来るのか、というのを教えてくれる。 なかなか有料アセットに手を出しづらい(がっつりゲーム開発してるわけでもない)ので、実際に動かして紹介してくれるというのはありがたい。
◆ 自動車と飛行機は何が違うのか? ~コンシューマーゲーム開発者から見た Unity~
>コンシューマ 変更が度々起こると、コストがすごいので仕様・仕組みをがっちり固める。 ゴールに対して直線的に、最短距離で進んでいくので早い気がする
>Unity 変更・調整を少人数・低労力で行うことができるので、低コストで繰り返せる。 最初はぶれぶれかもしれないが、完成に近づくにつれでどんどん固まっていく。 “道具を正しく使い”: 1つずつ進めてゴールへ向かっていく “より早く目に見える形で”: 納得が行くまで試行、イメージの統一。 これがUnityではできる。
つまりはワークフローの違い。 CEDEC2011で、自動車と飛行機の違いという講演があり、まさしくここで感じたことと同じだった。
Unityは、そのシステムがイテレーションを意識しているので、開発手順だったりアプリだったりも合わせないといけない。 >パラメータをエディタから読み込む >Unityで編集できないのでUnity外で管理はしない >オブジェクト間の依存性を減らす >コンポーネントベースなのでスクリプトを細分化する などなど、Unityを邪魔しない設計が重要。
このようにUnityはラピッドプロトタイピングに力強さがある。 けど、それだけ、という理由でUnityを使うのであれば、元々の自社エンジンだったり、他のツールでもいいのでは。
Unityを選ぶなら他の強みを活かす。 >マルチプラットフォーム >すべてを変えられるエディタ拡張 >意識せずともリッチなグラフィック
◆Unity for WiiUとNintendoWebFrameworkについて
あと、Day1に聞きそびれた任天堂のやつ関連で質問してきました。法人向けしかないようで、個人で使えないのはなぜか。
任天堂は今までのノウハウを生かして、ビジネスとしてこういったツールを出している。 個人相手ではどのようにビジネスを展開するか、ということがまだ考えられていないため、個人向けにはまだ出せない。他にも、任天堂としてはWiiUでアプリ・ゲームを出して欲しい。そうなると必然的に販売ルートを確保できるような相手じゃないと難しい。 たとえばGooglePlayのようなアプリを配布するプラットフォームの準備が出来れば個人開発者の可能性も大きく高まる。 任天堂としてWiiUでアプリ・ゲームを出して欲しいので、法人向けと書いてあるがその法人の規模は特に問わない。 どうしてもツールを触ってみたい、WiiUでゲームを出したい、というのであれば起業するのも1つの手。 非公開のAPIを叩いたりアヤシイ事をするのは、そもそも開発者登録を済ませる必要があるのでやってもらってもかまわない。ただ、その部分の仕様が変わったりする可能性があるのでオススメはできない。
ちょっと抜けていたり足りなかったりするかもしれませんが、大体このような感じだったと思います。 WebFrameworkのほうはちょっと触ってみたかっただけあって残念。。 Unity for WiiUのほうは、UnityPro相当の機能が無料で全部つかえるっぽいです。