init
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
|
||||
namespace VOID.Generic.World
|
||||
{
|
||||
public class ComplexArea : SerializedMonoBehaviour
|
||||
{
|
||||
[SerializeField] [ReadOnly] public List<Area> areas;
|
||||
|
||||
[ReadOnly] [BoxGroup("variant", false)]
|
||||
public bool isVariant;
|
||||
|
||||
[ReadOnly] [HideIf(nameof(isVariant))] [BoxGroup("variant", false)]
|
||||
public List<ComplexArea> variants = new();
|
||||
|
||||
[ReadOnly] [ShowIf(nameof(isVariant))] [BoxGroup("variant", false)]
|
||||
public ComplexArea original;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private GameObject GetGameObjectForAreas()
|
||||
{
|
||||
const string areasGameObjectName = "_areas";
|
||||
var areasGameObject = gameObject.transform.Find(areasGameObjectName)?.gameObject;
|
||||
if (areasGameObject) return areasGameObject;
|
||||
areasGameObject = new GameObject(areasGameObjectName);
|
||||
areasGameObject.transform.position = Vector3.zero;
|
||||
areasGameObject.transform.parent = gameObject.transform;
|
||||
areasGameObject.transform.SetAsFirstSibling();
|
||||
return areasGameObject;
|
||||
}
|
||||
|
||||
[Title("Generate")]
|
||||
[Button]
|
||||
private void GenerateAreas()
|
||||
{
|
||||
areas.ForEach(area => DestroyImmediate(area.gameObject));
|
||||
areas.Clear();
|
||||
GenerateMissingAreas();
|
||||
}
|
||||
|
||||
[Button]
|
||||
private void GenerateMissingAreas()
|
||||
{
|
||||
// Bounds thats contains everything in this ComplexArea Prefab
|
||||
var complexAreaBounds = new Bounds();
|
||||
GetComponentsInChildren<Collider>()
|
||||
.ForEach(collider => complexAreaBounds.Encapsulate(collider.bounds));
|
||||
GetComponentsInChildren<MeshRenderer>()
|
||||
.ForEach(meshRenderer => complexAreaBounds.Encapsulate(meshRenderer.bounds));
|
||||
|
||||
// To calculate position index we need only width (x) and length (z)
|
||||
var startIndex = new Vector2Int(
|
||||
Mathf.RoundToInt(complexAreaBounds.min.x / Area.Size),
|
||||
Mathf.RoundToInt(complexAreaBounds.min.z / Area.Size)
|
||||
);
|
||||
var endIndex = new Vector2Int(
|
||||
Mathf.RoundToInt(complexAreaBounds.max.x / Area.Size),
|
||||
Mathf.RoundToInt(complexAreaBounds.max.z / Area.Size)
|
||||
);
|
||||
|
||||
var areasGameObject = GetGameObjectForAreas();
|
||||
|
||||
// Create areas for everything inside bounds
|
||||
for (var x = startIndex.x; x <= endIndex.x; x++)
|
||||
{
|
||||
for (var y = startIndex.y; y <= endIndex.y; y++)
|
||||
{
|
||||
if (areas.Any(area => area.position.x == x && area.position.y == y)) continue;
|
||||
|
||||
var areaGameObject = new GameObject();
|
||||
areaGameObject.AddComponent<Area>();
|
||||
areaGameObject.transform.parent = areasGameObject.transform;
|
||||
areaGameObject.transform.position = new Vector3(x * Area.Size, 0, y * Area.Size);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
[Button]
|
||||
private void GenerateVariants()
|
||||
{
|
||||
Editor.EditorWindow.World.ComplexAreaRotateVariantGenerator.GenerateRotatedVariants(this);
|
||||
}
|
||||
|
||||
[Title("Update")]
|
||||
[Button(ButtonSizes.Large)]
|
||||
public void UpdateAll()
|
||||
{
|
||||
UpdateAreaList();
|
||||
UpdatePositionIndexes();
|
||||
UpdateNames();
|
||||
UpdateConnections();
|
||||
}
|
||||
|
||||
[ResponsiveButtonGroup("Update")]
|
||||
[Button]
|
||||
private void UpdateAreaList()
|
||||
{
|
||||
areas = gameObject.GetComponentsInChildren<Area>().ToList();
|
||||
areas.ForEach(area => area.complexArea = this);
|
||||
}
|
||||
|
||||
[ResponsiveButtonGroup("Update")]
|
||||
[Button]
|
||||
private void UpdatePositionIndexes()
|
||||
{
|
||||
areas.ForEach(area =>
|
||||
{
|
||||
var position = area.transform.position;
|
||||
area.position.x = Mathf.RoundToInt(position.x / Area.Size);
|
||||
area.position.y = Mathf.RoundToInt(position.z / Area.Size);
|
||||
});
|
||||
}
|
||||
|
||||
[ResponsiveButtonGroup("Update")]
|
||||
[Button]
|
||||
private void UpdateNames()
|
||||
{
|
||||
UpdatePositionIndexes();
|
||||
areas.ForEach(area => area.name = $"{nameof(Area)} ({area.position.x},{area.position.y})");
|
||||
}
|
||||
|
||||
[ResponsiveButtonGroup("Update")]
|
||||
[Button]
|
||||
private void UpdateConnections()
|
||||
{
|
||||
UpdatePositionIndexes();
|
||||
areas.ForEach(area =>
|
||||
{
|
||||
var forwardArea = areas.Find(subArea => (area.position + Vector2Int.up).Equals(subArea.position));
|
||||
var rightArea = areas.Find(subArea => (area.position + Vector2Int.right).Equals(subArea.position));
|
||||
var backArea = areas.Find(subArea => (area.position + Vector2Int.down).Equals(subArea.position));
|
||||
var leftArea = areas.Find(subArea => (area.position + Vector2Int.left).Equals(subArea.position));
|
||||
|
||||
area.forwardConnection.direction = Direction2D.Forward;
|
||||
area.rightConnection.direction = Direction2D.Right;
|
||||
area.backConnection.direction = Direction2D.Back;
|
||||
area.leftConnection.direction = Direction2D.Left;
|
||||
|
||||
if (forwardArea)
|
||||
area.forwardConnection.type = AreaConnectionType.Inner;
|
||||
else if (area.forwardConnection.type == AreaConnectionType.Inner)
|
||||
area.forwardConnection.type = AreaConnectionType.None;
|
||||
|
||||
if (rightArea)
|
||||
area.rightConnection.type = AreaConnectionType.Inner;
|
||||
else if (area.rightConnection.type == AreaConnectionType.Inner)
|
||||
area.rightConnection.type = AreaConnectionType.None;
|
||||
|
||||
if (backArea)
|
||||
area.backConnection.type = AreaConnectionType.Inner;
|
||||
else if (area.backConnection.type == AreaConnectionType.Inner)
|
||||
area.backConnection.type = AreaConnectionType.None;
|
||||
|
||||
if (leftArea)
|
||||
area.leftConnection.type = AreaConnectionType.Inner;
|
||||
else if (area.leftConnection.type == AreaConnectionType.Inner)
|
||||
area.leftConnection.type = AreaConnectionType.None;
|
||||
});
|
||||
}
|
||||
|
||||
[Title("Auto-Fix")]
|
||||
[Button(ButtonSizes.Large)]
|
||||
public void AutoFixAll()
|
||||
{
|
||||
AutoFixAreaTransforms();
|
||||
AutoFixAreaHierarchy();
|
||||
}
|
||||
|
||||
[ResponsiveButtonGroup("AutoFix")]
|
||||
[Button]
|
||||
private void AutoFixAreaTransforms()
|
||||
{
|
||||
areas.ForEach(area =>
|
||||
{
|
||||
var position = area.transform.localPosition;
|
||||
position.x = Mathf.RoundToInt(position.x / Area.Size) * (int)Area.Size;
|
||||
position.y = Mathf.RoundToInt(position.y / Area.Size) * (int)Area.Size;
|
||||
position.z = Mathf.RoundToInt(position.z / Area.Size) * (int)Area.Size;
|
||||
area.transform.localPosition = position;
|
||||
});
|
||||
}
|
||||
|
||||
[ResponsiveButtonGroup("AutoFix")]
|
||||
[Button]
|
||||
private void AutoFixAreaHierarchy()
|
||||
{
|
||||
var areasGameObject = GetGameObjectForAreas();
|
||||
GetComponentsInChildren<Area>()
|
||||
.ForEach(area => area.gameObject.transform.parent = areasGameObject.transform);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user