Tsuzu's Notes

主にIT系備忘録

【Siv3D AdC 2015 15日目】 3DゲームとそのためのBullet&Siv3D連携ライブラリを作った話

この記事はSiv3D Advent Calendar 2015の記事です。

Tsuzuです。STEINS;GATE 0をやっていたら記事が書けず前日に焦って書いてます、ごめんなさい。
かれこれSiv3Dを使い始めて1年近くが過ぎたようです...。時がすぎるのは早いですね。
今回は今年、私の学校の文化祭で部活で展示したゲームを作った話をさせていただきます。

ゲームの概要

3Dの四人対戦ゲームです。 ルールはとても単純で、自分の陣地に、地面に落ちているオブジェクトを運んでくる、というだけです。オブジェクトの形状によって得点が異なります。 また、このゲームは4人で遊ぶことを前提として作られているためCPU対戦などは搭載しておりません。 f:id:tsuyochi23182:20151214145349p:plain

製作について

実装コストの高いDirectXを直で触ったり、C言語的なインターフェースのDxLibを使うのは気が進まなかったので現代的なC++で書くことができるSiv3Dを利用させていただきました。また、内部的に物理演算を利用する必要があったため、Bullet Physicsを利用しました。
そして製作する上で最も苦労したのが3Dの複数視点です。Siv3Dの3D機能はまだ不完全(これからどんどん良くなるようなので期待です!)のため、複数の視点を扱うことはできませんでした。そのため、4つのexeに描画を分けて行わせることで対処しました。サーバプログラムとクライアントプログラムをわけ、プロセス間通信にはThriftを利用しました。(今回はThriftを利用しましたが次期Siv3DではTCP通信に対応するようなのでそれを使えそうです。Thriftでは転送用に別途クラスを定義する必要があったので大分手間が省けそうです。)
また、四元数(Quaternion)はあまり使ったことがなく、慣れなかったので度々苦労しました。 今回、システム側の製作に時間をかけてしまってデザインなどに力を注げなかったのがとても悔しいです...。また、Siv3DのSlackや、TwitterでSiv3D製作者の@Reputelessさんには度々アドバイスをいただきました。製作者と簡単にコミュニケーションが取れるのはこのライブラリの他ではなかなかない、とても良い点だといつも感じています。

Siv3DとBulletの連携ライブラリ

実は、大変でしたが楽しかったところでもあります。製作の中で一番最初に行いました。
Siv3D(正確にはDirectX)とBulletでは座標系が異なります。それ自体の変換はZ軸の値をひっくり返すだけで良いのですが、各部分に適用させるとなるとこんがらがりました...。
仕組みとしては内部的にSiv3DとBullet側のbodyを同時に保持するクラスを作り、update関数が呼ばれるときにアップデートとstepを行い、draw関数が呼ばれたときに物理演算から座標および回転を取得してそれをSiv3Dで描画するようにしています。
拡張性のためには描画処理を内包するのは良くないとも考えましたが、とりあえず今回使いやすくなれば良いと思い、内包した形にしました。今後描画時に関数を指定して自由度を挙げれるようなものにしようと思っています。
需要はないと思うんですが近いうちにコードを綺麗にしてバグ修正をして公開しようと思っています。よろしければ使ってやってください。

おわりに

いつもSiv3Dと製作者の方にはお世話になっています。ありがとうございます。
1月には新バージョンも出るということで新機能をVisual Studio 2015で使えることを楽しみにしています。個人的にはMac版も待ち遠しいです(

明日の記事はChunChunMorningさんです。よろしくお願いします。