Unity 玉転がし#01 ステージとプレイヤーを作る

チュートリアル

Unity チュートリアル 玉転がしゲーム作成の第1回目です。

今回はプレイエリアとなるステージと、ユーザーが操作するプレイヤーオブジェクトを作成します。

この工程を通して、ゲームオブジェクトの作り方、スクリプトをアタッチする方法を覚えましょう。

それでは、以下、解説。

この記事の Unity バージョンは、2019.2.5f1 です。

1.プロジェクトを作る

まずは、プロジェクトを作成しましょう。

Unity を起動したら、テンプレートは3D、プロジェクト名は「Roll-a-Ball」としてください。

2.ステージを作る

では、以下の手順に沿ってステージを作っていきます。

  1. 床を作る
    ・ヒエラルキーで Create → 3D Object → Plane を選択、名前を「Floor」とします。
  2. 壁を4つ作る
    ・Create → 3D Object  → Cube を選択、名前を「Wall」とします。
    ・Wall を選択し、Ctrl + D を押して3つコピーを作ります。
  3. 位置とサイズを設定する
    ・Floor を選択し、インスペクターで Transform の position を 0, 0, 0 にします。
    ・Wall は、以下のとおりにposition と scale を設定します。
     Wall   → position 0, 0, 10.5  scale 20, 1, 1
     Wall(1) → position 0, 0, -10.5  scale 20, 1, 1
     Wall(2) → position -10.5, 0, 0  scale 1, 1, 22
     Wall(3) → position 10.5, 0, 0  scale 1, 1, 22
  4. 床の色を変える
    ・好きな色に変更してください。

オブジェクトの色変えのやり方はこちらをどうぞ。


ねこくん
ねこくん

上のとおりに設定するとこんなかんじになるよ!

玉転がしステージ

ステージはいい感じにできましたね。では、次です。

3.プレイヤーを作る

以下、プレイヤーの作成手順です。

  1. ボールを作る
    ・ヒエラルキーでCreate → 3D Object → Sphere を選択、名前を「Player」とします。
    ・インスペクターで Transform の position を 0, 0.5, 0 にします。
  2. ボールの色を変える
    ・好きな色に変更してください。
  3. 物理シミュレーションを有効にする
    ・ヒエラルキーでPlayerを選択し、Add Component → Physics → Rigidbody を選択します。
  4. プレイヤーを操作するスクリプトを作る
    ・プロジェクトウィンドウで Create → Folder を選択、名前を「Scripts」とします。
    ・Scriptsフォルダを右クリックし、Create → C# Script を選択、名前を「Player」とします。
    ※スクリプトの名前は、作成直後に必ず設定してください。あとで変えるとエラーが発生します。
    ・ヒエラルキーでPlayerを選択し、Add Component → Scripts → Player でアタッチします。

ねこくん
ねこくん

プレイヤーのボールができたよ!

玉転がしプレイヤー

スクリプトでボールを移動させる

あとはスクリプトを編集して、ユーザー入力でボールを移動できるようにしましょう。

C# やプログラミングはよくわからないという方は、とりあえずコピペで問題ないです。

のちのち学習して理解できるようになりましょう。

では、Playerスクリプトをダブルクリックしてください。

デフォルトなら Visual Studio が立ち上がりますので、下記のように変更します。

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

public class Player : MonoBehaviour
{
	public float speed = 5.0f; // 移動速度。

	private Vector3 moveDirection = Vector3.zero; // 移動方向。

	private Rigidbody rb = null;

	private void Start()
	{
		rb = GetComponent<Rigidbody>();
	}

	private void Update()
	{
		moveDirection.x = Input.GetAxis( "Horizontal" ); // 左右のキー入力値を取得する。
		moveDirection.z = Input.GetAxis( "Vertical" );   // 上下のキー入力値を取得する。
	}

	private void FixedUpdate()
	{
		if( rb )
		{
			// Rigidbodyに力を加えて移動させる。
			rb.AddForce( moveDirection * speed, ForceMode.Force );
		}
	}
}

これで準備完了です。

見やすいようにカメラの位置を調整しましょう。

Main Camera の position を 0, 8, -6、rotation を 50, 0, 0 にします。

では、プレイボタンを押してゲームを実行してください。

キーボードの矢印キーを押して、ボールが移動するか確かめてみましょう。

ステージとボール

カメラがボールについてくるようにする

とりあえず、プレイヤーとステージはできましたね。

ただ、このままだとステージ全体が見えていないので、プレイヤーが画面外に行ってしまいますね。

プレイヤーが見えないとゲームプレイに支障が出ますので

カメラがプレイヤーについてくるようにスクリプトを用意しましょう。

「FollowCamera」というスクリプトを作成し、下記のコードを追加してください。

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

public class FollowCamera : MonoBehaviour
{
	public Transform target;
	public float distance = 10.0f;
	public Vector3 angle = new Vector3();

	private void FixedUpdate()
	{
		if ( target )
		{
			// 指定の角度でカメラの正面方向を設定する。
			var forward = ( Quaternion.Euler( angle ) * Vector3.forward );
			transform.forward = forward;

			// 追跡対象の座標から指定した距離分、離れたところに補間で移動する。
			var position = target.position - forward * distance;
			transform.position = Vector3.Lerp( transform.position, position, 0.2f );
		}
	}
}

これを Main Camera にアタッチします。

インスペクターから Add Component → Scripts → FollowCamera とやってもいいですし、

スクリプトを Main Camera にドラッグ&ドロップしてアタッチすることもできます。

アタッチできたら、プロパティを設定しましょう。

Target には Player を設定し、Angle は X を 50 としておきます。

FollowCamera

では、再度実行して確認。

FollowCameraテスト

カメラがついてくるようになりましたね。

今回はここまでです。

次回はここに、アイテムと障害物を追加してゲームのルールを整えましょう。


スクリプト補足

Start や Update、FixedUpdate の実行タイミングについては公式リファレンスをどうぞ。
イベント関数の実行順

Playerスクリプトで、Update と FixedUpdate を使い分けている理由は2つあります。
① Input はUpdate のみで呼び出すことが推奨とされている。
② Rigidbody の AddForce は、FixedUpdate で呼び出すことが推奨とされている。

Input の更新 や Update は1フレームに1度行われますが、FixedUpdate は更新頻度が異なります。
そのため、FixedUpdate で Input を使うと入力の状態が正しくとれなかったり、
Update で AddForce を使うと思ったように動いてくれないことがあります。
実際、どのような使い方で問題になるかは以下のとおりです。

 FixedUpdate で Input.GetKeyDown や GetKeyUp などで押し離しの瞬間を取得する。
 FixedUpdate で Input.GetKey などで押されているかどうかを取得する。
 Update で AddForce を ForceMode.Force で呼び出す。
 Update で AddForce を ForceMode.Impulse で呼び出す。

このように、問題なく使用できるときもあるのですが、
私は同じような処理は1箇所にまとめたいタイプですので、
Input は Update でしか使いませんし、Rigidbody は FixedUpdate でしか操作しません。



コメント

タイトルとURLをコピーしました