【Unity】ハンドルで開閉するゲートに重力を加える

投稿者: | 2020-06-05

ハンドルを回して開閉するゲートに重力を加えます。前の記事では、マウスドラッグによってハンドルとゲートを両方動かしていましたが、今回はゲートだけを動かして、ゲートの速度を使ってハンドルを回転させてみました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class ValveScript3 : MonoBehaviour
{
    //[SerializeField] Text text01;
    [SerializeField] float handleSpeed = 5f;
    [SerializeField] Rigidbody rb_gate;

    HingeJoint hj;
    JointLimits jl;

    Vector3 mPos;
    Vector3 screenSizeHalf;
    float previousRad;

    Rigidbody rb;
    bool awake = false;
    bool mouseButtonDown = false;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent();
        rb.maxAngularVelocity = Mathf.Infinity;
        hj = GetComponent();
        rb_gate.useGravity = true;
    }

    public void Activate(bool b)
    {
        if (b)
        {
            screenSizeHalf.x = Screen.width / 2f;
            screenSizeHalf.y = Screen.height / 2f;
            screenSizeHalf.z = 0f;

            mPos = Input.mousePosition - screenSizeHalf;
            previousRad = Mathf.Atan2(mPos.x, mPos.y);
            mouseButtonDown = true;
            awake = true;
        }
        else
            mouseButtonDown = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (awake || mouseButtonDown)
        {                   
            mPos = Input.mousePosition - screenSizeHalf;
                 
            float rad = Mathf.Atan2(mPos.x, mPos.y); // 上向きとマウス位置のなす角
            float dRad = rad - previousRad; // 前のフレームの角度との差

            float t = Mathf.Tan(dRad);

            //text01.text = t + "";

            // 速度が大きすぎないとき
            if (Mathf.Abs(t) <= 1f && mouseButtonDown)
            {
                // ゲートを動かす
                rb_gate.AddForce(Vector3.up * t * 4f, ForceMode.Impulse);
            }

            // ハンドルを握っていてマウスを動かしていないとき
            if(t == 0 && mouseButtonDown) rb_gate.AddForce(Vector3.up * Time.deltaTime * 35f, ForceMode.Impulse);

            previousRad = rad; // 今のフレームの角度を保存

            // ハンドルを動かす
            rb.angularVelocity = rb_gate.velocity * handleSpeed;

            if (rb.angularVelocity.y == 0f && !mouseButtonDown) awake = false;            
        }
    }
}

ハンドルがプレイヤーにクリックされたら、クリックが離されても、ハンドルの角速度が0になるまで計算を続けるようにしました。

マウスドラッグによって得られる値を使ってゲートを動かして、ハンドルは角速度にゲートの速度を代入して回転させています。

今回はゲートに重力を加えていますが、マウスを動かさなくても、ハンドルを握っている間は、ゲートに上方向の力を加えて、ゲートの落下速度を抑えています。

tの値は、フレームとフレームの平均的な間隔が変わると若干偏ってしまうようですが、Time.deltaTimeを使っても治らなくて保留しています。

ゲートの動き方はAddForceの第一引数のベクトルの大きさやRigidbodyのmass,dragなどの値で調節できます。ゲートにはスクリプトを付けていません。

コメントを残す

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