Unityでアナログ時計を作る方法(Unityの練習)2/2

Unity アナログ時計 スクリプト Unity

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

Unityで2Dのアナログ時計を作る方法の続きです。

1回目を見ていない方はこちら↓をご覧ださい

進行具合の確認

前回の記事で、PowerPointで時計の画像を作り、Unity のSceneと呼ばれる枠の中にその画像を配置するところまでを進めました。

ここからやっていく主な作業は、スクリプトを書き、時計の針を動かしていく作業です。

回転の中心を設定する

スクリプトを書いて時計の針を動かした時に、針の根本を回転の軸として回っていた方が、スクリプトの中にあるミスを発見しやすいです。

そこで、まずは針の回転の中心を設定していきます。

1. アセット(Assets)の中から「時針」「分針」「秒針」の中からどれでもいいので、クリックして選択肢します。

2. 画面右側に次のような情報(インスペクター)が表示されるのを確認します。

3. その中にある「Sprite Editor」と書かれたボタンを選択します。

すると次のようなウィンドウが表示されます。

4. 青い輪っかを回転の中心になる位置まで移動します。

回転の中心というのは、時計を組み立てたときに時計の針のなかでど真ん中にくる位置のことです。

5. 「Apply」を押します。

6. ここまでの作業を残りの2つの針に対しても行います。

もしかすると、位置がずれてしまうかもしれません。お手数かけて申し訳ありませんが、もう一度位置を設定し直してください。

スプライトにスクリプトを追加する

前回説明しましたが、2DのUnityのにおいてシーン(Scene)の中に入っている画像のことを「Sprite」といいいます。

カタカナだと「スプライト」になります。

時計の針や時計のそれ以外の部分もスプライトということになります。

「時針」「分針」「秒針」のそれぞれのスプライトに対して、スクリプト(プログラム)を追加することで、針を動かしていきます。

1. 「ヒエラルキー(Hierarchy)」の中から「secondHand」をクリックします。

2. 画面右側にsecondHandの情報が表示されるのを確認します。繰り返しになりますが、これをインスペクター(Inspector)と言います。

3. インスペクターの一番下にある「Add Component」をクリックします。

4. 選択肢が出てくるため、一番下にある「New script」を選択します。

5. スクリプトの名前を入力する画面になるので、「secondHandManager」などの名前にしておきましょう。

一概には言えませんが、Unityではプログラムの名前をつける際に、「スプライトの名前 + Manager」にのようにすることが多いようです。

この場合では、スプライトの名前が「secondHand」であるため、「secondHandManager」という名前にしました。

6. 名前を付けられたら、Enterキーを押すか、下にある「Create and Add」というボタンを押します。

インスペクターの中に「Second Hand Manager(先ほどつけた名前)」の項目が表示されればOKです。

「second」が「Second」になっていたり、単語ごとにスペースが空いていたりして、先ほどつけた名前とは完全に一致していないと思いますが、こういう仕様なので大丈夫です。

7. 「時針」と「分針」に対しても、1~6までのような作業を行います。ちなみに私は、時針のスクリプト名を「hourHandManager」にし、分針のスクリプト名を「minuteHandManager」にしました。

8. 一応アセット(Assets)の中にも「#」のマークがついたファイルが3つ追加されていることを確認してください。

「#」マークがついているのは、これらのファイルが「C#」というプログラミング言語のファイルだからです。

スクリプトを編集する

これからスプライトに追加したスクリプトを編集していきます。

次に示すスクリプトを別々に編集します。

  • 「秒針」のスプライトに追加したスクリプト
  • 「分針」のスプライトに追加したスクリプト
  • 「時針」のスプライトに追加したスクリプト

「秒針」のスプライトに追加したスクリプト

3つの針のうち、秒針は1番動いていることを確認しやすいです。動きを確認できた方が、スクリプトのなかのミスを見つけやすいため、最初は秒針のスクリプトを編集していきます。

1. アセットの中にある秒針のスクリプトのファイルをダブルクリックします。コードエディターが起動すると思います。

何も編集していない時点ですでに次のようなプログラムが書かれていると思います。

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

public class secondHandManager : MonoBehaviour
{
  // Start is called before the first frame update
  void Start()
  {

  }

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

  }
}

5行目の「secondHandManager」はスクリプトにつけた名前によって変わります。

2. 次のスクリプトみたいになるように、スクリプトを書き加えます。

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

public class secondHandManager : MonoBehaviour
{
  // Start is called before the first frame update
  void Start()
  {
    
  }

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

上から4行目の「using System」で、現在時刻を取得できるようにしています。実際に時間を取得しているのは17行目のDateTime.Now.Secondプロパティです。

18行目に書かれている「GetComponent<Transform>().localEulerAngles」は、秒針の傾きを表しています。「GetComponent<インスペクターの項目名>()」のように書くことで、インスペクターの情報をスクリプトから変更することができるようです。ただし、全てそのような規則になっているというわけではありません。

また、18行目の「new Vector3(0, 0, -360 / 60.0f * s)」では、現在の時刻から、秒針の傾きを決めています。時計は一周が360度ですが、秒針は60秒で1周してしまうので、1秒に360/60度(60度)ずつ回転する必要があります。

3. スクリプトファイルを保存して、Unityの「Game」に移ってから再生ボタンを押し動作確認をします。

「分針」のスプライトに追加したスクリプト

次は分針を動かすためのスクリプトを書いていきます。

1. 秒針の時と同じように分針のスクリプトファイルをダブルクリックして開きます。

2. 次のスクリプトを書きます。

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

public class minuteHandManager : MonoBehaviour
{
  // Start is called before the first frame update
  void Start()
  {

  }

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

17行目の変数sをmに変えて、DateTime.Now.Minuteプロパティで現在の秒ではなく現在の分を取得するようにしただけです。

あとは、秒針のスクリプトと同じです。

3. 秒針の時と同じように動作確認を行なってください。

「時針」のスプライトに追加したスクリプト

最後に時針のスクリプトを書いていきます。このスクリプトは少し工夫が必要です。

1. 秒針と分針の時と同じように時針のスクリプトファイルをダブルクリックして開きます。

2. 次のスクリプトを書きます。

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

public class hourHandManager : MonoBehaviour
{
  // Start is called before the first frame update
  void Start()
  {

  }

  // Update is called once per frame
  void Update()
  {
    int m = DateTime.Now.Minute;
		int h = DateTime.Now.Hour;
		float HHA = -((360 / 12.0f * h) + (30 / 60.0f * m));
    GetComponent<Transform>().localEulerAngles = new Vector3(0, 0, HHA);
  }
}

注目していただきたいのが、19行目と20行目のコードです。

HHAは「HourHandAngle」の略で、「new Vector3(0, 0, HHA)」のようにしているのは、スクリプトが横に長くなってしまうためです。

このことはあまり重要ではなく、重要なのは単に「-((360 / 12.0f * h) + (30 / 60.0f * m)) 」の部分です。

本来は「-360 / 12.0f * h」のように書き1時間に1回、360/12度動くようにすれば、現在時刻を知ることはできます。しかし、これだけでは普通の時計の動きとは少し違う時計ができてしまいます。普通の時計は、時針も1時間に1回ではなく1時間の間に少しずつ動き、結果的に360/12度(30度)動くようになっていることが多いです。

そこで、さらに現在の「分」も取得して、それを使って、時針がちょっとずつ動くように調節します。

そうするとコードは「-360 / 12.0f * h – 30 / 60.0f * m」となります。さらに、かっこを使って少し整えると「-((360 / 12.0f * h) + (30 / 60.0f * m)) 」となります。

完成形

これでアナログ時計の完成になります。作った方はお疲れ様でした。

完成すると次のように動きます。

分針と時針が動いているところを確認するには、気長に待つ必要があります💦

コメント

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