简答题
一、解释游戏对象和资源的区别与联系
区别:游戏对象是具有一定属性和功能的类的实体化,直接出现在游戏场景中,游戏中的每一个对象都是一个游戏对象。比如:人物角色、建筑场景等等。资源通常指修饰游戏对象、配置游戏的文件数据,比如预设、音频文件等等。
联系:资源可以通过实例化为具体的游戏对象,也可以作为游戏对象中的某种属性或者动作,被一个或多个游戏对象使用。
二、下载几个游戏案例,分别总结资源、对象组织的结构(指资源的目录结构与游戏对象树的层次结构)
游戏对象树的层次结构:主要包括摄像机包、游戏的控制、场景布局以及自定义对象等。
资源的目录组织结构:主要包括音频Audio、图像Images、预设Prefabs、场景Scenes、脚本Scripts,以及使用说明等。
三、编写一个代码,使用debug语句来验证MonoBehaviour基本行为或事件触发的条件
(1)基本行为包括Awake() Start() Update() FixedUpdate() LateUpdate()
(2)常用事件包括OnGUI() OnDisable() OnEnable()
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
void Awake() {
Debug.Log ("Awake");
}
// Start is called before the first frame update
void Start () {
Debug.Log ("Start");
}
// Update is called once per frame
void Update () {
Debug.Log ("Update");
}
void FixedUpdate() {
Debug.Log ("FixedUpdate");
}
void LateUpdate() {
Debug.Log ("LateUpdate");
}
void OnGUI() {
Debug.Log ("GUI");
}
void Reset() {
Debug.Log ("Reset");
}
void OnDisable() {
Debug.Log ("Disable");
}
void OnDestroy() {
Debug.Log ("Destroy");
}
}
四、查找脚本手册,了解 GameObject,Transform,Component 对象
(1)分别翻译官方对三个对象的描述(Description)
游戏对象(GameObject):Unity场景中所有个体的基类。
变换(Transform):描述物体的位置、旋转、大小。
组件(Component):附加在游戏对象上的所有东西的基类。
(2)描述下图中table 对象(实体)的属性、table 的 Transform 的属性、table 的部件
本题目要求是把可视化图形编程界面与Unity API 对应起来,当你在 Inspector 面板上每一个内容,应该知道对应 API。例如:table 的对象是 GameObject,第一个选择框是 activeSelf 属性。
table 对象(实体)的属性
Name: 对象的名字
Static: 准备静态几何结构以用于自动批处理;计算遮挡剔除 (Occlusion Culling)
Tag: 用于通过 Tag 名称来快速查找对象
Layer: 可用于仅对某些特定的对象组投射光线、渲染或应用光照
Transform 的属性
Position: X、Y 和 Z 坐标中变换的位置。(0, 0, 0)
Rotation: 围绕 X、Y 和 Z 轴的旋转,以度计。(0, 0, 0)
Scale: 沿 X、Y 和 Z 轴的缩放,“1” 是原始大小。(1, 1, 1)
(3)用UML图描述 三者的关系(请使用 UMLet 14.1.1 stand-alone版本出图)
五、资源预设(Prefabs)与 对象克隆 (clone)
(1)预设(Prefabs)有什么好处?
预设就是预制好的游戏对象,包含了完整的组件和属性,可看作是游戏对象的模板。利用预制能够批量实例化出具有相同属性的游戏对象。预设与实例之间是联系的,改变预设的属性能够更改所有与之关联的对象的属性。
(2)预设与对象克隆(clone or copy or Instantiate of Unity Object) 关系?
对象克隆只是对对象的复制,新对象与克隆本体之间没有关联,不会相互影响。而对预设进行修改会作用到该预设所有的实例上。
(3)制作table 预制,写一段代码将 table 预制资源实例化成游戏对象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class createTable : MonoBehaviour
{
public GameObject table;
// Start is called before the first frame update
void Start()
{
GameObject temp = (GameObject)Instantiate(table, transform.position, transform.rotation);
}
// Update is called once per frame
void Update()
{
}
}
编程实践、小游戏
游戏内容:井字棋
项目代码地址
效果图如下
完整代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
private int player;
private int result;
private int [,] matrix2D;
private int [] repent;
void OnGUI()
{
GUIStyle TitleStyle = new GUIStyle();
TitleStyle.normal.background = null;
TitleStyle.normal.textColor= new Color(0, 0, 0, 1);
TitleStyle.fontSize = 30;
GUIStyle fontStyle1 = new GUIStyle();
fontStyle1.normal.background = null;
fontStyle1.normal.textColor= new Color(1, 1, 1, 1);
fontStyle1.fontSize = 15;
GUIStyle fontStyle2 = new GUIStyle();
fontStyle2.normal.background = null;
fontStyle2.normal.textColor= new Color(1, 0, 1, 1);
fontStyle2.fontSize = 15;
GUI.Label(new Rect(130,20,100,100),"Tic Tac Toe",TitleStyle);
if (GUI.Button(new Rect(250, 90, 80, 40), "Restart"))
Reset();
if ( result == 0 && GUI.Button(new Rect(250, 130, 80, 40), "Repent"))
Repent();
for(int i = 0;i < 3;i ++ ){
for(int j = 0;j < 3;++ j){
// if(result != 0) continue;
if(matrix2D[i,j] == 1)
GUI.Button(new Rect(50*i+50, 50*j+70, 50, 50), "X");
else if(matrix2D[i,j] == 2)
GUI.Button(new Rect(50*i+50, 50*j+70, 50, 50), "O");
else if(result != 0){
if(GUI.Button(new Rect(50*i+50, 50*j+70, 50, 50), ""))
;
}
else{
if(GUI.Button(new Rect(50*i+50, 50*j+70, 50, 50), "")){
matrix2D[i,j] = 1 + player % 2;
repent[0] = i; repent[1] = j;
result = check();
player ++;
}
}
}
}
if (result == 1) {
GUI.Label (new Rect (250, 190, 80, 40), "Player1 wins!", fontStyle2);
} else if (result == 2) {
GUI.Label (new Rect (250, 190, 80, 40), "Player2 wins!", fontStyle2);
} else {
GUI.Label (new Rect (260, 190, 80, 40), "Playing...", fontStyle1);
}
}
// Start is called before the first frame update
void Start()
{
Reset();
}
void Reset(){
player = 0;
result = 0;
matrix2D = new int [3,3]{
{0,0,0},
{0,0,0},
{0,0,0}
};
repent = new int [2] {0,0};
}
void Repent(){
player ++;
matrix2D[repent[0],repent[1]] = 0;
}
int check(){
for(int i = 0;i < 3;i ++){
if(matrix2D[i,0] == matrix2D[i,1] && matrix2D[i,1]== matrix2D[i,2] && matrix2D[i,0] != 0) return matrix2D[i,0];
if(matrix2D[0,i] == matrix2D[1,i] && matrix2D[1,i]== matrix2D[2,i] && matrix2D[0,i] != 0) return matrix2D[0,i];
}
if(matrix2D[0,0] == matrix2D[1,1] && matrix2D[1,1] ==matrix2D[2,2]) return matrix2D[1,1];
if(matrix2D[0,2] == matrix2D[1,1] && matrix2D[1,1] ==matrix2D[2,0]) return matrix2D[1,1];
return 0;
}
// Update is called once per frame
void Update(){
}
}