【Unity】アクション系タイマー

タイマー記事の続きでっす。

今回はアクション系のタイマーを説明していきます。
アクション系のタイマーって、何?と思われる方もおられるかと…

タイマーって数値をカウントして0になれば終了するものですが、
数値が減少して行くのって分かりやすいですが、少々味気ないものです。

ローディングやダウンロードで数値だけが動いているとイライラしたり
これって私だけ(;´▽`A`` セッカチナモンデ

少しキャラが動いたりしてると紛れるかと思います。

また通常タイマーと違って、可愛らしいキャラを使った、
視覚タイマーをアプリとして公開されている方もおられます。

簡単ですが、アクション系のタイマーを作ってみたいと思います。

タイマー動画で上げたキャラは、某メーカーのキャラに似ていますが、
違うので注意でっす。
パクパクまんと言うキャラです。(V)o\o(V)ふぉふぉふぉ

パクパクまん、ボール、吹き出しのスプライトをインポートします。
ボールは、Green、Yellow、Red、の三色を用意します。
Timer⑨.jpg
Redだけ大きいのは気にしないで下さい(;^_^A アセアセ・・・

続いて、Canvasに空オブジェクトを作成してActionParentにリネーム、
この中に配置していきます。

Imageを追加して、パクパクを用意します。
Timer⑪.jpg
スプライトは口を閉じている方を選択して、transformを設定します。
今回は、Y200 X-200に設定しました。

pakpakに空オブジェクトを追加してOpenにリネーム
Timer⑫.jpg
位置はpakpakの口の前あたりにセットします。
BoxCollider2Dを追加して、スクショのサイズに変更します。

このコラインダーにボールが当たると口を開くようにします。

続いて、pakpakオブジェクトにもコラインダーを設置します。
Timer⑬.jpg
口の付け根当たりにコラインダーを配置します。
だいたいオフセット-10くらいでOKでっす。

このコラインダーにボールが当たると、
口を閉じてボールが消えるようにします。

二つのコラインダーは、大きさ30×30程度の大きさでいいかと思います。

パクパクまんの用意ができたので、ボールの準備をします。
ActionParentにImageを追加して、GreenBallにリネーム
Timer⑭.jpg
スプライトにGreenBallをアタッチ
位置は、Y座標はpakpakと同じ高さで、X座標を0にします。

pakpakとX座標が200離れた位置になります。
ボールは口に1秒毎に入るようにするので、-200/秒のスピードで動かします。

GreenBallには、
Timer⑮.jpg
CircleCollider2DとRigidbody2Dを追加します。

コラインダーのサイズは、Ballサイズに調整します。
Rigidbodyは、キネマチックにして、完全なキネマチックコンタクトをチェックします。

GreenBallができたので、
Timer⑯.jpg
3つ複製を作り、X座標を200づつずらして配置します。
GreenBallはプレハブ化します。

GreenBallを元にYellowとRedのプレハブも作ります。
RedBallまで作れたら最後のBallを作ります。
Timer⑰.jpg
RedBallをEndBallにリネームして、タグをEndBallに設定します。
タイマーカウントの終了Ballとなります。

各ボールのプレハブ化ができたら原盤は削除して、GreenBallが4つ残った状態にします。

EndBallが口に入ったらタイマー終了を分かるようにしたいので、
Timer⑱.jpg
こんな感じの終了吹き出しを用意しました。(´`;) センスナイ

このオブジェクトをfalseして、EndBallが口に入ると呼び出すようにします。

これでエディターの準備が整ったので、スクリプトを作成します。
TimerManager

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

