Last active
April 12, 2019 01:07
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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>()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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~