- Home /
How to raycast an object or an array of objects to place it on the terrain ground if object is under terrain?
So if object is up in the air, it can be raycasted to place down on the terrain. But what if object is under terrain? For some reason, when it is raycasted from below terrain, and btw terrain is at (0,0,0), the trransform of the pivot of the raycasted object changes to (0,0,0). I cant pinpoint how exactly this is happening. Im pasting the code.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;
public class Raycast_drop : MonoBehaviour { public Transform[] GO_targets_arr; public Button BTN_start; public bool includeChildren; public bool includeRotation;
void Awake()
{
this.BTN_start.onClick.AddListener(() => { OnClick_INI(); });
}
public void OnClick_INI()
{
if (includeChildren == true)
{
Store_and_Raycast_GO_withChildren();
}
else
{
Raycast_only_ROOTobjects();
}
}
public void Store_and_Raycast_GO_withChildren()
{
for (int i = 0; i < GO_targets_arr.Length; i++)
{
Transform[] GOarr_withchildren = GO_targets_arr[i].GetComponentsInChildren<Transform>();
for (int j = 0; j < GOarr_withchildren.Length; j++)
{
StartCoroutine(ResetPosition_with_Raycasting(GOarr_withchildren[j]));
}
}
}
public void Raycast_only_ROOTobjects()
{
for (int i = 0; i < GO_targets_arr.Length; i++)
{
StartCoroutine(ResetPosition_with_Raycasting(GO_targets_arr[i]));
}
}
IEnumerator ResetPosition_with_Raycasting(Transform target_Ray)
{
RaycastHit hit_Info;
Ray ray_cast_down = new Ray(target_Ray.position, -target_Ray.up * 10000);
Ray ray_cast_up = new Ray(target_Ray.position, target_Ray.up * 10000);
if (Physics.Raycast(ray_cast_down, out hit_Info) == true)
{
Debug.DrawRay(target_Ray.position, -target_Ray.up * 10000, Color.red, 1000);
if (includeRotation == true)
{
target_Ray.position = hit_Info.point;
target_Ray.rotation = Quaternion.FromToRotation(Vector3.up, hit_Info.normal);
Debug.Log("successful reset position and rotation of object raycasting downwards" + target_Ray);
}
else
{
target_Ray.position = hit_Info.point;
Debug.Log("successful reset position of object raycasting downwards" + target_Ray);
}
}
else if (Physics.Raycast(ray_cast_down, out hit_Info) == false)
{
Debug.DrawRay(target_Ray.position, Vector3.up * 10000, Color.red, 1000);
if (includeRotation == true)
{
target_Ray.position = hit_Info.point;
target_Ray.rotation = Quaternion.FromToRotation(Vector3.up, hit_Info.normal);
Debug.Log("succesful reset position and rotation of object raycasting upwards" + target_Ray);
}
else
{
target_Ray.position = hit_Info.point;
Debug.Log("succesful reset position of object raycasting upwards" + target_Ray);
}
}
yield return null;
}
}
Answer by Koyemsi · Jun 01 at 06:13 PM
Hi, I think the solution would be to use RaycastAll() rather than Raycast().
Be aware that the order of the hits found may be random. But you can store them in an array, then sort the array by distance.
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hits = Physics.RaycastAll(ray, 100f);
System.Array.Sort(hits, (x, y) => x.distance.CompareTo(y.distance));
Hope this will help...
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Illuminating a 3D object's edges OnMouseOver (script in c#)? 1 Answer
Flip over an object (smooth transition) 3 Answers