Place GameObject on terrain even if player is looking up

Hi
I am trying to place a GameObject infront of the player and on the ground “terrain”.

I have this code in my Update():

if (Input.GetMouseButtonDown(1)) { // Högerknappen på musen
            Vector3 playerPosition = transform.position;
            Vector3 playerDirection = transform.forward;
            Quaternion playerRotation = transform.rotation;
            float spawnDistance = 1.0f;
            Vector3 spawnPos = playerPosition + playerDirection * spawnDistance;


            GameObject insObj;
            insObj = Instantiate(waterExtractor, spawnPos,Quaternion.identity) as GameObject;

            RaycastHit hit;
            Vector3 ray = insObj.transform.TransformDirection(Vector3.down);
            Physics.Raycast(insObj.transform.position, ray,out hit);
            insObj.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
            insObj.transform.localPosition = new Vector3(insObj.transform.localPosition.x, ((insObj.transform.localPosition.y - hit.distance)), insObj.transform.localPosition.z);
        }

This works great as long as I dont look upwards. Then the object is placed up in the air. What am I doing wrong here? Please check the small clip on youtube for demostration of my problem : Placement problem

Looking over your code, this is what I think is happening.
Unless you have some kind of collider in your sky, your raycast should not be returning a hit.
So, you have instantiated an object and later try to modify it’s position with an empty value, so it sits there.
I would recommend starting with the raycast, and checking if there is a hit, like:

 if (Physics.Raycast(ray, out hit))  

and then doing an instantiate with the hit.point as the position.

Instantiate(waterExtractor, hit.point,Quaternion.identity) as GameObject;

I hope this helps.

@Justinger : I have now changed my code and it works now :slight_smile: My code now is:

        if (Input.GetMouseButtonDown(1)) { // Högerknappen på musen
            Vector3 playerPosition = transform.position;
            Vector3 playerDirection = transform.forward;
            Quaternion playerRotation = transform.rotation;
            float spawnDistance = 1.0f;
            Vector3 spawnPos = playerPosition + playerDirection * spawnDistance;
            Vector3 fwd = transform.TransformDirection(Vector3.forward);
            RaycastHit hit;
            if (Physics.Raycast(transform.position, fwd, out hit, 5.0f)) {
                if (hit.transform.GetComponent<Collider>().name == "Terrain") {
                    GameObject insObj;
                    insObj = Instantiate(waterExtractor, spawnPos, Quaternion.identity) as GameObject;
                    insObj.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
                    RaycastHit hit2;
                    if (Physics.Raycast(insObj.transform.position, Vector3.down, out hit2)) {
                        insObj.transform.localPosition = new Vector3(insObj.transform.localPosition.x, ((insObj.transform.localPosition.y - hit2.distance)), insObj.transform.localPosition.z);

                    }
                }
            }

I dont know if it was how you was thinking. Now I will just clean up the code and check so the player cant put another object up on the first one :slight_smile: Thanks for the help