0
\$\begingroup\$
using UnityEngine;

[ExecuteAlways]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class CustomPlane : MonoBehaviour {

    public float width = 1;
    public float length = 1;

    private float oldWidth;
    private float oldHeight;

    public void Start()
    {
        oldWidth = width;
        oldHeight = length;

        Create();
    }

    private void Update()
    {
        if(oldWidth != width || oldHeight != length)
        {
            Create();

            oldWidth = width;
            oldHeight = length;
        }
    }

    private void Create()
    {
        MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>();

        Mesh mesh = new Mesh();

        Vector3[] vertices = new Vector3[4]
        {
            new Vector3(0, 0, 0),
            new Vector3(width, 0, 0),
            new Vector3(0, length, 0),
            new Vector3(width, length, 0)
        };
        mesh.vertices = vertices;

        int[] tris = new int[6]
        {
            // lower left triangle
            0, 2, 1,
            // upper right triangle
            2, 3, 1
        };
        mesh.triangles = tris;

        Vector3[] normals = new Vector3[4]
        {
            -Vector3.forward,
            -Vector3.forward,
            -Vector3.forward,
            -Vector3.forward
        };
        mesh.normals = normals;

        Vector2[] uv = new Vector2[4]
        {
            new Vector2(0, 0),
            new Vector2(1, 0),
            new Vector2(0, 1),
            new Vector2(1, 1)
        };
        mesh.uv = uv;

        meshFilter.mesh = mesh;
    }
}

Later, the problem is I want to fire a ray on the plane and that ray will also get to a terrain.

The plane is above the terrain in the air I want to shoot a ray on the plane and that it will spawn objects too also on the terrain.

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class SpawnObjects : MonoBehaviour
{
    public GameObject prefabToSpawn;
    public Terrain terrain;
    public CustomPlane plane;
    public float yOffset = 0.5f;
    [SerializeField] private LayerMask terrainLayer;

    private float terrainWidth;
    private float terrainLength;
    private float xTerrainPos;
    private float zTerrainPos;

    private float planeWidth;
    private float planeLength;
    private float xPlanePos;
    private float zPlanePos;

    private float yValTerrain;
    private float yValPlane;

    private float randXTerrain;
    private float randZTerrain;

    private float randXPlane;
    private float randZPlane;

    private Collider terrainCollider;
    void Awake()
    {
        if (terrain != null)
        {
            //Get terrain size
            terrainWidth = terrain.terrainData.size.x;
            terrainLength = terrain.terrainData.size.z;

            //Get terrain position
            xTerrainPos = terrain.transform.position.x;
            zTerrainPos = terrain.transform.position.z;

            terrainCollider = terrain.GetComponent<Collider>();
        }

        if (plane != null)
        {
            planeWidth = plane.width;
            planeLength = plane.length;
            xPlanePos = plane.transform.position.x;
            zPlanePos = plane.transform.position.z;
        }
    }
    private void Update()
    {
        SpawnThroughPlane();
    }

    public void SpawnThroughPlane()
    {
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if (plane.GetComponent<MeshCollider>().Raycast(ray, out hit, Mathf.Infinity))
            {
                var prefab = Instantiate(prefabToSpawn);

                Vector3 pos = prefab.transform.position;
                pos.y = terrain.SampleHeight(prefab.transform.position);
                prefab.transform.position = hit.point + pos;
            }
        }
    }
}

This spawn objects on the plane but not on the terrain I think because the plane collider blocks it to get to the terrain.

Not sure what to do to solve it.

I tried in the SpawnThroughPlane method to use :

var ray = new Ray(plane.transform.position, Vector3.down);

And

if(Physics.Raycast(ray, out var hit, Mathf.infinity, terrainLayer))

And on the top of the script added

[SerializeField] private LayerMask terrainLayer;

Then I added in the editor a new layer at index 8 name Terrain and changed the Terrain layer to Terrain and in this variable terrainLayer I set it to Terrain too but it didn't work it's spawning the objects on the same position on the terrain and not on the plane at all.

Update :

A screenshot that will explain better what I'm trying to archive.

Example

I want that when I click the mouse it will spawn objects on the mouse cursor position only on the plane area and that where I click on the plane it will spawn also the objects on the terrain. to convert the positions from the plane to the terrain positions.

Imagine it like a cloud that drop rain. When I click on the plane this is where a drop will be falling on the terrain. The plane is like a cloud.

\$\endgroup\$
2
  • \$\begingroup\$ Others may be able to decipher this, but I'm afraid it makes no sense to me. I'd suggest you edit your question and start again, assuming we don't have an intimate knowledge of your project and what you're trying to accomplish... \$\endgroup\$
    – Basic
    Nov 22 at 21:54
  • 1
    \$\begingroup\$ @Basic I will edit with some screenshots. \$\endgroup\$
    – Jhon RA
    Nov 22 at 22:04
0
\$\begingroup\$

Your question contains much code but defines your issue a bit vaguely. I hope I understood what you're trying to achieve, though.

If you want to spawn objects both on the plane in the air and on the corresponding position on the terrain, you can:

Vector3 posOnPlane = Physics.Raycast(...);
float heightFromTerrain = Terrain.activeTerrain.SampleHeight(posOnPlane);
  • Spawn the second instance in the new position across the terrain.
posOnPlane.y -= heightFromTerrain;
Instantiate(groundedGameObject, posOnPlane, Quaternion.identity);
\$\endgroup\$
1
  • \$\begingroup\$ Working I changed things a bit but it's working. \$\endgroup\$
    – Jhon RA
    Nov 23 at 0:24

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.