床の上でキャラクターを切り替える
Assets/
Scenes/
Arena.unity
Scripts/
Prefabs/
すでにあるものこのレッスンで追加
ここが Tab 01 の節目です。平らな床、その上に立つ三人のキャラクター、そして 1 / 2 / 3 キーで操作対象を切り替えます。
同時にアクティブなのは一人だけで、残りは床に立ったまま待機します。
ステップ 1 — 仮のキャラクターを三人
- 1
を作り、Knight と名付けて Position を 0、1、0 にします。
- 2
既定の Capsule は高さ 2 m でピボットが中心なので、Y = 1 にすれば足がちょうど床に着きます。
- 3
二回複製して(Ctrl/Cmd + D)→ Mage を -3、1、0、Archer を 3、1、0 に置きます。
- 4
それぞれに色付きの material を当てます:緑、紫、琥珀。これで一目で誰だか分かります。
- 5
Characters という空の GameObject を作り、三人まとめてその中にドラッグします。
ステップ 2 — 全員共通の移動スクリプト
using UnityEngine;
public class SimpleMover : MonoBehaviour
{
[SerializeField] private float speed = 6f;
[SerializeField] private float turnSpeed = 12f;
void Update()
{
// -1 .. 1 from A/D and W/S
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
Vector3 dir = new Vector3(h, 0f, v);
if (dir.sqrMagnitude < 0.01f) return; // no input, nothing to do
dir.Normalize(); // diagonal is not faster
transform.position += dir * speed * Time.deltaTime;
// face the direction of travel
Quaternion target = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, target, turnSpeed * Time.deltaTime);
}
}GetAxisRaw は -1、0、1 を即座に返します。GetAxis は数フレームかけてならしますが、ここは raw の方が反応が鋭く感じます。
sqrMagnitude は平方根を取らない大きさです。計算が安く、ここでは閾値と比較するだけで済みます。
Slerp は毎フレームわずかな分だけ回すので、一瞬で向きを変えるのではなく滑らかな旋回に見えます。
ステップ 3 — 切り替え役
コツはシンプルです。リストを持って一つを有効にし、残りを無効にするだけ。オブジェクト全体ではなく SimpleMover を無効にすれば、キャラクターは全員床に見えるまま残ります。
using System.Collections.Generic;
using UnityEngine;
public class CharacterSwitcher : MonoBehaviour
{
[SerializeField] private List<SimpleMover> characters = new List<SimpleMover>();
[SerializeField] private Transform highlightRing; // optional marker
private int activeIndex = 0;
void Start()
{
Select(0);
}
void Update()
{
// number keys 1..9
for (int i = 0; i < characters.Count && i < 9; i++)
if (Input.GetKeyDown(KeyCode.Alpha1 + i))
Select(i);
// Tab cycles to the next one
if (Input.GetKeyDown(KeyCode.Tab))
Select((activeIndex + 1) % characters.Count);
}
public void Select(int index)
{
if (index < 0 || index >= characters.Count) return;
activeIndex = index;
for (int i = 0; i < characters.Count; i++)
characters[i].enabled = (i == index); // only one may move
if (highlightRing != null)
highlightRing.SetParent(characters[index].transform, false);
Debug.Log("Now controlling: " + characters[index].name);
}
public Transform ActiveCharacter => characters[activeIndex].transform;
}- 1
GameManager という空の GameObject を作って CharacterSwitcher をアタッチします。
- 2
Inspector で Characters のサイズを 3 にし、Knight、Mage、Archer を各スロットへドラッグします。
- 3
潰した cylinder(scale 1.2、0.02、1.2)を Highlight Ring に入れておくと、誰が選ばれているか一目で分かります。
- 4
Play を押したら、WASD で移動、1 2 3 または Tab で切り替えてください。
なぜ GameObject ではなくスクリプトを無効にするのか?
✓ characters[i].enabled = false
✖ SetActive(false)
ステップ 4 — アクティブなキャラクターをカメラに追従させる
using UnityEngine;
public class SwapCamera : MonoBehaviour
{
[SerializeField] private CharacterSwitcher switcher;
[SerializeField] private Vector3 offset = new Vector3(0f, 12f, -14f);
[SerializeField] private float smooth = 4f;
void LateUpdate() // after everyone has moved
{
Transform target = switcher.ActiveCharacter;
Vector3 wanted = target.position + offset;
transform.position = Vector3.Lerp(transform.position, wanted, smooth * Time.deltaTime);
transform.LookAt(target.position + Vector3.up);
}
}いまのリングにできること
平らな床、material、カメラ、ライトを備えた 3D シーン。
手でもループでも量産できるブロックの prefab。
同じ床にいる複数のキャラクターと、その間を行き来する操作権。
次のレッスンではこの上にメニューと音楽をのせますが、中身には触りません。
Tab 02 では Knight をその場で進化させます—— GameObject も名前も switcher のスロットもそのままで、モデル・アニメーション・スキル・artifact を備えた本物のキャラクターにします。Mage と Archer は capsule のまま残すので、違いがはっきり分かります。