top of page
検索

【Unity】現実時間に同期したスタミナゲージ

  • uniteen
  • 2015年5月31日
  • 読了時間: 5分

暑いですね。

金曜日に、会社でチーム対抗の飛び込み営業訓練があったのですが、こんなインドアな私が10時間近く外で飛び込み営業をしていましたwなんとか私のチームは1位で目標達成しましたが、チームのお荷物になっていたので、開発だけじゃなく、営業も頑張ろうと思いました。飛び込み営業できる開発側の人間はなかなかいないでしょうしね。

今回は現実時間に同期し、シーン移動などをしても離れていた時間だけスタミナ値を回復させる

スタミナゲージの実装方法をご紹介します。パズドラとかのあれです。

スクリーンショット 2015-05-31 15.48.45.png

以下コード

using UnityEngine; using UnityEngine.UI; using System.Collections; using System; using System.Collections.Generic; public class StaminaManager : MonoBehaviour { public Text staminatext; //現在のスタミナを表示する public Text staminacounter; //現在の残り時間を表示する private float fillAmount;  //ゲージのfillamount値 public Image staminaBar; // スタミナバーの画像 public int recoveryTimePerStamina ; // 1スタミナ回復するのに必要な時間[秒] public int maxStaminaValue; // スタミナの上限数 public int nowStaminaValue; // 現在のスタミナ数 private int restStaminaTime; // スタミナが1回復するまでの残り時間 //テストコード public int spendStaminaValue; //スタミナの消費量 public Text staminaspend; //スタミナ消費テキスト public Text staminarecover_all; //全回復テキスト void Start () { AwakeStaminaDefine(); StaminaDecrease(); } void Update(){ updateData (); updateStamina(); } void StaminaDecrease(){ //1秒ごとのインヴォークで、残り時間から1ずつ引いていく。 this.restStaminaTime -= 1; Invoke ("StaminaDecrease", 1); } void updateStamina(){ // テストコード staminaspend.text = "スタミナ消費" + spendStaminaValue; staminarecover_all.text = "スタミナ全回復"; //スタミナゲージの減り具合 staminaBar.fillAmount = fillAmount; fillAmount = (float)nowStaminaValue / (float)maxStaminaValue; // スタミナ回復残り時間を分と秒で表示するための変数 int minutes = this.restStaminaTime / 60; int seconds = this.restStaminaTime % 60; // 表示するテキスト staminacounter.text = "あと" + String.Format("{0:D2}",minutes) + ":" + String.Format("{0:D2}",seconds) + " "; staminatext.text = nowStaminaValue + " / " + this.maxStaminaValue; // スタミナがマックスの場合 if(nowStaminaValue == this.maxStaminaValue) { //this.staminaMax(); staminacounter.text = "" ; this.restStaminaTime = recoveryTimePerStamina; return; } // 最後の00:00の部分は見せないため、00:00秒になったら時間をリセットする if (this.restStaminaTime == 0) { nowStaminaValue += 1; this.restStaminaTime = recoveryTimePerStamina; return; } } void updateData(){ //現在の時刻をGameInformationに記録 // 現在の時刻を取得 System.DateTime now = System.DateTime.Now; // 文字列に変換して保存 GameInformation.nowStaminaValue = this.nowStaminaValue; GameInformation.restStaminaTime = this.restStaminaTime; PlayerPrefs.SetString("lasttime", now.ToString()); PlayerPrefs.SetInt ("NSV",GameInformation.nowStaminaValue); PlayerPrefs.SetInt ("RST",GameInformation.restStaminaTime); } // スタミナ消費 // スタミナが足りない場合はfalseを返す public void staminacomponent(){ this.spendStamina(spendStaminaValue); } public bool spendStamina(int spendStaminaValue) { bool isSuccess = false; if (nowStaminaValue < spendStaminaValue) { Debug.Log("スタミナが足りません"); return isSuccess; }else{ nowStaminaValue -= spendStaminaValue; } isSuccess = true; return isSuccess; } //起動時の処理 public void AwakeStaminaDefine() { //PlayerPrefsからセーブ時のデータを取得 // 初回起動時は取得できないので代わりに後ろの代数をいれる this.nowStaminaValue = PlayerPrefs.GetInt ("NSV", this.maxStaminaValue); this.restStaminaTime = PlayerPrefs.GetInt ("RST", this.recoveryTimePerStamina); string timestring = PlayerPrefs.GetString ("lasttime", System.DateTime.Now.ToString ()); // 保存しておいた時刻は文字列なので時刻(DateTime)に変換 System.DateTime datetime = System.DateTime.Parse (timestring); // 現在の時刻-保存しておいた時刻で経過時間を求める System.TimeSpan span = System.DateTime.Now - datetime; // 経過時間を秒で取得 double spantime = span.TotalSeconds; // 差分時間によって回復できるスタミナ数と、その余りの時間 int recoveryStaminaNum = (int)spantime / recoveryTimePerStamina; int resttime = (int)spantime % recoveryTimePerStamina; //スタミナ数を加算 nowStaminaValue += recoveryStaminaNum; // スタミナが1回復するまでの残り時間を余りの時間で引く // 残り時間より余りの時間のほうが大きかった場合、マイナスになってしまうので、繰り上げる if (this.restStaminaTime >= resttime) { this.restStaminaTime -= resttime; } else { this.restStaminaTime = recoveryTimePerStamina + this.restStaminaTime - resttime; } // スタミナ上限値よりも超えた場合はマックスにする。余りの時間も0にする if (this.maxStaminaValue < nowStaminaValue) { nowStaminaValue = this.maxStaminaValue; resttime = 0; } } // スタミナを全回復 public void recoverMax() { nowStaminaValue = this.maxStaminaValue; this.restStaminaTime = this.recoveryTimePerStamina; } }

【各コードの説明】

スクリーンショット 2015-05-31 15.45.43.png

数値の定義。大雑把にこんな感じでいいと思います。もっといろんな項目を増やしたければ、

各自増やしてください。

スクリーンショット 2015-05-31 15.47.38.png

最初の実行関数と、常に実行する関数

AwakeStaminaDefineは、起動時に保存しておいた時間データを読み取り、現実時間と現在のスタミナゲージとをリンクさせるための関数です。

スクリーンショット 2015-05-31 15.52.07.png

StaminaDecreaseは、インヴォークを使って、現実時間1秒ごとに残り時間を1ずつ引いています。1引く関数を1秒ごとに呼びだすことで、擬似的にタイマー的な役割をもたせています。

Updateで、Time.deltatime使えばよくね?と言われてしまうかもですが、それだとintでは残り時間を減らすことはできません。1以下の数値は全て0として扱われてしまうので。doubleで全数値を扱えばいいのかもしれませんが、管理がめんどくさいので、インヴォークで済ませてしまっています。もちろん一部doubleも使っています。

スクリーンショット 2015-05-31 15.55.19.png

updateDataで、現在の情報を記録しつづけています。

スクリーンショット 2015-05-31 16.01.47.png

GameInformation(別のスクリプト)では、各数値をstaticで保存しつづけています。ドントデストロイ関数で壊れないようにしておけば、いつでも保存していた数値を取り出せます

スクリーンショット 2015-05-31 16.03.59.png

updateStaminaで、スタミナの総合管理をしています。

前回fillAmount値を使ったゲージの実装を紹介しましたが、一つ注意です。

int値を使ったデータ管理をしている場合は、一時的に(float)をつけないと、0 or 1 の極端なゲージになってしまいます。1以下は全て0なので。

スクリーンショット 2015-05-31 16.09.54.png

あとはテスト用に、スタミナを直接動かせるボタンを用意しました。これは別になくてもいいです。あとでスタミナを動かしたいスクリプトに貼り付けてください。

スクリーンショット 2015-05-31 16.13.03.png

まあざっとこんな感じですね。 一回フォーマットを作っておけば、いろんなところで使えそうです。

では。


 
 
 

Comentarios


  • Facebook Black Round
  • Google+ Black Round
  • Twitter Black Round
bottom of page