19.Unity重要组件和API-Transform父子关系
19.1 知识点
获取和设置父对象
parent变量 获取父对象 返回父对象的transform
// 变换的父级。
// print(this.transform.parent);
// print(this.transform.parent.name);
this.transform.parent = 设置父对象
// 断绝父子关系
// this.transform.parent = null;
// 认爸爸
// this.transform.parent = GameObject.Find("Father2").transform;
SetParent方法 设置父对象
// 设置变换的父级。
// 参数一:父对象
// 参数二:是否保留世界坐标的位置、角度、缩放信息
// 如果为 true,则修改相对于父级的位置、缩放和旋转,使对象保持与之前相同的世界空间位置、旋转和缩放。
// true 会保留世界坐标下的状态和父对象进行计算,得到本地坐标系的信息
// false 不会保留,会直接把世界坐标系下的位置、角度、缩放直接赋值到本地坐标系下,可以理解为粗暴的把世界坐标下的变换赋值到面板上
// this.transform.SetParent(null); // 断绝父子关系
// this.transform.SetParent(GameObject.Find("Father2").transform); // 认爸爸
// this.transform.SetParent(GameObject.Find("Father3").transform, false);
断绝与所有子对象的关系
DetachChildren方法 断绝与所有子对象的关系
// 清除所有子项的父级。
// 注意:不能影响自己的儿子和孙子的关系,只能断绝自己和儿子的关系
// this.transform.DetachChildren();
获取子对象
Find方法 按名字查找儿子 找到儿子的 transform信息
// 按名字查找子项,然后返回它。
// print(this.transform.Find("Cube (1)").name);
// Find 方法能够找到失活的对象!!!!! GameObject 相关的查找不能找到失活对象,它只能找到自己的儿子,找不到自己的孙子!!!!!!
// 虽然它的效率比 GameObject.Find 相关要高一些,但是前提是你必须知道父亲是谁才能找到
childCount变量 得到有多少个儿子
// 父变换具有的子项数。
// 失活的儿子也会算在内,只会找儿子不找孙子,所以孙子不会算数量
// print(this.transform.childCount);
GetChild方法 遍历所有儿子
for (int i = 0; i < this.transform.childCount; i++)
{
print("儿子的名字:" + this.transform.GetChild(i).name);
}
儿子的操作
IsChildOf方法 判断自己的爸爸是谁
// 该变换是否为 parent 的子项?
// 一个对象判断自己是不是另一个对象的儿子
// if (son.IsChildOf(this.transform))
// {
// print("是我的儿子");
// }
GetSiblingIndex方法 得到自己作为儿子的编号
// 获取同级索引。
// print(son.GetSiblingIndex());
SetAsFirstSibling方法 把自己设置为第一个儿子
// 将变换移动到本地变换列表的开头。
// son.SetAsFirstSibling();
SetAsLastSibling方法 把自己设置为最后一个儿子
// 将变换移动到本地变换列表的末尾。
// son.SetAsLastSibling();
SetSiblingIndex方法 把自己设置为指定个儿子
// 设置同级索引。
// 就算你填的数量超出了范围(负数或者更大的数)也不会报错,会直接设置成最后一个编号
// son.SetSiblingIndex(1);
总结
- 获取和设置父对象相关的内容
- 获取子对象
- 抛弃妻子
- 儿子的操作
19.2 知识点代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson19_必不可少Transform_父子关系 : MonoBehaviour
{
public Transform son;
void Start()
{
#region 知识点一 获取和设置父对象
//parent变量 获取父对象 返回父对象的transform
//变换的父级。
//print(this.transform.parent);
//print(this.transform.parent.name);
//this.transform.parent = 设置父对象
//断绝父子关系
//this.transform.parent = null;
//认爸爸
//this.transform.parent = GameObject.Find("Father2").transform;
//SetParent方法 设置父对象
//设置变换的父级。
//参数一:父对象
//参数二:是否保留世界坐标的 位置 角度 缩放 信息
//如果为 true,则修改相对于父级的位置、缩放和旋转,使对象保持与之前相同的世界空间位置、旋转和缩放。
//true 会保留 世界坐标下的状态 和 父对象 进行计算 得到本地坐标系的信息
//false 不会保留 会直接把世界坐标系下的 位置角度缩放 直接赋值到 本地坐标系下 可以理解为粗暴的把世界坐标下的变换赋值到面板上
//this.transform.SetParent(null);//断绝父子关系
//this.transform.SetParent(GameObject.Find("Father2").transform);//认爸爸
//this.transform.SetParent(GameObject.Find("Father3").transform, false);
#endregion
#region 知识点二 抛妻弃子
//DetachChildren方法 就是和自己的所有儿子 断绝关系 没有父子关系了
//清除所有子项的父级。
//注意:不能影响自己儿子和孙子的关系 只能断绝自己和儿子的关系
//this.transform.DetachChildren();
#endregion
#region 知识点三 获取子对象
//Find发明方法 按名字查找儿子 找到儿子的 transform信息
//按 n 查找子项,然后返回它。
print(this.transform.Find("Cube (1)").name);
//Find方法 是能够找到 失活的对象的 !!!!! GameObject相关的 查找 是不能找到失活对象的
//他只能找到自己的儿子 找不到自己的孙子 !!!!!!
//print(this.transform.Find("Cube (1)(2)").name);
//虽然它的效率 比GameObject.Find相关 要高一些 但是 前提是你必须知道父亲是谁 才能找
//childCount方法 得到有多少个儿子
//父变换具有的子项数。
//失活的儿子也会算数量
//只会找儿子不找孙子 所以孙子不会算数量
print(this.transform.childCount);
//GetChild方法 通过索引号 去得到自己对应的儿子
//按索引返回变换子项。
//如果编号 超出了儿子数量的范围 那会直接报错的
//返回值 是 transform 可以得到对应儿子的 位置相关信息
this.transform.GetChild(0);
//遍历所有儿子
for (int i = 0; i < this.transform.childCount; i++)
{
print("儿子的名字:" + this.transform.GetChild(i).name);
}
#endregion
#region 知识点四 儿子的操作
//IsChildOf方法 判断自己的爸爸是谁
//该变换是否为 parent 的子项?
//一个对象 判断自己是不是另一个对象的儿子
//if (son.IsChildOf(this.transform))
//{
// print("是我的儿子");
//}
//GetSiblingIndex方法得到自己作为儿子的编号
//获取同级索引。
//print(son.GetSiblingIndex());
//SetAsFirstSibling方法 把自己设置为第一个儿子
//将变换移动到本地变换列表的开头。
//son.SetAsFirstSibling();
//SetAsLastSibling方法 把自己设置为最后一个儿子
//将变换移动到本地变换列表的末尾。
//son.SetAsLastSibling();
//SetSiblingIndex方法 把自己设置为指定个儿子
//设置同级索引。
//就算你填的数量 超出了范围(负数或者更大的数) 也不会报错 会直接设置成最后一个编号
//son.SetSiblingIndex(1);
#endregion
}
//总结
//设置父对象相关的内容
//获取子对象
//抛弃妻子
//儿子的操作
}
19.3 练习题
请为Transform写一个拓展方法,可以将它的子对象按名字的长短进行排序改变他们的顺序,名字短的在前面,名字长的在后面
设置一个拓展方法类:
public static class Lesson19_练习题拓展方法
{
}
为Transform添加名字排序的拓展方法:
/// <summary>
/// 这个方法 是我们为Transform写的一个拓展方法
/// 主要用来把子对象按名字长短排序
/// </summary>
/// <param name="obj"></param>
public static void Sort(this Transform obj)
{
//有什么知识点 是和排序相关
//使用List的排序 比较符合我们的需求
//我们的思路 就是把子对象 放到一个 list容器中 然后对list进行排序
//排序完毕后 遍历list 去设置 这个顺序中的 对象的 子对象位置
//遍历添加子对象到子对象list中
List<Transform> list = new List<Transform>();
for (int i = 0; i < obj.childCount; i++)
{
list.Add(obj.GetChild(i));
}
//这是根据 名字长短进行排序 利用的 是list的排序 传个函数进去
list.Sort(
(a, b) =>
{
if (a.name.Length < b.name.Length)
return -1;
else
return 1;
}
);
//根据 list中的排序结果 重新设置每一个对象的 索引编号
for (int i = 0; i < list.Count; i++)
{
list[i].SetSiblingIndex(i);
}
}
调用添加名字排序的拓展方法:
this.transform.Sort();
请为Transform写一个拓展方法,传入一个名字查找子对象,即使是子对象的子对象也能查找到
为Transform添加搜索全部子对象的拓展方法:
/// <summary>
/// 根据名字找到 子对象 不管藏多深
/// </summary>
/// <param name="father">调用方法的对象</param>
/// <param name="childName">要找的对象名字</param>
/// <returns></returns>
public static Transform CustomFind(this Transform father, string childName)
{
//如何查找子对象的子对象
//我要找的对象
Transform target = null;
//先从自己身上的子对象找
target = father.Find(childName);
if (target != null)
return target;
//如果在自己身上没有找到 那就遍历的去找自己的子对象的子对象
for (int i = 0; i < father.childCount; i++)
{
//让子对象去帮我找 有没有这个名字的对象
//递归查找
target = father.GetChild(i).CustomFind(childName);
//找到了 直接返回
if (target != null)
return target;
}
return target;
}
调用搜索全部子对象的拓展方法:
print(this.transform.CustomFind("林文韬").name);
19.4 练习题代码
Lesson19_练习题
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson19_练习题 : MonoBehaviour
{
void Start()
{
#region 练习题一
//请为Transform写一个拓展方法,可以将它的子对象按名字的长短进行排序改变他们的顺序,
//名字短的在前面,名字长的在后面
this.transform.Sort();
#endregion
#region 练习题二
//请为Transform写一个拓展方法,传入一个名字查找子对象,即使是子对象的子对象也能查找到
print(this.transform.CustomFind("林文韬").name);
#endregion
}
}
Lesson19_练习题拓展方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class Lesson19_练习题拓展方法
{
/// <summary>
/// 这个方法 是我们为Transform写的一个拓展方法
/// 主要用来把子对象按名字长短排序
/// </summary>
/// <param name="obj"></param>
public static void Sort(this Transform obj)
{
//有什么知识点 是和排序相关
//使用List的排序 比较符合我们的需求
//我们的思路 就是把子对象 放到一个 list容器中 然后对list进行排序
//排序完毕后 遍历list 去设置 这个顺序中的 对象的 子对象位置
//遍历添加子对象到子对象list中
List<Transform> list = new List<Transform>();
for (int i = 0; i < obj.childCount; i++)
{
list.Add(obj.GetChild(i));
}
//这是根据 名字长短进行排序 利用的 是list的排序 传个函数进去
list.Sort(
(a, b) =>
{
if (a.name.Length < b.name.Length)
return -1;
else
return 1;
}
);
//根据 list中的排序结果 重新设置每一个对象的 索引编号
for (int i = 0; i < list.Count; i++)
{
list[i].SetSiblingIndex(i);
}
}
/// <summary>
/// 根据名字找到 子对象 不管藏多深
/// </summary>
/// <param name="father">调用方法的对象</param>
/// <param name="childName">要找的对象名字</param>
/// <returns></returns>
public static Transform CustomFind(this Transform father, string childName)
{
//如何查找子对象的子对象
//我要找的对象
Transform target = null;
//先从自己身上的子对象找
target = father.Find(childName);
if (target != null)
return target;
//如果在自己身上没有找到 那就遍历的去找自己的子对象的子对象
for (int i = 0; i < father.childCount; i++)
{
//让子对象去帮我找 有没有这个名字的对象
//递归查找
target = father.GetChild(i).CustomFind(childName);
//找到了 直接返回
if (target != null)
return target;
}
return target;
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com