文章目录

  • C# Classes for Behaviours
  • Custom Classes
    • 1. Custom Classes
    • 2. Serialized Custom Class RPG Item Database Example
    • 3. When and Why to Use Custom Classes
  • Challenge: Customer Database
  • Custom Class - RPG Spell System Presentation

C# Classes for Behaviours

  • 我们在 unity 中新建一个 C# 脚本,都会生成一个默认的 Class:public class Test : MonoBehaviour ,这个类继承于 MonoBehaviour 这个基类,这样的脚本可以挂载到游戏对象下面。
  • 而 Class 是面向对象编程的核心,这会让我们的程序模块化,更清晰,更容易理解
    • 比如我们可以有一个脚本挂载在 Player 这个游戏对象下面,控制 Player 的各种运动
    • 同时有一个脚本挂载在 arrow 下面,控制玩家发射的弓箭运动
    • 这些脚本都需要继承于 MonoBehaviour
  • 当然我们也可以有不继承于 MonoBehaviour 的 Class
  • 对于一个 Class 下面,我们也可以利用 Methods 用于区分不同的功能
    • 比如对于 Player 控制的类
    • 我们可以有一个方法用于控制移动
    • 还可以有一个方法控制发射弓箭
    • 还可以有个方法控制升级和能力提升,等等
    • 而在 Update 这个主要的方法中,只需要在需要的时候调用对应的功能方法即可
    • 便于管理代码,查询 bug

Custom Classes

1. Custom Classes

  • 假设我们有一个射击游戏

    • 我们可以获取不同的枪
    • 这个时候,对于不同的枪,就不适合定义在 Player 的脚本下面
    • 最好单独设计一个 Class 来存放不同的枪的定义

那么问题来了,如何定义一个 Class 呢?

  • 首先我们要知道,这个 Class 下面需要涵盖哪些东西

    • 比如枪的名字,攻击力,冷却时间,描述等
    • 所以我们可以把这里的 Class 理解为一种整体的描述
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Weapon // 创建一个武器的类,这里不需要继承 MonoBehaviour
{public string name;public int attack;public float coolDown;public string description;
}public class Player : MonoBehaviour
{public Weapon smallGun; // 创建一个变量,类型为武器public Weapon bigGun;// Start is called before the first frame updatevoid Start(){smallGun = new Weapon(); // 实例化,即武器被实际创建出来smallGun.name = "Mini"; // 设定名字smallGun.attack = 2; // 攻击力smallGun.coolDown = 0.1f; // 冷却时间smallGun.description = "It's a small gun!"; // 描述bigGun = new Weapon(){name = "Bob",attack = 20,coolDown = 2.2f,description = "It's a very big gun!"}; // 也可以通过这种方式实例化的时候同时设定属性}// Update is called once per framevoid Update(){}
}

注意,在 C# 中,也可以在一个 Class 中创建新的 Class。

上面的写法看起来还是比较复杂,我们还可以用构造函数使得写法更清晰明了:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Weapon // 创建一个武器的类,这里不需要继承 MonoBehaviour
{public string name;public int attack;public float coolDown;public string description;public Weapon(string name, int attack, float coolDown, string description)// 构造函数{this.name = name;this.attack = attack;this.coolDown = coolDown;this.description = description;}
}public class Player : MonoBehaviour
{public Weapon smallGun; // 创建一个变量,类型为武器public Weapon bigGun;// Start is called before the first frame updatevoid Start(){smallGun = new Weapon("Mini", 2, 0.1f, "It's a small gun!");// 实例化,并设定属性bigGun = new Weapon("Bob", 20, 2.2f, "It's a very big gun!");// 实例化,并设定属性}// Update is called once per framevoid Update(){}
}

构造函数,就是在实例化一个 Class 的时候运行的代码,注意构造函数的名字需要和 Class 的名字相同。

我们还可以直接调用显示相应的信息:Debug.Log(smallGun.name);

这样在游戏中,我们就可以换武器了!

2. Serialized Custom Class RPG Item Database Example

  • 如何为一个 RPG 游戏创建一个道具的数据库

    • 我们需要设计一个 Class 来定义 item
  • 首先创建一个 C# 脚本,命名为 Item

    • 这里可以把 : MonoBehaviour 删除,因为这个脚本不需要挂载到游戏对象下面
    • 假设我们每个道具有 3 个属性:id,名字,描述
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Item
{public int id;public string name;public string description;public Item(){// 空的构造函数,用于初始化空的道具// 这里多个构造函数是允许的// 即我们实例化的时候会发现两种构造形式,一种不需要传入参数,一种需要 3 个参数}public Item(int id,string name,string description){this.id = id;this.name = name;this.description = description;}
}
  • 然后我们再创建一个 C# 脚本,命名为 ItemDatabase

    • 这个 Class 是继承于 MonoBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ItemDatabase : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}
  • 再随便创建一个空的游戏对象,命名为 ItemDatabase

    • 把 ItemDatabase 脚本挂载到这个游戏对象下面

现在我们想要创建一个道具:一把剑

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ItemDatabase : MonoBehaviour
{public Item sword;public Item Axe;// Start is called before the first frame updatevoid Start(){sword = new Item(0, "sword", "It's a sword");Axe = new Item(); // 由于有两种构造函数,这里可以选择先生成再赋值Axe.id = 1;Axe.name = "axe";Axe.description = "It's great!";}// Update is called once per framevoid Update(){}
}

我们也可以把创建道具的过程提取出来放置到一个函数中。

  • Unity 中还有一个特殊功能叫做 serialization,即可以让我们创建的 Class 在 inspector 中可见

