[Unity] 基础的编程思想, 组件式开发
熟悉 C# 开发的朋友, 在刚进入 Unity 开发时, 不可避免的会有一些迷惑, 例如不清楚 Unity 自己的思想, 如何设计与架构一个应用程序之类的. 本篇文章简要的介绍一下 Unity 的基础编程思想.
独立
Unity 很少使用 C# 的标准库, 例如 C# 的网络, 事件驱动, 对象模型, 这些概念在 Unity 中几乎不会被用到. 甚至于, 连标准的 System 命名空间都很少被引用.
Unity 自己实现了一套较为完善的标准库, 以适用于游戏开发. 例如最简单的 “随机数”, 在 Unity 中, UnityEngine.Random
类实现了随机数生成. 并且它是一个静态类, 不需要我们创建随机数对象, 即可使用.
Unity 用到的, 最多是 C# 中的集合, LINQ 查询这些. 甚至于, Unity 中的 UI 事件处理器, 都不是一个标准的 C# EventHandler
. 完完全全算得上邪教.
命名
刚开始使用 Unity 的你, 肯定会疑惑, 为什么 Unity 的脚本中, 用于获取 Transform
组件的属性, 叫做 transform
, 而不是 Transform
. 一个公开的属性, 却不使用大驼峰命名法, 而是使用小驼峰?
事实上, Unity 压根不用 C# 的命名规范, 只有一部分与 C# 的命名规范统一. 例如, 它的类型还是大驼峰的, 它的接口也是以 I
开头的大驼峰命名. 不过单单属性命名与 C# 不统一这件事, 就已经能让大多数注重优雅的 C# 程序员火冒三丈了.
对象
刚刚也提到了, Unity 自己单独实现了一整套标准库, 只有少部分是使用 C# 的东西. 事实上, 在 Unity 中, 所有 Unity 可引用的对象都是由 UnityEngine.Object
派生而来的. 例如游戏对象 UnityEngine.GameObject
, 还有诸如 Camea
, RigidBody
这些各种各样的组件.
Unity 的对象封装了很多静态方法, 例如克隆一个对象, 销毁一个对象, 在场景中查找某个类型的对象. 由于我们在 Unity 中编辑的 C# 代码大多是一个继承了 UnityEngine.MonoBehavior
的脚本, 而它又间接继承 UnityEngine.Object
, 所以我们在代码中访问这些方法的时候, 就不需要写类名, 直接调用即可.
游戏对象与组件
在 C# 中, 实现功能的拓展是通过继承来实现的, 例如 Button
继承 Control
, 并在 Control
的基础上拓展出自己的功能, 但是 Unity 不是这样.
Unity 中, 每一个场景中的对象, 就单纯只是一个 GameObject
, 它自己本身没有任何功能. 如果要给一个对象添加一些功能, 就要为它挂载一些组件. 例如游戏中原始的一个 Sphere
物体, 它由 Transform
, MeshFilter
, MeshRenderer
, SphereCollider
这些组件构成, 他们分别负责承载 “物体的变换, 包括位置, 旋转, 缩放”, “网格的存储”, “网格的渲染”, “碰撞相关功能”.
不过, Unity 中的组件本身还是存在继承关系的. 例如 SphereCollider
和 BoxCollider
都是 Collider
的派生类.
只要理解了任何游戏中的物体都有一个最基本的游戏对象和提供功能的组件构成, 就可以理解大部分问题了. 根据这一点, 如果你想自己手动创建一个 Sphere
, 也可以先创建一个空对象, 然后按照 Sphere
的构成, 将所需要的组件逐个添加上去, 并正确的设置好属性, 就可以完美的复制出和自带的 Sphere
一模一样的物体了.
组件之间的依赖与互斥
组件也是有相互的关系的, 就像我们所用的 控制反转
中的服务一样, 我们将功能抽成一个个服务, 而服务之间存在依赖关系. Unity 的组件也是如此.
如果要使功能正常运行, 就需要同时添加组件所依赖的组件. 例如要实现物理效果, 我们需要添加一个 RigidBody
组件, 但是要使物体之间能够产生碰撞, 就需要再添加一个 Collider
. 如果单独添加 RigidBody
, 虽然物体会受重力影响, 但是因为不会产生碰撞, 所以会直接穿过其他物体.
至于组件的互斥, 有两种, 一种是完全不能共存的, 例如无法为一个物体同时添加 BoxCollider
和 BoxCollider2D
, 如果尝试添加, 编辑器中会提示 “组件冲突”. 另一种则是, 可以同时添加, 但是会产生一些奇怪效果的. 例如 CharacterController
和 RigidBody
同时添加到物体中时, 就会引起移动相关的问题.
全局单例与静态类
Unity 中很少使用静态类, 除非你要用静态类承载一些工具方法. 但如果是一些逻辑相关的东西, 那它基本都是像普通的脚本一样是非静态的, 而想要全局访问, 在 Unity 中更多使用的是 “单例模式”.
在平常的开发中, 我们大抵是很少用到单例的. 因为直接用静态就可以解决问题. 但是 Unity 中使用静态的话, 我们就没办法将它作为组件挂载到游戏对象上, 而且也不能通过 Unity 的编辑器对它的一些变量进行赋值, 不是很方便. 所以 Unity 单例用的更多.
需要注意的是, 平常编程中所使用的单例是没办法直接应用在 Unity 上的, Unity 的对象产生与销毁都与平常的开发有所不同, 需要做一点针对 Unity 的 “本地化” 才能正确使用.
管理类
Unity 会使用大量的 “管理类” 用来集中管理逻辑. 甚至于, 当你创建一个名字为 GameManager
的脚本时, 它的图标不是一个 C# 脚本图标, 而是一个特殊的齿轮图标. 由此可见 Unity 开发中有多重视这个.
相比较我们平常的桌面开发, 后端开发, 之所以 Unity 更常使用所谓的管理类, 是因为 Unity 游戏对象的通信是比较麻烦的, 而且一整个游戏的逻辑也更加复杂, 例如一场战斗的进行, 这时使用一个 “战斗管理” 的类来记录战斗相关的数据, 调用角色进行战斗, 要更加方便些.
相关文章:
[Unity] 基础的编程思想, 组件式开发
熟悉 C# 开发的朋友, 在刚进入 Unity 开发时, 不可避免的会有一些迷惑, 例如不清楚 Unity 自己的思想, 如何设计与架构一个应用程序之类的. 本篇文章简要的介绍一下 Unity 的基础编程思想. 独立 Unity 很少使用 C# 的标准库, 例如 C# 的网络, 事件驱动, 对象模型, 这些概念在 …...

