Page 1 of 1
FSMで状態遷移したタイミングだけで衝突をとりたい
Posted: 2020/01/14 13:41
by Einst
こんにちは、Arborはじめて2日目の初心者です。
状態遷移したタイミングでColliderに触れているかどうかを判断するのに良い方法はありませんか?
剣が握られる、握られてない(手離す)という状態で、離したタイミングでさやに触れていたらさやに
収めるなどを作る場合どうすれば良いでしょうか?
OnTriggerEnterTransitionなどで、さや格納状態に遷移させるのも考えたのですが。剣を落とした状態
で、さやを握って剣に触れさせるとさやに入ってしまします。
OnStateBeginのタイミングで衝突判定するとか
OnTriggerEnterTransitionを初回状態遷移時のみ有効にするとか
何か良い方法はありませんか?
Re: FSMで状態遷移したタイミングだけで衝突をとりたい
Posted: 2020/01/14 23:15
by caitsithware
ステートと衝突判定のタイミングに関するご質問ですね。
Einst wrote: ↑2020/01/14 13:41
剣が握られる、握られてない(手離す)という状態で、離したタイミングでさやに触れていたらさやに
収めるなどを作る場合どうすれば良いでしょうか?
「離したタイミング」という一瞬のみの判定でしたら、「鞘に収めるチェックステート」を作成し、OnTriggerEnterTransitionやOnTriggerStayTransitionとTimeTransitionを組み合わせてみるというのはいかがでしょうか。
- OnTriggerEnterTransitionやOnTriggerStayTransitionではチェック対象のTagを鞘に限定し、触れているようであれば「収めるステート」に遷移。
- TimeTransitionでは数フレーム分(ほぼ一瞬)待ってから「離したステート」に遷移。
という感じです。
Einst wrote: ↑2020/01/14 13:41
OnStateBeginのタイミングで衝突判定するとか
OnStateBeginのタイミングでの衝突判定については、Unityの仕様上の話となります。
Physics.Raycastなどの判定メソッドを使用したり、別途Trigger系イベントをプーリングするスクリプト(一旦フラグ立てておいて後からでも判定できるようにする処理)などを自作する必要があります。
こちらについては、Arborの範疇を超えているためこれ以上のサポートは致しません。
Unityマニュアルやチュートリアルを参考に、スクリプトを作成してみてください。
Einst wrote: ↑2020/01/14 13:41
OnTriggerEnterTransitionを初回状態遷移時のみ有効にするとか
何か良い方法はありませんか?
初めから組み込まれているスクリプトについては汎用性のため、お望みの機能がないことがあります。
StateBehaviour等のスクリプトを自作するのを推奨しておりますので、一度自作もご検討ください。
StateBehaviour | Arbor Documentation
Re: FSMで状態遷移したタイミングだけで衝突をとりたい
Posted: 2020/01/15 04:38
by Einst
回答ありがとうございます。基本、お教えいただいた通りで動きました。
1.チェック用のステートを設け、OnTriggerStayTtransitionで、収めるステートに飛ぶ
2.収めるステート内で独自処理
2.1.カスタムのStateBehaviourを作成しOnTriggerStayTtransitionからColliderを受け取り。
2.2.ColliderからさやのGameObjectを取得し、刀のParentに設定
2.3.刀をisKinematecをTrueに設定
public class StoreNozzle : StateBehaviour {
public InputSlotCollider sayaCollider;
public override void OnStateBegin()
{
Collider collider = null;
if (sayaCollider.GetValue(ref collider))
{
gameObject.transform.parent = collider.gameObject;
gameObject.transform.localPosition = new Vector3(0f,0f,0f);
Rigidbody nozzleRigidBody = gameObject.GetComponent<Rigidbody>();
nozzleRigidBody.isKinematic = true;
}
}
}