I have a scene where objects of variable sizes are placed in variable locations every frame. The next frame, they’re removed and replaced with different objects in different places. This means they overlap with each other quite easily. I was trying to make a script that will get rid of an object that overlaps another but it’s not working due to physics calculation taking multiple frames to compute. I need a way to get this done in one frame but I’m not coming up with any. I just want it to check if its hitbox is touching another hitbox and then run the remove function if it is.
You can use these and similar functions to perform immediate direct queries into the physics scene:
3D:
2D:
Can overlap box truly be accurately run any number of times within the same frame? I am using it, I am visualizing it, it’s often showing the boxes overlap, and it’s not doing what I tell it to on overlap detection.
According to debug, it’s detecting nothing sometimes, even the hitbox I spawn it inside of.
Of course it can. Why would there be a limit? It wouldn’t make sense. If OverlapBox isn’t working then you’re doing something wrong such as not specifying the box at the position you think you are no matter what your visualizer is doing. Maybe you’re updating the positions of Rigidbody(2D) via the Transform which doesn’t update the Rigidbody(2D) there and then which is why you should never modify the Transform like that. If you know all that then maybe there’s something else you’re doing wrong perhaps.
All we can see is vague description of what you’re doing.
Put a collider in the scene. Then use another GameObject and do some simply OverlapBox tests to veriify it works as you expect or if you’re doing something odd. Do this AWAY from your main project to verify it.
Alright, apologies. After several days of googling, I just managed to find the solution.
It derived from the fact that I was moving my OverlapBoxes around at the start of each frame but the physics engine wasn’t updating it. I found an old thread from someone with a very similar issue, and it turns out I needed to call “Physics.SyncTransform()”. And that seems to work perfectly for what I’m doing.
No, don’t call that. It has horrible performance and isn’t meant for using as standard. You found a workaround for doing something you shouldn’t be doing but honestly, if you’re happy with that then continue.
So you’re using 3D physics? I thought it was 2D physics being as you were asking on another thread “This rect.overlaps is just a 2D equivalent of OverlapBox() yeah?”
Oh, crap. Yeah, performance is going to be an issue.
Yes, this is all 3D physics. A bunch of 3D objects scattered throughout a scene that I need to prevent from overlapping automatically in pretty much all circumstances, for now I’m settling with just removing one if it detects it overlaps with another.
So OverlapBox() seems like the best solution for what I’m doing, but now I’ve narrowed down the fact that it can’t detect transform changes fast enough within one frame to detect that it’s overlapping with something else. So how do I sync all that with something besides Physics.SyncTransform()?
Why can’t you let the physics stop them overlapping? This is what it does.
We seriously need at least an image, a video preferable because you have it in your head; we have a rough description.
At risk of complicating this discussion, I’m using the Unity Perception package, and from what I can tell, this is a pretty weird thing to be doing within it that it doesn’t fully account for.
It doesn’t use update, it uses a function called “OnIterationStart” that does everything you want within the span of a scenario iteration, which in my case is a single frame. I don’t want to alter my project by making a scenario more than 1 frame for this, and from my tests doing that, it doesn’t even help with physics detection and breaks some other things involving perception in my use case.
So to wait for an update or fixedupdate of any kind is pointless, as far as I can tell, because once the next frame (or iteration) occurs, I reset everything and all data from the previous frame is now useless.
Still have no idea what it is you’re doing though. You are explaining when whatever it is you’re doing is happening.
You can perform a manual simulation step per-frame?
To be honest, I can’t realy figure out what it is you’re doin with back/forth like this so if you’re instantly placing lots of physics stuff then checking for overlap then next frame you’re doing the same then you need to run physics per-frame but if not, then manually sync transforms.
Yes, that’s exactly what I’m doing. I’m placing a lot of objects in the scene within one frame and they only remain for that same frame, because then it loops and they’re gone and replaced with new objects in the next frame. So all that overlapping logic needs to occur within that same frame that they exist.They don’t necessarily need to be physics objects, but physics is the easiest method I can think of to check if they’re overlapping with each other.
Physics.Simulate is also working to solve this overlap detection issue, thank you. Is this a fairly good performance solution?
So when you place these objects, set the Rigidbody.position and NOT the Transform.position then because these things are surely not visual. If you’re using prefabs then specify the position/orientation in the prefab Instantiate call rather than changing it after because the change after (as discussed) will only happen when it’s sync’d during a simultion step or you manually calling it. This way, the Rigidbody is created at the correct position there and then.
Right, I forgot about Rigidbody shenanigans. It works great now. Thanks!
It’s actually Transform shenanigans. Changing the Transform doesn’t do anything but change the Transform. Nothing else in Unity knows about it, even the renderers. They only read it when they render just like physics has to check if the user has decided to change it (bad idea) on any GameObject that has physics components when it simulates.
Unity does this because it wants no side-effects or performance issues changing the Transform. It does mean internal systems such as physics know nothing about such changes.