【Unity】SpringJointコンポーネントを使ってワイヤーアクションみたいなものを作った
ワイヤーアクション、いいですよね…。
海腹川背みたいな挙動のものが作りたいな~~~とふと思いました。
youtu.be
なので作りました。
SpringJointでワイヤーアクションっぽい挙動できた!
— 73(なーさん) (@kd_honmono73) 2023年4月23日
これ、ランゲームに使えそうなのでしばらくこれを使って詰めて見よう pic.twitter.com/CaKiSeloVk
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 ふりこ(振り子)の問題を解くときに大切なこと