3D 游戏与编程——作业二
1、简答题
1)解释 游戏对象(GameObject)和 资源(Assets)的区别和联系
Assets 是游戏中具体的资源,比如 texture,mesh,material,shader,script 等,它们存在于文件夹中,不一定用到;GameObject 是游戏中实际存在的对象,由 Assets 实例化而来,是对 Assets 的引用和复制的关系。
2)下载几个游戏案例,总结资源、对象组织的结构(指资源的目录组织结构与游戏对象树的层次结构)
以上是某个游戏的资源的结构,包含模型,预制,脚本等游戏资源,分门别类地存放在不同文件夹中,便于整理和使用。
上图是该游戏对象的结构,根据对象的类型(General, Player, Lever, Game-Mode)存放在不同文件夹下,便于修改,组织。
3)编写一个代码,使用debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件。(基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate();常用事件包括 OnGUI() OnDisable() OnEnable() )
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FirstBeh : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Debug.Log("This Start!");
}
// Update is called once per frame
void Update()
{
Debug.Log("This Updated");
}
void OnEnable()
{
Debug.Log("This Enabled");
}
void OnDisable()
{
Debug.Log("This Disabled");
}
void Awake()
{
Debug.Log("This Awaked");
}
void LateUpdated()
{
Debug.Log("This LateUpdated");
}
void FixedUpdate()
{
Debug.Log("This FixedUpdate");
}
private void OnGUI()
{
Debug.Log("This is ONGUI");
}
}
Awake:当一个游戏对象实例被载入时被调用,或是脚本构造时调用
Start:第一次进入游戏循环时调用
Update:当行为启用时,其 Update 在每一帧被调用
Fixedupdate:当行为启用时,其 Fixedupdate 在每一时间片被物理引擎调用
OnGUI:渲染和处理 GUI 事件时调用
OnEnable:当对象变为可用或激活状态时被调用
OnDisable:当对象变为不可用或非激活状态时被调用
LateUpdate:所有 Update 调用完之后,被游戏循环调用
4)查找脚本手册,了解 GameObject,Transform,Component 对象
分别翻译官方对三个对象的描述(Description)
描述下图中 table 对象(实体)的属性、table的Transform的属性、table的部件
用UML 图描述 三者的关系(请使用UMLet 14.1.1 stand-alone版本出图)、
Description:
- GameObject:是Unity场景里面所有实体的基类。
- Transform:物体的位置、旋转和缩放。
- Component:一切附加到游戏物体的基类。
描述:
- activeSelf:可以定义对象的名称,动静态等属性
- Transform:可以定义对象的位置、面向方向、大小
- Box Collider:可以调整坐标系的位置、大小
- Component:可以给对象增加行为
5)资源预设(Prefabs)与对象克隆(clone)
预设(Prefabs)有什么好处?
预设与对象克隆(clone or copy or Instantiate of Unity Object)关系?
制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象
资源预设(Prefabs)的好处:
预设就是将设计游戏中所需要的游戏对象进行设计打包,成为一个新的整体,在接下来的设计中作为一个新对象与其他组件发生交互。预设充分发挥了“组合优于继承”的思想和面向对象的思想,让我们在设计过程中更加灵活快捷。
预设与对象克隆的关系:
克隆是将已经存在的游戏对象,或者是资源当中的预设进行复制。预设本身不需要有实例化的游戏对象,而克隆需要复制实例化的游戏对象。而且如果要集中修改通过将预设实例化创建出来的对象,只需要修改预设就能全都修改,方便批量修改。而如果要修改克隆出来的对象只能一个一个修改。
void Start() { print("hello"); Debug.Log("start!"); Object temp = Resources.Load("new_table"); GameObject cube = Instantiate(temp) as GameObject; cube.transform.position = new Vector3(0, 5, 0); }
2、编程实践,小游戏
简单计算器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Calculator : MonoBehaviour
{
public string str_res;
public static string str_a;
public static string str_b;
public static string str_opera;
float res;
void Start()
{
Init();
}
void Init()
{
str_res = "0";
str_a = "";
str_b = "";
str_opera = "";
res = 0;
}
void OnGUI()
{
GUI.Box(new Rect(0, 0, 350, 220), "");
//对数字进行处理
if (GUI.Button(new Rect(0, 0, 50, 30), "1"))
{
str_a += "1";
str_res = str_a;
}
if (GUI.Button(new Rect(60, 0, 50, 30), "2"))
{
str_a += "2";
str_res = str_a;
}
if (GUI.Button(new Rect(120, 0, 50, 30), "3"))
{
str_a += "3";
str_res = str_a;
}
if (GUI.Button(new Rect(180, 0, 50, 30), "4"))
{
str_a += "4";
str_res = str_a;
}
if (GUI.Button(new Rect(0, 40, 50, 30), "5"))
{
str_a += "5";
str_res = str_a;
}
if (GUI.Button(new Rect(60, 40, 50, 30), "6"))
{
str_a += "6";
str_res = str_a;
}
if (GUI.Button(new Rect(120, 40, 50, 30), "7"))
{
str_a += "7";
str_res = str_a;
}
if (GUI.Button(new Rect(180, 40, 50, 30), "8"))
{
str_a += "8";
str_res = str_a;
}
if (GUI.Button(new Rect(0, 80, 50, 30), "9"))
{
str_a += "9";
str_res = str_a;
}
if (GUI.Button(new Rect(60, 80, 50, 30), "0"))
{
str_a += "0";
str_res = str_a;
}
//计算符号
if (GUI.Button(new Rect(120, 80, 50, 30), "+"))
{
str_opera = "+";
print(str_b);
if (str_a != null)
{
str_b = str_a;
}
str_a = "";
str_res = str_b;
}
if (GUI.Button(new Rect(60, 120, 50, 30), "-"))
{
str_opera = "-";
if (str_a != null)
{
str_b = str_a;
}
str_a = "";
str_res = str_b;
}
if (GUI.Button(new Rect(0, 120, 50, 30), "*"))
{
str_opera = "*";
if (str_a != null)
{
str_b = str_a;
}
str_a = "";
str_res = str_b;
}
if (GUI.Button(new Rect(180, 80, 50, 30), "/"))
{
str_opera = "/";
if (str_a != null)
{
str_b = str_a;
}
str_a = "";
str_res = str_b;
}
if (GUI.Button(new Rect(0, 160, 50, 30), "C"))
{
if (str_a == "")
{
str_res = "0";
return;
}
else
{
str_a = str_a.Substring(0, str_a.Length - 1);
}
str_res = str_a;
}
if (GUI.Button(new Rect(120, 120, 50, 30), "="))
{
if (str_opera == "+")
{
res = float.Parse(str_b) + float.Parse(str_a);
}
else if (str_opera == "-")
{
res = float.Parse(str_b) - float.Parse(str_a);
}
else if (str_opera == "*")
{
res = float.Parse(str_b) * float.Parse(str_a);
}
else if (str_opera == "/")
{
res = float.Parse(str_b) / float.Parse(str_a);
}
str_b = res.ToString();
str_a = "";
str_res = res.ToString();
}
if (GUI.Button(new Rect(180, 120, 50, 30), "CE"))
{
str_a = "";
str_a = "";
res = 0;
str_res = "";
}
GUI.Label(new Rect(300, 0, 100, 30), str_res);
}
}
测试截图: