Open STARasGAMES opened 2 years ago
I changed the way cubes are drawn. Now they properly preview how the mesh will be split by the tool, with the scale and rotation applied. However, it doesn't work when only one axis is selected.
Also, this script accounts for cases when the root object has MeshCollider, and in parameters GenerateColliders is set to true.
/* https://github.com/artnas/Unity-Plane-Mesh-Splitter */
/* https://github.com/artnas/Unity-Plane-Mesh-Splitter/issues/8 */
using System;
using System.Collections.Generic;
using UnityEngine;
namespace MeshSplit
{
public class MeshSplitController : MonoBehaviour
{
public bool AutoSplitAtAwake;
public MeshSplitParameters Parameters;
public bool DrawGridGizmosWhenSelected = false;
private Mesh _baseMesh;
private MeshRenderer _baseRenderer;
// generated children are kept here, so the script knows what to delete on Split() or Clear()
[HideInInspector]
[SerializeField]
private List<GameObject> _children;
private void Awake()
{
if (AutoSplitAtAwake)
{
Split();
}
}
public void Split()
{
DestroyChildren();
if (GetUsedAxisCount() < 1)
{
throw new Exception("You have to choose at least 1 axis.");
}
var meshFilter = GetComponent<MeshFilter>();
if (meshFilter)
{
_baseMesh = meshFilter.sharedMesh;
}
else
{
throw new Exception("MeshFilter component is required.");
}
_baseRenderer = GetComponent<MeshRenderer>();
if (_baseRenderer)
{
_baseRenderer.enabled = false;
}
var meshCollider = GetComponent<MeshCollider>();
if (meshCollider && Parameters.GenerateColliders)
{
meshCollider.enabled = false;
}
var meshSplitter = new MeshSplitter(Parameters);
var subMeshes = meshSplitter.Split(_baseMesh);
_children = new List<GameObject>();
foreach (var subMesh in subMeshes)
{
CreateChild(subMesh);
}
}
private void CreateChild((Vector3Int gridPoint, Mesh mesh) subMesh)
{
var newGameObject = new GameObject
{
name = "SubMesh " + subMesh.gridPoint
};
newGameObject.transform.SetParent(transform, false);
if (Parameters.UseParentLayer)
{
newGameObject.layer = gameObject.layer;
}
if (Parameters.UseParentStaticFlag)
{
newGameObject.isStatic = gameObject.isStatic;
}
// assign the new mesh to this submeshes mesh filter
var newMeshFilter = newGameObject.AddComponent<MeshFilter>();
newMeshFilter.sharedMesh = subMesh.mesh;
var newMeshRenderer = newGameObject.AddComponent<MeshRenderer>();
if (Parameters.UseParentMeshRendererSettings && _baseRenderer)
{
newMeshRenderer.sharedMaterial = _baseRenderer.sharedMaterial;
newMeshRenderer.sortingOrder = _baseRenderer.sortingOrder;
newMeshRenderer.sortingLayerID = _baseRenderer.sortingLayerID;
newMeshRenderer.shadowCastingMode = _baseRenderer.shadowCastingMode;
}
if (Parameters.GenerateColliders)
{
var meshCollider = newGameObject.AddComponent<MeshCollider>();
meshCollider.convex = Parameters.UseConvexColliders;
meshCollider.sharedMesh = subMesh.mesh;
}
_children.Add(newGameObject);
}
private int GetUsedAxisCount()
{
return (Parameters.SplitAxisX ? 1 : 0) + (Parameters.SplitAxisY ? 1 : 0) + (Parameters.SplitAxisZ ? 1 : 0);
}
public void Clear()
{
DestroyChildren();
var meshRenderer = GetComponent<MeshRenderer>();
if (meshRenderer)
{
meshRenderer.enabled = true;
}
}
private void DestroyChildren()
{
if (_children == null) return;
foreach (var t in _children)
{
DestroyImmediate(t.GetComponent<MeshFilter>().sharedMesh);
DestroyImmediate(t);
}
_children.Clear();
}
private void OnDrawGizmosSelected()
{
var meshFilter = GetComponent<MeshFilter>();
var renderer = GetComponent<Renderer>();
if (!DrawGridGizmosWhenSelected || !meshFilter || !meshFilter.sharedMesh || !renderer)
return;
var t = transform;
var bounds = meshFilter.sharedMesh.bounds;
var xSize = Parameters.SplitAxisX ? Mathf.Ceil(bounds.extents.x) : 0 + Parameters.GridSize / 2f;
var ySize = Parameters.SplitAxisY ? Mathf.Ceil(bounds.extents.y) : 0 + Parameters.GridSize /2f;
var zSize = Parameters.SplitAxisZ ? Mathf.Ceil(bounds.extents.z) : 0 + Parameters.GridSize/2f;
var center = bounds.center;
Gizmos.color = new Color(1, 1, 1, 0.3f);
// X aligned lines
for (var y = -ySize; y <= ySize; y += Parameters.GridSize)
{
for (var z = -zSize; z <= zSize; z += Parameters.GridSize)
{
var start = t.TransformPoint(center + new Vector3(-xSize, y, z));
var end = t.TransformPoint(center + new Vector3(xSize, y, z));
Gizmos.DrawLine(start, end);
}
}
// Y aligned lines
for (var x = -xSize; x <= xSize; x += Parameters.GridSize)
{
for (var z = -zSize; z <= zSize; z += Parameters.GridSize)
{
var start = t.TransformPoint(center + new Vector3(x, -ySize, z));
var end = t.TransformPoint(center + new Vector3(x, ySize, z));
Gizmos.DrawLine(start, end);
}
}
// Z aligned lines
for (var y = -ySize; y <= ySize + 1; y += Parameters.GridSize)
{
for (var x = -xSize; x <= xSize + 1; x += Parameters.GridSize)
{
var start = t.TransformPoint(center + new Vector3(x, y, -zSize));
var end = t.TransformPoint(center + new Vector3(x, y, zSize));
Gizmos.DrawLine(start, end);
}
}
}
}
}
Hey. This is very cool, want to make a pull request?
However, it doesn't work when only one axis is selected.
I'll take a look at that
Hey. This is very cool, want to make a pull request?
For this, I need to fix a bunch of issues :)
Here is how it looks
Transform handle is in pivot local position
Also, Gizmos don't account for selected split axes