TapTapTap!!!(12)~ライフ管理機能を追加する~

TapTapTap!!!(11)~Unity の Ads 機能を使用する~ではUnity 上に広告を出すことができるというのを知ったので、 TapTapTap!!! に広告を追加してみた。今回はソーシャルゲームでよく見かけるライフ管理機能を実装する。
今回はやることが多いので予め完成のイメージ図を以下に示す。

1.テキストオブジェクトを作成する
「ライフ管理完成イメージ」の丈夫にある「Life」と「00:00」のテキストオブジェクトを作成し、任意の位置に配置する。テキストオブジェクトの作成方法についてはTapTapTap!!!(5)~ボタン出現時に文字を表示する~で行っているためここでは省略する。
2.ライフゲージを作成する
今回、ライフゲージは Sphere で作成した。Sphere の作成方法は [GameObject] > [3D Object] > [Sphere] から配置する。これらを今回は5つ作成し、プレイできるライフは赤にプレイできないときのライフは灰色で示していきたいと思う。

そのままSphereを配置すると黒っぽく配置されると思うのでこの Sphere に対してMaterial を設定して、色を変更したいと思う。
3.Material を作成する
まずは Project タブに「Materials」という名前のフォルダを作成する。TapTapTap!!!(2)~ボタンを出現・消滅させる~で行っているのでここでは省略する。
Material を作成するためには「Materials」フォルダを右クリックし、[Create] > [Material] をクリックする。このとき名称は「ActiveLife」としておくことにする。

作成した「ActiveLife」をクリックし、[Inspector] > [Albed] の色を設定する。ここでは赤色とした。これを作成した Sphere に対してドラッグアンドドロップする。しかしながら、これだけでは赤黒い Sphere となってしまうので光源の設定を変更する。
4.光源の変更
光源の変更方法は2通りあり、任意に光源を設定しそこから光らせる方法とそもそも光源の設定をなくしてしまう方法だ。今回は後者の光源の設定をなくしてしまう方法を選択したいと思う。
光源の設定をなくす方法は [Window] > [Lighting] > [Settings] から行う。

[Settings] をクリックすると以下の画面が表示されるので[Ambient Color] の色を白に設定することで、Material で使用した色をそのまま使用できるだろう。

