我想将碰撞体数组转换为游戏对象数组。这是我知道如何做到这一点的唯一方法,但它感觉不是最佳的。有没有更好的方法可以做到这一点?
GameObject[] GetOverLap(){
GameObject[] gameObjects;
Collider[] colliders = Physics.OverlapSphere(transform.position, radius, layer);
gameObjects = new GameObject[colliders.Length];
for(int i = 0; i < colliders.Length; i++){
gameObjects[i] = colliders[i].gameObject;
}
return gameObjects;
}
以下是完整的代码块:
protected GameObject[] GetOverLap(GameType gameType){
GameObject[] gameObjects = null;
if(gameType == GameType._3D){
Collider[] colliders = Physics.OverlapSphere(transform.position, radius, layer);
gameObjects = new GameObject[colliders.Length];
for(int i = 0; i < colliders.Length; i++){
gameObjects[i] = colliders[i].gameObject;
}
}else if(gameType == GameType._2D){
Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, radius, layer);
gameObjects = new GameObject[colliders.Length];
for(int i = 0; i < colliders.Length; i++){
gameObjects[i] = colliders[i].gameObject;
}
}
return gameObjects;
}
它是重复的,无论如何都要压缩它,因为在 if/else 中唯一不同的行是OverlapSphere/OverlapCircleAll
.
使用 Array.ConvertAll。这个看起来很干净。
有关 msdn 的完整文档可在此处找到。
你可以直接使用Linq。
using System.Linq;
...
protected GameObject[] GetOverLap(GameType gameType){
List<Component> collComponents = new List<Component>();
List<GameObject> gameObjects = new List<GameObject>();
if (gameType == GameType._3D)
collComponents = Physics.OverlapSphere(transform.position, radius, layer).Cast<UnityEngine.Component>().ToList();
else if (gameType == GameType._2D)
collComponents = Physics2D.OverlapCircleAll(transform.position, radius, layer).Cast<UnityEngine.Component>().ToList();
foreach (Component c in collComponents)
gameObjects.Add (c.gameObject);
return gameObjects.ToArray();
}
我通常更喜欢将列表而不是数组用于一般目的 - 我喜欢他们的方法而不是可用于数组的方法。无论如何,我希望这段代码有助于提高您的可读性。
我希望这有所帮助!
更新:更新了代码,感谢@DRapp的建议。
简而言之,我建议使用自动映射器框架。因为,基本上你正在做的是将一个类/对象映射到另一个类/对象。
映射将消除主代码的复杂性,并简化语法。因此,它看起来类似于:
GameObject[] gameObjects = null;
if (gameType == GameType._3D){
gameObjects = Mapper.Map<Collider, GameObject>(colliders); }
else if(gameType == GameType._2D) {
gameObjects = Mapper.Map<Collider2D, GameObject> (colliders); };
基本上,您将在一个通用映射器文件中实现所有映射逻辑。默认情况下,当每个对象中的属性名称和类型相同时,自动映射器执行属性映射:
mapper.CreateMap<Collider, GameObject>();
mapper.CreateMap<Collider2D, GameObject>();
如果属性名称或类型不同,则需要定义单独的映射。快速示例类似于以下代码片段:
mapper.CreateMap<Collider, GameObject>()
.ForMember(dest => dest.Prop1, opt => opt.Ignore())
.ForMember(dest => dest.StateName, opt => opt.MapFrom(src => src.StateProvinceName));
.ForMember(dest => dest.Prop2, opt => opt.Ignore());
和分别对于 Collider2D:
mapper.CreateMap<Collider2D, GameObject>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.StaffId))
.ForMember(dest => dest.PersonName, opt => opt.MapFrom(src => src.StaffName));