旋转和定位一排游戏对象,无缝连接。

huangapple go评论64阅读模式
英文:

Rotating and positioning a row of gameobjects without gaps

问题

以下是您要翻译的内容:

我有一个带有一小段道路的房屋预制体,就像这样:

旋转和定位一排游戏对象,无缝连接。

我想把它们并排排列,创建一条街道,但我也想让它们稍微倾斜,以便道路似乎通向远处。更像是这样:

旋转和定位一排游戏对象,无缝连接。

我已经能够放置它们并旋转它们,但我在确定位置方面遇到了很多问题。我猜想我可能没有应用某些数学技巧或其他东西。

这是我的代码:

        int houseCount = 0;
        float offsetX = 0;
        float offsetZ = 0;
        while (houseCount < 30)
        {
            GameObject house = GameObject.Instantiate(housePrefab);
            house.transform.Rotate(new Vector3(0,-20f,0), Space.Self);
            house.transform.position = new Vector3(offsetX, 0, offsetZ);

            // 计算下一个房屋的偏移量
            HouseUnit unit = house.GetComponent<HouseUnit>();
            MeshRenderer renderer = unit.GetHouseBase().GetComponent<MeshRenderer>();
            Vector3 size = renderer.bounds.size;
            offsetX += size.x;
            offsetZ += size.z / 2f;

            Debug.Log(size);
            houseCount++;
        }

unit.GetHouseBase() 返回道路段,它是一个简单的平面。我认为这是基于位置的最合逻辑的部分,因为它既是最宽的部分,又是我需要连接的部分。

运行此代码会产生以下结果:

旋转和定位一排游戏对象,无缝连接。

它们的对齐情况还不错,但我无法弄清楚如何关闭那个间隙。是否有人有任何建议,或者可以向我指出资源?提前感谢。

英文:

I have a prefab of a house with a bit of road attached, like so:

旋转和定位一排游戏对象,无缝连接。

I want to arrange these side-by-side to create a street, but I also want to have them at a slight angle so that the road seems to head off into the distance. Something more like this:

旋转和定位一排游戏对象,无缝连接。

I've been able to place them and rotate them, but I'm having a lot of trouble figuring out the positioning. I'm guessing there's some maths trick I'm not applying or something.

This is my code so far:

        int houseCount = 0;
        float offsetX = 0;
        float offsetZ = 0;
        while (houseCount &lt; 30)
        {
            GameObject house = GameObject.Instantiate(housePrefab);
            house.transform.Rotate(new Vector3(0,-20f,0), Space.Self);
            house.transform.position = new Vector3(offsetX, 0, offsetZ);

            // Calculate offset for next house
            HouseUnit unit = house.GetComponent&lt;HouseUnit&gt;();
            MeshRenderer renderer = unit.GetHouseBase().GetComponent&lt;MeshRenderer&gt;();
            Vector3 size = renderer.bounds.size;
            offsetX += size.x;
            offsetZ += size.z / 2f;

            Debug.Log(size);
            houseCount++;
        }

unit.GetHouseBase() returns the road segment, which is a simple plane. I figured that was the most logical bit to base the positioning on since it's a) the widest part, and b) the bit I need to connect up.

Running this gives the following result:

旋转和定位一排游戏对象,无缝连接。

They're not lining up too badly, but I can't figure out how to close that gap. Has anyone got any suggestions, or resources they can point me at? Thanks in advance.

答案1

得分: 1

请提供您要翻译的具体内容,以便我可以为您进行翻译。

英文:

See MeshRenderer has wrong bounds when rotated

As a short summary:

  • Unity takes Mesh.bounds which are in local space (unscaled, unrotated, untranslated)
  • Unity then wraps this bounds within the Renderer.bounds
  • Since Bounce are always world axis aligned the Renderer.bounds grows when rotating the object in order to fit the now rotated mesh bounds within

Just re-posting the image for better illustration

旋转和定位一排游戏对象,无缝连接。


So what I would do is

  1. Have a common parent object
  2. Do all house placements while parent object is not rotated
    <br>=> Can rely on Renderer.bounds to be accurate
  3. Then in the end rotate the parent according to your needs
    <br>=> and all children (houses) automatically along with it
  4. [optional] If you then really really do not want that parent object there for whatever reason, simply once you are done un-parent all the houses maintaining their current positions and rotations and destroy the parent

something like e.g.

// either already have that common parent or create one now
var parent = new GameObject().transform;

// if using previously existing parent store original position and rotation
var position = parent.position;
var rotation = parent.rotation;

// ensure not rotated
parent.position = Vector3.zero;
parent.rotation = Quaternion.identity;

// span houses into parent
var offsetX = 0f;
for(var houseCount = 0; houseCount &lt; 30; houseCount++)
{
    var house = Instantiate(housePrefab, parent, Vector3.right * offsetX, Quaternion.identity);

    // Calculate offset for next house
    var size = house.GetComponentInChildren&lt;Renderer&gt;().bounds.size;
    offsetX += size.x;
}

parent.position = position;
// either reapply previous rotation (if already was rotated)
parent.rotation = rotation;
// or rotate now to your desired 20&#176;
parent.rotation = Quaternion.Euler(0, -20f, 0);


// [optional] as said if you then d not want the parent anymore you could also add
while(parent.childCount &gt; 0)
{
    var child = parent.GetChild(0);
    child.SetParent(parent.parent, true);
}
Destroy(parent.gameObject);

答案2

得分: 0

renderer.bounds是世界空间中的边界框,所以如果你旋转了渲染器,边界框也会变化。你可以尝试使用renderer.localBounds或者Mesh.bounds,这些属性返回的是本地空间中的边界框。但请注意它们是可变的,通常是由所有顶点计算得出的,这意味着它们不能保证完全准确。如果你仍然发现有间隙,你可以使用内置的立方体手动测量道路的宽度,其宽度为1。

英文:

renderer.bounds is the bounding box in world space, so if you rotate the renderer, the bounds changes too. You can try renderer.localBounds or Mesh.bounds, these properties return the bounding box in local space. But please notice they are variable and usually calculated by all the vertex, that means they are not guaranteed to be accurate. If you still find gaps, you can manually measure the width of the road with the built-in cube, its width is 1.

huangapple
  • 本文由 发表于 2023年5月17日 09:37:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76268046.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定