SVN 项目管理笔记
SVN 项目管理笔记 主要是介绍 SVN 管理项目的常用操作,方便以后查阅!!! 一、本地项目提交到SVN流程 在SVN仓库下创建和项目名同样的文件夹目录;选中本地项目文件,选择SVN->checkout,第一个是远程仓库项…...

Android获取手机已安装应用列表JAVA实现
最终效果: 设计 实现java代码: //获取包列表private List<String> getPkgList() {List<String> packages new ArrayList<String>();try {//使用命令行方式获取包列表Process p Runtime.getRuntime().exec("pm list packages");//取得命令行输出…...
【校招VIP】有一个比赛获奖项目和参与的开源小项目,秋招项目竞争力够不够?三个标准,自己都可以估算
有个24届的学生问我:现在没有实习,能不能参与大厂秋招?手里有两个项目,一个是比赛的获奖项目,一个是CSDN上博主做的开源小项目,这两个项目竞争力够不够? 其实项目这块,无非就是三个…...
量化开发学习入门-概念篇
1.网格交易法 网格交易法(Grid Trading)是一种基于价格波动和区间震荡的交易策略。它适用于市场处于横盘或震荡的情况下。 网格交易法的基本思想是在设定的价格区间内均匀地建立多个买入和卖出水平(网格),并在价格上…...
【草稿】关于文本句子分割(中文+英文)以及向量处理
获取文本 主函数 Main # -*- encoding: utf-8 -*- # Author: SWHL # Contact: liekkaskono163.com from pathlib import Path from typing import Dict, List, Unionimport filetypefrom ..utils import logger from .image_loader import ImageLoader from .office_loader i…...

