Unity 3D之UI设置父子关系Instantiate 和 setParent坑 您所在的位置:网站首页 unity改变物体的位置 Unity 3D之UI设置父子关系Instantiate 和 setParent坑

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

2023-09-16 12:43| 来源: 网络整理| 查看: 265

 

把一个对象挂到另一个对象时,大小比例的对应:

    GameObject obj = UICommon.Instance.LoadReward(reward);         obj.transform.localScale = new Vector3(0.5f, 0.5f, 0f);         obj.transform.SetParent(Img_RewardIcon.transform, false);

 

instantiate实例化时坐标错误示范:(坐标会乱掉)

1

2

3

4

5

6

7

public static CardBase Create(Transform parent) {         GameObject go = (GameObject)Instantiate (Resources.Load("Prefabs/normal/CardBase"));         go.transform.parent = parent;         go.transform.localPosition = parent.localPosition;         go.transform.localScale = parent.localScale;         return go.GetComponent ();     }

正确示范:

1

2

3

4

5

6

7

public static CardBase Create(Transform parent) {         GameObject go = (GameObject)Instantiate (Resources.Load("Prefabs/normal/CardBase"));         go.transform.parent = parent;        go.transform.localPosition = Vector3.zero;         go.transform.localScale = Vector3.one;         return go.GetComponent ();     }

 

通常我们所用的SetParent是不带第二个参数的。

但是世界坐标系中的物体在与UGUI相结合使用时,往往会出现问题,这个问题基本上都出自于SetParent()的第二个参数。

最核心的是理解什么是Transform, 他标记的位置是相对父物体的!参考:https://blog.csdn.net/qq_42672770/article/details/106219792

首先看一个基础列子:

一个空的GameObject的Transform值:

一个Cube的Transform值:

他们的关系:

Game视图:

我们直接在Hierarchy面板中拖动Cube到空物体下,让t他成为空物体的子物体。

然后在Game视图中可以发现,Cube基本没有变化,而Transform值改变。

Cube的transform值:

刚才在面板中的操作相当于在代码中的操作Cube.SetParent(GameObject.transform)。(可以去试试)

所以,通俗一点来讲当SetParent方法只有第一个参数,或者第二个参数为true时,

物体的transform值会根据父物体的transform值做相应的改变,使物体在没有设置父物体前在世界坐标系中的大小旋转位置和设置父物体后在世界坐标系中的位置旋转大小一致。

当我们将cube拖出来,添加脚本

 

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

 

public class NewBehaviourScript1 : MonoBehaviour {

 

public Transform parentTransform;

 

void Start () {

transform.SetParent(parentTransform, false);

}

 

/*private void Start()

{

transform.SetParent(parentTransform, true);

}*/

 

}

然后在Unity中发现:

Game视图:

Cube的transform值:

所以通俗一点来讲,当第二个参数为false的时候。

物体的transform不会根据当前设置的父物体的transform的值所改变,也就是transform值不变。

这样Cube在设置父物体前后就会有所改变了。

 

 

 写在前面:

在做项目的时候,难免会碰到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中对于第二个参数的定义如下:

worldPositionStaysIf 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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有