秒針を上下に動かす|Unityで針が縦に動く時計を作る

Image by Gerd Altmann from Pixabay Unity
Image by Gerd Altmann from Pixabay

こんにちは、コンスキです。

Unityを使って、時計の針が縦に動く時計を作っていきます。

その中でも今回は「秒針」を上下に動かす過程を解します。

作ることになった経緯に関してはこちらに描いてあります。

秒針と秒棒の区別

ただ単に秒針呼ぶと回転する秒針と上下に動く秒針のどちらを言っているか分かりづらいですね。

区別するために、回転する秒針を「秒針」と上下に動く秒針を「秒棒」と呼びます。

秒棒を上下に動かす方法

どのようにして秒針を上下に動かすかを考えてみます。

現在、スクリプトを使って、秒針を回転させることはできています。

こちらの記事で、紹介しているやり方です。

そこで、回転している時の秒針の傾きを使って、秒棒の上下の位置を決めます。

次の式が使えそうです。

xy座標の上にある半径の大きさがrの円を考えます。

さらに、その円の半径が時計の針ように回転した場合を考えます。

その半径とプラス側のx軸との角度をθとします。

そのときに、半径の先端のy座標を知ることができるというものです。

他のスクリプトの変数を使う

秒棒を上下に動かすには秒針の角度を使えばいいことはわかったのですが、ここで問題があります。

それは、秒針と秒棒のスクリプトが分かれていることです。

2つのスクリプトが分かれているということは、秒棒のスクリプトの中で、他のスクリプトの変数を使う必要があるということです。

秒針側のスクリプト

秒針のスクリプトで秒棒の角度を使うためには、角度の変数を宣言するときに「public」をつけて宣言しておく必要があります

次のスクリプトは、秒針を動かすためのスクリプトです。

8行目に注目してください。

「public Vector3 secondHandAngle」と宣言しています。

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

public class SecondHandManager : MonoBehaviour
{
  public Vector3 secondHandAngle;
  // Start is called before the first frame update
  void Start()
  {
    
  }

  // Update is called once per frame
  void Update()
  {
    int s = DateTime.Now.Second;
    secondHandAngle = new Vector3(0, 0, -360 / 60.0f * s);
    GetComponent<Transform>().localEulerAngles = secondHandAngle;
 }
}

秒棒側のスクリプト

次のスクリプトは、秒棒を動かすためのスクリプトです。

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

public class SecondBarManager : MonoBehaviour
{
    GameObject secondHand;
    SecondHandManager script;
    // Start is called before the first frame update
    void Start()
    {
        secondHand = GameObject.Find ("Second Hand");
        script = secondHand.GetComponent<SecondHandManager>();
    }

    // Update is called once per frame
    void Update()
    {
        var secondHandAngle = script.secondHandAngle;
        double theta = (double)(secondHandAngle.z + 90.0);
        double radian = Math.PI * theta / 180.0;
        float y = (float)(384.0 * Math.Sin(radian));
        GetComponent<Transform>().position = new Vector3(356.0f, y, 0);               
    }
}

まず、13行目と14行目を注目してください。

この2行で、秒針を動かすスクリプトの変数を使うための準備をしています。

すこし正確にいうと、13行目ではSecond Handという名前のゲームオブジェクト(スプライト)のオブジェクトの変数を用意して、14行目ではその変数を使って、スクリプトの変数を入れた変数を用意しています。

次に20行目です。

この行でようやく、秒針の角度の変数を取得しています。

秒針の角度から秒棒の位置を決める

ここからは、秒棒の縦方向の縦方向の位置を決めるスクリプトを見ていきます。

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

public class SecondBarManager : MonoBehaviour
{
    GameObject secondHand;
    SecondHandManager script;
    // Start is called before the first frame update
    void Start()
    {
        secondHand = GameObject.Find ("Second Hand");
        script = secondHand.GetComponent<SecondHandManager>();
    }

    // Update is called once per frame
    void Update()
    {
        var secondHandAngle = script.secondHandAngle;
        double theta = (double)(secondHandAngle.z + 90.0);
        double radian = Math.PI * theta / 180.0;
        float y = (float)(384.0 * Math.Sin(radian));
        GetComponent<Transform>().position = new Vector3(356.0f, y, 0);               
    }
}

まず、21行目に注目してください。

この行でやっているのは、角度の調整です。

20行目にある「secondHandAngle」というのは、時計の12時の位置から秒針までの角度です。

一方でy = rsinθの式のθは「秒針とプラス側のx軸との角度」です。

そのため、「secondHandAngle」を直接使うことはできません。

そこで、90.0を足して、「秒針とプラス側のx軸との角度」に直しています。

次に22行目では、角度をラジアンにしています。

1ラジアンが180であるためそのような式になります。

そして、23行目で「y=rsinθ」を使って、秒棒のy座標を計算しています。

ここでは秒針の長さではなく、時計の中心から数字が位置する場所までの長さ(384)を半径にしています。

最後に、24行目で計算で求めたy座標を秒棒の座標に設定しています。

完成形

今回やったのは秒棒だけですが、回転の動きから上下の動きに変えることができました。

秒針の先端が縦方向の真ん中にいくほど、秒棒の動く幅が大きくなることがわかります。

コメント

  1. […] […]

タイトルとURLをコピーしました