C#
Unity3D
Unity
Unity2D

[Unity] ピンボールゲームのフリッパーを実装する

More than 3 years have passed since last update.

ピンボールゲームを作る上で実装必須のフリッパー※ですが、意外とその実装方法が見つからなくて困りました。
※ボールを打つための「 \ / 」部分です。

思い描いていた動作がHingeJointを使うことで実現できたので、その方法をまとめておきます。

事前準備

まずはCubeを新規作成します。
TransformのScaleをX = 4にして少し横長にします。
transform.png

次に、このCubeにRigidbodyとHingeJointのComponentを追加します。
RigidbodyはUse Gravityのチェックを外します。
HingeJointはAnchorの位置を(0.5, 0, 0)に、Axisの向きを(0, 0, 1)に変更し、Use Springにチェックをつけます。
Rigidbody_HingeJoint.png

スクリプト

事前準備で作成したCubeに、以下のスクリプトを追加します。
追加後、Game画面上でマウスを左クリックするとフリッパーが動きます。

flipper.cs
using UnityEngine;
using System.Collections;

public class flipper : MonoBehaviour {

    public float spring = 40000;
    public float damper = 1000;
    public float openAngle = 45;
    public float closeAngle = -45;

    private HingeJoint hj;
    private Rigidbody rb;

    void Start () {
        hj = gameObject.GetComponent<HingeJoint>();
        hj.useSpring = true;
        rb = gameObject.GetComponent<Rigidbody>();
        rb.useGravity = false;
        closeFlipper ();
    }

    void Update () {

        if (Input.GetMouseButtonDown (0)) {
            openFlipper();
        }
        if (Input.GetMouseButtonUp (0)) {
            closeFlipper();
        }

    }

    public void openFlipper(){
        JointSpring spr = hj.spring;
        spr.spring = spring;
        spr.damper = damper;
        spr.targetPosition = openAngle;
        hj.spring = spr;
    }

    public void closeFlipper(){
        JointSpring spr = hj.spring;
        spr.spring = spring;
        spr.damper = damper;
        spr.targetPosition = closeAngle;
        hj.spring = spr;
    }

}

解説

    public float spring = 40000;
    public float damper = 1000;
    public float openAngle = 45;
    public float closeAngle = -45;

springはバネの強さで、これを大きくすると勢いよく動くようになります。
damperはバネの戻りにくさで、これを大きくするとあまりビヨンビヨンしなくなります。
openAngleはフリッパーが開いた時の角度で、closeAngleはフリッパーが閉じた時の角度です。
これらのパラメータは適宜調整してください。

        hj = gameObject.GetComponent<HingeJoint>();
        hj.useSpring = true;
        rb = gameObject.GetComponent<Rigidbody>();
        rb.useGravity = false;

これは、チェックの付け忘れ/外し忘れ防止のために、念のため書いているだけです。不要であれば削除可能です。