隐藏3D模型及GetComponentsInChildren的使用

隐藏3D模型及GetComponentsInChildren的使用

有时游戏设计的需求,在场景中的3D模型物件未必都是一开始就一直是显示的状态,有可能会因为某些事件的发生而必须将物件隐藏,或因为某些事件的发生必须使该物件再次显示出来,通常在大部份的状况,我们可能会先制作一个Prefabs,在需要该物件时利用Instantiate()建立一个实例物件,使物件在场景中运作,在不需要该物件时利用Destroy()将此物件销毁,可是如果我们的需求是必须持续使用该物件,物件本身带有某些资料值会持续使用到,那么就不能随意将其销毁,但此时需有一段时间不能使该物件出现在画面上,那么我们应该怎么做呢?

物件的隐藏与显示,这个定义上很广泛,主要就是让镜头里看不到此物件,以下就来讨论几种方式

将物件移出镜头外

通常游戏场景都会有地板、背景等,我们如果暂时需要将物件隐藏掉,可暂时改变物件在3D空间的座标位置,将它藏在地板下、背景后,甚至是镜头后方,这样就可以很轻易的隐藏画面中的物件,不过,有些缺点,就是当需要再次将物件显示在画面之中时,必须将物件放回正确的位置,如果游戏场景及镜头都是定点固定不动的,那么将物件放回原来位置并不难,但如果游戏场景、镜头都是依照游戏进行在不断运作改变方向及内容的话,此时在处理物件座标定位上可能就要多费点功夫了。

统一储存相关资讯

如上面第一段所提到的,在需要时产生物件,在不需要显示时销毁物件,需要延续使用的相关数据,统一储存在某个记忆位置、档案、资料库...中,如此做法其实相当直接,不需要的东西就丢,但也有同样的问题,当该物件于下次需要显示时,我们必须要很清楚知道他应该出现的位置,然后在这个位置产生物件,使游戏进行不会错乱掉,但对于有使用物理碰撞反弹等等的游戏,那就很难去预测到该出现的正确位置,而且如果这些位置数据还要自己写程式计算的话,Unity的物理引擎反倒显得无用武之地了。

关闭物件,使物件无法运作

当游戏进行到某事件发生时,我们不想将物件销毁,而只想让物件在目前位置消失并停止运作,等待之后事件发生时再显示出来,此时我们就可以利用GameObject.active将该物件关闭,或使用GameObject.SetActiveRecursively()直接将该物件及他的子物件全部关闭,使他停止运作,因为物件被停止了,所以此时他将不会显示在画面上,而物件本身带有的Component也都会停止运作,待之后事件发生需要显示该物件时再将其开启,不过此时很容易发生一种情形是,GameObject.Find()要找回此物件并将其开启时,却发现找不到,因为Find()只会帮你找出正在活动中的物件,所以在将物件关闭前,我们必须将此物件放至预先定义好的变数成员中,使我们的程式保有他的参照,在需要开启时才能利用此参照找回这个已被关闭的物件;因为已持有他的参照,所以此物件虽然是在关闭的状态,但我们仍然能对他控制,使他改变位置或变更其他数据,但也因为是关闭的状态,所以我们付予他的任何主动功能动作将不会运作。

只控制renderer的开关

这是最直接的方式,利用renderer.enabled来控制模型渲染是否启用,关闭了就只是看不到该物件,但全部的Component仍然正常运作中,待需要显示时再将它开启,不过通常一个模型并不单单只有一个物件,例如一个人物可能分为上半身、下半身、身体、手、脚、头等等,甚至是更细部,所以我们可能就会想利用类似这样的方式将子物件的模型渲染都关闭..

for(var_child:TransforminparentObject){

_child.renderer.enabled=false;

}

但是如果整个模型构造不只一层,而是多层次的树状结构,那么我们可能就需要用巢状式的forin回圈一层一层的执行renderer.enabled=false,此时又必须考虑到每个模型的树状结构都不同,总不能为每个模型都客制化写一个巢状回圈让他们去做隐藏,这样子写程式就太笨了,于是我们可能会写一个script专门做这个动作,不过我们并不知道模型的结构会有几层,这么做还真是不好处理;幸好Unity有个GameObject.GetComponentsInChildren()帮我们解决了这个问题,在这部份,我们不再去考虑模型本身是否有子物件或者是有几层的结构,一句话就能取得全部并控制他们;官方说明页面的范例,我照样的改到我的程式中并无法取得我需要的东西,所以在此提供我的写法以供参考...

varmeshObject:Transform;

_components:Component[]=meshObject.GetComponentsInChildren(Renderer);

for(var_comp:Componentin_component){

_comp.renderer.enabled=false;

}

如此,我们很方便的就能为物件隐藏或显示,但物件在游戏场景中仍正常动作中,如果设计了一些物理运作或碰撞事件,那么物件碰到某物件或移动到某个区域就自己隐藏起来,隐藏后仍继续活动,可能又碰到了某物件或到了某个特定区域又再自己显示出来,如此下去,我们可以省掉许多程式运算及控制,只要在适当的时候告诉物件应该隐藏或显示就行了。

GetComponentsInChildren()不只是用在物件的renderer的控制上,还可用在任何Component的控制上,所以我们可以将数个相关的物件都放到一个空物件中,以群组的方式利用GetComponentsInChildren()来统一管理并控制其中的Component及script中的变数成员及函式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容