目录
解释游戏对象(GameObjects)和资源(Assets)的区别和联系
下载几个游戏实例,分别总结资源、对象组织的结构
编写一个代码,使用 debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件
查找脚本手册,了解 GameObject,Transform,Component 对象
分别翻译官方对三个对象的描述(Description)
描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件
总结
井字棋全部代码
解释游戏对象(GameObjects)和资源(Assets)的区别和联系
游戏对象(GameObjects):游戏中的每个对象都是一个游戏对象 (GameObject),游戏对象是统一体中代表人物、道具和场景的基本对象。它们本身并没有完成多少工作,但是它们充当组件的容器,组件实现真正的功能。
资源(Assets):游戏中可能用到的各种东西,比如模型、声音文件、贴图文件等等都是资源(Assets)。资源(Assets)是可以在游戏或项目中使用的任何项目的表示。资源(Assets)可能来自Unity之外创建的文件,例如3D模型、音频文件、图像或Unity支持的任何其他类型的文件。还有一些资产类型可以在Unity中创建,比如动画控制器、音频混频器或渲染纹理。在unity3d中的Project部分就对应了项目文件夹里的assets文件夹,就是专门用来存储项目中使用到的各种东西。在Project里添加模型、声音文件、贴图文件时assets文件夹里的东西也会改变。
区别:对象由资源组成,资源组成对象,且可以被多个对象使用。对象是资源的具体化的实例,资源是对象的组成成分。
联系:资源可以作为模板,实例化成具体的游戏对象,也可以作为游戏对象中的某种属性,同时也可以被多个游戏对象同时使用。
下载几个游戏实例,分别总结资源、对象组织的结构
在GitHub上下载了一个叫tappyplane的游戏
该游戏资源的内容分为预制、场景、脚本、纹理,资源的结构如下:
对象组织的结构,这个游戏只有一个main camera的对象。
![](https://img.php1.cn/3cd4a/1eebe/cd5/6789f68dabde0aed.png)
编写一个代码,使用 debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件
基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate()
常用事件包括 OnGUI() OnDisable() OnEnable()
using System.Collections;using System.Collections.Generic;using UnityEngine;public class intbesh : MonoBehaviour {// 初始化private void Awake(){Debug.Log("It is an awake!");}void Start () {Debug.Log("It is a start!");}//每帧调用一次更新void Update () {Debug.Log("It is an update!");}//固定更新private void FixedUpdate(){Debug.Log("It is a fixedupdate!");}private void OnGUI(){Debug.Log("It is ONGUI!");}private void OnDisable(){Debug.Log("It is OnDisable!");}private void OnEnable(){Debug.Log("It is OnEnable!");}}
运行结果如下图:
分析可得
awake:当一个脚本实例被载入时被调用
start:在所有update函数之前被调用一次
update:当行为启用时,其update在每一帧被调用
fixedupdate:当行为启用时,其fixedupdate在每一时间片被调用
OnGUI:渲染和处理GUI事件时调用
OnEnable:当对象变为可用或激活状态时被调用
OnDisable:当对象变为不可用或非激活状态时被调用
分别翻译官方对三个对象的描述(Description)
本题目要求是把可视化图形编程界面与 Unity API 对应起来,当你在 Inspector 面板上每一个内容,应该知道对应 API。
例如:table 的对象是 GameObject,第一个选择框是 activeSelf 属性。
用 UML 图描述 三者的关系(请使用 UMLet 14.1.1 stand-alone版本出图)
GameObject :GameObjects are the fundamental objects in Unity that represent characters, props and scenery. They do not accomplish much in themselves but they act as containers for Components, which implement the real functionality.
翻译:游戏对象是代表人物、道具和风景的基本统一对象。它们本身并不能完成很多工作,但它们充当组件的容器,实现真正的功能。
Transform :The Transform component determines the Position, Rotation, and Scale of each object in the scene. Every GameObject has a Transform.
翻译: 转换组件确定场景中每个对象的位置、旋转和缩放。每个游戏对象都有一个变换。
Component :Components are the nuts & bolts of objects and behaviors in a game. They are the functional pieces of every GameObject.
翻译: 组件是游戏中对象和行为的螺母和螺栓。它们是每个游戏对象的功能部件。
第一个选择框是activeSelf:定义对象的名称,动静态等属性;
第二个选择框是Transform:定义对象的位置、面向方向、大小;
第三个选择框是Box Collider:调整坐标系的位置、大小;
第四个选择框是Component:给对象增加行为。
![](https://img.php1.cn/3cd4a/1eebe/cd5/6c257b6ba227cc3e.webp?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01heWtpZGQ=,size_16,color_FFFFFF,t_70)
资源预设(Prefabs)与 对象克隆 (clone)
预设(Prefabs)有什么好处?
预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?
制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象
预设(Prefabs)的好处:
预设可以提前将设计游戏中所需要的游戏对象进行设计打包,成为一个模板。在我们需要用到这些模板时,可以直接从资源当中加载,成为一个游戏对象,使我们在设计游戏中更加便捷。
预设和克隆之间的关系:
克隆是出来的对象独立于原来的对象,在修改的过程中不会影响原有的对象。但是通过预设实例化的对象是相互关联的,修改预设会改变通过该预设实例化出来的对象。
table 预制:
public GameObject table;void Start () {GameObject newTable = (GameObject)Instantiate(table.gameObject);}
编程实践,小游戏
游戏内容: 井字棋 或 贷款计算器 或 简单计算器 等等
技术限制: 仅允许使用 IMGUI 构建 UI
作业目的:
了解 OnGUI() 事件,提升 debug 能力
提升阅读 API 文档能力
首先是几个参数的使用
![](https://img.php1.cn/3cd4a/1eebe/cd5/bcafc120671304eb.webp)
Button用来记录井字棋里填的内容如X或者O;
Result用来记录胜负结果;
Button_state用来记录格子的使用情况,0表示为使用,1表示填入X,2表示填入O;
Turn用来记录轮次。
Init函数
![](https://img.php1.cn/3cd4a/1eebe/cd5/780a3060eeed6a4e.webp)
用来初始化格子
生成底下的结果和重新开始按钮,调用init函数进行初始化
![](https://img.php1.cn/3cd4a/1eebe/cd5/b428d8f746fb8d47.webp)
生成井字格
![](https://img.php1.cn/3cd4a/1eebe/cd5/d34245582687a4e6.webp)
检测玩家的选择,并做相应的处理
![](https://img.php1.cn/3cd4a/1e618/c5a/d5d40da532c3a782.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01heWtpZGQ=,size_16,color_FFFFFF,t_70)
ifIsEnd函数检查游戏是否结束,其中又分为四个部分,横排、竖排、对角线检查以及平局检查
![](https://img.php1.cn/3cd4a/1eebe/cd5/1113165c4904ecc5.webp?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01heWtpZGQ=,size_16,color_FFFFFF,t_70)
总结:这次的作业我收获了很多,对unity3d的了解更深了,对其的基础知识和基本操作有了更多的认识。在井字棋游戏的实现上,我了解 了OnGUI() 事件,也提升 了debug 能力,同时提升了阅读 API 文档的能力。总体来说收获很多。
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class mybutton : MonoBehaviour
{ private string[] button &#61; new string[9];private string result &#61; "";private int[] button_state &#61; new int[9];//0-空&#xff0c;1-X按下&#xff0c;2-O按下private int turn &#61; 0;//1-X的回合&#xff0c;0-O的回合void Start(){init();}void init(){turn &#61; 0;//o先走for (int i &#61; 0; i <9; i&#43;&#43;){button[i] &#61; "";button_state[i] &#61; 0;}}void Update(){}void OnGUI(){GUI.Button(new Rect(20, 320, 100, 40), result);if (GUI.Button(new Rect(160, 320, 100, 40), "重新开始")){init();//调用初始化函数&#xff0c;将棋盘清空result &#61; "";}//若游戏结束则重新创建棋盘int a, b;if (ifIsEnd()){a &#61; 20;b &#61; 20;for (int j &#61; 0; j <3; j&#43;&#43;){for (int k &#61; 0; k <3; k&#43;&#43;){GUI.Button(new Rect(a, b, 80, 80), button[3 * j &#43; k]);a &#43;&#61; 80;}b &#43;&#61; 80;a &#61; 20;}if (GUI.Button(new Rect(160, 320, 100, 40), "重新开始")){init();result &#61; "";}return;}//检测玩家操作a &#61; 20;b &#61; 20;for (int j &#61; 0; j <3; j&#43;&#43;){for (int k &#61; 0; k <3; k&#43;&#43;){if (GUI.Button(new Rect(a, b, 80, 80), button[3 * j &#43; k])){if (button_state[3 * j &#43; k] &#61;&#61; 0 && turn &#61;&#61; 0){button[3 * j &#43; k] &#61; "O";button_state[3 * j &#43; k] &#61; 2;}else if (button_state[3 * j &#43; k] &#61;&#61; 0 && turn &#61;&#61; 1){button[3 * j &#43; k] &#61; "X";button_state[3 * j &#43; k] &#61; 1;}turn &#61; (turn &#43; 1) % 2;}a &#43;&#61; 80;}b &#43;&#61; 80;a &#61; 20;}}//检查游戏是否结束,需要分别检查横竖对角线&#xff0c;结果有X赢、O赢和平局bool ifIsEnd(){//检查横排&#xff0c;012、345、678for (int j &#61; 0; j <7; j &#61; j &#43; 3){if (button_state[j] &#61;&#61; button_state[j &#43; 1] && button_state[j &#43; 1] &#61;&#61; button_state[j &#43; 2]){if (button_state[j] &#61;&#61; 1){result &#61; "X赢!";return true;}else if (button_state[j] &#61;&#61; 2){result &#61; "O赢!";return true;}}}//检查竖排&#xff0c;036、147、258for (int j &#61; 0; j <3; j&#43;&#43;){if (button_state[j] &#61;&#61; button_state[j &#43; 3] && button_state[j &#43; 3] &#61;&#61; button_state[j &#43; 6]){if (button_state[j] &#61;&#61; 1){result &#61; "X赢&#xff01;";return true;}else if (button_state[j] &#61;&#61; 2){result &#61; "O赢&#xff01;";return true;}}}//检查对角线048、246if (button_state[0] &#61;&#61; button_state[4] && button_state[4] &#61;&#61; button_state[8]){if (button_state[0] &#61;&#61; 1){result &#61; "X赢&#xff01;";return true;}else if (button_state[0] &#61;&#61; 2){result &#61; "O赢&#xff01;";return true;}}if (button_state[2] &#61;&#61; button_state[4] && button_state[4] &#61;&#61; button_state[6]){if (button_state[2] &#61;&#61; 1){result &#61; "X赢&#xff01;";return true;}else if (button_state[2] &#61;&#61; 2){result &#61; "O赢&#xff01;";return true;}}//检查是否平局int m &#61; 0;for (int j &#61; 0; j <9; j&#43;&#43;){if (button_state[j] &#61;&#61; 0){m &#61; 1;break;}}if (m &#61;&#61; 0){result &#61; "平局";return true;}return false;}
}