Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Unity物理におまかせゴルフ
〜ぐるぐるイーグル〜
株式会社 Aiming
ソフトウェアエンジニア
西尾 昌哲
http://sp-eagle.com
2014年 4月14日 iOS版リリース
2014年 12月15日 Android版リリース
ゲーム紹介
自己紹介
株式会社Aiming
ソフトウェアエンジニア
西尾 昌哲
http://www.facebook.com/syoutetu
このスライドの概要
Unity4の物理エンジンを利用して
ゴルフゲームを作ってみた結果、得られた経験
・ 物理オブジェクトの構成や設定周り
・ 物理エンジンにまかせっきりにできたこと
・ 特殊な制御しなければできなかったこと
などを紹介
・ ゴルフゲームを構成する物理オブジェクト
・ ゴルフボールの挙動について
・ パフォーマンスについて
・ デバッグについて
・ 物理エンジンを使ってみた感想
目次
Unityの物理エンジン
PhysXというメジャーな物理エンジンを
利用している
・ Unity5でPhysX3.3にアップデートされた
・ Unreal Engine4もこれ
現在はNVIDIAが開発している
NVIDIAの開発者登録すれば
...
ゴルフゲームを構成する
物理オブジェクト
・ ゴルフコース
・ ゴルフボール
・ その他の障害物
・ 物理マテリアル
物理エンジン周りのアセット(データ)説明
ゴルフコース
Mayaで作成した描画用のメッシュから
そのまま当たり判定用のMesh Colliderを作成
ゴルフコース
描画用のメッシュをコリジョンにも使ったのは
以下の理由から
・ ゲームプレイと密接に関わるので精度を
下げたくなかった
・ コリジョンモデルを用意する手間を
減らしたかった
・ パフォーマンスが低下するようなら、コリジョン用に
別...
ゴルフボール
球体のモデルにRigidbodyと
Sphere Colliderを適用している
直径は5cmで、実際のボールより
少し大きいのは画面に映ったときに
見えづらく感じたから
(そのため、カップも大きく作ってある)
その他の障害物
地面に配置してある建物や木
水面に浮かぶボートなど
その他の障害物
パフォーマンス低下を防ぐため
描画用のメッシュが細かい場合は
粗いコリジョンメッシュを用意している
(結局パフォーマンスはそれほど問題にならなかったので
こうする必要はなかったのかも)
描画用
1506Triangles
コリジ...
物理マテリアル
地形や障害物のColliderに設定されている
物理マテリアルは、物理挙動と
地形判定に使用している
例えば、ボールが停止したときに
真下にRaycastして地形を判定
ゴルフボールの挙動について
・ショット時にボールに与える力
・ボールの停止制御
・コリジョン抜け対策
・落下予測地点の計算
・グリーン周りの調整
・カップ周りの調整
ショット時にボールに与える力
プレイヤーや地形のパラメータから
最終的にRigidbodyに力とトルクを設定
rigidbody.AddForce(force, ForceMode.Impulse);
rigidbody.AddTorque(t...
ボールの停止制御
RigidbodyがSleep状態になると停止判定
・ スリープに入った時のイベントは見つからなかったので
Update()でIsSleepingをチェックしている
・ RigidbodyのSleepVelocityやSlee...
コリジョン抜け対策
厚みのないメッシュコリジョンと
高速に移動するボールとの衝突は
判定の通り抜けが多発した
・ 1フレームでボールがメッシュを完全に
突き抜けてしまうと当たり判定が失敗する
・ RigidbodyのCollision Dete...
Dont Go Through Things
前フレームから現フレームへのRigidbodyの移動が
メッシュを突き抜けていたら、
メッシュに軽く重なるくらいの位置に戻す処理をしている
・ 物理マテリアルに設定されている物理挙動も再現できている...
落下予測地点の計算
このゲームには落下予測地点
と呼ばれるUIがあり、ショットした
ボールが地面に落下する地点
・ ただし、高低差なしで無風の場合
しかし、物理エンジンを使っているので
事前に落下地点を予測できない
・ 実際にシミュレーションて...
落下予測地点の計算
実際にいろんな条件でボールをショットした
パターンのデータを事前に作っておいて、
ゲームプレイ中はそのデータを補間計算して
落下予測地点としている
・ クラブの自動選択の時も、このデータを使っている
飛距離のサンプリング
プレイヤーのパワーパラメータのレベル(160段階) ×
パター以外のすべてのクラブ(13種類) ×
すべてのカーブショットの弾道(27種類) ×
パワーゲージの%(現状は20%ごとに5回サンプリング)
= 約28万回のショ...
グリーン周りの調整
パターの時にボールが転がるように設定すると
外から打ち込んだときにも転がってしまい
とてもグリーンに乗りにくい
・ 物理マテリアルのパラメータだけではどうしても
調整できなかった
グリーンの物理マテリアルを2つ用意して
パタ...
カップ周りの調整
カップ側面でボールが止まる事が稀に発生
(速度が足りなくてRigidbodyがSleep状態になる)
結局、その状態を判定してカップ方向に
少しだけ力を加えてカップインさせる
というちょっと無理矢理な方法で解決
パフォーマンスについて
・最も重いゴルフコースは?
・物理エンジン周りの設定
最も重いゴルフコースは?
MeshColliderの数が一番多いのは
スイートシュガーエデン Hole5
219個のMeshCollider(合計31786Triangles)
最も重いゴルフコースは?
MeshColliderのトライアングル数が一番多いのは
ミヤビツシマ Hole8
164個のMeshCollider(合計65201Triangles)
物理エンジン周りの設定
動かないオブジェクトには
Staticフラグを付ける
Layer Collision Matrixで
衝突判定するレイヤーを
必要最小限に設定する
設定はメニューの
Edit - Project Settings - P...
デバッグについて
カップインしたとき1万回に1回くらいの割合で
ボールがカップから抜け落ちることがある
ということがリリース後に発覚
手動では再現しない(開発中は1度も起きなかった)
自動的にカップにボールを打ち込む
プログラムを作って、現象の...
ボール抜け落ちチェック
ボールがカップから落下したら検出される
原因は、前述 Dont Go Through Things の
コリジョン抜け対策のところで、微細な移動の場合は
その処理を飛ばしていた為だったらしい
グリーン上のランダムな位置か...
物理エンジン使ってみた感想
良かった点
・ 自前でやるより工数は削減できたと思う
・ モバイルでもパフォーマンスは良い
(過度な期待は禁物だけど、他のゲームでも演出などで
気軽に使う事ができると思う)
良くなかった点
(ただし、自前で実装しても...
Upcoming SlideShare
Loading in …5
×

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

27,531 views

Published on

DeNA合同勉強会資料
「Unity物理におまかせゴルフ ぐるぐるイーグル」

Published in: Software
  • Login to see the comments

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

  1. 1. Unity物理におまかせゴルフ 〜ぐるぐるイーグル〜 株式会社 Aiming ソフトウェアエンジニア 西尾 昌哲
  2. 2. http://sp-eagle.com 2014年 4月14日 iOS版リリース 2014年 12月15日 Android版リリース ゲーム紹介
  3. 3. 自己紹介 株式会社Aiming ソフトウェアエンジニア 西尾 昌哲 http://www.facebook.com/syoutetu
  4. 4. このスライドの概要 Unity4の物理エンジンを利用して ゴルフゲームを作ってみた結果、得られた経験 ・ 物理オブジェクトの構成や設定周り ・ 物理エンジンにまかせっきりにできたこと ・ 特殊な制御しなければできなかったこと などを紹介
  5. 5. ・ ゴルフゲームを構成する物理オブジェクト ・ ゴルフボールの挙動について ・ パフォーマンスについて ・ デバッグについて ・ 物理エンジンを使ってみた感想 目次
  6. 6. Unityの物理エンジン PhysXというメジャーな物理エンジンを 利用している ・ Unity5でPhysX3.3にアップデートされた ・ Unreal Engine4もこれ 現在はNVIDIAが開発している NVIDIAの開発者登録すれば githubのソースコードも見ることができる https://developer.nvidia.com/physx-sdk
  7. 7. ゴルフゲームを構成する 物理オブジェクト ・ ゴルフコース ・ ゴルフボール ・ その他の障害物 ・ 物理マテリアル 物理エンジン周りのアセット(データ)説明
  8. 8. ゴルフコース Mayaで作成した描画用のメッシュから そのまま当たり判定用のMesh Colliderを作成
  9. 9. ゴルフコース 描画用のメッシュをコリジョンにも使ったのは 以下の理由から ・ ゲームプレイと密接に関わるので精度を 下げたくなかった ・ コリジョンモデルを用意する手間を 減らしたかった ・ パフォーマンスが低下するようなら、コリジョン用に 別モデルを用意する予定だったが、その必要はなかった
  10. 10. ゴルフボール 球体のモデルにRigidbodyと Sphere Colliderを適用している 直径は5cmで、実際のボールより 少し大きいのは画面に映ったときに 見えづらく感じたから (そのため、カップも大きく作ってある)
  11. 11. その他の障害物 地面に配置してある建物や木 水面に浮かぶボートなど
  12. 12. その他の障害物 パフォーマンス低下を防ぐため 描画用のメッシュが細かい場合は 粗いコリジョンメッシュを用意している (結局パフォーマンスはそれほど問題にならなかったので こうする必要はなかったのかも) 描画用 1506Triangles コリジョン用 218Triangles
  13. 13. 物理マテリアル 地形や障害物のColliderに設定されている 物理マテリアルは、物理挙動と 地形判定に使用している 例えば、ボールが停止したときに 真下にRaycastして地形を判定
  14. 14. ゴルフボールの挙動について ・ショット時にボールに与える力 ・ボールの停止制御 ・コリジョン抜け対策 ・落下予測地点の計算 ・グリーン周りの調整 ・カップ周りの調整
  15. 15. ショット時にボールに与える力 プレイヤーや地形のパラメータから 最終的にRigidbodyに力とトルクを設定 rigidbody.AddForce(force, ForceMode.Impulse); rigidbody.AddTorque(torque, ForceMode.Impulse); トルクによるボールの回転(AngularVelocity)は 空中でボール軌道が曲がる時のパラメータ としても使っている 複雑な計算はしていなくてAddForceをしているだけ
  16. 16. ボールの停止制御 RigidbodyがSleep状態になると停止判定 ・ スリープに入った時のイベントは見つからなかったので Update()でIsSleepingをチェックしている ・ RigidbodyのSleepVelocityやSleepAngularVelocityも ボールの転がり調整のために低く設定している 特殊な地形に対するのボールの挙動は RigidbodyのDrag、AngularDragを調整 ・ 例えば、バンカーに突入したときは 大きな値を設定してSleep状態に向かうようにする
  17. 17. コリジョン抜け対策 厚みのないメッシュコリジョンと 高速に移動するボールとの衝突は 判定の通り抜けが多発した ・ 1フレームでボールがメッシュを完全に 突き抜けてしまうと当たり判定が失敗する ・ RigidbodyのCollision Detectionの設定を Continuous Dynamicにすると抜けなくなるが ボールが跳ねる挙動などがおかしくなってしまった
  18. 18. Dont Go Through Things 前フレームから現フレームへのRigidbodyの移動が メッシュを突き抜けていたら、 メッシュに軽く重なるくらいの位置に戻す処理をしている ・ 物理マテリアルに設定されている物理挙動も再現できている ・ ただし、このゲームでは1つ問題があった(後述のデバッグ) 現フレームの 修正したボールの位置 前フレームの ボールの位置 現フレームの 突き抜けたボールの位置 http://wiki.unity3d.com/index.php?title=DontGoThroughThings Dont Go Through Things 地面
  19. 19. 落下予測地点の計算 このゲームには落下予測地点 と呼ばれるUIがあり、ショットした ボールが地面に落下する地点 ・ ただし、高低差なしで無風の場合 しかし、物理エンジンを使っているので 事前に落下地点を予測できない ・ 実際にシミュレーションてみないと、 どこに飛ぶかわからない
  20. 20. 落下予測地点の計算 実際にいろんな条件でボールをショットした パターンのデータを事前に作っておいて、 ゲームプレイ中はそのデータを補間計算して 落下予測地点としている ・ クラブの自動選択の時も、このデータを使っている
  21. 21. 飛距離のサンプリング プレイヤーのパワーパラメータのレベル(160段階) × パター以外のすべてのクラブ(13種類) × すべてのカーブショットの弾道(27種類) × パワーゲージの%(現状は20%ごとに5回サンプリング) = 約28万回のショットをサンプリング
  22. 22. グリーン周りの調整 パターの時にボールが転がるように設定すると 外から打ち込んだときにも転がってしまい とてもグリーンに乗りにくい ・ 物理マテリアルのパラメータだけではどうしても 調整できなかった グリーンの物理マテリアルを2つ用意して パターを使う時とそれ以外で切り替えている ・ プログラムでも少し調整している
  23. 23. カップ周りの調整 カップ側面でボールが止まる事が稀に発生 (速度が足りなくてRigidbodyがSleep状態になる) 結局、その状態を判定してカップ方向に 少しだけ力を加えてカップインさせる というちょっと無理矢理な方法で解決
  24. 24. パフォーマンスについて ・最も重いゴルフコースは? ・物理エンジン周りの設定
  25. 25. 最も重いゴルフコースは? MeshColliderの数が一番多いのは スイートシュガーエデン Hole5 219個のMeshCollider(合計31786Triangles)
  26. 26. 最も重いゴルフコースは? MeshColliderのトライアングル数が一番多いのは ミヤビツシマ Hole8 164個のMeshCollider(合計65201Triangles)
  27. 27. 物理エンジン周りの設定 動かないオブジェクトには Staticフラグを付ける Layer Collision Matrixで 衝突判定するレイヤーを 必要最小限に設定する 設定はメニューの Edit - Project Settings - Physics
  28. 28. デバッグについて カップインしたとき1万回に1回くらいの割合で ボールがカップから抜け落ちることがある ということがリリース後に発覚 手動では再現しない(開発中は1度も起きなかった) 自動的にカップにボールを打ち込む プログラムを作って、現象の確認と問題修正
  29. 29. ボール抜け落ちチェック ボールがカップから落下したら検出される 原因は、前述 Dont Go Through Things の コリジョン抜け対策のところで、微細な移動の場合は その処理を飛ばしていた為だったらしい グリーン上のランダムな位置からカップ方向に ランダムなパワーで自動的にパッティングを数万回実行
  30. 30. 物理エンジン使ってみた感想 良かった点 ・ 自前でやるより工数は削減できたと思う ・ モバイルでもパフォーマンスは良い (過度な期待は禁物だけど、他のゲームでも演出などで 気軽に使う事ができると思う) 良くなかった点 (ただし、自前で実装しても同じような問題に遭遇しそう) ・ 物理マテリアルの調整は面倒 (エンジニア以外に任せることも可能) ・ デバッグも面倒

×