SprUnityを開発するためのUnityプロジェクトが Springhead2\src\Unity にあります。SprUnityに必要なスクリプトはできるだけこのUnityプロジェクト内で開発してください(もし異なるUnityプロジェクトで開発した場合も最終 的にこのプロジェクトに含めてください) 。
プロジェクトのフォルダ構成は以下の通りです。
+- Scenes/ 開発用の各種シーン +- Springhead/ Springheadアセット一式。このフォルダをエクスポートする想定 +- Editor/ SpringheadのためのUnityエディタ拡張スクリプト +- Plugins/ Springhead C# DLLがここに入る +- PHxxxx.cs PHxxxxを使うためのUnity Script +- ...
Springhead C# DLLをビルドするとSpringhead2\bin\win64に出力されるので、開発用Unityプロジェクトで利用するにはSpringhead2\src\Unity\Assets\Springhead\Pluginsに コピーする必要があります。
Unity上で利用したいSpringheadクラスごとに2Behaviourスクリプトを作り、そのスクリプトにSpringheadオブジェクトの作成・Unityとの同期等を担当させてください。例えばPHSolidを担当するスクリプト はPHSolidBehaviourで、このスクリプトはゲーム開始時にSpringheadシーン内にPHSolidを作成し、1ステップごとにPHSolidの位置に応じてゲームオブジェクトの位置を変更します。
Behaviourスクリプトの各変数・関数の役割を、PHSceneBehaviourを題材に解説します。
using UnityEngine; using SprCs; public class PHSolidBehaviour : SprSceneObjBehaviour {
Springheadの機能を利用するのにSprCs名前空間をusingしておくと便利です。
PHSdkやPHSceneの子要素を作成するBehaviourスクリプトは、SprSceneObjBehaviourを継承してください。これによりPHSceneBehaviourを探してPHSceneを取得するphSceneプロパティや、phSdkプロパティが使えるよう になるほか、インスペクタの値が変更された時に自動的にSpringheadオブジェクトのSetDescが呼ばれる機能などが実装されます。
public PHSolidDescStruct desc = null; public override CsObject descStruct { get { return desc; } set { desc = value as PHSolidDescStruct; } } public override void ApplyDesc(CsObject from, CsObject to) { (from as PHSolidDescStruct).ApplyTo(to as PHSolidDesc); } public override CsObject CreateDesc() { return new PHSolidDesc(); }
XXXDescStruct型のpublic変数を作ることで、デスクリプタの内容が設定項目としてインスペクタに表示されます。 ここではXXXDescではなくXXXDescStructを利用してください。また、初期値は必ずnullとして 下さい。
SprSceneObjBehaviourを継承するクラスは、descStructプロパティ、ApplyDesc関数、CreateDesc関数を定義しなければなりません。これらはインスペクタの値が変更されたときに自動でSpringheadオブジェクトに反映される ようにするために必要です(必要が無い場合は中身のない(あるいはnullを返す)関数を定義して下さい) 。
public override ObjectIf Build() { PHSolidIf so = phScene.CreateSolid (desc); so.SetName("so:" + gameObject.name); Vector3 v = gameObject.transform.position; Quaternion q = gameObject.transform.rotation; so.SetPose (new Posed(q.w, q.x, q.y, q.z, v.x, v.y, v.z)); return so; }
Build()は、ゲーム開始時に、Awake()のタイミングで実行されます3。
ここでdescに従ってSpringheadオブジェクトを作成し、作成したオブジェクトをreturnしてください。
Build()の戻り値はBehaviourの sprObject プロパティに代入され、Behaviour内部や他のBehaviourからアクセス可能になります。
void Link () { // PHSolid場合は特にやることはない }
Link()はあらゆるオブジェクトのBuild()より後で呼ばれます。具体的には、Build()がAwake()のタイミングで実行されるのに対し、Link()はStart()のタイミングで実行されます。
全オブジェクトの構築が終了した後に、構築されたオブジェクト同士の関係を設定(“Link”)する作業をここで行います。例えばPHIKEndEffectorをPHIKActuatorにAddChildObjectするなど、全オブジェクト作成後でないと行 えないような処理をここに記述します。
public void Update () { if (sprObject != null) { PHSolidIf so = sprObject as PHSolidIf; if (so.IsDynamical()) { // Dynamicalな剛体はSpringheadのシミュレーション結果をUnityに反映 Posed p = so.GetPose(); gameObject.transform.position = new Vector3((float)p.px, (float)p.py, (float)p.pz); gameObject.transform.rotation = new Quaternion((float)p.x, (float)p.y, (float)p.z, (float)p.w); } else { // Dynamicalでない剛体はUnityの位置をSpringheadに反映(操作可能) Vector3 v = gameObject.transform.position; Quaternion q = gameObject.transform.rotation; so.SetPose(new Posed(q.w, q.x, q.y, q.z, v.x, v.y, v.z)); } } }
Updateには、Springheadのシミュレーション結果をUnityのオブジェクトに反映するコードを書いて下さい。
※なお、実際のPHSolidBehaviourでは、UpdateではなくUpdatePose関数が定義され、PHSceneBehaviourのUpdateが各SolidのUpdatePoseを呼ぶようになっています。これは剛体オブジェクトの位置の反映をPHSolidBehaviourのUpdateで行った場合、スキンメ ッシュの描画がうまくいかないためです。
2 議論の余地あり
3 スクリプトのイベント関数については http://docs.unity3d.com/ja/current/Manual/ExecutionOrder.html を参照
各Stepにおいて、PHSceneBehaviourは他のPhysics系スクリプトより先に実行される必要があります。新たにスクリプトを追加した場合などは、開発者が適切な実行順序を設定してください。設定したスクリプト実行順序はエクスポートされる情報に含まれるので、 SprUnityのユーザは特に気にせず利用できます。
実行順序の設定は Editメニュー → Project Settings → Script Execution Order から行います。