0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity初心者】Unityでネットゲームを作りたい【10】UIのスライダーを使ったスタミナ表示~とりあえずメイン画面に物を置いてみた

Last updated at Posted at 2025-01-21

UIのスライダーを使ったスタミナ表示

前に気になってコピペしたけど使えなかったヤツ
今なら理解できるかと再挑戦しました
Unityでスマホゲームによくあるスタミナ機能を作るこちらを参照
こんなん出来たらいいよね~
で、コピペ

StaminaController.cs

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

/// <summary>
/// 最近のスマホゲームによくある「スタミナ」を扱うクラス
/// </summary>
public class StaminaController : MonoBehaviour
{

    // UIに表示する場合はInspectorから以下を設定してあげる
    [SerializeField]
    private Text staminaNumText; // スタミナの値を表示するテキスト

    [SerializeField]
    private Text restStaminaTimeText; // スタミナが1回復するまでの残り時間を表示するテキスト

   [SerializeField]
    private Slider staminaBarSlider; // スタミナの割合を表示するバー

    private bool isInitializeFinished = false;
    private int nowStaminaNum;
    private int maxStaminaNum;
    private DateTime recoveryStartTime;
    private int recoverTimePerStamina;

    void Start()
    {
        // テスト -> [現在のスタミナ30、スタミナ最大50、現在時刻から回復開始、300秒(5分)で1回復する] で初期化する
        // 使うときにゲームを管理しているクラスとかからプレイヤーのスタミナと回復開始時刻と1回復する秒数を渡してあげる感じ
        Init(100, 100, DateTime.Now, 300);
    }

    void Update()
    {
        if (isInitializeFinished)
        {
            UpdateStamina();
            UpdateStaminaBar();
        }
    }

    /// <summary>
    /// 使うときはこの初期化を呼び出す
    /// </summary>
    /// <param name="nowStaminaNum">スタミナ現在値</param>
    /// <param name="maxStaminaNum">スタミナ最大値</param>
    /// <param name="recoveryStartTime">スタミナ回復を開始した時間</param>
    /// <param name="recoverTimePerStamina">スタミナを1回復する時間(秒)</param>
    public void Init(int nowStaminaNum, int maxStaminaNum, DateTime recoveryStartTime, int recoverTimePerStamina)
    {
        this.nowStaminaNum = nowStaminaNum;
        this.maxStaminaNum = maxStaminaNum;
        this.recoveryStartTime = recoveryStartTime;
        this.recoverTimePerStamina = recoverTimePerStamina;

        Debug.Log("スタミナ " + this.nowStaminaNum + " / " + this.maxStaminaNum
                  + " スタミナが最大値未満になった時間:" + this.recoveryStartTime);

        isInitializeFinished = true;
    }

    /// <summary>
    /// 現在の日時を取得する
    /// </summary>
    /// <returns>現在の日時を返す</returns>
    private DateTime GetTimeNow()
    {
        return DateTime.Now; // ゲームを管理しているクラスとかからサーバ時間を渡してあげるようにしたい
    }

    /// <summary>
    /// スタミナが最大値以上かどうか
    /// </summary>
    /// <returns><c>true</c>最大以上である <c>false</c>最大ではない</returns>
    public bool IsStaminaFull()
    {
        return nowStaminaNum >= maxStaminaNum;
    }

    /// <summary>
    /// スタミナの更新
    /// </summary>
    private void UpdateStamina()
    {
        // スタミナが最大以上の場合は表示更新のみ
        if (IsStaminaFull())
        {
            if (staminaNumText != null) staminaNumText.text = "" + nowStaminaNum + " / " + maxStaminaNum;
            if (restStaminaTimeText != null) restStaminaTimeText.text = "MAX";

            return;
        }

        DateTime time = GetTimeNow();
        TimeSpan diff = time - recoveryStartTime;
        double totalSeconds = diff.TotalSeconds;

        // 経過時間分のスタミナを回復させる
        while (totalSeconds > recoverTimePerStamina)
        {
            if (IsStaminaFull()) break;

            totalSeconds -= recoverTimePerStamina;
            recoveryStartTime = recoveryStartTime.Add(TimeSpan.FromSeconds(recoverTimePerStamina));
            nowStaminaNum++;
        }

        double restTime = recoverTimePerStamina - totalSeconds + 1; // 「+1」->00:00を見せないため
        int minutes = (int)restTime / 60;
        int seconds = (int)restTime % 60;

        if (staminaNumText != null) staminaNumText.text = "" + nowStaminaNum + " / " + maxStaminaNum;
        if (restStaminaTimeText != null) restStaminaTimeText.text = ""
              + string.Format("{0:D2}", minutes) + ":" + string.Format("{0:D2}", seconds);
    }