【瑞吉外卖】所遇问题及解决方法
太菜了实习之余瑞吉外卖补充一下基础知识(,不然真啥也不会了。 请输入正确的手机号! 是因为我测试了我的手机号,爆红,以为方法有错。但其实是前端代码检查手机号是否符合规范的语句有点()啊啊…...
【Hugo入门】基础用法
检查Hugo是否安装 hugo version显示所有可用命令 hugo help显示指定命令的可用子命令,例如查询server的所有子命令 hugo server --help建立你的网站,cd进入你的项目根目录运行 hugo默认发布内容到自动创建的public文件夹。 覆盖hugo或hugo server的默…...

Java实现一个简单的图书管理系统(内有源码)
简介 哈喽哈喽大家好啊,之前作者也是讲了Java不少的知识点了,为了巩固之前的知识点再为了让我们深入Java面向对象这一基本特性,就让我们完成一个图书管理系统的小项目吧。 项目简介:通过管理员和普通用户的两种操作界面࿰…...

网络安全等级保护2.0
等保介绍 信息系统运维安全管理规定(范文)| 资料 等保测评是为了符合国家法律发挥的需求,而不是安全认证(ISO) 一般情况没有高危安全风险一般可以通过,但若发现高位安全风险则一票否决 二级两年一次 三…...

【sql】MongoDB 增删改查 高级用法
【sql】MongoDB 增删改查 高级用法 相关使用文档 MongoDB Query API — MongoDB Manual https://www.mongodb.com/docs/manual/reference/sql-comparison //增 //新增数据2种方式 db.msg.save({"name":"springboot😀"}); db.msg.insert({&qu…...
怎么做才能有效更新和优化产品手册文档
更新和优化产品手册文档是确保用户获得准确和最新信息的重要步骤。如果不及时地更新和优化信息,很容易导致我们的产品有滞后性,不能满足客户最新的需求。所以looklook总结了一些相关内容,以下是一些建议来更新和优化产品手册文档:…...
#P0867. 小武老师的烤全羊
问题描述 小武老师特别喜欢吃烤全羊,小武老师吃烤全羊很特别,为什么特别呢?因为他有 1010 种配料(芥末、孜然等),每种配料可以放 11 到 33 克,任意烤全羊的美味程度为所有配料质量之和。 现在&…...

视频汇聚/视频云存储/视频监控管理平台EasyCVR提升网络稳定小tips来啦!
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...
C 语言学习
数组的指针 在c中,几乎所以使用数组名的表达式中,数组名的值是一个指针常量,也就是数组 第 一个元素的地址。注意这个值是指针常量,不是变量。 int a[10]{ ….....}; int *q; q&a[0] ; <>…...
TCP网络连接异常情况的处理
在网络连接中,经常会出现一些意外情况,导致TCP连接不能正常工作,对于这些意外情况,TCP内部有自己的解决方法 一.进程崩溃 在网络通讯时可能会出现进程突然崩溃的情况,当进程崩溃后进程就没了,就会导致进程…...
单片机之从C语言基础到专家编程 - 4 C语言基础 - 4.10语句
1 表达式语句 表达式语句由表达式加上分号“;”组成。其一般形式为: 表达式; 执行表达式语句就是计算表达式的值。例如 caa; 2 函数调用语句 由函数名、实际参数加上分号“;”组成。其一般形式为: 函数名(实际参数表); 例如 printf(“Hello !”);…...
Windows 通过服务名称搜索软件启动路径启动软件
文章目录 Windows 通过服务名称搜索软件启动路径启动软件 Windows 通过服务名称搜索软件启动路径启动软件 注意:QQ管家和360安全,正常情况下使用 taskkill 无法停止,因为在安全设置中有个“自保护”,正常情况下会默认勾选上&#…...

如何更高效的写出更健全的代码,一篇文章教会你如何拥有一个良好的代码风格
前言:在平常的写代码的过程中,或多或少的遇到很多奇怪的 bug ,尤其是一些大的程序,明明上一部分都是好好的,写下一块的时候突然多几百个 bug 的情况,然后这一块写完了后编译的时候直接傻眼了,看…...

Java如何调用接口API并返回数据(两种方法)
Java如何调用接口API并返回数据(两种方法) java处理请求接口后返回的json数据-直接处理json字符串 处理思路: 将返回的数据接收到一个String对象中(有时候需要自己选择性的取舍接收) 再将string转换为JSONObject对象 …...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...