Initial Commit

This commit is contained in:
jellejurre
2025-07-19 01:03:02 +02:00
commit e7904e3140
304 changed files with 22521 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
using UnityEngine;
using UnityEditor;
//Made by Dreadrith#3238
//Discord: https://discord.gg/ZsPfrGn
//Github: https://github.com/Dreadrith/DreadScripts
//Gumroad: https://gumroad.com/dreadrith
//Ko-fi: https://ko-fi.com/dreadrith
namespace DreadScripts.AutoBounds
{
public class AutoBounds
{
private const float boundsPercentIncrease = 25;
//Sets bounds to auto-calculated dimensions starting from the target
[MenuItem("DreadTools/Utility/AutoBounds/Auto")]
private static void CalculateBounds()
{
//Get Selection
GameObject go = Selection.activeGameObject;
if (!go) return;
//Check for animator and to use hips instead of target as root
//Always using target as root may make the bounds follow improperly
Animator ani = go.GetComponent<Animator>();
bool isHuman = ani && ani.avatar && ani.isHuman;
Transform rootBone = isHuman ? ani.GetBoneTransform(HumanBodyBones.Hips) ?? go.transform : go.transform;
//Get child renderers including disabled
var renderers = go.GetComponentsInChildren<SkinnedMeshRenderer>(true);
//Get Max Extent by getting the biggest dimension
//Avatars can rotate their armature around meaning this dimension can go in any direction, so reuse it for every dimension
//Probably not the best logic or calculation but it usually works
float maxExtent = 0;
foreach (var r in renderers)
{
if (!r.sharedMesh) continue;
Transform currentRootBone = r.rootBone ?? r.transform;
var currentExtent = GetMaxAxis(rootBone.InverseTransformPoint(currentRootBone.position)) + GetMaxAxis(r.sharedMesh.bounds.size);
if (maxExtent < currentExtent) maxExtent = currentExtent;
}
//If human, hips should stay the center
//Otherwise, center the bounds vertically based on current dimensions
Vector3 center = new Vector3(0, isHuman ? 0 : maxExtent / 2, 0);
//Increase area by percentage for safe measure
maxExtent *= 1 + boundsPercentIncrease / 100;
Vector3 extents = new Vector3(maxExtent, maxExtent, maxExtent);
//Set auto calculated bounds starting from target as root
SetBounds(go.transform, rootBone, new Bounds(center, extents));
}
//Sets sampled bounds from target starting from top most parent of target
[MenuItem("DreadTools/Utility/AutoBounds/Sample")]
private static void SampleBounds()
{
//Get Selection
GameObject go = Selection.activeGameObject;
if (!go) return;
//Get renderer for sampling
SkinnedMeshRenderer sampleRenderer = go.GetComponent<SkinnedMeshRenderer>();
if (!sampleRenderer)
{
Debug.LogWarning("No skinned mesh renderer on selected gameobject.");
return;
}
//Set the samples bounds start from the top most parent
SetBounds(go.transform.root, sampleRenderer.rootBone, sampleRenderer.bounds);
}
//Sets all children skinned mesh renderers of the root to the given bounds
private static void SetBounds(Transform root, Transform rootbone, Bounds myBounds)
{
foreach (var r in root.GetComponentsInChildren<SkinnedMeshRenderer>(true))
{
r.rootBone = rootbone;
r.localBounds = myBounds;
EditorUtility.SetDirty(r);
}
}
private static float GetMaxAxis(Vector3 v) => Mathf.Max(v.x, v.y, v.z);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b593cd90629c1ec408e9482136c2ce62
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
{
"name": "AutoBoundsEditor",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9ba96ad25be5a4649abd6919a2505e50
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: