Skip to content

Instantly share code, notes, and snippets.

@Westerveld
Last active April 12, 2019 01:07
Show Gist options
  • Save Westerveld/fc81c4f51846c7153df8715fe5b76ddd to your computer and use it in GitHub Desktop.
Save Westerveld/fc81c4f51846c7153df8715fe5b76ddd to your computer and use it in GitHub Desktop.
This can be used in unity to convert the scale of the object to be the size of its collider. Note: it does also remove the mesh and resets the scale of the object
// Ethan Bruins 2019
// https://gist.github.com/Westerveld/fc81c4f51846c7153df8715fe5b76ddd
using UnityEngine;
using UnityEditor;
public class SetColliderSizeFromScale : EditorWindow
{
//Shows up in the hierachy when placed in the GameObject menu
[MenuItem("GameObject/Convert Scale To Collider", false, 0)]
public static void ConvertObjectStatic()
{
//Get the selected item in the hierarchy
GameObject[] objsToChange = Selection.gameObjects;
Vector3 size;
//Check it has a collider
for (int i = 0; i < objsToChange.Length; i++)
{
//Check it doesnt have a local scale of (1,1,1) because there would be no point doing the change
if (objsToChange[i].transform.localScale == Vector3.one)
continue;
size = objsToChange[i].transform.localScale;
if (objsToChange[i].GetComponent<BoxCollider>())
{
//Get the collider
BoxCollider col = objsToChange[i].GetComponent<BoxCollider>();
//Set the size of the collider to our local scale
col.size = size;
//Revert the local scale to (1,1,1)
objsToChange[i].transform.localScale = Vector3.one;
//Remove MeshRenderer and MeshFilter
DestroyMesh(objsToChange[i]);
}
else if(objsToChange[i].GetComponent<SphereCollider>())
{
//Get the collider
SphereCollider col = objsToChange[i].GetComponent<SphereCollider>();
//Set the radius of the sphere collider
col.radius = GetBiggestValue(size) / 2;
//Revert the local scale to (1,1,1)
objsToChange[i].transform.localScale = Vector3.one;
//Remove MeshRenderer and MeshFilter
DestroyMesh(objsToChange[i]);
}
else if(objsToChange[i].GetComponent<CapsuleCollider>())
{
//Get the collider
CapsuleCollider col = objsToChange[i].GetComponent<CapsuleCollider>();
//Get the biggest axis of the vector
col.direction = GetLargestAxis(size);
//Get the value of the biggest axis, and multiply by two for height
col.height = GetAxisValue(size, col.direction) * 2;
//Get the second biggest value, and divide it in two for the radius
col.radius = GetOtherValue(size, col.direction) / 2;
//Revert the local scale to (1,1,1)
objsToChange[i].transform.localScale = Vector3.one;
//Remove MeshRenderer and Mesh Filter
DestroyMesh(objsToChange[i]);
}
else
{
//Return an error if no collider
Debug.LogError("No box collider on " + objsToChange[i].name);
}
}
}
//Returns the biggest value unless they are all the same then just returns z value. Usefull for the sphere
static float GetBiggestValue(Vector3 vector)
{
if (vector.x > vector.y && vector.x > vector.z)
{
//X is biggest
return vector.x;
}
else if (vector.y > vector.x && vector.y > vector.z)
{
//Y is biggest
return vector.y;
}
else
{
//Z is biggest
return vector.z;
}
}
static int GetLargestAxis(Vector3 vector)
{
if (vector.x > vector.y && vector.x > vector.z)
{
//X is biggest
return 0;
}
else if (vector.z > vector.x && vector.z > vector.y)
{
//Y is biggest
return 2;
}
else
{
//Default to Y as thats the intial direction of the capsule collider
return 1;
}
}
static float GetAxisValue(Vector3 vector, int axis)
{
switch (axis)
{
case 0:
return vector.x;
case 1:
return vector.y;
case 2:
return vector.z;
}
return 0;
}
static float GetOtherValue(Vector3 vector, int axis)
{
switch (axis)
{
case 0:
if (vector.y > vector.z)
return vector.y;
else
return vector.z;
case 1:
if (vector.x > vector.z)
return vector.x;
else
return vector.z;
case 2:
if (vector.x > vector.y)
return vector.x;
else
return vector.y;
}
return 0;
}
static void DestroyMesh(GameObject go)
{
//Ensure the components is on the object, then delete them
if(go.GetComponent<MeshRenderer>())
DestroyImmediate(go.GetComponent<MeshRenderer>());
if(go.GetComponent<MeshFilter>())
DestroyImmediate(go.GetComponent<MeshFilter>());
}
}
@Kuuo
Copy link

Kuuo commented Apr 12, 2019

Hi~
I see you have a method "GetAxisValue" (Line 119)
you can actually use vector[size] to do the same thing!
see: https://docs.unity3d.com/ScriptReference/Vector3.Index_operator.html

Just FYI, have a good day~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment