【问题标题】:Advice on Instantiation?关于实例化的建议?
【发布时间】:2019-09-30 18:13:14
【问题描述】:

这是我关于 Stack Overflow 的第一个问题。我是编码新手,所以请耐心等待我和我可怕的代码。

void ChickenInstantiate()
    {
        LocOfChkn.Add(spawnLoc);
        int i = 0;
        for (int ChickenCount = 0; ChickenCount < maxChickenCount; ChickenCount++)
        {
            while (Vector3.Distance(spawnLoc, LocOfChkn[i]) < 2)
            {
                spawnLoc = new Vector3(Random.Range(randXMin, randXMax), Random.Range(randYMin, randYMax), 1);
                spawnLoc.z = 5;
                i += 1;
                if (i >= LocOfChkn.Count)
                {
                    break;
                }
            }
            Instantiate(ChickenPrefab1, spawnLoc, Quaternion.identity);
            LocOfChkn.Add(spawnLoc);
            i = 0;
        }
    }

这是一些用于安装预制件的代码,但要确保它不会在一个区域内实例化,坦率地说,我不知道应该如何修复它——它完全坏了;鸡没有出现,我什至不确定它们是否在正确的区域产卵,等等(spawnLoc 的第一个实例是在启动时定义的,顺便说一句)

我正在使用当前最新版本的统一和视觉工作室。

【问题讨论】:

  • ChickenInstantiate 在哪里调用?
  • 提示:1) 使您的命名描述性。避免使用“Loc”而不是“Location”、“Chkn”而不是“Chicken”以及其他此类首字母缩写词废话。没关系对他人的可读性;您将花费 分钟 尝试尽快破译和理解自己的代码,以节省一些 几分之一秒 的打字时间;只需使用 IDE 的自动完成热键,您就可以保存除第一次之外的所有内容。
  • 2) 决定一个命名约定并遵循它。对于任何给定类型的数据,即字段、方法、类等,您不应该在一个地方有camelCase,在另一个地方有PascalCase,在另一个地方有snake_case。命名约定将为您节省时间和理智。我建议像 Rider / Resharper 中默认的那样。这是我在尝试了许多其他命名约定后使用的。谷歌它,你会找到它。 --- 顺序也很重要。如果您使用主题-动作,例如 chickenMovement here,请不要使用 movementOfChiken (action-subject) there。但这还不够标准化。
  • 假设 spawnLoc 是一个Vector3,它不是一个“实例”,它是一个结构。这意味着在将其添加到 LocOfChkn 之后对其进行修改将不会执行任何操作。

标签: c# unity3d instantiation


【解决方案1】:
  • 您应该为您添加到locOfChkn 的第一个位置Instantiate 一只鸡。这既可以确保您的代码正在运行,又可以避免出现问题。

  • 使用 VSCode 或您最喜欢的 IDE 对您的函数进行逐步评估,以准确了解正在发生的事情。除此之外,为每个步骤添加Debug.Logs。

  • 检查任何生成的鸡的层次结构。也许他们被禁用了。

现在讨论其他问题:

  • 请按照 C# 约定编写代码。 Chkn 和 Loc 非常不直观。

  • 如果在评估距离时忽略 z 位置,请考虑使用 Vector2.Distance。

  • 将字段用于仅在一个函数中使用的值是没有用的。只需将 spawnLoc 设置为 ChickenInstantiate 中的 var。

这是您的代码的清理版本

void InstantiateChicken()
{
    List<Vector3> chickenPositions = new List<Vector3>();

    for (int i = 0; i < maxChickenCount; i++)
    {
        bool doesCollide;
        Vector3 spawnLocation;
        do
        {
            spawnLocation = new Vector3(
                Random.Range(randXMin, randXMax),
                Random.Range(randYMin, randYMax),
                5);
            doesCollide = false;
            foreach (var pos in chickPositions)
            {
                if (Vector2.Distance(pos, spawnLocation) < 2f)
                    doesCollide = true;
            }
        }
        while (doesCollide);

        Instantiate(chickenPrefab1, spawnLocation, Quaternion.identity);
        chickenPositions.Add(spawnLocation);
    }
}

或者,只需手动放置所有鸡,并让它们在产卵时以随机因素偏移它们的位置。

【讨论】:

  • 非常感谢您的帮助。包含一个 Foreach 循环让我恢复了一些旧的记忆;我完全忘记了它的存在。关于约定的提示也很有帮助,我已经检查了我的代码并更改了所有错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多