こんにちは、コンスキです。
今回は、以前から作っている針が縦に動く時計の作成の続きです。
時針を上下に動かす
タイトルの「端まで行ったら瞬間移動させる」の説明をする前に、まだ作っていない時棒を動かすスクリプトについて話します。
ここまでの「秒棒」と「分棒」と同じように、縦に動く時針のことを時棒と呼んでいます。

時針においても、考え方は秒針や分針の時と変わりません。
そのため、スクリプトの説明はしないことにします。
スクリプトだけを下に示します。
時針を動かすためのスクリプト
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class HourHandManager : MonoBehaviour
{
public Vector3 hourHandAngle;
// 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));
hourHandAngle = new Vector3(0, 0, HHA);
GetComponent<Transform>().localEulerAngles = hourHandAngle;
}
}
時棒を動かすためのスクリプト
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class HourBarManager : MonoBehaviour
{
GameObject hourHand;
HourHandManager script;
// Start is called before the first frame update
void Start()
{
hourHand = GameObject.Find ("Hour Hand");
script = hourHand.GetComponent<HourHandManager>();
}
// Update is called once per frame
void Update()
{
var hourHandAngle = script.hourHandAngle;
double theta = (double)(hourHandAngle.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);
}
}
端まで行ったら左右に移動させる
「秒棒」「分棒」「時棒」全ての棒を上下に動かすことを完了しましたが、この状態では最初に考えていた動きとは異なっています。
最初に考えていた棒の動きは、右の文字盤では下向きに棒が動き、左の文字盤では棒が上向きに動くというものです。
詳しく説明します。
もう一度、デザインカンプ(完成予想図)を見てみましょう。
この図を見れば初めに僕が考えていた動きがわかるかもしれません。

このデザインカンプの右側の時計だけに注目してください。
その時計の両端に数字が書かれていることが分かるでしょうか。

これは時刻を表しています。
普通の時計にある、文字盤に書かれている数字と同じ意味を持つものです。

だとすると「秒棒」「分棒」「時棒」は全て、次のような向きで動かなければなりません。
そうでないと、棒が時間をさかのぼっていることになってしまうためです。

つまり、右の文字盤では下向きに、左の文字盤では上向きだけ動かなければなりません。
しかし、現在の状態だと、棒はそのようには動いていません。
棒は左の文字盤で上にも下にも動いています。
ここで必要になってくるのが、棒が「端まで行ったらもう一方の文字盤に瞬間移動する」という動きです。

スクリプト
「端まで行ったらもう一方の文字盤に瞬間移動する」という動きを実現するために次のようにスクリプトを書き換えます。
ちなみに書き換えているのは、色が色が濃くなっている部分だけです。
それ以外の部分に関しては変更を加えていません。
秒棒を動かすためのスクリプト
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));
float x = radian <= -Math.PI /2 && radian > -Math.PI * 3/2 ? 356.0f : 537.0f;
GetComponent<Transform>().position = new Vector3(x, y, 0);
}
}
25行目に注目してください。
「new Vector3(x, y, 0)」のように、以前は使っていなかった「x」という変数を引数として渡しています。
このようにしている理由は、秒針の角度を使って、秒棒のx座標(横方向の位置)を決めるためです。
それでは、この変数xを宣言している24行目に注目してください。
float x = radian <= -Math.PI /2 && radian > -Math.PI * 3/2 ? 356.0f : 537.0f;
さらに代入演算子「=」の右側に注目します。
ここでは、三項演算子を使って角度によって、変数xに入れるx座標を変えています。
この式を日本語と図で説明すると次のようになります。

ちなみに、356は左の文字盤のx座標を意味していて、537は右の文字盤のx座標を意味しています。

分棒を動かすためのスクリプト
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class MinuteBarManager : MonoBehaviour
{
GameObject minuteHand;
MinuteHandManager script;
// Start is called before the first frame update
void Start()
{
minuteHand = GameObject.Find ("Minute Hand");
script = minuteHand.GetComponent<MinuteHandManager>();
}
// Update is called once per frame
void Update()
{
var minuteHandAngle = script.minuteHandAngle;
double theta = (double)(minuteHandAngle.z + 90.0);
double radian = Math.PI * theta / 180.0;
float y = (float)(384.0 * Math.Sin(radian));
float x = radian <= -Math.PI /2 && radian > -Math.PI * 3/2 ? 356.0f : 537.0f;
GetComponent<Transform>().position = new Vector3(x, y, 0);
}
}
25、26行目は秒針のスクリプトの24行目、25行目と全く同じです。
時棒を動かすためのスクリプト
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class HourBarManager : MonoBehaviour
{
GameObject hourHand;
HourHandManager script;
// Start is called before the first frame update
void Start()
{
hourHand = GameObject.Find ("Hour Hand");
script = hourHand.GetComponent<HourHandManager>();
}
// Update is called once per frame
void Update()
{
var hourHandAngle = script.hourHandAngle;
double theta = (double)(hourHandAngle.z + 90.0);
double radian = Math.PI * theta / 180.0;
float y = (float)(384.0 * Math.Sin(radian));
float x = radian <= -Math.PI /2 && radian > -Math.PI * 3/2 ? 356.0f : 537.0f;
GetComponent<Transform>().position = new Vector3(x, y, 0);
}
}
24行目と25行目は秒針のスクリプトと全く同じです。
完成形
完成した時計は次のようになりました。
コメント