Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to evenly distribute objects to fill a curved space in Unity 3D?

I would like to fill this auditorium seating area with chairs (in the editor) and have them all face the same focal point (the stage). I will then be randomly filling the chairs with different people (during runtime). After each run the chairs should stay the same, but the people should be cleared so that during the next run the crowd looks different.

The seating area does not currently have a collider attached to it, and neither do the chairs or people.

enter image description here

I found this code which has taken care of rotating the chairs so they target the same focal point. But I'm still curious if there are any better methods to do this.

//C# Example (LookAtPoint.cs)
using UnityEngine;
[ExecuteInEditMode]
public class LookAtPoint : MonoBehaviour
{
    public Vector3 lookAtPoint = Vector3.zero;

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

Additional Screenshots

enter image description here

enter image description here

enter image description here

like image 847
johnny117 Avatar asked Apr 09 '17 05:04

johnny117


People also ask

How do you drag objects in unity?

The basic method of dragging and dropping an object with the mouse in Unity typically involves adding a Collider component to the object and then using a physics function, such as Overlap Point or Raycast to detect when it's clicked.

How do you move Gameobjects in unity?

To move an object with the keyboard, or with any other input device, simply multiply the direction of movement you want to apply, such as forward, for example, by the Input Axis you want to use to control it.


1 Answers

You can write a editor script to automatically place them evenly. In this script,

I don't handle world and local/model space in following code. Remember to do it when you need to.

  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.

like image 129
zwcloud Avatar answered Oct 18 '22 05:10

zwcloud