Roll a Ball Tutorial 2023

演習で扱うチュートリアル

新版RollaBall https://learn.unity.com/project/roll-a-ball (メニューは日本語、動画は英語)

古いチュートリアル

旧版RollaBall https://learn.unity.com/project/roll-a-ball-tutorial-jp 玉転がし(日本語版)

ビジュアルスクリプティング版チュートリアル

https://learn.unity.com/project/bolt-roll-a-ball-tutorial (日本語版)

ゲーム画面の構成とプレイヤー(1/2)

ゲーム画面の構成とプレイヤー(2/2)

UnityのC#スクリプトのイベント処理

スクリプトのライフサイクルの概要を読んでおくとよい。

UnityのC#スクリプトのメソッドの役割が解説されている。主なものを以下に示す。

Awake

Start

FixedUpdate

OnTrigger系

OnCollision系

OnMouse系

Update

LateUpdate

ゲーム画面の構成とプレイヤー

Roll a Ball プロジェクトを作成する。D:ドライブの自分の演習用フォルダ「Game3121888などに作成すること。

Unity  Hub 新しいプロジェクト

サンプル 3D Sample Scene(URP)

テンプレートをダウンロード を押す

URPは Universal Render Pipeline の略でUnityが推奨しているレンダーパイプライン(CG描画方式)
通常のUnity コア 3D テンプレートはビルトインレンダーパイプライン(組み込みパイプライン)でUnityに依存したCG描画になる。
URPではゲームデバイスごとに最適化された描画が可能。シェーダーのカスタマイズもできる。ハイエンド機向けゲームにはHDRPが別に用意されている。


プロジェクト名 RollaBall

保存場所 D:ドライブの自分用のフォルダ

バージョン 2022.3.7f1 LTS



テンプレートに含まれる素材(Assets)を片付ける

 Project の Assets フォルダに

フォルダ名 Templates

 を作成し最初からAssetsに入っていたフォルダやファイルを全てTemplatesに移動する。



1. ゲーム画面の構成

新規シーン作成 File  → New Scene

Scene Temlatesの選択は「Basic(Built-in)」でCreateする。

File → Save  でシーンを名前を付けて保存する。

シーン名 MiniGame

  フォルダ Scenes を作成してMiniGameを移動する(Save時に新しいフォルダを作成することもできる)。


プロジェクトに素材別のフォルダ

 Scenes
Materials
Scripts
Input

を作成して素材を整理できるようにしておく。


シーンにオブジェクト(Ground Player)、マテリアル(Background と Player)を作成する。

フォルダ Scenesのシーン Minigame を編集

Hierarchyに以下の2つを追加

新規作成:
オブジェクト Ground

3D Object -> Plane
Transform Scale x 2 y 1 z 2

オブジェクト Player

3D Object -> Sphere
Transform Position x 0 y 0.5 z 0

調整:
オブジェクトDirectional Light

Color 全て255 (白色)に変更
Transform Rotation X 50 Y 50 に調整


 新規作成 フォルダ Materials

新規作成 マテリアル Background

Surface  Inputs

Base Map
RGB を それぞれ130に変更
Metallic Map 0
Smoothness 0.25



ゲームオブジェクトBackgroundにマテリアルBackgroundをDnDで設定。


新規作成 マテリアル Player
Base Map
RGB を それぞれ 0 220 255 に変更
Metallic Map 0
Smoothness 0.75

ゲームオブジェクトPlayerにマテリアルPlayerをDnDで設定。


2. プレイヤーの移動



Is Kinematic OFF のまま変更なし。第3回のコードでは物理エンジンによるオブジェクトの移動は行わないのでONに設定した。



再起動の確認プロンプトが表示される → Yes で再起動を許可 → Sceneファイルを保存


File → Build Settings

Architecture Intel_64bit であることを確認(32bitになっていたら変更)



Hierarchy Player  にPlayer Inputコンポーネントを追加

Add Component → Input → Player Input

Create Actions ボタンを押す

フォルダ名 Input 作成

RollaBall.inputactions を保存

Player Input の Actions に RollaBallがセットされていることを確認

例) Input Systemのセットアップ + Assetsフォルダの整理 + C#スクリプトの設定

Playerオブジェクトに
Add Component から

New Scritpt

スクリプト名 PlayerController
を追加する(公式のRoll a Ball チュートリアルの以下のコードをコピーしてVisualStudioから編集)

プロジェクトに Scripts フォルダを作成して PlayerController を移動


