Unity3D培训
美国上市Unity3D培训机构

400-111-8989

VR培训

在Unity中定义统一的对象搜索接口

  • 发布:Unity3D培训
  • 来源:Unity3D教程
  • 时间:2016-12-08 13:27

很多时候我们要在unity中以各种方式搜索对象。比如按名字搜索、按tag、layer或者是查找名字为xxx开头的对象。

本文是介绍以一种统一的接口来搜索对象。

1、定义统一的搜索接口

///

/// 游戏对象搜索接口

///

public interface IGameObjectFinder

{

///

/// 搜索

///

/// 搜索的开始位置/根节点

/// 搜索存放的结果

void Find(Transform root, List findResult);

}

2、定义一个使用上面搜索接口的方法

public class Finder{

///

/// 查找指定根节点下符合指定的查找器的Transform并保持到findResult中

///

///

///

///

public static void Find(Transform root, List findResult, IGameObjectFinder finder)

{

if (root == null)

{

throw new Exception("root can not be null, it defines the starting point of the find path");

}

if (findResult == null)

{

throw new Exception("findResult can not be null, it used to collect the find result");

}

if (finder == null)

{

throw new Exception("finder can not be null, it defines how to find transform");

}

finder.Find(root, findResult);

}

}

可以看到,2步骤只是简单调用1的接口进行搜索。但是1只是接口,有啥用?接着看。

3、实现一个查找某个组件的接口

///

/// 根据组件搜索

///

///

public class GameObjectFinderByComponent : IGameObjectFinder where T : Component

{

public void Find(Transform root, List findResult)

{

foreach (var componentsInChild in root.GetComponentsInChildren())

{

findResult.Add(componentsInChild.transform);

}

}

}

可以看到只要实现IGameObjectFinder就可以了。那么如果这时候想调用,应该怎么调用呢?

比如想查找transform下面的刚体组件,然后保存到result里面。只要:

Finder.Find(transform, result, new GameObjectFinderByComponent());

什么?看起来好像有点小题大作,直接用GetComponentsInChildren不就好吗?

先不急。我们继续看看其它查找需求。比如我想查找名字为xxx的对象。

4、实现一个迭代查找首先,要查找指定节点下的某个名字的所有节点(不管深度多少),这个需要遍历。那么,我们可以先抽象出一个遍历的接口。

为了保证搜索的统一,那么我们还是从IGameObjectFinder中继承。

///

/// 迭代遍历搜索

///

public class GameObjectFinderByIteration : IGameObjectFinder

{

private IGameObjectFinderForIteration finderForIteration;

public GameObjectFinderByIteration(IGameObjectFinderForIteration finderForIteration)

{

this.finderForIteration = finderForIteration;

}

public void Find(Transform root, List findResult)

{

for (int i = 0, childCount = root.childCount; i < childCount; i++)

{

Transform t = root.GetChild(i);

if (finderForIteration.isVaild(t))

{

findResult.Add(t);

}

Find(t, findResult);

}

}

}

这个代码的意思就是:我先把开始节点下面的每个子节点通过另一个接口IGameObjectFinderForIteration来判断是否符合要求,是的话则加入结果列表。然后继续查找这个子结点下的其他子节点。(该搜索是不包括第一个开始节点的)

IGameObjectFinderForIteration的接口也很简单:

///

/// 迭代搜索判断

///

public interface IGameObjectFinderForIteration

{

///

/// 指定节点是否合法

///

///

///

bool isVaild(Transform node);

}

好的,这样就意味着我们要想查找某个根节点下的所有子节点(包括直接和间接的),只要实现一个IGameObjectFinderForIteration。那么OK。看看怎么按名字搜索。

///

/// 迭代遍历按名字搜索

///

public class FinderForIterationByName : IGameObjectFinderForIteration

{

protected readonly string NAME;

public FinderForIterationByName(string name)

{

NAME = name;

}

public bool isVaild(Transform getChild)

{

return getChild.gameObject.name.Equals(NAME);

}

}

使用也很简单,加入想找transform节点下,名字为“abc”的对象,并保存在result列表里面。只要这样:Finder.Find(transform, result, new GameObjectFinderByIteration(new FinderForIterationByName("abc")));

5、有什么用?很多人可能还不明白有什么用,通过上面的抽象。你可以发现我们把搜索全部统一为:

Finder.Find(transform, result, objectFinderImpl);

1、代码是统一的,不管你的搜索条件有多复杂。便于代码管理、维护、拓展。

2、可配置,你可以简单通过数字关联不同的搜索器的实现,然后通过附带的参数传递给具体的搜索器,来实现通过配置文本采用不同的搜索器进行搜索。这个在你做新手引导的时候很好用,因为,策划可能有时候要把一个xxx手指放到什么图标、什么按钮那里。那你就可以把这些查找交给策划来配置了~

3、如果还没明白有什么用,那就无视吧。总有一天你还会回来的。

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:unity3d教程:让unity中物理效果更加明显
下一篇:U3D图像的处理过程-Unity3d培训机构
选择城市和中心
贵州省

广西省

海南省