Raycast Question (421764)

Ok here is what I am trying to do and maybe im off base on my path of solving the issue.

I have lets say a Cube with scale of 4,1,4. I have a plane below that will have some other gameobjects of different height on them. The cube mentioned above is in the air being dragged around. What I am trying to do is send out a raycast see if the distance is equal everywhere the cube would sit. So lets say there is a cliff you don’t want to place half the building on land.

From the looks when I debug it, the raycast is sent from the middle of the object is there a way I can tell it to ray cast either a whole square area or at least tell it to send out a raycast at a specific point in the object? If I could do that then I could just tell it to test the 4 corners and the center if all equal distance then place object.

Thanks!

Thought I would add a screen shot to maybe help explain it better.

Box 1 is the object that will eventually be set on the ground.

2 is a object that is in the way so we don’t want to set out object on or in it.

3 is going to be the “ghost” object showing where it will be placed on the ground.

As you can see everything is working like it should but object 3 is underneath object 2 because the raycast is just outside the bounds of object 2 as soon as it moves to the left a little more it will pop object to on top of of it.

But if we were to set object 1 onto the map part of it would end up inside of object 2.

Let me know if there needs to be any more clarification!

Thanks!!

376219--13022--$raycast_138.jpg

I’d also like to know the best or “proper” way to do something like this.

I’m assuming you’re thinking along the lines of building placement etc in an RTS game?

One way that might work though is to have an invisible, empty gameobject that you position at each of the four corners of the cube in turn (through code obviously). That object could then be used to perform the raycasts for you instead of the cube object itself. If all four results come back matching, then you can go ahead and place the object.

This isn’t a terribly good solution though if you’re not always using cubes (which I’m guessing is pretty likely).

Thats the route I was going to take if no one responded :slight_smile: I mean it wouldn’t hurt performance much but like you said I am sure its not the best route.

I was thinking of more just creating 1 game object that was the same size but extended from the ground to the object that’s floating and if it received any collision don’t let it be placed.

This seems pretty reasonable.

If that doesn’t work though for some reason, you could do it ‘manually’ by comparing the projection onto the ground plane of the object you’re placing to the projections of the other objects in the scene. You could use AABBs for this, or, if your objects are actually all boxes (aligned so they’re parallel to the ground plane) and spheres, you could probably use the actual projections of the objects.

Thought I would post what worked for me this was almost so simple its sad…

There very possibly is a better way to code this but this was just about getting it to work and that it does and does a good job. Let me know if it helped you guys out and if you need any help with it. Maybe I’ll whip up a whole object placement tutorial once this is done, lots of people looking for help on it.

 var childObject : Transform;

function Update () {
	var up = transform.TransformDirection(Vector3.up);
	var hit : RaycastHit;
	
	// Get our current position so we know where the raycast needs to be
	var tempX = transform.position.x;
	var tempY = transform.position.y;
	var tempZ = transform.position.z;
	
	// Get the width and depth of the object so we can tell the raycast where to go
	var tempWidth = transform.collider.size.x;
	var tempDepth = transform.collider.size.y;
	
	// The position of the raycast
	var startPos1 = Vector3(tempX - tempWidth,tempY,tempZ - tempDepth);
	var startPos2 = Vector3(tempX + tempWidth,tempY,tempZ + tempDepth);
	var startPos3 = Vector3(tempX +tempWidth,tempY,tempZ - tempDepth);
	var startPos4 = Vector3(tempX - tempWidth,tempY,tempZ + tempDepth);
		
	Debug.DrawRay(startPos1, -up * 100, Color.green);
	Debug.DrawRay(startPos2, -up * 100, Color.green);
	Debug.DrawRay(startPos3, -up * 100, Color.green);
	Debug.DrawRay(startPos4, -up * 100, Color.green);
	
	if(Physics.Raycast(startPos1, -up, hit, 100)){
		var childHeight = childObject.localScale.y;
		childObject.position.x = hit.point.x + tempWidth;
		childObject.position.y = hit.point.y + (childHeight / 2);
		childObject.position.z = hit.point.z + tempDepth;
		childObject.rotation = Quaternion.identity;
	}
}

The above will give you something like:

377752--13074--$raycast2_173.jpg

That wont prevent you from placing objects with overlap though. Taking the picture you posted as an example, what happens when the cube and spere overlap just enough that one side of the box would overlap the sphere, but the corners don’t?

Unless you’re snapping the objects you want to place to a grid, and know you don’t have any objects that protrude outside the grid they’ve been placed in?

Although I can’t tell for sure from the code, I don’t think the OP is raycasting from the four corners, but rather is using a raycast to determine the position of a child object resting at ground level, which is then used to determine if the parent object can be placed there. (At least that’s the impression I got from the image.)

The main thing I was going for is making sure all 4 corners were level before placing the object. Checking all 4 corners will let me do that. For the project I’m working on its mainly to avoid having half a building on a cliff and the other half hanging off or having half the object on top of another. If only half the object is over something the .distance on all 4 corners will be different.

As far as the other post goes -
The child object is going to have to have a collider on it so it knows if its colliding with another building that way they cannot stack buildings on top of each other. Other then that all the child object is going to be a transparent copy so they can see where on the map it will be placed. If its hanging half over something or hitting another building it will change the alpha to a redish so they know it cannot be placed there.

I wont have anything in this project that sticks out more then others so that’s not a big issue for me. But that would still be a simple fix with a box collider on the child object. For me at least the child object will always be the same size as the parent object so if it has a collider I can tell if something is sticking out and hitting it.

Am I making any sense? :slight_smile:

That makes sense; you’re doing what Jesse surmised rather than what I assumed (i.e. using collision tests from the ground-level ‘shadow’ object to detect placement conflicts, rather than relying on the raycasts for that).

Since you need colliders on your buildings and other placeables anyway, this approach makes sense and is more reliable than anything you could do with simple raycasts. It also gives you the benefit of being able to place non-rectilinear, even non-convex shapes (e.g. a U-shaped building wrapping around one leg of an L-shaped building or something) – and of preventing such placements, simply by changing the shape of the collider.