离散仿真引擎基础

久未见 提交于 2019-11-29 11:58:32

1、简答题

(1)解释 游戏对象(GameObjects) 和 资源(Assets)的区别与联系。

游戏对象

游戏对象指的是在游戏场景中出现的对象,包括BOSS、NPC等等。

资源

资源相当于一种模板,包括图片、音频、视频、代码文件等。

联系

游戏对象可以保存为资源;资源可以作为游戏对象的模板。

(2)下载几个游戏案例,分别总结资源、对象组织的结构(指资源的目录组织结构与游戏对象树的层次结构)

打开steam的文件夹
在这里插入图片描述
music、skins、resource均属于资源组织结构文件
steam、steamapps文件中的软件文件属于对象组织结构文件

(3)编写一个代码,使用 debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件

基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate()

常用事件包括 OnGUI() OnDisable() OnEnable()

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

public class NewBehaviourScript : MonoBehaviour {

	void Start()
    {
        Debug.Log("Start");
    }

    private void Awake()
    {
        Debug.Log("Awake");
    }

    void Update()
    {
        Debug.Log("Update");
    }

    private void FixedUpdate()
    {
        Debug.Log("FixedUpdate");
    }

    private void LateUpdate()
    {
        Debug.Log("LateUpdate");
    }

    private void OnGUI()
    {
        Debug.Log("OnGUI");
    }

    private void OnDisable()
    {
        Debug.Log("OnDisable");
    }

    private void OnEnable()
    {
        Debug.Log("OnEnable");
    }
}

查看Console
在这里插入图片描述

Awake

当前控制脚本实例被装载的时候调用。一般用于初始化整个实例使用。

Start

当前控制脚本第一次执行Update之前调用。

Update

每帧都执行一次。这是最常用的事件函数。

FixedUpdate

每固定帧绘制时执行一次。

LateUpdate

在每帧执行完毕调用,他是在所有update结束后才掉,比较适合用于命令脚本的执行。

OnDisable

当对象变为不可用或非激活状态时此函数被调用。当物体被销毁时它将被调用,并且可用于任意清理代码。当脚本编译完成之后被重加载时,OnDisable将被调用。

OnEnable

当对象变为可用或激活状态时此函数被调用。

OnGUI

绘制GUI时候触发。一般在这个函数里绘制GUI菜单。

(4)查找脚本手册,了解 GameObject,Transform,Component 对象

分别翻译官方对三个对象的描述(Description)

GameObject:Base class for all entities in Unity Scenes.
游戏对象:Unity视图中所有实体的基类。

Transform:Position, rotation and scale of an object.
变换:一个对象的位置、循环以及大小。

Component:Base class for everything attached to GameObjects.
组件:所有附加到游戏对象上的东西的基类。

(5)资源预设(Prefabs)与 对象克隆 (clone)

预设(Prefabs)有什么好处?

通过预设可以在一定程度上简化创建的过程。预设的目的是为相同属性的对象创建模板,这样再次创建对象时可以变得相当简便。

预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?

首先,两者的目的都是为了得到属性相同的一堆游戏对象。但预设是固定了一个模板,通过模板创建的对象都是固定属性的,除非你改变模板的固有属性;而对象克隆是与被克隆对象的属性一样,当你改变被克隆对象后,再次克隆的新对象与原来克隆的对象属性不同。

2、编程实践,小游戏

  • 游戏内容: 井字棋 或 贷款计算器 或 简单计算器 等等
  • 技术限制: 仅允许使用 IMGUI 构建 UI
  • 作业目的:
    • 了解 OnGUI() 事件,提升 debug 能力
    • 提升阅读 API 文档能力

代码如下:

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

public class NewBehaviourScript : MonoBehaviour
{
 
    private int empty;
    private int turn;
    private int[,] chess = new int[3, 3];

    void Start()
    {
        reset();
    }

    void reset()
    {
        empty = 9;
        turn = 1;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++){
                chess[i, j] = 0;
            }
        }
    }
 
    private void OnGUI()
    {
        int result = is_win();

        GUI.skin.button.fontSize = 50;
        GUI.skin.label.fontSize = 20;

        if(GUI.Button(new Rect(150,200,200,80), "Reset")) {
            reset();
        }
 
        if(result == 1) {
            GUI.Label(new Rect(500, 20, 100, 50), "X wins");
        }
        else if (result == 2) {
            GUI.Label(new Rect(500, 20, 100, 50), "O wins");
        }
        else if (result == 3) {
            GUI.Label(new Rect(470, 20, 200, 50), "It's a draw");
        }
 
        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                if (chess[i, j] == 1) {
                    GUI.Button(new Rect(i * 100 + 400, j * 100 + 80, 100, 100), "X");
                }
                if (chess[i, j] == 2) {
                    GUI.Button(new Rect(i * 100 + 400, j * 100 + 80, 100, 100), "O");
                }
                if(GUI.Button(new Rect(i * 100 + 400, j * 100 + 80, 100, 100), "")) {
                    if(result == 0) {
                        if (turn == 1) chess[i, j] = 1;
                        if (turn == 2) chess[i, j] = 2;
                        empty--;
                        if(empty%2 == 1) {
                            turn = 1;
                        }
                        else {
                            turn = 2;
                        }
                    }
                }
            }
        }
    }
 
    int is_win()
    {
        int win = chess[0, 0];
        if (win != 0) {
            if (win == chess[0, 1] && win == chess[0, 2]) {
                return win;
            }
            if (win == chess[1, 0] && win == chess[2, 0]) {
                return win;
            }
        }

        win = chess[2, 2];
        if (win != 0) {
            if (win == chess[2, 0] && win == chess[2, 1]) {
                return win;
            }
            if (win == chess[0, 2] && win == chess[1, 2]) {
                return win;
            }
        }

        win = chess[1, 1];
        if(win != 0) {
            if (win == chess[0, 0] && win == chess[2, 2]) {
                return win;
            }
            if (win == chess[0, 2] && win == chess[2, 0]) {
                return win;
            }
            if (win == chess[0, 1] && win == chess[2, 1]) {
                return win;
            }
            if (win == chess[1, 0] && win == chess[1, 2]) {
                return win;
            }
        }

        if(empty == 0) {
            return 3;
        }
        else {
            return 0;
        }
    }
}

reset()初始化棋盘;
OnGUI()中编写UI并编写button的落子;
is_win()通过对角线上三个位置判断是否有一方赢。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!