【Unity】レバーで機械をオンオフする

投稿者: | 2020-06-02

レバーを使って機械をオンオフしてみます。

まずレバーを作ってHingeジョイントを付けます。レバーの根本で、レバーの回転に垂直な方向に軸を設定しました。レバーが元の位置に戻るようにSpringを使います。また、Limitsでレバーの動かせる範囲に制限を付けます。

レバーはスプリングでTarget Positionの位置に戻りますが、重力も加わります。

レバーにスクリプトを付けます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

[RequireComponent(typeof(HingeJoint))]
public class LeverScript : MonoBehaviour
{
    
    HingeJoint hj;
    bool locked = false;
    JointLimits defLimits;
    JointSpring defSpring;

    public bool useMax = true;
    public bool useMin = true;
    public bool useLock = false;

    [SerializeField] UnityEvent minEvent = new UnityEvent();
    [SerializeField] UnityEvent maxEvent = new UnityEvent();

    // Start is called before the first frame update
    void Start()
    {
        hj = GetComponent();
        defLimits = hj.limits;
        defSpring = hj.spring;
    }

    // Update is called once per frame
    void Update()
    {

        if (!locked && hj.velocity > 0f)
        {
            // レバーを限界付近まで押す
            if (useMin && hj.angle <= defLimits.min + 1)
            {
                // レバーをロックする時
                if (useLock)
                {
                    locked = true;

                    JointLimits jl = hj.limits;
                    jl.max = defLimits.min + 8;
                    hj.limits = jl;

                    minEvent.Invoke();
                }
                // ロックしないとき
                else
                {
                    JointSpring js = hj.spring;
                    js.targetPosition = defLimits.min + 5;
                    hj.spring = js;

                    minEvent.Invoke();
                }
            }
            // レバーを限界付近まで引く
            else if (useMax && hj.angle >= defLimits.max - 1)
            {
                // レバーをロックするとき
                if (useLock)
                {
                    locked = true;

                    JointLimits jl = hj.limits;
                    jl.min = defLimits.max - 8;
                    hj.limits = jl;

                    maxEvent.Invoke();
                }
                // ロックしないとき
                else
                {
                    JointSpring js = hj.spring;
                    js.targetPosition = defLimits.max + 5;
                    hj.spring = js;

                    maxEvent.Invoke();
                }
            }
        }

        if (Input.GetKeyDown(KeyCode.U))
        {
            UnLockLever();
        }
       
    }

    // ロックを解除する
    public void UnLockLever()
    {
        locked = false;
        hj.limits = defLimits;
        hj.spring = defSpring;
    }

}

今回はレバーをロックするときとしない時を切り替えられるようにしました。ロックする時はヒンジジョイントのLimitsの片方を近づけて、ロックしない時は、SpringのTarget Positionをレバーを動かした方の限界付近に移動して、レバーがそこにとどまるようにします。

レバーでオンオフする歯車にもヒンジジョイントが付いていて、Motorで動くようになっています。

歯車につけたスクリプトでHingeJoint.useMotorをtrueにすると動き出します。Rigidbodyの抵抗の値が小さいと、falseにしてから動きが止まるまでに時間がかかるようです。

歯車のスクリプトのメソッドをレバーから実行するときは、UnityEventを使うと便利です。

UnityEvent.Invoke()を実行すると、インスペクタで登録したすべてのメソッドが実行されます。引数も設定できます。

// レバー
[SerializeField] UnityEvent minEvent = new UnityEvent();

minEvent.Invoke();

//---
// 歯車
public void UseMotor(bool b)
{
    hj.useMotor = b;

}

レバーをロックしない場合は、レバーを限界付近まで上げ下げすると、Springによってそこでレバーが止まります。

コメントを残す

メールアドレスが公開されることはありません。