![見出し画像](https://assets.st-note.com/production/uploads/images/151308928/rectangle_large_type_2_b00f3b1bae55b1835a8408d92b246e68.png?width=1200)
【Unity】「魔理沙の本返し」のScript公開
unityroomで不定期に開催されているunity1week(Unity1週間ゲームジャム)に参加しました。今回で9回連続9回目になります。今回の期間は2024年8月12日から8月18日までで、テーマは「かえす」でした。
この記事では、このゲームの根幹をなすスクリプト4つを紹介します。途中から有償といたします。
1.GameManager
少し失敗したかもしれません。
StageMangerに機能をつけすぎて、GameManagerがスッカラカンになってしまいました。
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
// GameManagerのシングルトンインスタンス。どのシーンからでもアクセス可能。
public static GameManager instance;
// プレイヤーのスタミナを表示するUIのスライダー
private Slider staminaSlider;
// ゲーム内で使用するオーディオクリップ
public AudioClip booksetSound; // 本をセットする音
public AudioClip goalSound; // ゴールしたときの音
public AudioClip bgm; // ゲーム中に再生するBGM
// シングルトンパターンを実装するためのAwakeメソッド
private void Awake() {
if (instance == null) {
// インスタンスが存在しない場合、このオブジェクトをインスタンスとして設定
instance = this;
// DontDestroyOnLoad(gameObject); // シーンを切り替えてもGameManagerを破棄しない(コメントアウトされている)
} else {
// すでにインスタンスが存在する場合、このオブジェクトを破棄
Destroy(gameObject);
}
}
// ゲーム開始時に呼び出されるStartメソッド
public void Start()
{
// ゲームの時間を通常速度にリセット
Time.timeScale = 1;
// 現在再生中のBGMを停止
SoundManager.i.StopBgm();
// "Stamina"タグが付いているオブジェクトからSliderコンポーネントを取得
// スタミナバーが存在する場合、そのコンポーネントを取得
if (GameObject.FindGameObjectWithTag("Stamina") != null)
{
staminaSlider = GameObject.FindGameObjectWithTag("Stamina").GetComponent<Slider>();
}
else
{
// スタミナバーがない場合、通常はタイトル画面やステージセレクト画面のため、BGMを再生
SoundManager.i.PlayBgm(bgm);
}
}
// プレイヤーのスタミナUIを更新するメソッド
// currentStamina: 現在のスタミナ値
// totalStamina: スタミナの最大値
public void UpdateStaminaUI(float currentStamina, float totalStamina)
{
if (staminaSlider != null)
{
// スライダーの最大値を設定
staminaSlider.maxValue = totalStamina;
// スライダーの現在の値を設定
staminaSlider.value = currentStamina;
}
}
// 指定されたステージをロードするメソッド
// stageName: ロードするステージのシーン名
public void LoadStage(string stageName) {
SceneManager.LoadScene(stageName); // 指定されたシーンをロード
}
// タイマーを停止するメソッド
public void StopTimer()
{
// 現在のシーン内でStageManagerコンポーネントを持つオブジェクトを検索
StageManager stageManager = FindObjectOfType<StageManager>();
if (stageManager != null)
{
// タイマーを停止
stageManager.isTimerRunning = false;
}
}
// ゲームオーバー時の処理を行うメソッド
public void GameOver()
{
// ここにゲームオーバー時の具体的な処理を追加
Debug.Log("Game Over"); // デバッグ用にログを出力
}
}
2.StageManger
ステージ毎に配置します。
ステージ毎のチェックポイント(本返却ポイント)などを管理します。
using System;
using UnityEngine;
using TMPro;
using System.Collections.Generic;
using UnityEngine.Playables;
using unityroom.Api; // UnityRoomのAPIを使用するための名前空間
public class StageManager : MonoBehaviour
{
[SerializeField]
private MarisaController player; // プレイヤーキャラクターのスクリプト参照
// UI要素の参照
[SerializeField]
private TextMeshProUGUI stageNameText; // ステージ名を表示するテキスト
[SerializeField]
private TextMeshProUGUI checkpointText; // チェックポイント数を表示するテキスト
[SerializeField]
private TextMeshProUGUI timeText; // 経過時間を表示するテキスト
[SerializeField]
private TextMeshProUGUI bestTimeText; // ベストタイムを表示するテキスト
[SerializeField]
public int stageNumber; // ステージ番号を保持するフィールド
[SerializeField]
private List<Transform> checkpoints; // チェックポイントのリスト
[SerializeField]
private AudioClip stageBgm; // ステージBGM
// ステージクリアに関連する設定
[Header("Stage Clear Settings")]
[SerializeField] private PlayableDirector stageClearTimeline; // ステージクリアのタイムライン
private bool allCheckpointsPassed = false; // 全てのチェックポイントに接触したかのフラグ
private int totalCheckpoints; // チェックポイントの総数
private int passedCheckpoints; // 通過したチェックポイント数
[NonSerialized] public float elapsedTime; // 経過時間を保持するフィールド
[NonSerialized] public bool isTimerRunning; // タイマーが動作しているかどうかを管理するフラグ
[SerializeField] private PlayableDirector CountDownTimeline; // カウントダウン用のタイムライン
// ベストタイムに関連する設定
[NonSerialized] public float bestTime; // ステージのベストタイム
public GameObject bestTimeUpdateText; // ベストタイム更新時に表示するテキスト
public TextMeshProUGUI clearTimeText; // ステージクリア後のタイムを表示するテキスト
// サウンド関連の設定
[SerializeField] AudioClip ClearSound; // ステージクリア時のSE
[SerializeField] AudioClip GameOverSound; // ゲームオーバー時のSE
[SerializeField] AudioClip CountDownSound; // カウントダウン時のSE
private void Start() {
// EasySaveを使用してステージのベストタイムを取得
bestTime = ES3.Load<float>("BestTime" + stageNumber, 9999.99f);
bestTimeText.text = string.Format("{0:0000.00}", bestTime); // ベストタイムをテキストに表示
// チェックポイントの総数と経過時間を初期化
totalCheckpoints = checkpoints.Count;
passedCheckpoints = 0;
elapsedTime = 0f;
// 各種UIの初期表示を更新
UpdateStageNameText(); // ステージ名を表示
UpdateCheckpointText(); // チェックポイント情報を表示
UpdateTimerText(); // 経過時間を表示
}
// ステージ開始時に呼び出されるメソッド
public void StageStart() {
isTimerRunning = true; // タイマーを開始
player.isGameStarted = true; // プレイヤーにゲーム開始を通知
SoundManager.i.PlayBgm(stageBgm); // ステージBGMを再生
}
// カウントダウン開始時に呼び出されるメソッド
public void CountdownStart() {
// カウントダウン用のタイムラインが設定されている場合、それを再生
if (CountDownTimeline != null)
{
CountDownTimeline.Play();
}
}
private void Update() {
// タイマーが動作中の場合のみ経過時間を更新
if (isTimerRunning)
{
elapsedTime += Time.deltaTime;
UpdateTimerText(); // 経過時間のUIを更新
}
}
// チェックポイントを通過した際に呼び出されるメソッド
public void CheckpointPassed(Transform checkpoint) {
if (checkpoints.Contains(checkpoint)) {
passedCheckpoints++; // 通過チェックポイント数を増加
checkpoints.Remove(checkpoint); // チェックポイントリストから削除
UpdateCheckpointText(); // チェックポイント数をUIに更新
}
}
// ステージ名のテキストを更新するメソッド
private void UpdateStageNameText() {
stageNameText.text = "Stage " + stageNumber; // ステージ名を表示
}
// チェックポイント数のテキストを更新するメソッド
private void UpdateCheckpointText() {
checkpointText.text = string.Format("{0}/{1}", passedCheckpoints, totalCheckpoints);
}
// 経過時間のテキストを更新するメソッド
private void UpdateTimerText() {
// 経過時間を4桁の少数点2桁で表示
timeText.text = string.Format("{0:0000.00}", elapsedTime);
}
// ステージクリア時に呼び出されるメソッド
private void StageClear() {
Debug.Log("Stage Cleared!");
// プレイヤーのアニメーションをidleDownに変更
player.animancer.Play(player.idleDown);
// ゴールのSEを再生
SoundManager.i.PlaySe(GameManager.instance.goalSound);
// 経過時間がベストタイムより短い場合、ベストタイムを更新
if (elapsedTime < bestTime) {
bestTime = elapsedTime; // ベストタイムを更新
ES3.Save<float>("BestTime" + stageNumber, bestTime); // ベストタイムを保存
bestTimeUpdateText.SetActive(true); // ベストタイム更新メッセージを表示
}
// クリアタイムをUIに表示
clearTimeText.text = string.Format("今回のタイム:"+"{0:F2}"+"秒", elapsedTime);
player.stageClear = true; // プレイヤーのstageClearフラグをtrueに設定
// スコアをUnityroomのAPIに送信
UnityroomApiClient.Instance.SendScore(stageNumber, elapsedTime, ScoreboardWriteMode.Always);
// すべての敵キャラクターにゲームオーバー処理を実行
EnemyController[] enemies = FindObjectsOfType<EnemyController>();
foreach (EnemyController enemy in enemies)
{
enemy.HandleGameOver(); // ゲームオーバー時の処理を実行
}
// タイマーを停止
isTimerRunning = false;
SoundManager.i.StopBgm(); // BGMを停止
// ステージクリア用のタイムラインを再生
if (stageClearTimeline != null)
{
stageClearTimeline.Play();
}
}
// チェックポイント通過時の処理
public void CheckpointPassed()
{
passedCheckpoints++; // 通過チェックポイント数を増加
SoundManager.i.PlaySe(GameManager.instance.booksetSound); // チェックポイント通過音を再生
UpdateCheckpointText(); // チェックポイント数をUIに更新
// すべてのチェックポイントを通過した場合、クリアの準備を行う
if (passedCheckpoints >= totalCheckpoints)
{
allCheckpointsPassed = true;
Debug.Log("All checkpoints passed. Return to the start to finish the stage.");
}
}
// ゴールに到達した際の処理
public void GoalReached()
{
// すべてのチェックポイントを通過している場合、ステージクリア処理を行う
if (allCheckpointsPassed)
{
StageClear(); // ステージクリア処理を呼び出す
}
else
{
Debug.Log("You must pass all checkpoints before returning to the start!"); // チェックポイントを通過していない場合、メッセージを表示
}
}
// ステージクリア時のサウンド再生
public void ClearSoundPlay()
{
SoundManager.i.PlaySe(ClearSound);
}
// ゲームオーバー時のサウンド再生
public void GameOverSoundPlay()
{
SoundManager.i.PlaySe(GameOverSound);
}
// カウントダウン時のサウンド再生
public void CountDownSoundPlay()
{
SoundManager.i.PlaySe(CountDownSound);
}
}
3.MarisaController
プレイヤーである魔理沙を動かすスクリプトです。
AnimancerProが必須です。
Playerタグをつける必要があります。
ここから先は
21,320字
/
2画像
¥ 100
この記事が気に入ったらサポートをしてみませんか?