- Home /
Terrain collider not following hills when raycasting
I am coding up a system to allow the player to place objects on the terrain at runtime. To find the position to place the object, I'm raycasting down from the object's origin until I hit the ground (layer 'ground'), which is the layer assigned to my terrain.
My problem is that when I place the object in a hilly area of the terrain, the raycast seems to be finding the bottom area of my terrain as if it were flat (as opposed to the highest point between the object and the terrain at the hill). It seems as though the terrain collider isn't following hills, and is simply flat.
My player walks up hills properly though (via the CharacterController).
Is there something special about terrain colliders vs. mesh colliders that causes raycasting against the terrain collider to ignore deformations in the terrain?
Answer by Intervention · Jan 10, 2015 at 06:02 PM
I have found the solution to my problem.
To detect the location of the terrain with respect to the object I ws trying to place, I was using a raycast down from the origin of the object I was trying to place and setting the object's position to the hitInfo's 'transform.position' field. When I switched to using the hitInfo.point field, my object then aligned properly with whatever the slope of the terrain was at that point. Here is the code that I'm using that works properly:
if ((raycastHit = Physics.Raycast(instantiatedModelForPlacement.transform.position, Vector3.down, out hitInfo)))
{
instantiatedModelForPlacement.transform.position = new Vector3(instantiatedModelForPlacement.transform.position.x,
hitInfo.point.y +
(instantiatedModelForPlacement.collider.bounds.size.y / 2) + 0.00 1f, //the small offset here is to get out of the collision
instantiatedModelForPlacement.transform.position.z);
instantiatedModelForPlacement.transform.rotation = Quaternion.FromToRotation(instantiatedModelForPlacement.transform.up, hitInfo.normal) * instantiatedModelForPlacement.transform.rotation;
}
Note the use of hitInfo.point.y to obtain the location of the terrain's y coordinate. instantiatedModelForPlacement is the model that the player is holding in front of them trying to place on the ground. There is more to this script, but this bit is the relevant part to my initial question.
Hope this helps someone else some day.
This was useful. Although when I reviewed my script, it was already considering this point. In my case, I still don't know why the Raycast misses the terrain collider sometimes...
$$anonymous$$y problem is: I have NPCs that get ragdolled (when hit by an explosion, or simply when the fall uncounscious for taking too much damage). What is going wrong is that the moment they start to get up, their root changes to a y = 0, and the getting up animation occurs at this height (not on the top of the terrain mesh, or on the top of a building), and they stay there.
Here is the part of the code I'm using that resets the NPCs root position, so the animation occurs exactly where their body is (it can be very far away, as a consequence of an explosion, for example):
//Now cast a ray from the computed position downwards and find the highest hit that does not belong to the character
RaycastHit[] hits=Physics.RaycastAll(new Ray(newRootPosition,Vector3.down));
newRootPosition.y=0;
foreach(RaycastHit hit in hits)
{
if (!hit.transform.IsChildOf(transform))
{
newRootPosition.y=$$anonymous$$athf.$$anonymous$$ax(newRootPosition.y, hit.point.y);
}
}
transform.position=newRootPosition;
//Get body orientation in ground plane for both the ragdolled pose and the animated get up pose
Vector3 ragdolledDirection=ragdolledHeadPosition-ragdolledFeetPosition;
ragdolledDirection.y=0;
Vector3 meanFeetPosition=0.5f*(anim.GetBoneTransform(HumanBodyBones.LeftFoot).position + anim.GetBoneTransform(HumanBodyBones.RightFoot).position);
Vector3 animatedDirection=anim.GetBoneTransform(HumanBodyBones.Head).position - meanFeetPosition;
animatedDirection.y=0;
//Try to match the rotations. Note that we can only rotate around Y axis, as the animated characted must stay upright,
//hence setting the y components of the vectors to zero.
transform.rotation*=Quaternion.FromToRotation(animatedDirection.normalized,ragdolledDirection.normalized);
If anyone could give me a help, I would appreciate.
Your answer
![](https://koobas.hobune.stream/wayback/20220613175639im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Instantiated Objects not being set at ground/terrain level?(Solved) 1 Answer
Building placement validation on curved terrain 0 Answers
How to get the y coordinate of a point based on the x and z coordinates 2 Answers
using Raycast.hit function my car gets up and doesnt get down ? 0 Answers
Random object placement. 1 Answer