Teachers open the door but You must enter by yourself.

Open Media Lab.
オープンメディアラボ

枠内で転がるボール
Rolling Ball in a Rectangular Area

枠内で転がるボールを制作しUnityの3Dコンテンツ作成の流れを学びます。

ウインドウレイアウト

Hierarchy
(左上)
階層という意味で、存在するオブジェクト(物体)を階層構造もつリストで表している。
Scene,Game
(中央上)
Sceneで3D空間を構築していく。Gameにタブ切り替えすると実際のゲーム実行画面になる。
Inspector
(右)
オブジェクトを選択すると、そのオブジェクトの情報が表示される。
Project
(下)
Assetsフォルダ内にMaterial(材質)やPhysic Material(物理特性)、プログラムファイルなどを置く。それらは、対象となるオブジェクトへの関連付けを行うことにより機能する。

操作手順
Procedure

新規プロジェクトの作成

Unity Hubを起動して、左端の4つの項目の内一番上の「プロジェクト」選択し、右端の「新規作成」ボタンを押して新しいプロジェクトの生成ウインドウを開き、Project nameを例えば「Ball」、Templateを「3D」として新しいプロジェクトを作成します。

シーン構築時のビュー設定

今回は平面上でのオブジェクト配置になりますので、上空から真下方向への平行投影のビューに設定します。中央上のウインドウでSceneタブに切り替え、Sceneウィンドウ内のXYZ(Gizmo)の下のPerspを右クリックして、Topを選択します。更にTopを右クリックし、PerspectiveはOff(チェックがついていない状態)にしておきます。この状態で画面の横方向がX軸(赤軸)、縦方向がZ軸(青軸)になっています。そして画面に垂直の上下方向はY軸(緑軸)になります。Unityでは高校数学における左手系の3次元座標系とは逆の右手系の座標軸配置になっているので注意してください。

床オブジェクトの生成

Hierarchyウィンドウの左上辺りでメニューの+ボタン/3D Object/Planeを選択し、シーンに床面となる平面を追加します。

※ オブジェクトの追加は上部メニューのGameObjectタブでもできます。

Hierarchyウィンドウに新しく生成されたPlaneを選択し、その状態でInspectorでScale/Xを0.6に変更し、平面の横方向のサイズを0.6倍します。これにより正方形が縦長の長方形に変わります。

同様にHierarchy/+ボタン/3D Object/Cubeで立方体を追加します。

オブジェクトのマテリアル設定

Projectウィンドウの左上辺りで+ボタン/Materialを選択し、新しいマテリアルをAssetsフォルダ内に生成し、名前を例えばBlueに変更します。(名前には日本語などの全角文字は使わず、単語の先頭は大文字にしておきましょう。)

作成したBlueのマテリアルを選択し、その状態でInspectorのAlbedoの横の四角形をクリックしてカラーピッカーを開き、色を好みのもの、例えば青色に変更します。

作成したBlueのマテリアルをドラッグしてSceneウインドウ内のCube上にもっていきCubeの色が変わったところでマウスボタンを離します。

枠の成形と配置

先ほど生成したCubeを選択した状態でInspectorのPositionを(-3, 0, 0)、Scaleを(0.5, 1, 10)に変更します。

HierarchyウィンドウでCubeを右クリックしDuplicateで複製します。複製とInspectorの属性の変更を繰り返して枠を作成していきます。

ここで一度、ゲーム再生をしてみましょう。画面中央上部にある三角矢印の再生ボタンを押すと、しばらくしてSceneタブからGameタブに自動的に切り替わりゲーム再生されます。シーン構築時とは異なる斜め方向から見たビューになっていることがわかります。

ゲーム再生時の視点変更

Main Cameraを選択しPositionを原点の真上である(0, 10, 0)に変更、初期状態ではZ軸(水平方向)を向いている視線を、X軸周りに90度回転させて真下を向くようにRotationを(90, 0, 0)に変更し、真上から見た視点に変更します。Unityでは回転の正負についても軸に対して左ねじが進む方向を正としている点に注意してください。ちなみにMain Cameraが選択されていると、GameシーンがSceneウィンドウの右下にCamera Previewウィンドウとして表示されています。

ボールの追加

Hierarchy/+ボタン/3D Object/Sphereで球を追加し、Positionを(0, 0.25, -3)、Scaleを(0.5, 0.5, 0.5)に変更します。赤色のマテリアルなどを追加しましょう。


