Skip to content

Instantly share code, notes, and snippets.

@rodolforubens
Last active March 25, 2023 11:12
Show Gist options
  • Save rodolforubens/2e47d11dd843a3b30ec9d13013c91107 to your computer and use it in GitHub Desktop.
Save rodolforubens/2e47d11dd843a3b30ec9d13013c91107 to your computer and use it in GitHub Desktop.
Unity Editor script to drop objects on the ground using collider, renderer or its pivot point as a base.
using UnityEditor;
using UnityEngine;
public static class PlaceOnGroundEditor
{
[MenuItem("Tools/Snap to ground %&D")]
public static void PlaceOnGround()
{
var transforms = new Transform[Selection.gameObjects.Length];
for(int i = 0; i < transforms.Length; i++) transforms[i] = Selection.gameObjects[i].transform;
Undo.RecordObjects(transforms, "Place objects on ground");
foreach (var obj in Selection.gameObjects)
{
var collider = obj.GetComponent<Collider>();
Vector3 pointOnGround = obj.transform.position;
if (collider != null)
{
pointOnGround = GetPointOnGround(collider);
}
else
{
var meshRenderer = obj.GetComponent<MeshRenderer>();
pointOnGround = meshRenderer != null ?
GetPointOnGround(meshRenderer) :
GetPointOnGround(obj.transform.position);
}
Debug.DrawRay(pointOnGround, Vector3.up, Color.magenta, 1f);
obj.transform.position = pointOnGround;
}
}
public static Vector3 GetPointOnGround(Collider collider)
{
Vector3 target = collider.transform.position;
var bounds = collider.bounds;
var localBoundsCenter = bounds.center - collider.transform.position;
var originalLayer = collider.gameObject.layer;
collider.gameObject.layer = 2;
if (Physics.Raycast(bounds.center, Vector3.down, out RaycastHit hitInfo, Mathf.Infinity, Physics.DefaultRaycastLayers))
{
var point = hitInfo.point;
target = point + Vector3.up * (bounds.size.y / 2f - localBoundsCenter.y);
target.x = collider.transform.position.x;
target.z = collider.transform.position.z;
}
collider.gameObject.layer = originalLayer;
return target;
}
public static Vector3 GetPointOnGround(MeshRenderer mesh)
{
Vector3 target = mesh.transform.position;
var bounds = mesh.bounds;
var localBoundsCenter = bounds.center - mesh.transform.position;
var originalLayer = mesh.gameObject.layer;
mesh.gameObject.layer = 2;
if (Physics.Raycast(bounds.center, Vector3.down, out RaycastHit hitInfo, Mathf.Infinity, Physics.DefaultRaycastLayers))
{
var point = hitInfo.point;
target = point + Vector3.up * (bounds.size.y / 2f - localBoundsCenter.y);
target.x = mesh.transform.position.x;
target.z = mesh.transform.position.z;
}
mesh.gameObject.layer = originalLayer;
return target;
}
public static Vector3 GetPointOnGround(Vector3 origin)
{
var target = origin;
if (Physics.Raycast(origin, Vector3.down, out RaycastHit hitInfo, Mathf.Infinity, Physics.DefaultRaycastLayers))
{
target = hitInfo.point;
}
return target;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment