2Dのピンボールゲームを作っているときに、フリッパーをHingeJoint2Dを用いて作る方法をご紹介

とりあえずフリッパーになるものを作る
まずはフリッパーとしての動きを行うものを作ります。というのも、後で少し調整が必要になるので、まずは動くものから。
Unity上でのセットアップ
今回は四角の画像をフリッパーに見立てて作ります。
2D Object>Sprites>Squareを追加。わかりやすいようにFlipperLeftと名前を変更します。
Scaleを調整して、下図のように変更してください。

FlipperLeftにHingeJoint2Dを追加します。
Physice 2D>Hinge Joint 2D
追加するとコンポーネントにRigidbody2Dも追加されます。

HingeJoint2DのEdit Joint Angular Limitsボタンを押して、アンカーの位置を変更します。
画像の左端中央になるように変更してください。シーンビューの青い丸をドラッグアンドドロップで位置調整することが出来ますが、うまく出来ない場合は水色の囲みの数字を参考に移動させてみてください。

Use Limitsにチェックを入れます。
Lower Angle:-15 、Upper Angle:30

この状態で一度再生してみてください。フリッパーがクタッと途中まで倒れてくれると成功。
フリッパーはモーターの機能を使って動かします。左側フリッパーはMotor Speedを-1000として設定します。これはゲームによって変更してください。

以上の設定が出来たら、再生中にUse Motorのチェックを入れたり入れなかったりするとフリッパーが動いてくれます。
スクリプトで制御する
Unityで操作してみましょう。
とりあえず動かす
以下のスクリプトをアタッチして、左クリックを押すとフリッパーが動いてくれます。
using UnityEngine;
public class Flipper : MonoBehaviour
{
private HingeJoint2D myHingeJoint;
private void Start()
{
myHingeJoint = GetComponent<HingeJoint2D>();
}
void Update()
{
myHingeJoint.useMotor = Input.GetMouseButton(0);
}
}
ただ、これでは実は不十分です。上から何かが接触するとたわんでしまいます。これは2Dじゃない方のHingeJointには見られない現象です。完全には修正できませんが、次のスクリプトで多少マシになります。
静止状態はたわまない処理を追加
フリッパーが静止中はRigidbody2DをStatic状態にすることで多少マシになります。
using UnityEngine;
public class Flipper : MonoBehaviour
{
private HingeJoint2D myHingeJoint;
private Rigidbody2D myRigidbody;
private void Start()
{
myHingeJoint = GetComponent<HingeJoint2D>();
myRigidbody = GetComponent<Rigidbody2D>();
}
void Update()
{
myHingeJoint.useMotor = Input.GetMouseButton(0);
if(Input.GetMouseButtonDown(0))
{
myRigidbody.bodyType = RigidbodyType2D.Dynamic;
}
}
private void FixedUpdate()
{
if(myRigidbody.IsSleeping() && !Input.GetMouseButton(0))
{
myRigidbody.bodyType = RigidbodyType2D.Static;
}
}
}
あとは跳ね返り係数とか、MotorSpeedとかを調整してお好みに仕上げてください!
コメント