    /// <summary>
    /// スタミナバーの表示更新
    /// </summary>
    private void UpdateStaminaBar()
    {
        if (staminaBarSlider != null)
        {
            // スタミナの現在値と最大値の割合をスタミナバーに反映する
            // バーは最大値を超えない
            float staminaPercentage = (float)nowStaminaNum / (float)maxStaminaNum;
            if (staminaPercentage >= 1) staminaPercentage = 1;
            staminaBarSlider.value = staminaPercentage;
        }
    }

    /// <summary>
    /// スタミナを消費する
    /// </summary>
    /// <returns><c>true</c>スタミナを消費した <c>false</c>スタミナが不足している</returns>
    /// <param name="spendStaminaNum">消費するスタミナ値</param>
    public bool SpendStamina(int spendStaminaNum)
    {
        if (nowStaminaNum < spendStaminaNum) return false;

        // スタミナ消費後の値がスタミナ最大値を下回った際に時間を保存する(回復開始となる時間)
        if (nowStaminaNum >= maxStaminaNum && (nowStaminaNum - spendStaminaNum) < maxStaminaNum)
        {
            recoveryStartTime = GetTimeNow();

            // ゲームを管理しているクラスとかで回復開始となる時間を保存しておく
            //SystemManager systemManager = GameObject.Find("SystemManager").GetComponent<SystemManager>();
            //systemManager.SaveTimeStamp(recoveryStartTime);
        }

        nowStaminaNum -= spendStaminaNum;

        return true;
    }

    /// <summary>
    /// スタミナを回復する
    /// </summary>
    /// <param name="num">回復する値</param>
    public void RecoverStamina(int num)
    {
        if (IsStaminaFull()) return;
        nowStaminaNum += num;
        if (nowStaminaNum > maxStaminaNum) nowStaminaNum = maxStaminaNum;
    }

    /// <summary>
    /// スタミナを最大値を無視して回復する
    /// </summary>
    /// <param name="num">回復する値</param>
    public void RecoverStaminaOverLimit(int num)
    {
        nowStaminaNum += num;
    }

    /// <summary>
    /// 最大値までスタミナを回復させる
    /// </summary>
    public void RecoverStaminaMax()
    {
        if (IsStaminaFull()) return;
        nowStaminaNum = maxStaminaNum;
    }

    /// <summary>
    /// 最大値分のスタミナを回復させる
    /// </summary>
    public void RecoverStaminaMaxOverLimit()
    {
        nowStaminaNum += maxStaminaNum;
    }
}

これ書いただけじゃそりゃ動かない
ちょっと前の私...

ふむふむ...
とりあえず

    // UIに表示する場合はInspectorから以下を設定してあげる
    [SerializeField]
    private Text staminaNumText; // スタミナの値を表示するテキスト

    [SerializeField]
    private Text restStaminaTimeText; // スタミナが1回復するまでの残り時間を表示するテキスト

   [SerializeField]
    private Slider staminaBarSlider; // スタミナの割合を表示するバー

とあるので、Text2つとスライダーを配置して同じ名前に変更

image.png
image.png
こんなのが出来た

image.png
これが持って移動できるやつらしいが今回は要らないので削除
【UnityC#講座】SliderでHPバーを作るこちらを参照して各数字を変更

んでテキストに
image.png
わかりやすいようにもう30/100って書いちゃう
んで、StaminabarSliderと名前の付けたスライダーにテキスト2つとスライダーを名前に合うように放り込む
image.png


image.png
できた~UIと対応させるのを色々やってきた成果かな?理解できた!チョイトウレシイ

時間をサーバー(PlayFab)から持ってきた値とかにすれば、管理しやすくなるかな
今後これをいじって行きたい
初期値は10000とかにして、新規の人はいっぱい行動できるようにしたいしね

対戦時のHP表示にも使えるみたいだから、今後に期待


スクリーンの移動

やっぱスクリーン移動時にいろいろ消えてる
image.png
image.png
でもメインの画面に使ったname表示がそのまま使えた!!
てことは、Json読み込んだのもそのま画面(シーン)が変わっても引き継いでいるいるみたい
これは助かる

フム...このままステータス画面作成と行ってみる


とりあえずメイン画面に物を置いてみた

【Unity入門】60分で作るシューティングゲーム 第3回こちらを参考に画像を切り取って設置してみた(ver6だとだいぶ操作違います)

....
image.png
こりゃ違和感ありすぎ
考えなきゃ(-_-;)

←前 【Unity初心者】Unityでネットゲームを作りたい【9】スクリプトの順番~苦手なレイアウトとか

 次→

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?