【Unity】SpringJointコンポーネントを使ってワイヤーアクションみたいなものを作った

ワイヤーアクション、いいですよね…。
海腹川背みたいな挙動のものが作りたいな~~~とふと思いました。
youtu.be



なので作りました。

SpringJoint

たまたま調べものをしている最中に
それらしい挙動をしてくれるコンポーネントを見つけたんです。
それがSpringJoint
docs.unity3d.com

ばねのジョイントはふたつのリジッドボディを一緒につなげ、ばねの力はある特定の間隔でオブジェクトを保持するように自動的に適用されます。
SpringJoint - Unity スクリプトリファレンス

というわけで仮で作っていた段階のソースコードをドン!

/// <summary>
/// ワイヤーアクション開始
/// </summary>
/// <param name="vec">方向ベクトル</param>
private void OnTryWireAction(Vector2 vec)
{
    // レイ判定
    Ray ray = new Ray(origin.position, new Vector3(0.0f, vec.y, vec.x));
    RaycastHit result = new RaycastHit();
    bool isHit = Physics.Raycast(ray, out result, laycastDistance, targetLayer);
    if(!isHit)
    {
        return;
    }

    // spring設定
    var spring = gameObject.AddComponent<SpringJoint>();
    spring.autoConfigureConnectedAnchor = false;
    spring.connectedBody = result.transform.gameObject.GetComponent<Rigidbody>();
    spring.connectedAnchor= result.transform.InverseTransformPoint(result.point);
    spring.spring = m_setting.spring;
    spring.damper = m_setting.damper;
}

やっていることは非常に単純。
まずは飛ばしたい位置から方向ベクトルを使い、レイを飛ばします

    Ray ray = new Ray(origin.position, new Vector3(0.0f, vec.y, vec.x));
    RaycastHit result = new RaycastHit();
    bool isHit = Physics.Raycast(ray, out result, laycastDistance, targetLayer);

その後、SpringJoint.connectedAnchorにレイが当たった位置、
つまり支点となる位置を代入します。

なお、SpringJoint.connectedAnchorの値はローカル座標にする必要があります。

    // spring設定
    var spring = gameObject.AddComponent<SpringJoint>();
    spring.autoConfigureConnectedAnchor = false;
    spring.connectedBody = result.transform.gameObject.GetComponent<Rigidbody>();
    spring.connectedAnchor= result.transform.InverseTransformPoint(result.point);

あとはバネの弾性を変更したり、
移動中はSpringJointを使わない処理をゴリゴリ書いていって完成!

思ったより面白い挙動が出来たので、ランゲームを作ろうかな…。
GW明けまでしばらく使ってみようと思います。

参考にしたサイト

Spring Joint - Unity マニュアル
働きアリ : science ふりこ(振り子)の問題を解くときに大切なこと