Make GameObject always vertical to Terrain

So I am working on my Animal AI and its working everything fine exept the fact that if the ground is not flat it breakes itself so is there a way to make the gameobject(animal) always vertical to the ground?

here my drawing

I am thinking about a solution for so long but i cant figure out how i should do this!
thanks!

Hi,
did you try try to send a ray and align the rotation of your object to the “normal” of your terrain under you raycast? Try to put your animal inside an empty game object and apply the rotation on your empty game object.

Unity Documentation

Hope this help!
Mike

as said by mikyjax, you need to raycast the terrain and get the normal. Then using your object rotate to that normal.

you have sample code in this forum post.
http://forum.unity3d.com/threads/aligning-object-to-surface-normal-with-quaternion-lookrotation.63619/

Hope it helps!

You don’t need to raycast the terrain. You can get the normal from the terrain data.

    public static void AlignTransform(Transform transform)
    {
        Vector3 sample = SampleNormal(transform.position);
       
        Vector3 proj = transform.forward - (Vector3.Dot(transform.forward, sample)) * sample;
        transform.rotation = Quaternion.LookRotation(proj, sample);
    }

    public static Vector3 SampleNormal(Vector3 position)
    {
        Terrain terrain = Terrain.activeTerrain;
        var terrainLocalPos = position - terrain.transform.position;
        var normalizedPos = new Vector2(
            Mathf.InverseLerp(0f, terrain.terrainData.size.x, terrainLocalPos.x),
            Mathf.InverseLerp(0f, terrain.terrainData.size.z, terrainLocalPos.z)
        );
        var terrainNormal = terrain.terrainData.GetInterpolatedNormal(normalizedPos.x, normalizedPos.y);

        return terrainNormal;
    }

private GameObject root;

    void Start ()
    {
    root = transform.root.gameObject;
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.tag == "Planet")
        {

        RaycastHit hit;
        if (Physics.Raycast(transform.position, -transform.up, out hit))
        {
        }

            //Makes the character to stand vertically to the ground
            float angle = Vector3.Angle(root.GetComponent<Transform>().up, hit.normal);
            Vector3 look = Vector3.Cross(root.GetComponent<Transform>().up, hit.normal);
            if (angle < 3 && angle > -3) { angle = 0; }
            root.GetComponent<Transform>().RotateAround(root.GetComponent<Transform>().position, look, angle * Time.deltaTime);
            Debug.Log(angle);
        }
    }

I discovered using the Object.GetComponent().RotateAround still can solve this problem.
Just only have to find out the rotate axis and the angle.
By using Vector3.Angle() and Vector3.Cross(), easily find out where to rotate.
Also the cross production determines it is angle or -angle automatically.