/*
空のGameObjectを生成し(名前をMain)
C# Script(名前をMain.cs)をアタッチする
名前がBall.cs,Pad.csのC# Scriptも生成しておく
*/
//Main.csの public class Main : MonoBehaviour{ }内に追加
void Start(){
	var plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
	plane.name = "Floor";
	plane.transform.position = Vector3.zero;
	plane.transform.localScale = new Vector3(0.6f, 1, 1);

	GameObject cube;
	cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
	cube.name = "WallWest";
	cube.transform.position = new Vector3(-3, 0, 0);
	cube.transform.localScale = new Vector3(0.5f, 1, 10);
	cube.GetComponent<Renderer>().material.color = new Color(0, 0, 1, 1);

	cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
	cube.name = "WallEast";
	cube.transform.position = new Vector3(3, 0, 0);
	cube.transform.localScale = new Vector3(0.5f, 1, 10);
	cube.GetComponent<Renderer>().material.color = new Color(0, 0, 1, 1);

	cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
	cube.name = "WallNorth";
	cube.transform.position = new Vector3(0, 0, 5);
	cube.transform.localScale = new Vector3(6, 1, 0.5f);
	cube.GetComponent<Renderer>().material.color = new Color(0, 0, 1, 1);

	cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
	cube.name = "WallSouth";
	cube.transform.position = new Vector3(0, 0, -5);
	cube.transform.localScale = new Vector3(6, 1, 0.5f);
	cube.GetComponent<Renderer>().material.color = new Color(0, 0, 1, 1);

	var camera=GameObject.Find("Main Camera");
	camera.transform.position = new Vector3(0, 10, 0);
	camera.transform.rotation=Quaternion.Euler(90,0,0);
	
	var ball = GameObject.CreatePrimitive(PrimitiveType.Sphere);
	ball.AddComponent<Ball>();

	var pad=GameObject.CreatePrimitive(PrimitiveType.Cube);
	pad.AddComponent<Pad>();
}

//void CreateWall(string name, Vector3 position, Vector3 scale) という関数を作成するとプログラムを簡素化できます。

//Ball.csに追加
public class Ball : MonoBehaviour
{
	public float speed = 3.0f;

	void Start(){
		name = "Ball";
		transform.position = new Vector3(0, 0.25f, -3);
		transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
		GetComponent<Renderer>().material.color = new Color(1, 0, 0, 1);
		var rb=gameObject.AddComponent<Rigidbody>();
		rb.velocity = new Vector3(speed, 0, speed);
		rb.useGravity=false;
	}
}

ボールの動きの追加

Unityでは物理法則に従うなど、オブジェクトの動きを自動的に生成する機能が備わっており、それらとユーザのプログラムとをうまく組み合わせてコンテンツを制作していきます。ここでもボールと、枠や床との跳ね返りはUnityにより自動的に生成します。

まずはボールに物理特性を与えます。Sphereが選択された状態で、Inspectorで一番下のAdd Componentボタンを押し、Physics/Rigidbody(剛体)を追加します。今回は重力は不要ですのでUse Gravityのチェックを外しておきます。(RidigbodyをSphereにアタッチするのだという意識をもってください。)

次にプログラムによりボールの初速度を与えます。Sphereが選択された状態で、Inspectorで一番下のAddComponentボタンを押し、New Scripを選択して(スクロールしないと表示されていない時もあります)名前はたとえばBallに変更し「Create and Add」ボタンを押して新しいスクリプトファイルを生成します。(ScriptをSphereにアタッチするのだという意識をもってください。)

Assetsフォルダに新しく生成されたC#ScriptのアイコンをダブルクリックするとVisualStudioが自動的に起動しC#のプログラムが編集可能になりますので、以下のようにコードを追加します。speedというfloat型の変数を定義し、それをSphereの速度のx方向とz方向に与えてします。これによりSphereは右上斜め45°方向の初速度をもちます。この処理はゲーム開始時に一度だけ行えばよいのでStart関数の中に記述します。ちなみにUpdate関数の方に記述すると、ゲーム開始後、描画フレームが更新されるごとに、繰り返しずっと実行されます。


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

public class Ball : MonoBehaviour
{
	public float speed = 3.0f;
	
	void Start()
	{
		GetComponent<Rigidbody>().velocity = new Vector3(speed, 0, speed);
	}
}

プログラムのエディタ側で保存して、Unity側でGameを実行すると、スクリプトが反映された動作を確認できます。再生するとボールが右上に向かって進んでいきます。ただし、壁とぶつかっても勢いよくは跳ね返りません。

跳ね返り特性の追加

Project/+ボタン/Physic Materialで新しいマテリアルをAssetsフォルダ内に生成し、名前を例えばBallとします。

ここでは摩擦は無くししっかり跳ね返るように、摩擦Friction類の2つは0に、反発係数のBouncinessは1に、Combine類は相手(この場合は枠)の値との結合方法なので、Sphereに設定した値が効くようFriction CombineはMinimum、Bounce CombineはMaximumに設定してみましょう。

HierarchyウィンドウでSphereを選び、作成したPhysic MaterialのアイコンをInspector内のSphere ColliderのMaterial枠にドラッグし、適用します。

初速度をもったボールが壁に当たると自動的に跳ね返ることを確認してください。


//Ball.csに追加
public class Ball : MonoBehaviour
{
	public float speed = 3.0f;

	void Start(){
		・・・

		var material=GetComponent<SphereCollider>().material=new PhysicMaterial();
		material.bounceCombine=PhysicMaterialCombine.Maximum;  
		material.frictionCombine=PhysicMaterialCombine.Minimum;       
		material.bounciness=1.0f;  
		material.dynamicFriction=0;  
		material.staticFriction=0;
	}
}

This site is powered by Powered by MathJax