Unity 3D类结构简介

  趁着周末,再来一发。对于Unity3D,我也是刚开始学习,希望能够与大家多多交流。好了,废话不多说,下面继续。

  本篇文章使用C#进行举例和说明。关于Unity 3D编辑器中的各种窗口,网上有很多资料了,这里不做介绍,默认大家都知道各个窗口的作用了,并会在Unity 3D编辑器中执行基本的操作。

  上一篇讲的是Unity 3D的基础知识,这篇讲一下我刚开始学习编写脚本时遇到的一些困惑,主要是Unity 3D自身继承结构方面的问题。

  脚本作为Unity 3D中的一个组件,是经常会使用到的。一个对象可以添加脚本组件,添加方式有两种:一种是直接拖到对象上,另一种是在对象的Inspector窗口中点击最下面的Add Component,然后选择需要的脚本就可以添加成功。第二种方式如下图所示:

  我们在编写脚本时,经常需要用到对各种场景对象(GameObject)的访问,在刚开始的使用时,对于对象的访问方法一直都比较模糊。很多教程上都是这么写的:定义一个类型为Transform的变量,然后将该变量与一个游戏对象关联,然后使用。

  关联变量与游戏对象主要有两种方式。

  方式一:当脚本添加到一个游戏对象上时,在该游戏对象的Inspector窗口可以看到该脚本里面定义的public变量(见下图红框中内容)。那么将需要关联游戏对象的Transform变量的访问属性指定为public,然后将游戏对象从Hierarchy直接拖到这个变量上面就可以了。游戏音乐等其他资源也都可以通过这种方式关联,不过游戏音乐一般会放在Project窗口中,将其从Project窗口直接拖动到AudioClip类型变量上即可,当然这个变量也得是public,否则只能通过代码的方式获取。

  方式二:在代码中使用类似GameObject.Find函数,与Find相关的有许多函数,例如FindGameObjectsWithTag()之类的,这些函数大家都可以去网上查询,Unity 3D官方文档里也有。各种Find函数都可以用来获取游戏对象。

  刚开始学习时,我的疑惑是:明明是游戏对象时GameObject类型,而Transform只是一个组件,为什么很多地方使用Transform去代表这个对象,然后通过Transform对象对其进行一些操作?

  为了解决我这个疑问,我去查了Unity 3D类结构图。它的设计刚开始看起来还有点绕,看明白的才知道是怎么回事。下面就讲一下我对这部分的理解。

  在Unity 3D中,不管是游戏对象(GameObject)类还是Component(组件)类,都继承于Object类。这里要明确:虽然游戏对象中包含了各种组件,但是它们从继承结构上来说是平级的。

