3D游戏编程作业blog2

1.简答题

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

区别:游戏对象是场景中所有物体的总称,是场景中可以看到的任何东西,可以是各种类别的物体。资源是指项目文件中需要用到的材料,可以是图片、音频等,统一存放在文件夹内。
联系: 游戏对象可以保存在资源里,游戏对象可以是资源实例化出来的物体。资源也可以是游戏对象的属性。资源可以创建对象,一个资源可以创建多个对象。

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

资源的目录组织结构:
性质相同的资源以文件夹的情形时放在一个文件里。资源主要包括动画,文本,场景,素材,模型,预设以及使用说明等。
游戏对象树的层次结构:
可以理解为树的分差,一个对象包含有多个子对象,子对象包含多个子对象

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

基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate()
常用事件包括 OnGUI() OnDisable() OnEnable()
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript1 : 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");
    }
}

运行结果如下


运行结果

awake:当一个脚本实例被载入时被调用
start:在所有update函数之前被调用一次
update:当行为启用时,其update在每一帧被调用
fixedupdate:当行为启用时,其fixedupdate在每一时间片被调用
OnGUI:渲染和处理GUI事件时调用
OnEnable:当对象变为可用或激活状态时被调用
OnDisable:当对象变为不可用或非激活状态时被调用

· 查找脚本手册,了解 GameObject,Transform,Component 对象

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

1) 游戏对象(GameObject) 用于表示任何可以存在于场景中的事物。
游戏中的每个对象(从角色和可收集物品到光源、摄像机和特效)都是 游戏对象。但是,游戏对象本身无法执行任何操作;您需要向游戏对象提供属性,然后游戏对象才能成为角色、环境或特效。
游戏对象 是 Unity 中的基础对象,表示角色、道具和景物。它们本身并没有取得多大作为,但它们充当 组件 的容器,而组件可实现功能。
为了向游戏对象提供成为光源、树或摄像机所需的属性,需要向游戏对象添加组件。根据要创建的对象类型,可以向游戏对象添加不同的组件组合。

2) 变换组件(Transform) 用于存储游戏对象的位置、旋转、缩放和父子化状态,因此非常重要。游戏对象始终附加一个变换组件,无法删除变换组件或创建没有变换组件的游戏对象。

3) 组件(Component) 是每个 游戏对象 的功能部件。组件包含可以编辑以定义游戏对象行为的属性。有关组件和游戏对象之间关系的详细信息,请参见游戏对象。

· 描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件

本题目要求是把可视化图形编程界面与 Unity API 对应起来,当你在 Inspector 面板上每一个内容,应该知道对应 API。
例如:table 的对象是 GameObject,第一个选择框是 activeSelf 属性。

自制了一个table预制


作业二2.png

table 的对象是 GameObject
第一个选择框是activeSelf:可以定义对象的名称,动静态等属性
第二个选择框是Transform:可以定义对象的位置、面向方向、大小
第三个选择框是Add Component:可以添加对象的属性组件

UML图如下:

UML图

· 资源预设(Perfabs)和对象克隆(clone)

预设(Perfabs)有什么好处?

Unity 的预设系统允许创建、配置和存储游戏对象及其所有组件、属性值和子游戏对象作为可重用资源。预设资源充当模板,在此模板的基础之上可以在场景中创建新的预制件实例。如果要在场景中的多个位置或项目中的多个场景之间重用以特定方式配置的游戏对象,比如非玩家角色 (NPC)、道具或景物,则应将此游戏对象转换为预设。这种方式比简单复制和粘贴游戏对象更好,因为预制件系统可以自动保持所有副本同步。

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

预设与克隆都能创建出相同的对象。预设创建出的对象与源预设依然有联系,后者的更改会影响到前者。但是克隆出的对象与源对象不再有联系。

制作table预制,写一段代码将table预制资源实例化成游戏对象

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoadTable : MonoBehaviour {
    public transform table;
    void Start()
    {
        GameObject newobj=Instantiate<Transform>(table,this.tranform).gameObject;
        newobj.transform.position=new Vector3(0,Random.range(-5,5),0);
    }
}

2.编程实践,小游戏

游戏内容: 井字棋 或 贷款计算器 或 简单计算器 等等

技术限制: 仅允许使用 IMGUI 构建 UI

选择:井字棋

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class GUIgame : MonoBehaviour
{
    private int[,] chess = new int[3, 3];
    private int empty=9;
    private int turn = 1;
    void Start()
    {
        Init();
    }

    private void OnGUI()
    {
        GUI.skin.button.fontSize = 20;
        GUI.skin.label.fontSize = 30;
        if (GUI.Button(new Rect(450, 400, 200, 80), "Restart"))
        {
            Init();
        }
        int result = is_Win();
        if (result == 1)
        {
            GUI.Label(new Rect(500, 20, 100, 50), "O wins");
        }
        else if (result == 2)
        {
            GUI.Label(new Rect(500, 20, 100, 50), "X wins");
        }
        else if (result == 3)
        {
            GUI.Label(new Rect(470, 20, 200, 50), "no one wins");
        }
        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), "O");
                if (chess[i, j] == 2) 
                    GUI.Button(new Rect(i * 100 + 400, j * 100 + 80, 100, 100), "X");
                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 temp = chess[1, 1];
        if (temp != 0)
        {
            if (temp == chess[0, 0] && temp == chess[2, 2])
            {
                return temp;
            }
            if (temp == chess[0, 2] && temp == chess[2, 0])
            {
                return temp;
            }
            if (temp == chess[0, 1] && temp == chess[2, 1])
            {
                return temp;
            }
            if (temp == chess[1, 0] && temp == chess[1, 2])
            {
                return temp;
            }
        }
        //判断是否中心的十字形或者X字形
        temp = chess[0, 0];
        if (temp != 0)
        {
            if (temp == chess[0, 1] && temp == chess[0, 2])
            {
                return temp;
            }
            if (temp == chess[1, 0] && temp == chess[2, 0])
            {
                return temp;
            }
        }
        //判断是否是第一行或者第一列相同
        temp = chess[2, 2];
        if (temp != 0)
        {
            if (temp == chess[2, 0] && temp == chess[2, 1])
            {
                return temp;
            }
            if (temp == chess[0, 2] && temp == chess[1, 2])
            {
                return temp;
            }
        }
        //判断是否是第三行或者第三列相同
        if (empty == 0)
        {
            return 3;//没有空的地方,因此双方平局
        }
        else
        {
            return 0;//还未分出胜负
        }
    }
    void Init()
    {
        empty = 9;
        turn = 1;
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                chess[i, j] = 0;
    }
}
效果图
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容