2019.9.30 Unity 3D之UI设置父子关系setParent坑

写在前面:

在做项目的时候,难免会碰到UI很多的情况,而动态加载UI就是一个很重要的问题。而动态加载UI就需要考虑到设置UI的父子关系。通常我们会使用transform.setparent(transform)来设置父子关系。到这里都还是没毛病。但是偏偏UI在设置父子关系的时候需要考虑到第二个参数。对于初学者往往会遇到UI加载出来,设置子物体后发现UI不见了,但是明明直接拖到UI层次中又是对的。这个问题就和第二个参数相关。

worldPositionStays。所以这也是一个需要思考的问题。

UI设置父物体的原因分析

在加载UI中,这个加载步骤其实是首先将UI实例加载到场景的根路径中,然后再设置到父物体中。这个过程可以用手工实现,先加UI拖到场景根路径中,然后在拖到父物体下,此时显示的效果就是最后的效果。

原因:在从根路径拖到父物体这个过程中,就发生了坐标的转化。具体分析和解决方法看下文。

setparent()

这里首先对这个函数进行分析。这个函数有两个重载:

public void SetParent(Transform parent);

public void SetParent(Transform parent, bool worldPositionStays);

第一个是我们常用的只有一个参数的函数,第二个是加了一个是否保持世界坐标系的布尔型变量。

API中对于第二个参数的定义如下:

worldPositionStays If true, the parent-relative position, scale and rotation are modified such that the object keeps the same world space position, rotation and scale as before.

官方解释大意是:如果为真,那么就保持之前的位置、旋转量、缩放值。而为否,的时候则保持局部坐标的位置、旋转、缩放。

直接可能不太能理解这个参数的意思,所以就往后看。

由此引发的问题

通常我们在设置父子关系的时候,我们希望设置完后,子物体要保持原来的样子。如果变了样,那么就会对游戏的交互产生较为严重的影响。3D物体相对还好,UI在设置父物体如果没有设置好会出现很严重的变形。

worldPositionStays

下面对这个参数带来的影响做了对比试验:

测试场景:

球体作为父物体,方块作为子物体,分别的参数:

     

选择方块作为子物体能够看出变化。

首先参数为true。

效果保持不变。球体和方块的局部坐标值分别为:

  

可以看到在效果上保证了方块不随球体的变化而变化,但是其局部坐标值发生了变化,以球体为中心,但在效果上仍然是之前的相对位置。

其次参数为false

从效果上,可以看出方块的旋转和缩放值已经发生了变化,不在保存原来的世界坐标系中的位置。球体和方块的局部坐标值分别为:

   

从参数上可以看出,方块在局部数值上保证了和之前全局坐标系中的数值相同。

可以看出产生的影响还是较大的。

对于UI

对于UI来说,我们是希望保留这种位置关系还是不保留呢?答案很明显,我们在做UI预设时是在UI的父物体下完成,保存到预设中的值也是UI局部坐标系中的值。

首先加载到场景根路径时,此时UI将之前局部坐标系的值换成全局坐标系。

要保证和之前UI一样,我们需要将这种位置关系带到UI父物体中。

于是应该设置为false。

测试效果://UI来源蛮牛教程

设为true:

设为false:

THISSKY出品,原文链接:http://www.cnblogs.com/zhuhongjongy/p/7226386.html

原文地址:https://www.cnblogs.com/LiTZen/p/11612047.html

时间: 2024-10-10 06:09:48

2019.9.30 Unity 3D之UI设置父子关系setParent坑的相关文章

将两个不同进程的窗口设置为父子关系

今天用WPF程序给一个第三方程序做插件,该程序支持通过菜单扩展的方式集成第三方程序,看起来像是弹出一个对话框. 但是,由于新写的WPF程序和原程序是没有任何关系的,一旦原程序重新获取焦点时,新弹出的WPF程序窗口就会切换到后台,看起来就不像子窗口了.看了一下之前的人们的做法,大多是将新蹦出来的窗口设置为TopMost,但这样就又引入了改窗口不能切换到后台隐藏的问题. 在网上搜了一下,找到了如下解决方法:http://stackoverflow.com/questions/2599053/how-

Unity 3D中的阴影设置

在Unity 3D中,经常需要用到光照阴影,即Directional Light的Shadow,Shadow分为Hard Shadow和Soft Shadow.区别是Soft Shadow的阴影边缘比较平滑,接近真实,但是性能消耗大于Hard Shadow. Lightmapping有3种选择:实时光照阴影(RealTimeOnly).场景烘焙阴影(BakedOnly).以及上面两者结合的阴影(Auto). RealTimeOnly:所有场景物体的光照都实时计算,实时光照对性能消耗比较大: Ba

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

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

Unity 3D学习笔记之一 界面介绍

因为学校的课程,本学期对Unity 3D有学习的要求,在博客中记录下自己的Unity学习之路(内容摘录自书本和视频,书本为Unity 4.x从入门到精通) 一.Unity界面介绍 首先进入Unity3D,在菜单栏,File中new project,选择自己的工作路径初始时我们先默认不引入任何的package. 进入Unity的界面中,先对界面进行一下简要的介绍.区域大致依次分为Hierarchy.Scene.Inspector.Project,和上方的菜单栏(Menu bar)和工具栏(Tool

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】学习笔记三十一:游戏元素——地形元素

地形元素 一般情况下,为了使游戏更具有美观性,会在游戏地形上放置很多的元素,这些元素是与地形分开的.主要包括:树木,草地,自定义网格模型. 树元素 首先导入系统提供的树木标准资源包,在project视图中,点击鼠标右键,然后从菜单中选择import-----tree creator.接着在地形菜单里点击第五个按钮,添加树模型.然后点击edit trees按钮,将弹出如下列表: add tree:添加一个树模型 edit tree:编辑一个树模型 remove tree:删除树模型 点击add t

C#程序员整理的Unity 3D笔记(二十):2D Toolkit之官方教程《Whack a Mole》

在上篇博客中,简单整理了一下Unity Native 2D功能:<C#程序员整理的Unity 3D笔记(十九):Unity 3D的Native 2D>. 本文开始学习2D商用比较广泛的2D Toolkit插件. 2D Toolkit插件在2D中的地位,犹如UI中NGUI对Unity GUI一样:虽然官方原生的2D还不错,但这是最近1年新版本才有的功能,2年前Unity 2D的王道还是得用插件的,故<2D Toolkit>就成了目前商业不错的选择. 在上周刚开始看的时候,就给自己提了

Unity 3D Game 粒子光环

介绍 参考 http://i-remember.fr/en 制作类似该网站效果 基本步骤 创建粒子光环(空对象) 将摄像机背景置为黑色 创建粒子系统,配置参数 新建 C# 脚本,命名为 ParticleRing ParticleRing.cs 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686

unity 3d yield 用法总结

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