序文
これは選択コース 3D ゲームのプログラミングとデザインの 2 番目の課題で、短答式の質問と Unity を使用した小さなゲームの作成が含まれます。間違いがある場合は、修正していただきありがとうございます。
短い答えの質問
ゲームオブジェクト(GameObject)とリソース(Asset)の違いと関係
ゲームオブジェクト: Unity のキャラクター、プロップ、またはシーンを表す基本オブジェクトは、さまざまな機能を実現するためにさまざまなコンポーネント (Component) を収容できるコンテナーです。
リソースとは、モデル、サウンド ファイル、テクスチャ ファイルなど、プロジェクトで使用されるさまざまなリソース ファイルを指します。
違い: ゲームオブジェクトはゲームの実行時に存在するオブジェクトであり、アセットはゲーム作成時にワークスペースで使用できるリソースです。
連絡先: リソースを使用してゲーム オブジェクトを作成できます。リソースは、特定のゲーム オブジェクトをインスタンス化するためのテンプレートにすることも、ゲーム オブジェクトの属性として使用して、複数のゲーム オブジェクトで同時に使用することもできます。
ゲームのケーススタディ
リソースのディレクトリ構成構造: 同様の機能を持つリソースが同じディレクトリに配置される
ゲームオブジェクトツリーの階層構造: ゲームオブジェクト間の関係は親または子となり、全体的なツリー構造が形成されます。
デバッグ ステートメントを使用して MonoBehaviour の基本動作またはイベント トリガーの条件を検証するコードを作成します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class intbesh : MonoBehaviour {
private void Awake()
{
Debug.Log("awake!");
}
void Start () {
Debug.Log("start!");
}
void Update () {
Debug.Log("update!");
}
private void FixedUpdate()
{
Debug.Log("fixedupdate!");
}
private void OnGUI()
{
Debug.Log("ONGUI!");
}
private void OnDisable()
{
Debug.Log("OnDisable!");
}
private void OnEnable()
{
Debug.Log("OnEnable!");
}
}
更新出力が多すぎるため、コンソールは表示されません。概要は次のとおりです。
- Start: ゲームループに最初に入ったときに呼び出されます。
- Update: 動作が有効な場合、Update はフレームごとに呼び出されます。
- Awake: スクリプト インスタンスがロードされたとき
- FixedUpdate: 動作が有効になっている場合、タイム スライスごとに呼び出されます。
- OnGUI: GUI イベントのレンダリングおよび処理時に呼び出されます。
- OnEnable: オブジェクトが使用可能になったとき、またはアクティブ化されたときに呼び出されます。
- OnDisable: オブジェクトが使用できなくなったとき、または非アクティブになったときに呼び出されます。
GameObject、Transform、Component オブジェクトについて学ぶには、スクリプト マニュアルを見つけてください。
3 つのオブジェクトの公式説明をそれぞれ翻訳します (説明)
GameObject は Unity の基本オブジェクトであり、キャラクター、小道具、ゲーム シーンを表します。これらはそれ自体ではあまり機能しませんが、コンポーネントのコンテナとして機能するため、実際の機能を実現できます。
Transform コンポーネントは、シーン内の各オブジェクトの位置、回転、スケールを決定します。すべてのゲームオブジェクトには Transform があります。
コンポーネントは、ゲーム内のオブジェクトと動作の詳細です。これらはすべてのゲームオブジェクトの機能部分です。
下図のテーブルオブジェクト(Entity)のプロパティ、テーブルのTransformのプロパティ、テーブルの構成要素を記述します。
テーブル オブジェクトの属性: name、activeSelf (ゲームオブジェクトのローカル アクティブ状態)、isStatic、layer (ゲーム オブジェクトが配置されているレイヤー)、tag (ゲーム オブジェクトのラベル)
テーブルの変換のプロパティは次のとおりです: 位置、回転、スケール
テーブルのコンポーネントは次のとおりです: メッシュ フィルター、メッシュ レンダラー、ボックス コライダー、First Beh
リソースのプリセット (Prefab) とオブジェクトのクローン作成 (clone)
プレハブの利点は何ですか?
プリセットを使用すると、同じプロパティを持つオブジェクトをすばやく作成でき、プリセット プロパティを変更すると、対応するすべてのインスタンスを同時に変更できるため、効率が向上します。
プリセットとオブジェクトのクローン作成 (Unity オブジェクトのクローン、コピー、またはインスタンス化) との関係は何ですか?
オブジェクト クローンのインスタンスは相互に影響しませんが、プリセットを変更すると、そのプリセットのすべてのインスタンスに影響します。
テーブル プリセットを作成し、テーブルのプレハブ リソースをゲーム オブジェクトにインスタンス化するコードを作成します。
public class FirstBeh : MonoBehaviour {
public GameObject table;
void Awake()
{
Debug.Log("awake!");
}
void Start () {
Debug.Log("Start");
GameObject aTable = (GameObject)Instantiate(table.gameObject);
aTable.name = "newTable";
aTable.transform.position = new Vector3(0,Random.Range(0,5),0);
aTable.transform.parent = this.transform;
}
void Update () {
//Debug.Log("Init Update");
}
}
プログラミング実習: 三目並べミニゲーム
C# スクリプトを作成してカメラにマウントします。
スクリプト コードは次のとおりです。
using UnityEngine;
using System.Collections;
public class TTT : MonoBehaviour {
//用二位数组存棋盘,0代表空,1代表O,2代表O
private int[,] chess = new int[3,3] {
{
0,0,0},{
0,0,0},{
0,0,0}};
//0是O的回合,1是X的回合
private int turn = 0;
private int res=0;
void Start () {
}
//OnGUI会自动刷新
void OnGUI() {
//x,y,w,h
if (GUI.Button(new Rect(310,300,100,50),"重新开始")) reset();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (chess [i,j] == 1) {
GUI.Button (new Rect (70 * i+250, 70 * j, 70, 70), "O");
Debug.Log(i+" "+j+":"+chess[i,j]);
res=check();
Debug.Log(res);
} else if (chess [i,j] == 2) {
GUI.Button (new Rect (70 * i+250, 70 * j, 70, 70), "X");
Debug.Log(i+" "+j+":"+chess[i,j]);
res=check();
Debug.Log(res);
} else {
if (GUI.Button (new Rect (70 * i+250, 70 * j, 70, 70), "")) {
if (res == 0) {
if (turn == 0) {
chess [i, j] = 1;
turn = 1;
} else {
chess [i, j] = 2;
turn = 0;
}
}
}
}
}
}
res = check();
if (res == 1) {
GUI.Label (new Rect (340, 230, 100, 50), "O赢");
} else if (res == 2) {
GUI.Label (new Rect (340, 230, 100, 50), "X赢");
} else if(res==3){
GUI.Label (new Rect (340, 230, 100, 50), "平局");
} else{
if(turn==0) GUI.Label (new Rect (335, 230, 100, 50), "O的回合");
else GUI.Label (new Rect (335, 230, 100, 50), "X的回合");
}
}
void reset() {
//重开置空
turn=0;
res=0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
chess [i,j] = 0;
}
}
turn = 0;
}
int check() {
//检查行
for (int i = 0; i < 3; i++) {
if (chess[i,0]!=0&&chess [i,0] == chess [i,1] && chess [i,1] == chess [i,2]) {
return chess [i,0];
}
}
//检查列
for (int j = 0; j < 3; j++) {
if (chess[0,j]!=0&&chess [0,j] == chess [1,j] && chess [1,j] == chess [2,j]) {
return chess [0,j];
}
}
//检查对角线
if ((chess[0,0]!=0&&chess [0, 0] == chess [1, 1] && chess [1, 1] == chess [2, 2]) ||
(chess[0,2]!=0&&chess [0, 2] == chess [1, 1] && chess [1, 1] == chess [2, 0])) {
return chess [1, 1];
}
//检查满
int count = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (chess [i, j] != 0)
count++;
}
}
if(count==9)return 3;
return 0;
}
}
効果は以下の通りです