【问题标题】:Looping through 2 arrays (Unity3d)循环遍历 2 个数组(Unity3d)
【发布时间】:2019-12-22 10:40:11
【问题描述】:

玩家资源和必需资源遵循类似的模式;

public struct RequiredResources
    {
        public Resource resource;
        public int quantityRequired;
    }

    public class Resource : ScriptableObject
    {
        [SerializeField]
        private string resourceName;
        public string GetName() { return resourceName; }

        [SerializeField]
        public Sprite icon;
        public Sprite GetIcon() { return icon; }
    }

玩家可用的资源如下; 食物、黄金、木材、石头

我希望使用这样的系统,以便可以根据需要轻松添加更多资源。放置建筑物时,它会列出建造它所需的资源清单,例如房屋可能需要花费; 黄金 = 5 木材 = 3

使用下面的代码,这将遍历资源并根据需要减少数量。基本上是玩家拥有的数量 - 成本,然后更新 UI。

public void UseResources()
    {
        foreach (RequiredResources requiredResources in building.GetResources())
        {
            foreach (ResourceManager.PlayersResources resource in player.playersResources)
            {
                if (requiredResources.resource.Equals(resource.GetResourceType()))
                {
                    resource.RemoveQuantity(requiredResources.quantityRequired);
                }
            }
        }
    }

但是,在运行此之前,我想检查播放器是否有足够的资源。当我使用类似的逻辑来返回真假,并且玩家有足够的木材(真)但没有足够的金币(假)时,它将删除两者的数量。我不知道如何正确地做到这一点。

public bool HasRequiredResources(RequiredResources[] requiredResources)
    {
        foreach (RequiredResources r in requiredResources) //go through all required resources
        {
            foreach (PlayersResources p in playersResources)
            {
                if (r.quantityRequired > p.GetCurrAmount())
                    Debug.Log("Has enough " + r.resource.name);
                    return false;
            }
        }
        return true; //reaching this point means that the faction has all required resources
    }

这就是我所拥有的,但它总是返回 false,我哪里出错了?我相信这是由于foreach内部的foreach。但是如何运行对第二个(PlayersResources)列表的搜索以返回相同的资源?

【问题讨论】:

  • 肯定是打印出来的,“够了”?我猜如果你有 1 个糖,2 个面粉,它检查 2 个面粉,它对 1 个糖说不,因为它不检查糖和面粉是相同的资源类型......跨度>

标签: c# unity3d


【解决方案1】:

我相信你的错误是因为你没有在 if 子句中包含 return 语句。所以 foreach 总是返回 false。作为最佳实践,您应该始终在 if 语句中使用花括号。这将为您节省数小时的调试时间。 试试这个...

foreach (PlayersResources p in playersResources)
{
    if (r.quantityRequired > p.GetCurrAmount())
        {
            Debug.Log("Has enough " + r.resource.name);
            return false;
        }
}

虽然不理解 Debug.Log 逻辑...

【讨论】:

  • 我相信你是对的,我昨天画了这么一片空白,现在用一双新鲜的眼睛访问我已经看到了我的错误!然而,jgfoot 为感兴趣的人提出了一个非常有效的解决方案,利用 Linq。非常感谢您抽出宝贵时间帮助欧拉!
  • 乐于助人。编码有时会变得很麻烦。
【解决方案2】:

看起来你的内部 foreach 循环没有检查这两个资源是否相同。例如,当所需资源仅为 5 个木材时,您正在检查用户是否有 5 个金币。

在第二个 foreach 循环中添加一个 if 语句进行检查,可能类似于 if (p.resourceName == r.resource.name) { ...

您还可以尝试使用 LINQ 语法。我不确定你的类中的字段名称,但似乎这样的东西对你有用:

return requiredResources.All(r =>
    playersResources.Any(p => r.resource.resourceName == p.resource.resourceName &&
       r.quantityRequired > p.GetCurrAmount())   
);

基本上,这意味着:如果对于 requiredResources 中的每个 r,playersResource 中至少有一个 p 与 r 具有相同的资源名称并且数量足够,则返回 true。

【讨论】:

  • 谢谢你!如此简单,如此有效!我还没有深入研究 Linq,但我肯定会对此进行研究。非常感谢您的帮助,圣诞快乐!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 2019-07-10
  • 2014-01-07
  • 2011-08-28
  • 1970-01-01
相关资源
最近更新 更多