Unity /搜索通过标签关闭列表中的对象

时间:2019-02-21 18:22:16

标签: unity3d

我在查找列表中最接近的对象时遇到问题。 标签共有三种类型(食物,石头和木头)。 我在一开始就生成它们,每种类型都有它们,如果我发现了一些资源,它们就不再隐藏了,我将它们添加到列表中,以便工人去获取它们。

因此在游戏后期,示例 我找到了3个石材资源,那么工人每次都应该首先收获最接近的石材。 但是我不知道如何迭代地抛出一个循环,仅用于搜索标签以及如何获取最接近的标签的位置。

这是我编写的方法的一些代码:

void FindNearestFoodRessource()
    {
        for (int i = 0; i < gameController.discoveredRessources.Count; i++)
        {
            //float dist = Vector3.Distance(gameController.discoveredRessources[i].transform.position, transform.position);
            GameObject nearestFoodRessource = GameObject.FindGameObjectWithTag("Food");

        }
    }

2 个答案:

答案 0 :(得分:1)

第一件事-不要在经常调用的方法中使用FindGameObject ****,这非常昂贵。

关于您的问题-只需检查所有资源的标签和距离:

float minDist = Vector3.Distance(gameController.discoveredRessources[0].transform.position, transform.position);
int minDistIndex = 0;
for (int i = 1; i < gameController.discoveredRessources.Count; i++)
{
    if (gameController.discoveredRessources[i].gameObject.CompareTag("Food"))
    {
        float dist = Vector3.Distance(gameController.discoveredRessources[i].transform.position, transform.position);
        if (dist < minDist)
        {
            minDist = dist;
            minDistIndex = i;
        }
    }
}
//Now you can move to gameController.discoveredRessources[minDistIndex]

找到后,您还可以将所有食物/石头/木材存储在单独的列表中

答案 1 :(得分:0)

使用Linq Where和此有用的扩展方法MinBy

using System;
using System.Collections.Generic;
using System.Linq;

public static class Linqextensions
{
    public static T MinBy<T, R>(this IEnumerable<T> en, Func<T, R> evaluate) where R : IComparable<R>
    {
        return en.Select(t => new Tuple<T, R>(t, evaluate(t)))
            .Aggregate((max, next) => next.Item2.CompareTo(max.Item2) < 0 ? next : max).Item1;
    }
}

(只需将该代码复制到您的项目中),您可以在“一行”行中完成

var closestItem = gameController.discoveredRessources
    // this is a filter only selecting the ones with tag = "Food"
    .Where(obj => obj.CompareTag("Food"))
    // this returns you the item from the list with the lowest distance
    .MinBy(obj => Vector3.Distance(obj.transform.position, transform.position));