在Unity 3D中,如何均匀分布对象以填充曲线空间是最佳方法?

5
我希望在编辑器中用椅子填充这个观众席,并使它们都面向同一个焦点(舞台)。然后,我将随机地用不同的人来填充这些椅子(在运行时)。每次运行后,椅子应保持不变,但人员应该被清除,以便在下一次运行时,人群看起来不同。
当前,座位区域、椅子和人员均未附加碰撞器。

enter image description here

我找到了这段代码,它已经处理好了旋转椅子以便它们对准同一个焦点的问题。但我仍然想知道是否有更好的方法来实现这个目标。
//C# Example (LookAtPoint.cs)
using UnityEngine;
[ExecuteInEditMode]
public class LookAtPoint : MonoBehaviour
{
    public Vector3 lookAtPoint = Vector3.zero;

    void Update()
    {
        transform.LookAt(lookAtPoint);
    }
}

额外的截图

enter image description here

enter image description here

enter image description here

1个回答

5
你可以 编写编辑器脚本 来自动地将它们均匀地放置。在这个脚本中,

以下代码中我没有处理世界空间和局部/模型空间。需要时请记得处理。

  1. Generate parallel rays that come from +y to -y in a grid. The patch size of this grid depends on how big you chair and the mesh(curved space) is. To get a proper patch size. Get the bounding box of a chair(A) and the curved space mesh(B), and then devide them(B/A) and use the result as the patch size.

    Mesh chairMR;//Mesh of the chair
    Mesh audiMR;//Mesh of the auditorium
    var patchSizeX = audiMR.bounds.size.X;
    var patchSizeZ = audiMR.bounds.size.Z;
    var countX = audiMR.bounds.size.x / chairMR.bounds.size.x;
    var countZ = audiMR.bounds.size.z / chairMR.bounds.size.z;
    

    So the number of rays you need to generate is about countX*countZ. Patch size is (patchSizeX, patchSizeZ).

    Then, origin points of the rays can be determined:

    //Generate parallel rays that come form +y to -y.
    List<Ray> rays = new List<Ray>(countX*countZ);
    for(var i=0; i<countX; ++i)
    {
        var x = audiMR.bounds.min.x + i * sizeX + tolerance /*add some tolerance so the placed chairs not intersect each other when rotate them towards the stage*/;
        for(var i=0; i<countZ; ++i)
        {
            var z = audiMR.bounds.min.z + i * sizeZ + tolerance;
            var ray = new Ray(new Vector3(x, 10000, z), Vector3.down);
            //You can also call `Physics.Raycast` here too.
        }
    }
    
  2. Get postions to place chairs.

    1. attach a MeshCollider to your mesh temporarily
    2. foreach ray, Physics.Raycast it (you can place some obstacles on places that will not have a chair placed. Set special layer for those obstacles.)
    3. get hit point and create a chair at the hit point and rotate it towards the stage
  3. Reuse these hit points to place your people at runtime.

    Convert each of them into a model/local space point. And save them into json or asset via serialization for later use at runtime: place people randomly.


好的,您建议在xy平面还是zy平面生成光线?我展示的图片是半圆形布局的一部分。还有3个其他的阶梯需要填充。此外,我不确定如何确定密度,座椅的边界框和曲线空间网格矢量吗?非常感谢您的帮助,这真的很困难。 - johnny117
你能提供一个屏幕截图展示你的曲面网格吗? - zwcloud
我放椅子的表面没有碰撞器(需要吗?)我喜欢你的方法,因为我的最终目标是随机地将人放在椅子上,并且定义点是理想的。我使用的样条方法(请参见新截图)很混乱。 - johnny117
是的,要使用射线投射,网格必须附加一个碰撞器。但我认为您需要更多地描述您想要什么以及在什么样的环境中。两个重要方面:1.这些椅子/人何时放置?在运行时还是仅在编辑器中?2.它们是否会再次随机放置?如果是这样,椅子和人都会被清除并重新放置吗?在运行时?请编辑您的问题以向我们展示更多信息。 - zwcloud
好的,完成了。如果需要其他信息,请告诉我。 - johnny117
太棒了,我会尝试并在接下来的几天内向您更新我的结果! - johnny117

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接