PlayerオブジェクトのC#スクリプトコンポーネント

 speed  フィールドの調整 値 10


PlayerController スクリプトの解説:

GetComponent<Rigidbody> 物理エンジンを利用するためのインターフェースを取得する

Vector3 3次元ベクトル。ここではボールに力を加える方向をx y z の成分を持つベクトルで決める

AddForce ボールに力を加える(引数のベクトル方向に引っ張る)
FixedUpdate メソッドでAddForceを使う理由:

物理シミュレーション完全マスター https://learning.unity3d.jp/1167/

InputActionとC#スクリプト

Playerオブジェクトに追加したPlayer Inputコンポーネントでは標準の移動方法はOnMoveメソッドのInputValue で X Y の2次元ベクトルになっている。
操作方法は ASDWキー と 矢印キー の組み合わせ(同時押し可能)で移動ベクトルXYを与えるようになっている。

作業のバックアップとして Assetsメニューから Export Package しておく。ファイル名は適当でよい。保存場所はデスクトップも選ぶことができる。個人用のバックアップとして各自で保管しておくとよい。

進捗管理: 2023年度4回はここまで

Unityの挙動とC#スクリプトの解説を入れて5分時間が余る程度。

カメラとプレイ領域、収集するオブジェクトの作成、回転用スクリプトの追加

カメラとプレイ領域

1.カメラの移動

Inspectorから位置と角度を調整

Main Camera
Position X=0 Y=10 Z=-10
Rotation X=45 Y=0 Z=0



Hierarchyで

Player を親オブジェクトとして、その子供にカメラを設定

動作確認(カメラも回る)

Main Camera を元の階層に戻す(親子関係は解除する)



オブジェクト Main Camera
Add Component → New Script から

スクリプト名 CameraController
を追加

Scripts フォルダに CameraController を移動


VisualStudioで編集
以下のスクリプトではMain Cameraのpositionを LateUpdate メソッドで移動させている。
他のゲームオブジェクトのUpdateメソッドの完了後にLateUpdateメソッドは処理される。
ゲームオブジェクトの位置関係に応じてカメラの位置を決めることができる
ここでは、Playerが移動した後でカメラを移動してゲーム画面内に捉えることができる。

Main Camera  オブジェクトを選択

Player ゲームオブジェクトを CameraController スクリプトコンポーネントの Player スロットに設定

【Unity】同じコンポーネントが複数アタッチされるのを防ぐ方法 https://ekulabo.com/disallow-multiple-component

【Unity】狙った順に処理したい時はスクリプトの実行順を指定する https://ekulabo.com/execution-order 

2. プレイエリアの構成


空のゲームオブジェクトを作成して四方の壁をグループ化する

Walls に名前を変更

キーボード Fキー でフォーカスを合わせる

West Wall に名前を変更
Scale を(0.5, 2, 20.5)
Position の X に -10  を設定

Edit > Duplicate   で East Wall を作成  X を10に変更

