https://www.jianshu.com/p/4592bf809c8b
一、Pivot属性详解
首先为了让大家更好的理解内容,我在Unity中创建了两个UI控件,一个Plane控件,作为父对象,一个Image控件,最为子对象,如下图: 然后我们选中红框,来看看它的RectTransform组件的属性,如下图:
你会看到有一堆的数据,那么这些数据是如何最终决定UI在屏幕中的位置和大小的呢?我们首先来看第一个重要的属性Pivot,因为它理解RectTransform这套UI布局方案的第一个关键
Pivot我们可以暂且称它为中心轴(这个翻译不太准确,但为了便于理解,先这么叫着),它是一个X,Y值范围是0到1的点,这个点的会在Anchor(锚点)计算位置的时候会使用到,下面用一张图来解释Pivot点的位置
设置Pivot的坐标系如上图,(0,0)表示红框物体的左下角的点,(1,1)表示红框物体的右上角的点
二、Anchor属性详解
关于Anchor锚点可能接触过UI的朋友都了解一些,但是Unity中Anchor应该称它为锚框更为合理,因为它是由两个锚点(Min,Max)组成的一个矩形,当然也可以组成一个点(两个点重合) 而Unity为了方便我们调整锚框,在编辑视图给出了锚框的标示,如下图:
当然上图是两个锚点重合的情况,所以看上去是一个点,下面我们利用两个锚点不重合的情况来说明一下:
三、Pivot和Anchor的结合
在了解了Pivot和Anchor分别是什么后,我们就来看看Unity是如何使用这个两个东西来控制UI的布局
第1种情况:两个锚点重合时我们先来看看两个锚点重合时的情况,这种情况是我们最常用也是最容易理解的方式 我们将Anchor锚点放在黑框的正中间,然后将Pivot中心轴放在红框的正中间,然后我们改变黑框的大小和位置,看看红框会有什么变化,如下图:
我们从上图可以看出,不管我们怎么拖动黑框,改变他大小和位置,红框的Pivot点到Anchor点的距离是始终不变的,也就是说红框物体会参照锚点来实时调整自己的位置,使自己的Pivot点到锚点的距离始终保持一致,而且值得一提的是,在这种情况下,红框物体的RectTransform组件中的属性是Width和Height,这个属性在后面的情况中会发生变化,大家需要注意下
总结下第1种情况的特点就是:子物体的大小不会随着父物体的大小变化而变化,但是位置会根据Pivot点到Anchor点的距离一致的原则发生对应的变化
第2种情况:两个锚点不重合时,即锚框的情况 当两个锚点(AnchorMin和AnchorMax)不重合时,两点就会确定一个矩形,这个矩形就是我们的锚框,如下图中的绿框就是我们的锚框区域 此时我们再观察一下红框物体的RectTransform属性,发现属性分别变成了Left、Top、Right、Bottom
那么这4个属性分别表示什么呢?我们看看下面的这个图
从上图我们看出,Unity以锚框的左下角为坐标系的原地(0, 0),然后红框的Left和Bottom两个数确定红框左下角的点在坐标系中的位置,原点和红框左下角的点确定一段距离(即上图的绿色箭头),不管黑框如何变化,这段距离都保持不变
同理,如上图所示,Unity以锚框的右上角为原点(0,0),然后红框的Right和Top两个数确定红框的右上角的在坐标系中的位置,原地和红框的右上角的点确定一段距离(即上图的绿色箭头),不管黑框如何边框,这段距离都保持不变
在黑框大小和位置变化的时候,Unity会保证红框的左下角到锚框的左下角距离不变,同时红框的右上角到锚框的右上角距离不变,来确定红框的相对位置和大小,看下图来感受一下变化: 注意上图中红框左下角到黑框左下角的距离,以及红框右上角到黑框右上角的距离,他们都是不变的
四、anchoredPosition属性详解
anchoredPosition根据名字的含义,我们大概可以猜出他是根据anchor锚点得出来个一个位置属性,他本身是一个点,如果在AnchorMin和AnchorMax是重合的情况下,anchoredPosition就是表示锚点到Pivot的位置,如下图所示: 但是如果AnchorMin和AnchorMax不重合的时候,anchoredPosition就比较复杂了,在这种情况下,Unity会根据Pivot、AnchorMin和AnchorMax计算出一个锚点,然后在通过Pivot和锚点来得出anchoredPosition的位置,关于如何计算规则,有兴趣的朋友可以自己逆推一下
五、offsetMin和offsetMax详解
offsetMin和offsetMax这两个属性比较好理解,其中offsetMin表示物体(本文中的红框)左下角相对AnchorMin的偏移,offsetMax表示物体右上角相对AnchorMax的偏移
六、sizeDelta详解
sizeDelta就是offsetMax - offsetMin的值,即物体左下角到右上角的变量,如下图所示:
Anchor(锚点):
https://www.jianshu.com/p/dbefa746e50d
每个控件都有一个Anchor属性,控件的4个顶点,分别与Anchor的4个点保持不变的距离,不受屏幕分辨率变化的影响。
系统默认设置控件的Anchor位置在其父物体的中心处,且不能离开父物体的范围。
将Anchor设置在父物体的左侧,可以实现左对齐的效果。
将Anchor设置在父物体的4个顶点上,子物体将随父物体同步缩放。
Pivot(轴):控件的中心点(或称为轴),控件围绕Pivot发生旋转(若想控件围绕某个顶点旋转,改变Pivot位置即可)
注意区别:
对象的Transform 的position为世界坐标。
对象的 Transform的 localPosition为当前对象轴心点与父UI对象轴心点的相对位置
对象的RectTransform继承自 Transform,编辑器中显示的PosX、PosY、PosZ指的是Pivot与其父物体Anchor间的相对位置,叫做anchoredPosition3D
RectTransform 矩形变换
class in UnityEngine/Inherits from: Transform
Variables 变量
anchoredPositionThe position of the pivot of this RectTransform relative to the anchor reference point. 该矩形变换相对于锚点参考点的中心点位置。anchoredPosition3DThe 3D position of the pivot of this RectTransform relative to the anchor reference point. 该矩阵变换相对于锚点参考点的中心点的3D位置。anchorMaxThe normalized position in the parent RectTransform that the upper right corner is anchored to. 该锚点在父矩阵变换中归一化位置,右上角是锚点。anchorMinThe normalized position in the parent RectTransform that the lower left corner is anchored to. 在父矩阵变换上归一化位置,该锚点在左下角。offsetMaxThe offset of the upper right corner of the rectangle relative to the upper right anchor. 矩形右上角相对于右上角锚点的偏移量。offsetMinThe offset of the lower left corner of the rectangle relative to the lower left anchor. 矩形左下角相对于左下角锚点的偏移量。pivotThe normalized position in this RectTransform that it rotates around. 在该矩阵变换的归一化位置,围绕该中心点旋转。rectThe calculated rectangle in the local space of the Transform. 计算矩形自身空间的变换。sizeDeltaThe size of this RectTransform relative to the distances between the anchors. 矩阵变换的大小相对于锚点之间的距离。 1.改变RectTransform的Left和Buttom
GetComponent().offsetMax = new Vector2(left, top);
offsetMax是一个Vector2类型
offsetMax.x即为RectTransform中的Left
offsetMax.y即为RectTransform中的Buttom
GetComponent().offsetMin = new Vector2(right, bottom);
offsetMin是一个Vector2类型
offsetMin.x即为RectTransform中的Right
offsetMin.y即为RectTransform中的Botttom
直接对sizeDelta属性进行赋值,其中X和Y可以对应理解成width和height。sizeDelta的具体含义:若anchors是一个点的话则代表宽高,否则为到锚点的距离
GetComponent().sizeDelta = new Vector2(width, height);
sizeDelta是一个Vector2类型
sizeDelta.x即为RectTransform中的width
sizeDelta.y即为RectTransform中的height
GetComponent().anchoredPosition3D = new Vector3(posx,posy,posz); //修改位置 GetComponent().anchoredPosition = new Vector2(posx,posy);//修改Pivot位置
anchoredPosition3D:
anchoredPosition:
GetComponent().anchorMin = new Vector2(0, 1); GetComponent().anchorMax = new Vector2(0, 1);
在代码中动态改变RectTransform大小的方法如下所示:
1:直接对sizeDelta属性进行赋值,其中X和Y可以对应理解成width和height。sizeDelta的具体含义:若anchors是一个点的话则代表宽高,否则为到锚点的距离
var rt = gameObject.GetComponent(); rt.sizeDelta = new Vector2(100, 30); 2:使用SetSizeWithCurrentAnchors函数来进行设定,其中Horizontal和Vertical分别对应宽和高。此函数受当前锚点和中心点的影响。
var rt = gameObject.GetComponent(); rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 100); rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 30); 3:使用SetInsetAndSizeFromParentEdge函数来进行设定。此函数不受锚点和中心的影响,其中第一个参数代表对齐方式,第二个参数为距离边界的距离,第三个参数为宽度。
var rt = gameObject.GetComponent(); rt.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Right, 0, 100); rt.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Bottom, 0, 30);
Public Functions 公共函数
GetLocalCornersGet the corners of the calculated rectangle in the local space of its Transform. 在该变换的本地空间中获取计算的矩形的折角的本地坐标。GetWorldCornersGet the corners of the calculated rectangle in world space. 获取世界空间中矩形计算的折角。SetInsetAndSizeFromParentEdgeSet the distance of this rectangle relative to a specified edge of the parent rectangle, while also setting its size. 设置父矩形的指定边缘的相对于该矩形的距离,当然也设置它的大小。SetSizeWithCurrentAnchorsMakes the RectTransform calculated rect be a given size on the specified axis. 使矩形变换计算矩形在指定坐标轴上是给定大小。Delegates 委托
ReapplyDrivenPropertiesDelegate used for the reapplyDrivenProperties event. 委托用于reapplyDrivenProperties事件。
RectTransformUtility 矩阵变换工具
class in UnityEngine
Description 描述
Utility class containing helper methods for working with RectTransform.
矩阵变换工作的工具类包含帮助方法。
Static Functions 静态函数
FlipLayoutAxesFlips the horizontal and vertical axes of the RectTransform size and alignment, and optionally its children as well. 翻转水平轴和垂直轴的 RectTransform 大小和对齐方式,并且选择性的子物体也一样。FlipLayoutOnAxisFlips the alignment of the RectTransform along the horizontal or vertical axis, and optionally its children as well. 沿着水平或者垂直轴翻转对齐的矩形变换,并且它的子物体也是可选择的。PixelAdjustPointConvert a given point in screen space into a pixel correct point. 将屏幕空间中给定的点转换成正确像素点。PixelAdjustRectGiven a rect transform, return the corner points in pixel accurate coordinates. 指定矩形变换,返回角点的精确坐标单位像素。RectangleContainsScreenPointDoes the RectTransform contain the screen point as seen from the given camera? 从指定摄像机中观看该矩形变换是否包含屏幕点?ScreenPointToLocalPointInRectangleTransform a screen space point to a position in the local space of a RectTransform that is on the plane of its rectangle. 屏幕空间点转换为矩形变换内部的本地位置,该点在它的矩形平面上。ScreenPointToWorldPointInRectangleTransform a screen space point to a position in world space that is on the plane of the given RectTransform. 屏幕空间点转换为世界空间点,该点在矩形变换的平面上。
二、UGUI的基本控件:
Canvas(画布):所有UI控件必须在Canvas上面绘制,也可以看做所有UI控件的父物体。
Panel(面板):主要的功能就是一个容器,可以放置其他控件,使其进行整体移动、旋转、缩放等。一个功能完备的UI界面,往往会使用多个Panel容器,甚至使用Panel嵌套。
Text(文本):富文本功能类似HTML中的标签。
Image(图像):图像源为2D Sprite格式。等比例调节图像大小,需要按住Shift键进行调节。Image Type的Sliced选项,需要对Sprite进行“九宫格”处理。
Raw Image(原始图像):图像源为Texture格式。
最后补充一个基本组件:
Mask(遮罩):遮罩并不是GUI的控件。它以父物体的范围约束子物体的显示,如果子物体过大,将只显示在父物体中的一部分。
三、UGUI的复合控件:
Button(按钮):由两个控件组成:1.添加了Button组件的Image控件,2.Text控件。Image控件是Text控件的父对象。
鉴于UGUI的高度自由,也可以理解为添加了Button组件、Image组件的空对象和添加了Text组件的空对象。
通过Transition对按钮的三态进行设置。
InputField(输入框):由三个控件组成:1.添加了Input Field组件的Image控件,2.Text控件(用作显示提示内容),3.Text控件(接收输入内容)。Image控件是两个Text控件的父对象。
Content Type对输入的字符类型进行预处理功能。
Toggle(开关):即可以做单选框又可以做复选框,系统默认为复选框。
由四个控件组成:1.添加了Toggle组件的空对象,2.Image控件(显示状态框的背景图),3.Image控件(显示当前状态),4.Text控件(用作显示选项内容)。
如何制作单选框:创建一个空对象,添加Toggle Group组件。在空对象下创建若干个Toggle控件,设置Group,并保持其中一个Toggle控件的Is On开关为true,其余为false。
Slider(滑动条):由6个控件组成:1.添加了Slider组件的空对象,2.Image控件(显示背景图像),3.空对象(控制填充区域),4.Image控件(显示填充图像),5.空对象(控制滑块移动区域),6.Image控件(显示滑块)
滑动条通过滑块驱动,在minValue和maxValue区间运动,根据当前的Value值,不断改变背景图像和填充图像的显示范围。
滑动条既可以用作音量控制等输入控件,去掉滑块后,也可以用作血量、进度等显示控件。
ScrollBar(滚动条):由3个控件组成:1.添加了Scrollbar组件的Image对象,2.空对象(控制滑块移动区域),3.Image控件(显示滑块)
滚动条与滑动条的原理类似,对比而言,滚动条背景色单一,数值范围固定为0到1,偏重于单步数值的设置
滚动条既可以用作垂直滚动文本(背包),也可以用作水平滚动时间轴,还可以垂直+水平进行图像的缩放。
四、UGUI的高级控件:
高级控件并不是UGUI直接提供的控件,需要自行组合,组合原理可以通过拆解复合控件学习。
Scroll Rect(滚动区域):在一个较小的区域显示较多的内部控件的时候使用的一种机制
Scroll Rect(空对象,设置一定的区域范围,作为当前显示的窗口,添加组件:Scroll Rect、Image、Mask)
Content(空对象,长度或宽度要大于Scroll Rect)
Scroll View若干个(根据需要,Image、Button控件随意添加)
ScrollBar(滚动条控件)
在Scroll Rect组件中设置Content项和Scrollbar项即可
TabPage(选项卡):能够在有限的空间中,放入更多的展示内容
TabPage(空对象)
ToggleGroup(空对象,添加Toggle Group组件)
Toggle若干个(根据需要,将Toggle设置为单选框)
DisplayContent(Image,作为背景图。Toggle Group和DisplayContent可以根据需要进行垂直或水平布局)
Page若干个(根据需要,数量需要与Toggle对应)
在Toggle的On Value Changed(Boolean)中设置对应Page的SetActive
总结:UGUI的功能很强大,DIY度相当高,虽然缺少了一部分功能,比如下拉框,树视图,列表视图等,但是通过组件的搭配使用,完全可以自己做出来
附录上个人这两天的学习笔记,思维导图确实是个好东西,学习ING~~~~
五、控件和组件的代码操控
1. 概述
我们在monoDevelop中书写脚本语言时,GameObject与gameobject, Transform和transform是同时存在的如下图, 那么它们有什么区别和联系呢? 1> GameObject与gameObject 2> Transform与transform
2. GameObject与gameObjectGameobject是一个类型,所有的游戏物件都是这个类型的对象。 gameobject是一个对象, 就跟java里面的this一样, 指的是这个脚本所附着的游戏物件 示例: public class ShowSliderValue : MonoBehaviour { private GameObject obje; //定义GameObject类型的指针 void Start(){ Text lal =gameObject.GetComponent (); //通过gameObject获取到Text组件. Debug.Log (“Text” + lal.text); //打印获取到组件的中的text的属性 } } 打印结果: Text中的值 输出台:
注意: Text lal =gameObject.GetComponent () 中可以省略 gameObject , 直接使用 GetComponent ()
//设置一个控件对象的 Image组件的 颜色属性的 透明度为完全透明
trans_SkillBox_AllSkills = FindChild(trans_SkillsBox.gameObject, "AllSkills");
//Color boxAllSkillsColor = trans_SkillBox_AllSkills.GetComponent().color;
//boxAllSkillsColor.a = 0;
trans_SkillBox_AllSkills.GetComponent().color = new Color(255, 255, 255, 0);
3. Transform与transform
Transform是一个类,用来描述物体的位置,大小,旋转等等信息。 transform是Transform类的对象,依附于每一个物体。也是当前游戏对象的一个组件(每个对象都会有这个组件).
4. transform与gameObject1> 二者的含义 transform : 当前游戏对象的transform组件 gameobject :当前游戏对象的实例 2> 两者的联系和区别 * 在unity中每个游戏对象都是一个gameobject. monodevelop中的gameobject就代表着本脚本所依附的对象. 每个gameobject都包含各种各样的组件,但从这点可以看出transform是gameobject的一个组件,控制着gameobject的位置,缩放,和旋转,而且每个gameobject都有而且必有一个transform组件 * gameobject.find用来获取场景中那个我们需要查找的对象(object)。
* transform.find方法则是获取当前对象的子对象下我们需要获取的目标对象位置信息。
1.GameObject.Find
函数原型: public static GameObject Find(string name);
说明:1.GameObject只能查找到active的物体
2.如果name指定路径,则按路径查找;否则递归查找,直到查找到第一个符合条件的GameObject或者返回null
2.transform.Find
函数原型: public Transform Find(string n);
说明:1.transform.Find用于查找子节点,它并不会递归的查找物体,也就是说它只会查找它的子节点,并不会查找子节点的子节点。
public void TimeCounter()
{
GameObject MonoStubTemp = GameObject.Find("MonoStubTemp");
if (MonoStubTemp == null)
{
MonoStubTemp = new GameObject();
MonoStubTemp.name = "MonoStubTemp";
MonoStubTemp.AddComponent().StartCoroutine(TimerProcess());
}
Debug.Log("开始计时器协程");
}
private class MonoStub:MonoBehaviour
{
}
/// 查找子节点对象
/// 内部使用递归查询3-14
public static Transform FindTheChildNode(GameObject Parent, string ChildName)
{
Transform serachTrans = null;
serachTrans = Parent.transform.Find(ChildName);
if (serachTrans == null)
{
foreach (Transform trans in Parent.transform)
{
serachTrans = FindTheChildNode(trans.gameObject, ChildName);
if (serachTrans != null)
{
return serachTrans;
}
}
}
return serachTrans;
}
* 注意: 在update()中尽量不使用find()方法,影响性能.
3> gameobject.transform与transform.gameobject * gameobject.transform,是获取当前游戏对象的transform组件.
所以在start函数中 gameobject.transform 和this.transform,指向的都是同一个对象。即:gameobject.transform == this.transform == transform * transform.gameobject:可以这么理解为:获取当前transform组件所在的gameobect 所以在start函数中()transform.gameobject == this.gameobject == gameobect 示例:
public class ShowSliderValue : MonoBehaviour
{
private GameObject obje; //定义GameObject类型的指针
private Transform trans;//定义Transform类型的指针
void Start()
{
Debug.Log ("gameObject.name:" + gameObject.name);
Debug.Log ("gameObject.transform.gameObject.name:" +
gameObject.transform.gameObject.name);
Debug.Log ("ThisGame.name:" + this.gameObject.name);
}
}
示例:创建物体,脚本挂载到Cube2上
#region 通过 GameObject.Find(""):查找游戏对象
//1.通过名称查找游戏对象
obj = GameObject.Find("Cube1");
obj.GetComponent().material.color = Color.red;
//2.查找Cube1的子节点 Cube2, find游戏对象名称都可以找到
obj = GameObject.Find("Cube2");
obj.GetComponent().material.color = Color.black;
//3.可以直接查找游戏对象的路径,可以查找同名的游戏对象,可以通过路径来区分
obj = GameObject.Find("Cube1/Cube2");
obj.GetComponent().material.color = Color.blue;
//4.如果同一个节点下有几个相同的名称的游戏对象,会查找到层级面板Hierarchy中最后的同名游戏对象
//通过递归的方法查找物体,返回层级面板中最后查找的物体
obj = GameObject.Find("Cube");
obj.GetComponent().material.color = Color.red;
GameObject.Find(""):查找游戏对象 * 1.可以查找任何层级的物体,不受脚本所绑定的物体层级位置的影响 * 2.可以指定层级查找,也可以不用指定层级去查找 * 若指定层级,则会在对应的层级中查找 * 若不去指定层级,则会在所有层级中查找(名称不能重复) * 3.如果没有指定层级,而查找的物体是多个相同名称的物体,则会查找到Hierarchy面板中列表的最后一个的同名物体 * 4.不支持查找隐藏的物体
transform.Find(); 查找游戏对象 * 1.只能查找到子集的物体 * 2.如果想查找其他层级(同级或者父级)的物体,则需要使用完整路径进行查找 * 3.支持查找隐藏的物体
#region transform.Find(); 查找游戏对象
//脚本挂载在Cube2上
///1.可以查找到子节点游戏物体
///2.可以查找到全路径的游戏物体
//1.查找Cube1
//tran = transform.Find("Cube1");//查找不到
//tran = transform.Find("Cube2");//查找不到
//tran = transform.Find("Cube3");//查找到了
// tran = transform.Find("/Cube1/Cube2"); //查找了
tran = transform.Find("/Cube");//查找到
tran.gameObject.GetComponent().material.color = Color.red;
#endregion
1 #region 通过父物体查找子物体
2 //注意: 只能获取到自己子节点,不可以获取到子节点的子节点
3 Transform tran = GameObject.Find("Cube1").transform.FindChild("Cube2").FindChild("Cube3");
4
5 //获取父节点
6 Transform parentTran = GameObject.Find("Cube3").transform.parent.parent;
7
8 //parentTran.childCount;有几个子节点
9 for (int i = 0; i < parentTran.childCount; i++)
10 {
11 parentTran.GetChild(i).name = i+"";
12 }
13
14
15 #endregion
通过父节点获取子节点
1 #region 通过标签查找子节点
2
3 //1.获取CubeTag 标记的游戏对象(单个)
4 GameObject obj = GameObject.FindWithTag("CubeTag");
5
6 obj = GameObject.FindGameObjectWithTag("CubeTag");
7 //获取CubeTag 标记的所有游戏对象,并存放放到一个数组中返回
8 GameObject[] objs = GameObject.FindGameObjectsWithTag("CubeTag");
9
10
11 #endregion
通过tag获取节点
1 #region 通过Type类型查找物体
2 //Object.FindObjectOfType
3 //Object.FindObjectsOfType
4 //返回Type类型的所有激活的加载的物体列表
5 //它将返回任何资源(网格,纹理, 预设,,,,)或激活的物体
6 //注意这个函数是非常慢的。不推荐在每帧使用这个函数,大多数情况下可以使用单例模式代替
7
8
9 //获取所有有碰撞器的物体
10 Collider[] cols = GameObject.FindObjectsOfType(typeof(Collider)) as Collider[];
11 foreach (Collider item in cols)
12 {
13 item.isTrigger = true; //所有的触发器打开
14 }
15
16
17 #endregion
通过Type获取节点
在实际开发中可能遇到这样的情况,给定一个节点,在这个子节点中递归的查找符合条件的节点。transform.Find不能递归查找,不能直接使用,GameObject.Find又做了很多无用功,关键若是重名还不一定能满足需求。于是我们可以自己写一个递归程序:
public static Transform FindChildRecursively(Transform parent, string name) { Transform t = null; t = parent.Find(name); if (t == null) { foreach (Transform tran in parent) { t = FindChildRecursively(tran, name); if (t != null) { return t; } } }
return t; } }
即使隐藏root节点gameObject也能进行查找的方法
找到了一个即使隐藏root节点gameObject也能进行查找的方法。 http://answers.unity3d.com/questions/52560/gameobjectfind-work-on-inactive-objects.html
代码预览:
GameObject[] pAllObjects = (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject)); foreach (GameObject pObject in pAllObjects) { if (pObject.transform.parent != null) { continue; } if (pObject.hideFlags == HideFlags.NotEditable || pObject.hideFlags == HideFlags.HideAndDontSave) { continue; } if (Application.isEditor) { string sAssetPath = AssetDatabase.GetAssetPath(pObject.transform.root.gameObject); if (!string.IsNullOrEmpty(sAssetPath)) { continue; } } Debug.Log(pObject.name); }