5.時間管理スクリプトを作成する
今回の主題の時間管理用のスクリプトを作成する。今回は新規に「LifeManager」と「LifeViewer」という名前のスクリプトファイルを作成する。スクリプトファイルの作成方法についてはTapTapTap!!!(2)~ボタンを出現・消滅させる~で行っているためここでは省略する。
「LifeManager」の処理内容は過去の保存データを読み込み、現在のライフを管理し、任意時間経過したらライフを回復し、ライフを使用したら現在ライフを減している。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 using System;
using UnityEngine;
public class LifeManager : MonoBehaviour
{
/// <summary>
/// 現在ライフ保存用のキー
/// </summary>
private static string CURRENT_LIFE = "CurrentLife";
/// <summary>
/// 最新ライフ回復時刻保存用のキー
/// </summary>
private static string LAST_RECOVERY_TIME = "RecoveryTime";
/// <summary>
/// 最大ライフ数
/// </summary>
[SerializeField]
private int MaxLife;
/// <summary>
/// 回復時間
/// </summary>
[SerializeField]
private int RecoveryTime;
/// <summary>
/// 現在のライフ
/// </summary>
public int CurrentLife { get; private set; }
/// <summary>
/// 最新ライフ回復時刻
/// </summary>
private DateTime LastRecoveryTime;
/// <summary>
/// 最新ライフ回復時刻と現在時刻の差
/// </summary>
private int DiffSeconds;
/// <summary>
/// 初期化処理。
/// 最終プレイ時のライフや回復時刻を読み込む。
/// 読み込めないときは最大ライフとする。
/// </summary>
public void Init()
{
// ライフの読み込み
if (PlayerPrefs.HasKey(CURRENT_LIFE))
{
CurrentLife = PlayerPrefs.GetInt(CURRENT_LIFE);
}
else
{
CurrentLife = MaxLife;
}
// 最新回復時刻の読み込み
DateTime NowTime = DateTime.Now;
if (PlayerPrefs.HasKey(LAST_RECOVERY_TIME))
{
string StrRecoveryTime = PlayerPrefs.GetString(LAST_RECOVERY_TIME);
LastRecoveryTime = DateTime.FromBinary(Convert.ToInt64(StrRecoveryTime));
DiffSeconds = (int)(NowTime - LastRecoveryTime).TotalSeconds;
CurrentLife += DiffSeconds / RecoveryTime;
if (RecoveryTime < DiffSeconds)
{
LastRecoveryTime = NowTime;
}
}
else
{
PlayerPrefs.SetString(LAST_RECOVERY_TIME, NowTime.ToBinary().ToString());
}
if (MaxLife < CurrentLife)
{
CurrentLife = MaxLife;
}
}
/// <summary>
/// 次の回復時刻までの時間取得
/// </summary>
/// <returns>次までの回復時間</returns>
public string GetNextTime()
{
if (MaxLife <= CurrentLife)
{
return "00:00";
}
return ((RecoveryTime- DiffSeconds) / 60) + ":" + ((RecoveryTime - DiffSeconds) % 60);
}
/// <summary>
/// ライフの使用。ゲームを開始する際にライフを使用する
/// </summary>
/// <returns>ライフが残っていれば true, 残っていなければ false</returns>
public bool UseLife()
{
if (0 < CurrentLife)
{
CurrentLife--;
PlayerPrefs.SetInt(CURRENT_LIFE, CurrentLife);
return true;
}
return false;
}
/// <summary>
/// 逐次の更新処理時間の保存やライフ回復処理を行う
/// </summary>
void Update()
{
if (MaxLife <= CurrentLife)
{
return;
}
DateTime NowTime = DateTime.Now;
DiffSeconds = (int)(NowTime - LastRecoveryTime).TotalSeconds;
if (RecoveryTime < DiffSeconds)
{
CurrentLife++;
LastRecoveryTime = NowTime;
PlayerPrefs.SetString(LAST_RECOVERY_TIME, NowTime.ToBinary().ToString());
PlayerPrefs.SetInt(CURRENT_LIFE,CurrentLife);
}
}
}
次に「LifeViewer」の処理内容は「LifeManager」の時刻と現在のライフを取得しライフ表示用のオブジェクトの色を変更する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 using UnityEngine;
using UnityEngine.UI;
public class LifeViewer : MonoBehaviour
{
/// <summary>
/// ライフ表示用オブジェクト
/// </summary>
[SerializeField]
private GameObject[] Lifes;
/// <summary>
/// 回復までの残り時間表示用テキスト
/// </summary>
[SerializeField]
private Text TimeText;
/// <summary>
/// 初期化処理。
/// LifeManager の初期化を行う。
/// </summary>
public void Init()
{
FindObjectOfType<LifeManager>().Init();
}
/// <summary>
/// 逐次更新処理。
/// LifeManager から現在の時刻とライフを取得して、ライフ表示用オブジェクトと
/// 回復までの残り時間表示用テキストを更新する。
/// </summary>
void Update()
{
TimeText.text = FindObjectOfType<LifeManager>().GetNextTime();
int CurrentLife = FindObjectOfType<LifeManager>().CurrentLife;
// 現在のライフ数に応じて、material の色を変更する。
for (int i = 0; i < CurrentLife; i++)
{
Lifes[i].GetComponent<Renderer>().material.color = Color.red;
}
for (int i = Lifes.Length - 1; CurrentLife <= i; i--)
{
Lifes[i].GetComponent<Renderer>().material.color = Color.gray;
}
}
}
作成した「LifeManager」と「LifeViewer」は「EventSystem」にドラッグアンドドロップして、各種パラメータを設定する。
6.今回作成したスクリプトを他のスクリプトに反映する
今回作成したスクリプトは「GameStart」と「MaxLevel」スクリプトに対して変更が必要となる変更内容は以下の通り。
「GameStart」に追加する処理は「LifeManager」 の UseLife を用いて、使用できるライフが残っていればそのままゲームを開始し、ライフが残っていなければそのまま何もしないというものだ。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 using UnityEngine;
using UnityEngine.SceneManagement;
public class GameStart : MonoBehaviour
{
/// <summary>
/// Game Start ボタンタップ時の処理
/// </summary>
public void OnClick()
{
if (FindObjectOfType<LifeManager>().UseLife())
{
SceneManager.LoadScene("taptaptap");
}
}
}
「GameStart」に追加する処理は「LifeViewer」の初期化処理を加える。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 using UnityEngine;
using UnityEngine.UI;
public class MaxLevel : MonoBehaviour
{
/// <summary>
/// 最高レベル表示用テキスト
/// </summary>
public Text maxLevel;
/// <summary>
/// 最高レベル用テキスト
/// </summary>
private string maxText = "最高レベル:";
/// <summary>
/// 開始処理
/// </summary>
void Start()
{
FindObjectOfType<LifeViewer>().Init();
if (PlayerPrefs.HasKey("PlayerData"))
{
int level = PlayerPrefs.GetInt("PlayerData");
maxLevel.text = maxText + level.ToString();
}
else
{
maxLevel.text = maxText + "-";
}
}
}
これで時間管理が行えるようになるはずだ。