画面、パネル、そして GameManager
Assets/
Scenes/
Arena.unity
Scripts/
Audio/
すでにあるものこのレッスンで追加
どんなゲームにも、世界の一部ではないオブジェクトがひとつあります。あなたが見ているものと、スピーカーから出てくるものを決める存在です。それを書く前に、二つの言葉をもう混同しないでください——Unity ではまったく別のものなので。
Screen と panel は別の言葉
✓ Screen
SceneManager.LoadScene("Arena")
.unity ファイルを持ちます。読み込むと今のシーンの中身はすべて破棄され、新しいシーンをディスクから組み立てます。まっさらにやり直したいときに使う方法です。✓ Panel
pausePanel.SetActive(true)
場所も世界も違う → screen。イントロはアリーナではないので、専用のシーンファイルを持ちます。
同じ場所で、何かを上に乗せる → panel。一時停止はアリーナの中で起きることなので、アリーナの中の GameObject です。
シーン切り替えをまたいで何かを残しておくのに DontDestroyOnLoad が必要なら、ほぼ確実にあなたが必要としていたのは panel です。
screen は二つ、それぞれがシーンファイル。panel は二つで、どちらも二つ目のシーンの中に住んでいます。下のアリーナは動きません。
ステップ 1 — イントロの screen、専用のシーン
全コースを通じて、二つ目のシーンを作る価値がある唯一の場所です。イントロには床もキャラも物理もないので、一瞬で読み込まれ、離れた瞬間に残しておくものは何ひとつありません。
- 1
→ Basic (URP) を選び、続けて → Assets/Scenes/Intro.unity。
- 2
を追加し、ゲーム名を書いた Text と、PLAY と表記した を置きます。
- 3
空のオブジェクトに Intro と名前を付け、IntroScreen.cs をアタッチし、ボタンの On Click () を LoadArena に向けます。
using UnityEngine;
using UnityEngine.SceneManagement;
public class IntroScreen : MonoBehaviour
{
public void LoadArena()
{
SceneManager.LoadScene("Arena");
}
}ステップ 2 — アリーナ全体から見える manager
Arena.unity に戻ります。ボタンは manager に一時停止を伝え、Knight に付けたスクリプトは攻撃が当たった音を出したい、となります。どちらも manager を持ってはいません。使うたびに FindObjectOfType で探しに行くのは遅いし間違いやすい。static フィールドひとつで片付きます。
using UnityEngine;
using UnityEngine.SceneManagement;
// Panels, not screens: both of these live inside Arena.unity.
public enum GamePanel { Hud, Pause }
public class GameManager : MonoBehaviour
{
// The whole arena reaches the manager through this one field.
public static GameManager I;
void Awake()
{
I = this;
}
}ステップ 3 — アリーナの中の二つの panel
- 1
。Unity がその隣に EventSystem を自動で追加します——触らないでください。ボタンがクリックできるのはこれのおかげです。
- 2
Canvas の中に空のオブジェクトを二つ作ります:HudPanel と PausePanel。どちらもただの入れ物です。
- 3
HudPanel には再生中に見せたいものを入れます——0 と書かれた Text で十分です。PausePanel には全屏の暗い Image、PAUSED の文字、RESUME ボタン、MENU ボタンを入れます。
[Header("Panels")]
public GameObject hudPanel;
public GameObject pausePanel;
public GamePanel current { get; private set; }
void Start()
{
ShowPanel(GamePanel.Hud); // the arena starts playable
}
public void ShowPanel(GamePanel next)
{
current = next;
hudPanel.SetActive(next == GamePanel.Hud);
pausePanel.SetActive(next == GamePanel.Pause);
// A pause panel that does not stop time is just a picture.
Time.timeScale = next == GamePanel.Pause ? 0f : 1f;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
ShowPanel(current == GamePanel.Pause ? GamePanel.Hud : GamePanel.Pause);
}
// Leaving the arena is a screen change, so it goes through SceneManager.
public void BackToIntro()
{
Time.timeScale = 1f;
SceneManager.LoadScene("Intro");
}panel につき一行、比較が判定してくれます。三つ目の panel を足すときも一行追加するだけで、if の連鎖をもう一つ書く必要はありません。
SetActive(false) はその panel の Update も止めるので、隠れている panel にフレームごとのコストはかかりません。
RESUME ボタンは
ShowPanelに、MENU ボタンはBackToIntroに向けます。片方は panel の切り替え、もう片方は screen の読み込み——同じメニューの中の、まったく違う二種類の移動です。
ステップ 4 — ループする音楽、しないクリック音
同じ GameManager オブジェクトに AudioSource を二つ置きます。片方は Loop にチェックを入れて音楽を鳴らし、もう片方は何も持たず、必要なときに一度だけ音を発します。
[Header("Sound")]
public AudioSource musicSource; // tick Loop on this one
public AudioSource sfxSource;
public AudioClip arenaMusic;
public AudioClip clickClip;
public void PlayMusic(AudioClip track)
{
// Asking for the track that is already playing must not restart it.
if (musicSource.clip == track && musicSource.isPlaying) return;
musicSource.clip = track;
musicSource.Play();
}
public void PlaySfx(AudioClip clip)
{
if (clip != null) sfxSource.PlayOneShot(clip);
}音が実際に出ていく場所
AudioListener は耳の役割で、シーンに必ず一つあるべきものです。レッスン 06 で Unity が Main Camera に関連付けました——そのままにして、Intro.unity にも自分専用の AudioListener があることを覚えておいてください。
音楽は screen の切り替えを生き残りません。Intro を読み込むとアリーナの AudioSource はシーンのほかのすべてと一緒に破棄されます。これが screen の代償であり、安易に作らない理由です。
clip は Assets/Audio に入れます——レッスン 05 で作ったフォルダです。音楽は .ogg、短い効果音は .wav。
両方の source で Play On Awake のチェックを外してください。音がいつ始まるかを決めるのは Inspector ではなく manager です。
ステップ 5 — つなぎ込む
- 1
GameManager を選んで を二つ追加します。一つ目に Loop をチェックし、両方の Play On Awake のチェックを外してください。
- 2
Inspector で HudPanel と PausePanel をそれぞれのスロットに、二つの Audio Source を Music Source と Sfx Source に、音声を Arena Music と Click Clip にドラッグします。
- 3
ShowPanel の直後、Start() に
PlayMusic(arenaMusic);を追加します。アリーナが開いた時点で音楽がもう鳴っている状態になります。 - 4
アリーナからではなく、Intro.unity を開いてそこから Play を押してください。プレイヤーが出会う順番はその通りで、Build Settings のリストが壊れているのに気づける唯一の方法でもあります。
- ✓Intro.unity から再生し、PLAY で音楽の鳴っているアリーナに移る。
- ✓Escape で PausePanel が出て Knight が動きを止め、もう一度 Escape で再開する。
- ✓panel を切り替えている間、床・ブロック・三人のキャラは一切動かない。
- ✓MENU でイントロに戻り、着いた先のイントロが固まっていない。