其中GameObject对象中包含了例如:audio, collider, rigidbody等组件变量,这些变量所关联的组件都是依附于该GameObject对象上的,同时也可以使用GetComponent获取依附于该对象上的组件(这两种方式都可以获取该对象上的组件),即下面两种方式效果是一样的(C#):

1 GameObject obj;
2 Rigidbody rigid = obj.GetComponent<rigidbody>();
3 Rigidbody rigid = obj.rigidbody;

  第一种组件获取方式比较方便,而第二种组件获取方式则比较通用。例如要获取一个脚本组件,GameObject默认是没有该变量的,那么此时只能通过第二种方式获取。例如脚本类名是Gun,那么在该脚本依附的GameObject上获取方式就是:  Gun gun = obj.GetComponent<Gun>(); 如果该GameObject没有该组件,则返回null。

  在Component类中,也包含了例如:audio, collider, rigidbody等组件变量,这些变量表示该Component所依附的对象上的audio组件、collider组件、rigidbody组件等。audio、collider、rigidbody等这些变量的类型分别是Audio类、Collider类和Rigidbody类,这些具体的组件类又都是继承于Component类的。即Component类中包含了继承于它的具体组件的对象,这些对象关联到了该组件依附于GameObject上的组件。而且,Component类中也有一个GetComponent方法,这个函数与GameObject中的功能是一样的,能够通过该函数获取该组件依附于的GameObject上的其他组件。

  举个例子,有一个GameObject obj,其中包含了两个组件:Transform和Rigidbody。

1 public GameObject obj; // 可以通过“关联变量与游戏对象的方式一”与对象进行关联,将其关联到一个包含Transform组件和Rigidbody组件的对象上
2 Transform m_trans1 = obj.transform;
3 Transform m_trans2 = obj.getComponent<Transform>();
4 Rigidbody m_rigid1 = obj.rigidbody;
5 Rigidbody m_rigid2 = obj.getComponent<rigidbody>();

  那么m_trans1、m_trans2、m_trans1.transform、m_rigid1.transform和m_rigid1.getComponent<Transform>()等都指向同一个东西,就是obj的Transform组件。同理m_rigid1、m_rigid2、m_trans1.rigidbody和m_rigid1.rigidbody等也是都代表了obj的Rigidbody组件,这几种访问方式都是可以的。

  这也就解释了我的疑惑,由于每个GameObject都必须有Transform组件,通过Transform组件,我们可以访问到该GameObject的其他组件,因此可以用Transform去代表这个GameObject。如果我们用Rigidbody去代表该GameObject就不好了,因为不是每个GameObject都有Rigidbody组件。Unity 3D提供的这组结构,使得组件的访问方法不止一种,这也是给初学者最大困惑的地方,不过我现在还不知道这几种访问方法在性能上是不是有区别(哪位小伙伴知道的话可以分享分享),但是不考虑性能的话,这几种访问方法都是可以的。

  看了上述那么复杂的结构,是不是感觉比较诡异?尤其是上面代码中提到的m_trans1和m_trans1.transform都指向同一个东西,刚开始学的时候看着还是很晕的。同时,在这里要感谢一下这位仁兄,看了他这篇文章《Unity 3D编程概览》,使我对于Unity 3D的类结构有了更清晰的认识。

  上面就是我对Unity 3D类结构的学习心得,由于刚开始学习,理解还不够深,如果文中存在不对的地方欢迎指正。

Unity 3D类结构简介

时间: 2024-08-06 17:19:01

Unity 3D类结构简介的相关文章

Unity 3D入门简介

最近在刚开始学习Unity 3D,在这里记录一下学习心得和学习笔记,边学边写,可能会比较零散.好了,废话不多说,今天从Unity 3D入门写起,主要简要介绍一下Unity 3D的和一些学习资料.以下如果不作特别说明,均是指Windows平台的Unity 3D,版本是4.5.1f3. Unity 3D是一款游戏开发引擎,目前支持2D和3D游戏的开发,其最大的优势就是跨平台性非常好,可以很容易的将PC端制作的游戏移植到Android.IOS等移动平台,当然也可以创建网页游戏.刚开始进行Unity 3

C#程序员整理的Unity 3D笔记(十):Unity3D的位移、旋转的3D数学模型

遇到一个想做的功能,但是实现不了,核心原因是因为对U3D的3D数学概念没有灵活吃透.故再次系统学习之—第三次学习3D数学. 本次,希望实现的功能很简单: 如在小地图中,希望可以动态画出Player当前的位置.z的朝向:用3条线.z轴正向.30°旋转.-30°旋转. 问题是:0点可以获得,P1点? P2点是未知的. 我尝试了2个小时,结果不竟如人意,少于沮丧. 不得不,再次花点时间系统的学习3D数学: 1 位移–向量和点: 点: 点和向量在数学上是一致的,实际生活中点的概念比较好理解,坐标点来定位

Unity 3D中不得不说的yield协程与消息传递

1. 协程 在Unity 3D中,我们刚开始写脚本的时候肯定会遇到类似下面这样的需求:每隔3秒发射一个烟花.怪物死亡后20秒再复活之类的.刚开始的时候喜欢把这些东西都塞到Update里面去,就像下面这样写. 1 float nowTime = 3.0f; 2 bool isDead = true; 3 float deadTime = 20.0f; 4 5 void startFireworks() 6 { 7 // 放烟花 8 } 9 10 void revival() 11 { 12 //

【Unity 3D】学习笔记二十八:unity工具类

unity为开发者提供了很多方便开发的工具,他们都是由系统封装的一些功能和方法.比如说:实现时间的time类,获取随机数的Random.Range( )方法等等. 时间类 time类,主要用来获取当前的系统时间. using UnityEngine; using System.Collections; public class Script_04_13 : MonoBehaviour { void OnGUI() { GUILayout.Label("当前游戏时间:" + Time.t

Unity 3D 实战核心技术详解 书籍出版

经过半年的努力,处女作<Unity 3D 实战核心技术详解>终于问世了,购买网址: http://www.broadview.com.cn/article/70 在12月5日到12日期间,在打折的基础上优惠,书籍内容全是干货,购买方式:可以查看网页中的"如何购买".

unity 3d yield 用法总结

最近,需要需要用unity 3d做点东西,但是了碰到了延迟加载问题,我总结余下: Coroutines & Yield是unity3d编程中重要的概念,它可以实现将一段程序延迟执行或者将其各个部分分布在一个时间段内连续执行,但是在Javascript与C#中实现Coroutines & Yield,在语法上却有一些区别: javascript中yield用法很简单,直接yield就行了,或者yield WaitForSeconds (2); c#中的用法如下: yield不可单独使用 需要

Unity 3d中Shader是什么,可以吃吗?

众所周知,Unity3d是一款跨平台非常广的游戏引擎,上手容易,界面友好,集成功能众多,是目前开发手游的主流引擎.本人有幸使用Unity 3d进行开发已一年多时间,已领略了这歀引擎的强大之处. 编写shader也是我工作内容的一部分,先来说说shader是什么吧,我以自己的理解说明一下: 首先 shader是一种语言,一种在GPU,也就是显卡上执行的高级语言.shader的本意是着色器,可以自定义GPU的渲染管线中的两个环节(即顶点和片段).由此,我们可以控制对象在屏幕上的渲染效果,甚至实现一些

【Unity 3D】学习笔记四十二:粒子特效

粒子特效 粒子特效的原理是将若干粒子无规则的组合在一起,来模拟火焰,爆炸,水滴,雾气等效果.要使用粒子特效首先要创建,在hierarchy视图中点击create--particle system即可 粒子发射器 粒子发射器是用于设定粒子的发射属性,比如说粒子的大小,数量和速度等.在创建完粒子对象后,在右侧inspector视图中便可以看到所有的粒子属性: emit:是否是使用粒子发射器. min size:粒子最小尺寸. max size:粒子最大尺寸. min energy:粒子的最小生命周期

【图说】Eclipse与Unity 3D协同工作

原地址:http://blog.csdn.net/h570768995/article/details/9355313 Eclipse开发过程中总会碰到很多的难题,如何利用好工具帮助我们更快捷的开发也是一件重要事. 下面介绍Eclipse与Unity 3D协同工作: 1,首先在Unity3D中简单建立一个工程文件 2,好的,接下来点击[File]->[Build setting] 3,然后点击[Build],记好你Build出来的.apk的名字.这时候在工程目录下会出现“temp”文件夹(没有B