为什么在实例化对象时它们在空中而不是在地面上?

Why when instantiating objects they are in the air and not on ground?

Circle部分把物体放在空中。 我怎样才能让他们在地面上? 他们站在空中。方阵是在地上,圆阵是在空中

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SquadFormation : MonoBehaviour
{
    enum Formation
    {
        Square, Circle
    }

    public Transform squadMemeber;
    public int columns = 4;
    public int space = 10;
    public int numObjects = 20;

    // Use this for initialization
    void Start()
    {
        ChangeFormation();
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void ChangeFormation()
    {
        Formation formation = Formation.Square;

        switch (formation)
        {
            /*case Formation.Square:

                for (int i = 0; i < 23; i++)
                {
                    Transform go = Instantiate(squadMemeber);
                    Vector3 pos = FormationSquare(i);
                    go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);
                    go.Rotate(new Vector3(0, -90, 0));
                }
                break;*/

            case Formation.Circle:

                Vector3 center = transform.position;
                for (int i = 0; i < numObjects; i++)
                {
                    Vector3 pos = RandomCircle(center, 5.0f);
                    var rot = Quaternion.LookRotation(pos - center);
                    Instantiate(squadMemeber, pos, rot);
                }
                break;
        }
    }

    Vector2 FormationSquare(int index) // call this func for all your objects
    {
        float posX = (index % columns) * space;
        float posY = (index / columns) * space;
        return new Vector2(posX, posY);
    }

    Vector3 RandomCircle(Vector3 center, float radius)
    {
        float ang = Random.value * 360;
        Vector3 pos;
        pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
        pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
        pos.y = center.y;
        return pos;
    }
}

它们应该在地面(Terrain)上实例化。 需要将它们定位在地面上。

更新:

这是我现在尝试的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SquadFormation : MonoBehaviour
{
    enum Formation
    {
        Square, Circle
    }

    public Transform squadMemeber;
    public int columns = 4;
    public int space = 10;
    public int numObjects = 20;
    public float yOffset = 1;

    // Use this for initialization
    void Start()
    {
        ChangeFormation();
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void ChangeFormation()
    {
        Formation formation = Formation.Circle;

        switch (formation)
        {
            /*case Formation.Square:

                for (int i = 0; i < 23; i++)
                {
                    Transform go = Instantiate(squadMemeber);
                    Vector3 pos = FormationSquare(i);
                    go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);
                    go.Rotate(new Vector3(0, -90, 0));
                }
                break;*/

            case Formation.Circle:

                Vector3 center = transform.position;
                for (int i = 0; i < numObjects; i++)
                {
                    Vector3 pos = RandomCircle(center, 5.0f);
                    var rot = Quaternion.LookRotation(pos - center);
                    pos.y = Terrain.activeTerrain.SampleHeight(pos);
                    pos.y = pos.y + yOffset;
                    Instantiate(squadMemeber, pos, rot);
                }
                break;
        }
    }

    Vector2 FormationSquare(int index) // call this func for all your objects
    {
        float posX = (index % columns) * space;
        float posY = (index / columns) * space;
        return new Vector2(posX, posY);
    }

    Vector3 RandomCircle(Vector3 center, float radius)
    {
        float ang = Random.value * 360;
        Vector3 pos;
        pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
        pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
        pos.y = center.y;
        return pos;
    }
}

我在 for 循环中添加了偏移量 yOffset 和这两行:

pos.y = Terrain.activeTerrain.SampleHeight(pos);
pos.y = pos.y + yOffset;

现在他们在地上,但躺在 back/stomach 上,而不是像在空中那样站立。

Why when instantiating objects they are in the air and not on ground?

您需要找到一种方法来计算地形的高度,然后将其用作您的 y 轴值。

获得pos后,用Terrain.activeTerrain.SampleHeight函数修改y轴。

Vector3 pos = RandomCircle(center, 5.0f);
pos.y = Terrain.activeTerrain.SampleHeight(pos);

可能会根据游戏对象的类型添加一个偏移量(yOffset 应该是一个浮点数)

pos.y = pos.y + yOffset;

现在,继续使用新的实例化 pos:

var rot = Quaternion.LookRotation(pos - center);
Instantiate(squadMemeber, pos, rot);

注:

根据角色的大小,您必须并且必须不断更改 yOffset 的值,直到获得所需的位置。这个位置应该适用于相同的角色。如果你想对不同大小的GameObjects做这个,你也必须修改yOffset直到你满意为止。

不是真正的答案,而是一些建议:

我在这里看到一些基本问题,无论如何您的代码有点混乱。有些事情应该相似,但事实并非如此。我认为这里的基线是您需要一些基本结构。

首先,您应该从这里确定您需要的基本部件开始。

需要解决三个基本问题:

  1. XY 位置
  2. Z 位置
  3. 旋转

最后一个是你的角色躺在地上的问题。看到正方形旋转了 -90 度了吗?我假设这个是这样做的。

但这里有一个更紧迫的问题,这里有一个问题:除了XY位置,正方形和圆形之间应该有什么区别?答案:none。您对待这两种情况的方式与应有的方式大不相同。代码应该看起来像这样:

Position xyPosition;
switch (formation)
    case Circle: xyPosition = randomCirclePosition(someargument)
    case Square: xyPosition = randomSquarePosition(someargument)
Position position = rotateUpright(xyPosition)
position = adjustZ(position)

看看差异是如何只应用在一个部分的?

立即跳到我眼前的是那些签名:Vector2 FormationSquareVector3 RandomCircle。特别是 Vector2Vector3。这是两种完全不同的方法。为什么?这会使您的代码不必要地异构,使其更难阅读。不允许我上面写的清晰结构。你为什么得到那么多?为什么不复制广场的旧代码,然后根据需要进行调整?

我说你是从网上抄来的方码,我猜对了吗?而且您出于某种原因难以理解它?也许是因为你不熟悉它背后的数学?如果是这样,我的 "answer" 是这样的:采用方形代码,直到您理解其中的任何一行后再继续。它做什么,为什么需要它,没有它会发生什么。如果您只是去注释行,那么就很好了,然后看看引擎中发生了什么。或者问问别人。但最重要的是你最终理解了每一行。

您可能还想在代码运行时将其放在 CodeReview 上。我在这里和那里看到了一些风格上的问题。就像凭空而来的神秘23

抱歉,如果这听起来有点任性或类似的话,或者如果我误判了这里的情况。