1
\$\begingroup\$

I want to allow the player to freely place cubes anywhere they like in 3D space, but the cube being moved around is not allowed to intersect with other objects.

Currently I do a ray cast based on where the mouse is (ScreenPointToRay), and position the cube at the hit point. This allows me to move the cube around, but it's possible to intersect other objects if the raycast hit is right next to an object.

I see that there is a Physics.BoxCast method, but I can't get this working based on where the mouse position is. Am not sure if this is even the best solution.

I was thinking of ray casting out from each 4 points of each face on the cube (4 up, 4 down, 4 right, 4 left, 4 forward, 4 back), but I feel this is a lot of raycasts just to prevent intersecting on movement and placement for a cube.

How can I prevent a cube that is being moved around, and then placed with the mouse from intersecting other objects?

\$\endgroup\$
  • \$\begingroup\$ Why don't you make use of colliders? \$\endgroup\$ – John Hamilton Jan 24 '18 at 16:21
2
\$\begingroup\$

I can think of three different approaches to your problem. One involves using an object silhouette or shape as a preview of where it's going to be placed; another is a real-time positioning of the object, providing interaction with surrounding instances; the last one is again real-time positioning though by computing the last valid position.

Paintbrush method

This method allows the user to place the cube in your 3D space by instantiating sort of ghost version of it (e.g. making it look translucent) and moving it around with the mouse, showing where user is going to actually draw it, like if they were using a brush.

All positions are valid for the brush preview, as long as no other objects are intersected; illegal coordinates will highlight the brush model in red hue, for example. You can check if a given position is valid with a simple AABB collision detection algorithm, given axis-aligned cubes.

Clicking a valid position will create a new instance of a cube, allowing the user to instantiate more.

enter image description here

Follow mouse method #1

With this method you create an actual cube in the first valid position using raycasting at creation only. Next, the cube will try to move as close as possible towards the position in space pointed by the cursor arrow, taking into account collisions with other object.

This way, the cube will be placed in the best possible position with respect to mouse position, being never misplaced since collision detection is active and the cube starting position is valid by definition.

enter image description here

To accomplish such behaviour you must check if the mouse position is a valid position for the cube. If so, place the cube there; otherwise, move the cube as close as possible to the mouse position, taking collisions into account.

Follow mouse method #2

Similar to the previous one, but if the current mouse position is not valid for the cube, place the cube there and then push it outside from any other instance it may be intersecting with. More tricky, but better results than the first variant.

enter image description here

Last valid position method

This is pretty much the Follow Mouse #1 method, but you update the cube position only when the mouse position points to a valid place for the cube; otherwise, the cube stands still.

enter image description here

Concerning implementation, all these methods require only collision detection to make sure cubes don't intersect, not a heavy workload for the CPU since AABB is quite simple and fast. Raycasting is used once only, by one single method. Colliders can be a solution, but you can write your own AABB collision detection algorithm (Jonathan Whiting's tutorial, at "Detecting Rectangle Collision) without the need to import that library, and dealing with such a simple collision tecnique on your own.

\$\endgroup\$
  • \$\begingroup\$ You said "raycasting is used once only". At the moment I am raycasting out from the camera to determine where to move the object around with the mouse. I never know the positions of cubes placed, so am not sure how I would do a AABB. I think I might have to do some sort of raycast overlap method instead? \$\endgroup\$ – JacketPotatoeFan Jan 25 '18 at 9:46
  • \$\begingroup\$ Ok, after some testing and looking over the Unity docs. I found there is a "Intersects" method on the bounds of a collider. So I think this should be good enough, it cuts down on the original idea of raycasting. \$\endgroup\$ – JacketPotatoeFan Jan 25 '18 at 11:06
  • \$\begingroup\$ Good choice, it doesn't put a heavy load on CPU for complex collision detection. \$\endgroup\$ – liggiorgio Jan 26 '18 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.