- Home /
How to enable clicking on thousands of dynamically changing objects
I have a procedural galaxy that has millions of stars(possibly billions in the future). I've created an object pool that is a List of stars that I add to and subtract from into a 3D array of Lists that represent the adjacent "grid locations" in my galaxy next to the camera. When the camera moves forward into another "grid location" the "Galaxy Script" will take stars out of this location in the array of list if it has too many back into the pool and deactivate them. Likewise, it will take some out of the pool and activate them if it has too few. Then it will make new stars out of these using random seeds and tweaking some values.
So I never instantiate new GameObjects nor do I Destroy() them. I don't even change their parents. I can fly my camera through my galaxy and at worse in its center the frame rate may have a lag spike of about 40ms tops that isn't really noticeable when thousands of stars are activated at once. But I have ideas on how to optimize that further later on.
I have just one major problem now. There is only one simple task I want to perform on these stars. I want to be able to click on them and retrieve their name and information. But using Box Colliders to raycast onto them simply will not work. With boxcolliders on my star prefab passing into a new grid location in my galaxy jumps from a 40ms spike to a 2.5 SECOND lag at the galaxy center where lots of stats are! Also, about a 500ms to 800ms lag around the edge of the galaxy. There absolutely has to be another much much much better way.
With colliders disabled:
With colliders enabled:
Ignore the looks for now. I know I have a lot of work to do there but as you can see In the profiler those physics spike are off the charts and that's not even at it's worst. Any help would be very much appreciated, thanks.
Answer by BastianUrbach · Dec 24, 2018 at 10:55 PM
So basically you have a large number of gameobjects that you move around rather than creating new ones? If that is the case then the problem might be that moving colliders without rigidbody seems to be relatively slow because they are usually treated like static objects by the physics engine (unfortunately I don't know the technical details, I just remember reading about it somewhere). Therefore the first thing you should try is adding a kinematic rigidbody to each collider. Also make sure to disable collisions between obiects in that layer in the physics settings. If that's not enough, you might have to write your own system for it. You can perform raycasts against a Bounds object without using colliders or the physics engine by using Bounds.IntersectRay.
Testing it just now adding kinematic rigidbodies definitely made things worse. I think the rigidbody thing was an issue prior to Unit 5 and I've already disabled that 'star' layer of the physics settings. I would be more interested in learning more about Bounds without colliders, thanks.
Basically Bounds is just a very simple struct that represents an axis aligned bounding box. It's not a component and it's not tied to the physics engine. You would have to create and keep track of the bounding boxes yourself since they can not be attached to a GameObject. Here's a simple example for raycasts against an array of bounding boxes:
private Bounds[] bounds;
bool Raycast(Ray ray, out int index) { float $$anonymous$$ = float.$$anonymous$$axValue; float current = 0; index = -1; for (int i = 0; i < bounds.Length; i++) { if (bounds[i].IntersectRay(ray, out current) && current < $$anonymous$$) { index = i; $$anonymous$$ = current; } } return index >= 0; }That method returns true if the ray hits one of the bounding boxes in the array and outputs the index of the box that was hit.
Raycasts will probably be significantly slower than with a physics engine but it will hopefully reduce the lag spikes when moving.
Thank you so much! I've been stressed about how to fix this problem for 2 days and your solution works perfectly with almost no additional performance loss when passing into new locations in my grid as far as I can tell. I simply created a 3D array of list of bounds to coincide with my 3D array of list of active stars and perform a raycast check on the bounds only when the mouse button is pressed.
I guess I should ask for help more often.
Your answer
Follow this Question
Related Questions
RaycastHit2D not getting any information? 2 Answers
Click to Move rotation + collider issue 0 Answers
rigidbody It's going up and bounces when is moving 1 Answer
Raycasting question 2 Answers
SInce when?!?!? (Raycast issue) 2 Answers