需要在我们创建的 Class 前面加上语句:[System.Serializable]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class Item
{public int id;public string name;public string description;public Item(){// 空的构造函数,用于初始化空的道具// 这里多个构造函数是允许的// 即我们实例化的时候会发现两种构造形式,一种不需要传入参数,一种需要 3 个参数}public Item(int id,string name,string description){this.id = id;this.name = name;this.description = description;}
}

保存脚本后,进入 unity,可以看到 inspector 中的脚本组件下面已经显示了 sword 和 axe

这时候我们甚至可以直接在 inspector 中对不同的属性进行设定

这个时候我们可以有更加灵活的编写方式,修改 ItemDatabase 的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ItemDatabase : MonoBehaviour
{public Item[] items;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}

这个时候回到 unity 中,我们可以任意定义想要创建几个武器(比如20个),并输入每个武器的属性。

这里有个小技巧:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class Item
{public string name; // 把名字放在第一个属性public int id;public string description;public Sprite icon; // 设定道具图标public Item(){// 空的构造函数,用于初始化空的道具// 这里多个构造函数是允许的// 即我们实例化的时候会发现两种构造形式,一种不需要传入参数,一种需要 3 个参数}public Item(int id,string name,string description){this.id = id;this.name = name;this.description = description;}
}

如果我们把 name 放在第一个属性,那么进入 unity 中编辑每个 item 的名字,Element 2这样的编号就自动会变成 item 的名字!其实只要第一个属性是字符串就会有这样的效果,但是通常我们会将名字放在第一个位置,而不是描述或者其他的属性。

使用 public Sprite icon; 在 unity 中可以拖动赋值道具显示图标。

在脚本中,我们可以调取这些 unity 中设定的武器的具体信息:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ItemDatabase : MonoBehaviour
{public Item[] items;// Start is called before the first frame updatevoid Start(){Debug.Log(items[1].name); // 显示 1 号武器的名字}// Update is called once per framevoid Update(){}
}

3. When and Why to Use Custom Classes

  • 为什么我们需要自己设计定制化的 Class 呢?

    • 假设我们有一个 RPG 游戏,而我们创建了一个脚本 sword 来设定一个武器,比如还有其他 20 种武器,那我一共需要创建 21 个脚本来设定武器吗?除了武器还有其他道具,加起来上千种,那难道要创建上千个脚本文件吗?当然不是!
    • 我们会发现,这些需要创建的武器也好,道具也好,都有很多的共同点,比如都有名字,都有一个描述,甚至有些游戏中都有一个价格,那就创建一个 Class 吧!
  • 所以什么时候需要自己创建一个 Class 呢?
    • 比如你制作个什么东西,发现有很多类似的东西需要制作,就像上面提到的武器,或者你要设计多种能力提升的光环,有的光环提升速度,有的提升攻击力,都可以考虑使用定制化 Class。
    • 有比如像要创建敌人,各种小怪,包括 boss 大多数属性都是共同的,比如有血量,攻击力,攻击频率,攻击范围等,这时候也可以考虑写个 Class 定义 enemy。

Challenge: Customer Database

  • 任务说明:

    • 设计一个 database,用于存储角色信息
    • 每个角色包含以下信息:名字,年龄,职业,攻击力,防御力,魔法值
    • 这里需要设计两个 Class,一个是定义角色,一个是数据库

首先建立一个脚本,定义角色的类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class Character // 记住这里不能继承 MonoBehaviour,否则会出错
{public string name;public int age;public string occupation;public int attack;public int defence;public int magic;public Character(string name,int age,string occupation,int attack, int defence, int magic) {this.name = name;this.age = age;this.occupation = occupation;this.attack = attack;this.defence = defence;this.magic = magic;}
}

创建一个空的游戏对象,定义为 CharacterDatabase,在其下面挂载数据库脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CharacterDatabase : MonoBehaviour
{public Character[] characters;// Start is called before the first frame updatevoid Start(){foreach(var item in characters){Debug.Log("Name: "+item.name+" Age: "+item.age);// 打印所有角色的名字和年龄}}// Update is called once per framevoid Update(){}
}

在 unity 中将角色个数设定为 3,然后输入 3 个角色的属性。

运行游戏后,即可打印出这 3 个角色的名字和年龄。

Custom Class - RPG Spell System Presentation

  • 任务说明:

    • 设定一个 cube 当作魔法师,会运用各种魔法
    • 魔法包括:名字,等级,伤害,熟练度
    • 设计一个魔法升级系统,每使用一次魔法增加熟练度,熟练度到100即升级,增加伤害
    • 魔法可以任意切换

创建一个魔法的类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class Magic
{public string name; // 魔法名字public int level; // 魔法等级public int damage; // 魔法伤害public int exp; // 魔法熟练度public Magic(string name,int level, int damage,int exp){this.name = name;this.level = level;this.damage = damage;this.exp = exp;}public void Cast() // 在该类下面设置一个释放魔法的方法{Debug.Log("Cast: " + name); // 释放魔法}
}

创建一个 cube 游戏对象,命名为 Magician,挂载一个同名的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Magician : MonoBehaviour
{public Magic[] magics;private int _id;// Start is called before the first frame updatevoid Start(){magics = new Magic[3];magics[0] = new Magic("Fire", 1, 10, 0);magics[1] = new Magic("Ice", 1, 20, 0);magics[2] = new Magic("Wind", 1, 30, 0);_id = 0; //设置默认魔法Debug.Log("You are using: " + magics[_id].name);}// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.Q)){_id = 0; // 按下 Q 切换到第一个魔法Debug.Log("You are using: " + magics[_id].name);}else if (Input.GetKeyDown(KeyCode.W)){_id = 1; // 按下 W 切换到第二个魔法Debug.Log("You are using: " + magics[_id].name);}else if (Input.GetKeyDown(KeyCode.E)){_id = 2; // 按下 E 切换到第三个魔法Debug.Log("You are using: " + magics[_id].name);}if (Input.GetKeyDown(KeyCode.Space)){magics[_id].Cast(); // 释放魔法magics[_id].exp += 20; // 每次释放增加 20 点熟练度if (magics[_id].exp == 100) // 熟练度达到 100{magics[_id].level += 1; // 该魔法等级提升magics[_id].damage = magics[_id].damage * magics[_id].level; // 伤害提升magics[_id].exp = 0; // 熟练度回到 0}}}
}

Unity的C#编程教程_52_类 Class 详解及应用练习(一)相关推荐

  1. ∑ n!(1! 2!)用c语言怎么编,数控车床编程教程,图文实例详解!

    原标题:数控车床编程教程,图文实例详解! 第一节数控车床编程基础 一.数控车编程特点 (1) 可以采用绝对值编程(用X.Z表示).增量值编程(用U.W表示)或者二者混合编程. (2) 直径方向(X方向 ...

  2. 数控车椭圆编程实例带图_数控车床编程教程,图文实例详解

    一.数控车编程特点 (1) 可以采用绝对值编程(用X.Z表示).增量值编程(用U.W表示)或者二者混合编程. (2) 直径方向(X方向) 系统默认为直径编程,也可以采用半径编程,但必须更改系统设定. ...

  3. hibernate教程--持久化类状态详解

    一. Hibernate的持久化类状态: 1.1 Hibernate的持久化类状态 持久化类:就是一个实体类 与 数据库表建立了映射. Hibernate为了方便管理持久化类,将持久化类分成了三种状态 ...

  4. java uml类图教程_Java利器之UML类图详解

    原标题:Java利器之UML类图详解 (点击上方公众号,可快速关注) 来源:伯乐在线专栏作者- Code4Android 如需转载,发送「转载」二字查看说明 前言 UML(Unified Modeli ...

  5. get方法报空指针_C++基础教程之指针拷贝详解

    C++基础教程之指针拷贝详解 指针是编程人员的梦魇,对C语言的开发者是如此,对C++的开发者也是如此.特别是在C++中,如果不注意处理类中的指针,非常容易出问题.如果朋友们不相信可以看看下面的代码: ...

  6. android 多闹钟实现代码,Android编程实现闹钟的方法详解

    Android编程实现闹钟的方法详解 发布时间:2020-09-30 10:18:02 来源:脚本之家 阅读:75 作者:Jacob-wj 本文实例讲述了Android编程实现闹钟的方法.分享给大家供 ...

  7. Nmap扫描教程之基础扫描详解

    Nmap扫描教程之基础扫描详解 Nmap扫描基础扫描 当用户对Nmap工具了解后,即可使用该工具实施扫描.通过上一章的介绍,用户可知Nmap工具可以分别对主机.端口.版本.操作系统等实施扫描.但是,在 ...

  8. Java记录 -22- Java的基类Object详解

    Java的基类Object详解 Java的JDK文档要经常查阅使用,最好查看英文的文档. Oracle官方在线 Java API Specifications http://www.oracle.co ...

  9. Java多线程编程中Future模式的详解

    转载自 https://www.cnblogs.com/winkey4986/p/6203225.html Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker ...

最新文章

  1. 数据分析之CE找数据大法
  2. 支持实践教学:清华大数据能力提升项目举办CIKM AnalytiCup2017冠军团队经验分享会
  3. 《C程序设计语言》读书笔记----习题1-21
  4. php拍视频上传,php视频拍照上传头像功能实现代码分享
  5. [翻译] TWRPickerSlider
  6. java 运行时路径_如何在运行时检查当前Java类路径(重复)
  7. RMI强制Full GC每小时运行一次
  8. Winform 下拉框绑定问题
  9. UPUPW PHP环境集成包,增加多个PHP版本支持,可选择使用
  10. .md文件好用编辑软件分享Typora
  11. MPC的终结——二次规划求解约束极值问题
  12. 分享一个Atmega128L单片机在IAR for AVR中的串口1收发数据的例程
  13. jspx框架使用总结-页面开发
  14. java实现PDF转tif格式并且设置颜色和dpi
  15. 海思AI芯片(35xx):板端运行报错
  16. 解决ubuntu无法解析域名、无网络连接问题
  17. mysql pdo 端口_链接Mysql的api mysqli和pdo
  18. 都在发做圣诞树,我来点不一样的,用python给对象戴一顶圣诞帽
  19. 【绊脚石】安装pycocotools和lap失败
  20. 财神来了 | 那些年伤害过你的分叉币

热门文章

  1. 自我介绍 写博客的计划
  2. 全国计算机等级考试二级 Python 软件安装指南
  3. 一位内核开发者的见闻
  4. 常用的相似性度量算法
  5. 华为计划未来3年投入1亿美元支持亚太初创生态;爱立信与麻省理工学院合作研究新一代移动网络 | 全球TMT...
  6. java-net-php-python-51ssm文件存储管理系统计算机毕业设计程序
  7. 如何挑选家用投影仪?投影仪哪个牌子的好
  8. 我来过,我很乖(催人泪下)
  9. 内存/闪存集体缺货涨价 原因竟是这?
  10. stm32启动过程、cortex-m3架构、堆栈代码位置、编译汇编链接分析