public class TimerManager : MonoBehaviour
{
//タイマー用変数
public float LimitTime; //タイマーの設定時間
private bool counting;          //タイマー稼働フラグ
private float Elapsedtime; //1秒を読み取る変数

//パクパクまん用変数
//各ボールプレハブ
public GameObject GreenPrefab, YellowPrefab, RedPrefab;
public GameObject EndBallPrefab; //最後のボールプレハブ
public GameObject ActionParent; //プレハブ生成時の親オブジェクト
private int CreateCount = 57; //ボールの生成カウント
private int axisX = 600; //生成座標X
private int axisY = 200; //生成座標Y

// Start is called before the first frame update
void Start()
{
}

// Update is called once per frame
void Update()
{
if (counting)
{
TimerCount();
}
}

//タイマー機能
void TimerCount()
{
//稼働時の経過時間
LimitTime -= Time.deltaTime;
Elapsedtime += Time.deltaTime;

//1秒毎の処理呼び出し
if (Elapsedtime >= 1)
{
CreateBall();
Elapsedtime -= 1.0f;
}

//タイマーの停止
if (LimitTime <= 0)
{
counting = false;
}
}

//ボールの生成
void CreateBall()
{
if (CreateCount == 0)
{
return;
}

GameObject ball = null;

//残りカウントからプレハブを選択して生成
if (CreateCount > 20)
{
ball = (GameObject)Instantiate(GreenPrefab);

}
else if (CreateCount > 10)
{
ball = (GameObject)Instantiate(YellowPrefab);
}
else if(CreateCount==1)
{
ball = (GameObject)Instantiate(EndBallPrefab);
}
else
{
ball = (GameObject)Instantiate(RedPrefab);
}

//生成したプレハブのtransform設定
ball.transform.SetParent(ActionParent.transform, false);
ball.transform.SetSiblingIndex(0);
ball.transform.localPosition = new Vector3(axisX, axisY, 0);

//生成カウントを減算
CreateCount--;
}

//タイマースタート
public void PushStart()
{
counting = true;
CreateBall();
}

//タイマー稼働フラグのProperty
public bool StartProperty
{
get { return counting; }
}

タイマー機能を利用して、1秒毎にBallを生成します。
プレハブの選択が複雑なのが勉強不足を物語っています。(;^_^A

Ballの生成位置は、4つのGreenBallを作成した一番右端のボール位置になります。
1秒毎にパクパクまんへBallを移動させるので、開始1秒後に右端に生成すれば、
間隔が同じでBallが繋がっていきます。

生成したBallがパクパクまんに移動しないといけないので、
Ball用のスクリプトを作成します。
BallController

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

public class BallController : MonoBehaviour
{
private GameObject timerManager; //TimerManager取得用
private TimerManager timerM; //TimerManagerスクリプト取得用
private Transform tran; //ボールのtransform取得用
private float coorX; //ボールのX座標変数
private float axisY = 200; //Y座標の固定位置


// Start is called before the first frame update
void Start()
{
//TimerManager取得
timerManager = GameObject.Find("TimerManager");
timerM = timerManager.GetComponent<TimerManager>();

//ボールのComponentとX座標を取得
tran = this.gameObject.GetComponent<RectTransform>();
coorX = tran.localPosition.x;
}

// Update is called once per frame
void Update()
{
//スタートボタンが押されたら移動開始
if (timerM.StartProperty)
{
BallMove();
}
}

//ボールの移動処理
void BallMove()
{
coorX -= Time.deltaTime * 200;
tran.localPosition = new Vector3(coorX, axisY, 0);
}
}

Ballはスタートボタンが押されてから動く必要があるので、
TimeManagerのスタートフラグを検知したら動くようにしています。

Ballの移動速度は、パクパクまんとBallの距離を200で取っているので、
deltaTime*200/1秒なので、単純に200を掛けています。

TimerManagerは、TimerManagerオブジェクトを用意してアタッチします。
LimitTimeの設定と各種オブジェクトのアタッチをします。

BallControllerは、Scene上にある4つのボールと各プレハブにアタッチします。

スタートボタンについては、今回は端折ります。


これで、スタートボタンを押せばボールが移動するようになったので、
パクパクまんとボールの処理を作ります。
OpenScript

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

public class OpenScript : MonoBehaviour
{
public GameObject Pakpak; //パクパク本体
public Sprite OpenMouth; //口を開けたスプライト
private Image pakpakImage; //パクパクのImageコンポーネント取得用


// Start is called before the first frame update
void Start()
{
//パクパクのImageコンポーネント取得
pakpakImage = Pakpak.GetComponent<Image>();
}

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

}

//ボールが接触したら口を開ける
void OnCollisionEnter2D(Collision2D collision)
{
pakpakImage.sprite = OpenMouth;
}
}

Imageを使うので、using UnityEngine.UI;を宣言します。
Collisionで衝突を検知したらpakpakオブジェクトのスプライトを
口を開けたものに差し替えます。

このスクリプトはOpenオブジェクトにアタッチします。
変数にpakpakオブジェクトと開口したスプライトをアタッチします。
CloseScript

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

public class CloseScript : MonoBehaviour
{
public GameObject Pakpak; //パクパク本体
public Sprite CloseMouth; //口を閉じたスプライト
private Image pakImage; //パクパクのImageコンポーネント取得用

public GameObject bubble; //満腹の吹き出し

// Start is called before the first frame update
void Start()
{
//パクパクのImageコンポーネント取得
pakImage = Pakpak.GetComponent<Image>();
}

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

}

//ボールが接触したら呼び出す
void OnCollisionEnter2D(Collision2D collision)
{
//衝突したボールの判定
//EndBallなら終了吹き出しをtrue
if (collision.gameObject.tag == "EndBall")
{
bubble.SetActive(true);
}
else
{
pakImage.sprite = CloseMouth;
}
Destroy(collision.gameObject);
}
}

同じくusing UnityEngine.UI;を宣言します。

pakpakの中のCollisionなので、衝突したボールを消去する処理をします。
ただし、EndBallタグのものだけは、吹き出しを呼び出すようにします。

これで終了までの処理が完成でっす。
後は、各public変数にアタッチをして、PLAYすれば動くと思います。

動きにかんしては、以前の記事の動画を参照して下さい。


ボールを動かすアクションだったのですが、
ボールを設置してパクパクが動くタイマーなども作れそうです。

使いどころが難しいタイマーですが、何かの参考になれば幸いでっす。

アクション系タイマーは以上となります。
今回はこのへんで~

(o・・o)/~マタネェ

この記事へのコメント