残り2つの壁を作成(スケール変更回転を利用


以下、スケール変更で作成する例

North Wall
Scale を(20.5, 2, 0.5)に変更

配置は X の代わりにZ方向で指定する。

X 0

Z 10

South Wall をNorthWallをコピーして作成

Z -10

壁のInspector の Collider で Is Triggerオフになっていることを確認する。

実行して動作確認(壁に衝突して抜けられない)

Global と Local 座標での回転について確認する

Layout を 2 by  3 に変更

シーンを実行して Player の挙動をシーンビューで確認。
回転モードを  Global と Local に切り替えて比較する。
TransformのRotation の表示もしている。

参照: Global と Local https://gametukurikata.com/basic/worldlocal

Center と Pivot https://qiita.com/eewano/items/6892a366b005ba8ff4e0

  LayoutDefaultに戻す

2 by 3 や 4 Split などのレイアウトがメニューに表示されない場合がある。
その際はメニューから、Reset All Layouts で復旧できる。

オブジェクトの収集、スコアの記録、ゲームのビルド



Hierarchy -> 3D Object -> Cube

名前 PickUp に修正

目立つように姿勢を変更

Y 0.5

Scale x y z すべて 0.5

Rotation x y z すべて 45

※ここでPickUp オブジェクトの移動モードの Global と Local 座標確認

↓の画像ではPickUpが複数配置されているが、この段階では1個だけ配置しておく。後の工程でPrefabを用いて複製する。

Global座標

Local座標 PickUpのギズモに注目

  RGB 255 200 0
Smoothness 0.25


PickUpオブジェクトにマテリアルをDnDで設定する。

回転用スクリプトの追加

Rotator を新規作成し、Scriptsフォルダへ移動

スクリプトは短いので入力してみてもよい。(Visual Studioではコード補完機能を利用可能

オブジェクトの回転スクリプトは Update メソッドに記述する

Prefabの作成、Pick Upを12個配置、Pick Upの収集

Prefab プレファブ(組み立て済み部品)の作成

Prefab化したPickUpオブジェクトがHierarchyで青文字に変わる。
「>」をクリックするとPrefab編集モードになる。シーンビューのメニューから階層を辿って元のシーンビューに戻す。

PickUpをHierarchyのPickUp Parentの階層の下にDnDして移動する。

  確認: 親オブジェクトを移動しても、PickUpの Transform Position は変化しない

シーンの座標 Global座標から → 親オブジェクトを基準にした Local座標


※PickUpはGlobal座標で移動すること。Local座標ではY軸方向にも動いてしまう。

どれか1つのPickupインスタンスを選択

マテリアルを変更


Inspectorの Overrides から Apply all で全プレハブのインスタンスに対して変更を適用


方法2:

Prefab を open して選択モード または select で PrefabのInspactor を開く

Prefabを編集して閉じる(シーンをクリック)

実験: PickUpのPrefabの色を変更してすべてのPrefabインスタンスに適用してみよう。

Materialを新規作成して色を適当に選ぶ。

PickUpのPrefabのMaterialsに新規作成したMaterialを設定する。

オブジェクトを円周上に配置する裏技

Inspectorのプロパティの値を関数で求める

オブジェクトを Ctrl + D で複製して まとめて選択

Position の Xcos(pi/6*#)*7

Position の Zsin(pi/6*#)*7

2. Pick Up オブジェクトの収集

PlayerController を編集する。
以下のOnTrigerEnter メソッドを追加する。


公式チュートリアルではこのコードは2回に分けて記述しているが、ここでまとめて作成する。


Hierarchyから

PickUpインスタンスをどれか1つ選択

Prefab編集モードに入る


PickUpオブジェクトにタグを追加して設定する

Inspectorの Tag が Untagged  に設定されている(タグ無し状態)ので修正する。

1/4ステップ

Add Tag をメニューから選択

2/4ステップ
タグを新規登録する。
  Tagsが List Emptyと空の状態なので、 + ボタンを押して

タグ名 PickUp
を大文字小文字に注意して入力し、Saveする。

3/4ステップ
PickUpのPrefabインスタンスを選択する

4/4ステップ
InspectorからTagを PickUp に変更する。

PickUpのInspectorから Box Collider の Is Trigger を有効にする

Is Trigger がon のオブジェクトは衝突しても通過できるようになる。
衝突の検出自体は有効のまま。


Prefab編集モードからシーンビューに戻る。

Prefabの編集 と Prefabインスタンスの編集の違いについて

Prefab編集モードに入らずシーン上のPrefabインスタンスを直接編集することができる。

以下の例は、PrefabインスタンスのPickUpゲームオブジェクトのInspectorからIs TriggerをOffにしている。

 Prefabの設定(Is Trigger)が上書されていることを示すために青くマークされている。
 ※インスタンス側で設定を上書きされた項目はPrefabの設定を変更しても影響を受けない。
  ※つまりPrefabを変更してもインスタンスに変更は起きない。

 対処方法1: PrefabのメニューからOverrides > Apply All する。

 対処方法2:Prefabインスタンスで上書きした設定を右クリックして

        Apply to Prefab でPrefabの設定をインスタンスの設定に合わせて修正
または
Rerert でインスタンス側の設定をPrefabの設定に復旧
       させる。

Prefabの解除方法

(誤ってPrefab化したなどで)Prefabのゲームオブジェクトを通常のゲームオブジェクトに戻すことができる。
HierarchyからPrefabを右クリックして Prefab -> Unpack
Unpack CompletelyするとPrefabの階層(PrefabにPrefabを内蔵して組み立てられた)を辿って内部のPrefabも元に戻る。

物理演算パフォーマンスの改善

PrefabsフォルダのPickUp をダブルクリックで開いて編集する。


PickUp に Rigidbody を設定(Add Component)

Is Kinematic を ON

PickUpをRigidbody Kinematic オブジェクトとして扱うようにする。


 説明

進捗管理: 2023年度第5回はここまで進んだ

水曜日クラス確認事項 PickUp は Rigidbodyかつkinematic か?

スコアとテキストの表示、ゲームのビルド

3. スコアとテキストの表示

PickUpにPlayerが接触した際のスコアカウントのコードを追加する。

拾ったPickUpの数を表示するコードを追加する。

PickUpを全て拾ったらメッセージを表示するコードを追加する。

公式チュートリアルでは上記の3ステップに分けて逐次コードを追加している。ここでは纏めてコードを追加(太字の部分)してもOK。

PlayerControllerスクリプトを編集する。

UIを追加する

Hierarchyの +ボタンからUIオブジェクトを追加

Hierarchy -> UI -> Text - TextMeshPro

Import TMP Essenstials

TMPパネルを閉じる

Canvas や EventSystem も自動的に追加されるがこれらを削除してはいけない。



EventSystem を選ぶ。
  コンポーネントのStandalone Input Moduleが古いままでエラーになっている。
以下のボタンをして修正する。

Replace with InputSystemUIInputModule


Canvasの下層 Text(TMP) の名前を変更

名前 CountText


CountTextオブジェクトをダブルクリックしてフォーカスする。配置場所の確認。
Canvasオブジェクトをダブルクリックしてフォーカスする。配置場所の確認。


3DシーンとUI画面の位置関係の確認

UIのCanvasを選択して F  back view から確認する。

ゲームの実行画面でズームしているとUIがフレームアウトして見えない場合があるのでx1倍で表示を確認する。

キー T を押してRect Toolで、UIテキストのサイズやPivotを編集できる。


シーンビューを  2D  モードに切り替える。


CountTextオブジェクトを選択する

Inspectorから調整

アンカーの設定(Shift + Alt キーで)左上隅をアンカーポイントに選択する。
Altキー同時押しでテキストUIの位置も移動する。
Shiftキー同時押しでPivotも変更される。

余白調整

Pos X 10
Pos Y -10 


参照:[Unity]直感的にわかりにくいアンカーの仕組みを徹底解説

Playerオブジェクトを選択してInspectorからPlayerControllerスクリプトを表示しておく

CountTextオブジェクトをHierarchyからDnDしてInspectorのCountTextスロットにセットする


シーンを再生して動作確認。「Count: 0」と表示されることを確認する

※ シーンの再生後、エラーでゲームは停止しする。WinText用のGameObjectを以下の工程でアタッチすることでエラーを修正する



同様にして WinTextオブジェクトを UI TextMeshProで作成する

テキストの色を黒に変更
Vertex Color をクリックしてカラーピッカーで選ぶ

フォントサイズ 32

ボールド体(太字) B

テキスト配置 alignment center(ボタン)

プレースフォルダのテキスト You Win!

Pos X 0

Pos Y 130
(位置を中央に移動)

サイズとテキストエリアのサイズに注意する。大きなサイズのフォントがテキストの表示範囲からはみ出ると非表示状態になる
その場合はテキストエリアを広げて対応する


先程と同様にして PlayerControllerスクリプト に WinTextオブジェクトをアタッチする(PlayerオブジェクトのInspectorをロックしておくと楽)

ピボット(pivot 基準点)の補足:

アンカー 中央

ピボット 中央 ( x 0.5 y 0.5)

Pos X 0 Pos Y 0

アンカー 左端

ピボット 中央 ( x 0.5 y 0.5)

Pos X 100 Pos Y 0

アンカー 左端

ピボット 左端 ( x 0 y 0.5)

Pos X 0 Pos Y 0

シーンビューを3Dに戻す。


シーンを再生してアイテムを全て拾う。スコアがカウントアップされる。
すべてのアイテムを収集後に「You Win!」メッセージが表示されることを確認する。


4. ゲームのビルド


RollaBall プロジェクトのフォルダに buildフォルダを新規作成してビルドする。

File -> Build Settings


から

ビルド設定パネルを表示して不要なシーンを削除

ここで作成したシーンMiniGameを

 Add open Scenesボタン

で追加

課題提出

中間課題として RollaBallプロジェクトのAssetsをExportして、Webclassの第7回課題(4・5・6回の内容を含む)に提出する。

ファイルサイズが大きくなるのでExportする際に Templates TextMesh Pro を除外してExportすること。

ファイルサイズがWebclassにアップロードできる容量を超える場合は、レポートフォルダに提出用のフォルダに提出する

例)必要なAssetを含めること。TemplatesとTextMesh Proのチェックを外す。

Exportする際に、以下のような警告がステータスバーに表示されるが無視してよい。
採点に際して、TextMesh Proのパッケージ依存は講義担当者側で解決する。