- Edited
[spine-c] ルートモーションに関して質問
添付した画像のような構造のスケルトンを作成しました。
rootボーンはSpineのデフォルトで生成される最上のボーンではなく、自前で作成したボーンになります。
Spineエディタのバージョンは3.8.99です。
添付画像にあるTFconstボーンをrootボーンのトランスフォームコンストレイントのターゲットにさせてTFconstボーンをアニメーションさせて移動させています。
そのため、rootボーンにはキーフレームを打っていません。
ゲームではrootボーンの移動速度を毎フレーム算出してスケルトンの移動を表現しています。
1モーションが完了したらキャラクターはゲーム内のワールド座標で移動を繰り返し前進するように実装してあります。
ゲームで動作させると正しくモーションは再生されるのですが、1モーションの移動が完了すると、キャラクターはSpineの原点に戻ってしまい、ただのループモーションが再生される形になってしました。
恐らくトランスフォームコンストレイントが適用されたrootボーンのワールド空間では無く、ローカルの値(キーフレームを打ってないのでx0、y0)を取得しているように思えます。
説明不足で大変申し訳ないのですが、自前のルートボーンのワールド座標を取得できる方法、またはルートモーションを動作させるドキュメント等はありませんか?
お手数をおかけいたしますが、よろしくお願いします。
こんにちは、作成された構成自体はご説明いただいた内容から理解できましたが、ゲーム開発にどのランタイムをご利用されていますか?(spine-unity, spine-cなど)
また、なぜルートボーンをトランスフォームコンストレイントで動かす必要があるのかについても教えていただけますと幸いです。
お手数ですがよろしくお願いいたします。
ご返信ありがとうございます。
ランタイムですが公式汎用のCを使っていました。
ランタイムを拡張して使用していますが、結果的にルートボーンはローカル座標しか取得できませんでした。
Spine側から得られる値がブラックボックス化していて、ワールドではなくローカル座標ではないかという結論でした。
ルートボーンにコンストレイントを使用する理由としては、
ゲーム内でのトランスフォームの値をrootボーン単体から取得している事と、3系ではXとYで独立したキーフレームが打てなかった為、TFconstボーンがY、その親ボーンがXの移動としてコンストレイントでTFconstのワールド座標をルートボーンに送っています。
他の使い方として、親のボーンはスタートからエンドまで単純にリニアに2つのキーフレームを打って、子のボーンで上下ブレや揺り戻しの補助動作のキーフレームで動きを作って、子ボーンのコンストレイントで対象ボーンにトランスフォームを送るという形も考えています。
現状ではルートボーンのローカル座標しか反映されてないという話だったので、ワールド座標が取得できれば解決できると考えています。
spBone_localToWorld()
を介して、( skeleton-> x / y
に対する)ワールド座標を取得できます。
https://github.com/EsotericSoftware/spine-runtimes/blob/4.0/spine-c/spine-c/include/spine/Bone.h#L89
spAnimationState
のcompleteイベントをリッスンするなどによって、ルートモーションアニメーションが完了した際にこれを行うことができます。その後、スケルトンx / yにワールドオフセットを追加できます。
You can obtain the world coordinates (relative to skeleton->x/y
) via spBone_localToWorld()
.
https://github.com/EsotericSoftware/spine-runtimes/blob/4.0/spine-c/spine-c/include/spine/Bone.h#L89
You can do this once the root motion animation is complete, e.g. by listening for the complete event of spAnimationState
. You can then add the world offset to the skeleton x/y.