先日作ったカウントダウンタイマーを発展させて、スタミナタイマーを作りたいと思います。
〜今回作るスタミナタイマー〜
- 10秒経ったらスタミナが1増える
- スタミナは最大値以上には増えない
- 「スタミナ消費」ボタンを押すとスタミナが減る
それでは早速作っていきましょう!
下準備
前回作ったカウントダウンタイマーを開きます。
前回未読の方は、すぐに作れるので読んでみてくださいね。
スタミナ量を表示するテキストを作ります。
CanvasにあるTimerTextオブジェクトを右クリック > Duplicateで複製し、名前を「Stamina」に変えておきます。
TimerTextと場所がかぶるのでシーンビューで場所を上にずらしましょう。テキストは0にしておきます。
さらに、説明用のテキストオブジェクトを作ります。あと2つTimerTextを複製して、タイマー用とスタミナ用の説明テキストを作りましょう。
オブジェクト名やテキストを編集して位置を調整し、このようにしました。(オブジェクトの並び順もGame画面の表示中に合わせて変えました)
スタミナ消費ボタンを作成します。
Hierarchy下の+ > UI > Legacy > Buttonを選択してボタンを作ります。名前は「スタミナ消費」にしました。
Hierarchyのスタミナ消費ボタンオブジェクトの左の▼をクリックし、ボタンのテキストを編集します。こちらも同じく「スタミナ消費」としました。
位置と大きさを調整し、このようにしました。Hierarchyとゲーム画面のオブジェクトは図のように対応しています。
時間経過でスタミナが増えるようにする
前回作成したTimerスクリプトを編集しましょう。
どう変更したいかを考えます。スタミナ消費ボタンは後回しにして、ひとまず
- カウントダウンタイマー(TimerTextオブジェクト)が0になったらスタミナの数値(Staminaオブジェクト)が1増えるようにする
- カウントダウンタイマーが0になったらまた10からカウントし直す
この2つの機能を付けていきましょう。スクリプトは次のようになります。
///追加部分 と ///変更部分 がそれぞれ前回のスクリプトから追加・変更した部分です。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // UIを使うときに必要
public class Timer : MonoBehaviour
{
[SerializeField]
Text TimerText;
float limitTime = 10; // 制限時間
/// 追加部分
float maxTime = 10; // タイマーの最大時間
[SerializeField]
Text StaminaText;
int stamina = 0; // スタミナの数値
///
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
limitTime -= Time.deltaTime;
if (limitTime < 0)
{
///変更部分
limitTime = maxTime; // タイマーを最大時間にリセット
IncrementStamina(); // スタミナを1増やす
///
}
TimerText.text = limitTime.ToString("F0"); // 残り時間を整数で表示
}
/// 追加部分
void IncrementStamina()
{
stamina++; // スタミナを1増やす
StaminaText.text = stamina.ToString("F0"); // スタミナの数値を整数で表示
}
///
}
スクリプトを書き換えたら保存してUnityに戻ります。
TimerオブジェクトをクリックしてInspectorを開き、「Stamina Text」の欄にStaminaオブジェクトをドラッグ&ドロップします。これでTimerスクリプト内のStaminaTextとUnity内のStaminaオブジェクトのTextが紐づきました。
動作を確認してみましょう。
10秒経つとスタミナが1増えて、カウントは10に戻っています。
スタミナ消費ボタンを作る
次に、見た目だけ作ってあったスタミナ消費ボタンを完成させましょう。
作りたい機能は
・押すとスタミナが1減るようにする
です。Timerスクリプトを編集します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // UIを使うときに必要
public class Timer : MonoBehaviour
{
[SerializeField]
Text TimerText;
float limitTime = 10; // 制限時間
float maxTime = 10; // タイマーの最大時間
[SerializeField]
Text StaminaText;
int stamina = 0; // スタミナの数値
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
limitTime -= Time.deltaTime;
if (limitTime < 0)
{
limitTime = maxTime; // タイマーを最大時間にリセット
IncrementStamina(); // スタミナを1増やす
}
TimerText.text = limitTime.ToString("F0"); // 残り時間を整数で表示
}
void IncrementStamina()
{
stamina++; // スタミナを1増やす
StaminaText.text = stamina.ToString("F0"); // スタミナの数値を整数で表示
}
///追加部分
void DecrementStamina()
{
stamina--; // スタミナを1減らす
StaminaText.text = stamina.ToString("F0"); // スタミナの数値を整数で表示
}
public void StaminaButtonDown()
{
if (stamina > 0) // スタミナがマイナスにならないように
{
DecrementStamina();
}
}
///
}
スタミナを1減らすメソッドDecrementStaminaメソッドと、スタミナボタンを押した時に呼び出すStaminaButtonDownメソッドを追記しました。
Unityに戻って、スタミナ消費ボタンからメソッドを呼び出せるように設定しましょう。
- ヒエラルキーでスタミナ消費ボタンオブジェクトを選択し、インスペクターのOn Click()の欄の右下の+をクリック
- Runtime Onlyの下の空欄にTimerオブジェクトをドラッグ
- No Functionをクリックし、Timer > StaminaButtonDown()を選択
これで、スタミナ消費ボタンが押されたらスタミナが1減るようになりました。
動作を確認しましょう。
うまく実装できました。ボタンを押すとスタミナが1減り、スタミナが既に0の時には減りません。
スタミナに最大値を設定する
スタミナを時間経過で増やし、スタミナ消費ボタンで減らすようにはできましたが、このままでは無限にスタミナが増えてしまうことになります。
スタミナに最大値を設定し、スタミナが最大になった時にはタイマーが止まるようにスクリプトを書き換えていきましょう。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // UIを使うときに必要
public class Timer : MonoBehaviour
{
[SerializeField]
Text TimerText;
float limitTime = 10; // 制限時間
float maxTime = 10; // タイマーの最大時間
[SerializeField]
Text StaminaText;
int stamina = 0; // スタミナの数値
///追加部分
int staminaMax = 3; // スタミナの最大値
///
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
limitTime -= Time.deltaTime;
/// 追加・変更部分
if (stamina == staminaMax) // スタミナ量が最大値だったら
{
limitTime = maxTime; // タイマーを最大時間にする
return;
}
else if (limitTime < 0)
{
limitTime = maxTime; // タイマーを最大時間にリセット
IncrementStamina(); // スタミナを1増やす
}
///
TimerText.text = limitTime.ToString("F0"); // 残り時間を整数で表示
}
void IncrementStamina()
{
stamina++; // スタミナを1増やす
StaminaText.text = stamina.ToString("F0"); // スタミナの数値を整数で表示
}
void DecrementStamina()
{
stamina--; // スタミナを1減らす
StaminaText.text = stamina.ToString("F0"); // スタミナの数値を整数で表示
}
public void StaminaButtonDown()
{
if (stamina > 0) // スタミナがマイナスにならないように
{
DecrementStamina();
}
}
}
/// 追加・変更部分 で、スタミナが最大になった時の処理を追加しました。スタミナが最大の時はタイマーのカウントもストップさせたいので、タイマーを最大値にしてその後の処理をreturnで中断しています。
この処理の追加に伴って、その後の if (limitTime < 0) を else if (limitTime < 0)に書き換えています。
保存して動作を確認しましょう。
スタミナが最大値以上には増えず、最大値になったらカウントもストップしています。スタミナ消費ボタンを押すと、スタミナが減ってカウントもまた始まっています。
スタミナタイマーが完成しました!
応用:ゲームで使うために
ひとまず完成しましたが、このままでは、ゲームを開いている間は良いのですが、ゲームを閉じている間はスタミナが増えないことになってしまいます。
スマートフォンゲームなどでは特に、ゲームを開いていない間に経過した時間の分もスタミナが増えていて欲しいですよね。
遊んでいる時しかスタミナが貯まらないスマホゲームはつらい…
次回は端末内の時刻を取得して、ゲームを閉じている間の時間もスタミナが貯まるように改造してみたいと思います。