CapersProject/Assets/EasyGridBuilder Pro/Scripts/Core Grid Scripts/Grid Buildables/BuildableFreeObject.cs

350 lines
12 KiB
C#
Raw Normal View History

2024-07-06 17:37:07 +00:00
using SoulGames.Utilities;
using UnityEngine;
namespace SoulGames.EasyGridBuilderPro
{
public class BuildableFreeObject : MonoBehaviour
{
private EasyGridBuilderPro ownGridSystem;
private EasyGridBuilderPro activeGridSystem;
private bool isObjectBuilt = false;
[Tooltip("Provide this Buildable Free Object's 'Buildable Free Object Type SO'")]
[SerializeField]private BuildableFreeObjectTypeSO buildableFreeObjectTypeSO;
[Tooltip("Rotate object automatically in XY Grid Axis. (Which means this object is originally prepared for the Grid Axis XZ)")]
[SerializeField]public bool rotateObjectForXY;
[Tooltip("Rotate object automatically in XZ Grid Axis. (Which means this object is originally prepared for the Grid Axis XY)")]
[SerializeField]public bool rotateObjectForXZ;
public static event OnBuildableFreeObjectBuiltDelegate OnBuildableFreeObjectBuilt;
public delegate void OnBuildableFreeObjectBuiltDelegate(BuildableFreeObject buildableFreeObject);
[Rename("Rotate Scale & Pivot For XY")]
[Tooltip("Set pivot on XY axis instead of XZ axis. (Use this if the object is originally prepared for the Grid Axis XY)")]
[SerializeField]private bool rotateForXY;
[Tooltip("Scale of the Object. (This is used to calculate grid object size and collision)")]
[SerializeField]private Vector3 objectScale;
[Tooltip("Offset of the Object Scale")]
[SerializeField]private Vector3 objectCenter;
[Tooltip("Custom Pivot position of this object")]
[SerializeField]private Vector3 objectCustomPivot;
private bool hasCollider = false;
private void Start()
{
if (MultiGridManager.Instance.activeGridSystem == null) return;
activeGridSystem = MultiGridManager.Instance.activeGridSystem;
GridObjectSelector.OnObjectSelect += OnObjectSelect;
GridObjectSelector.OnObjectDeselect += OnObjectDeselect;
GridObjectMover.OnObjectStartMoving += OnObjectStartMoving;
GridObjectMover.OnObjectStoppedMoving += OnObjectStoppedMoving;
}
private void OnDestroy()
{
GridObjectSelector.OnObjectSelect -= OnObjectSelect;
GridObjectSelector.OnObjectDeselect -= OnObjectDeselect;
GridObjectMover.OnObjectStartMoving -= OnObjectStartMoving;
GridObjectMover.OnObjectStoppedMoving -= OnObjectStoppedMoving;
}
private void OnObjectSelect(EasyGridBuilderPro ownSystem, GameObject selectedObject)
{
}
private void OnObjectDeselect(EasyGridBuilderPro ownSystem, GameObject selectedObject)
{
}
private void OnObjectStartMoving(EasyGridBuilderPro ownSystem, GameObject movingObject)
{
}
private void OnObjectStoppedMoving(EasyGridBuilderPro ownSystem, GameObject movingObject)
{
}
public static BuildableFreeObject Create(Vector3 worldPosition, float rotation, BuildableFreeObjectTypeSO buildableFreeObjectTypeSO, EasyGridBuilderPro system)
{
EasyGridBuilderPro activeGridSystem = system;
Transform placedObjectTransform = Instantiate(buildableFreeObjectTypeSO.objectPrefab[Random.Range(0, buildableFreeObjectTypeSO.objectPrefab.Length)], Vector3.zero, Quaternion.identity);
placedObjectTransform.name = placedObjectTransform.name.Replace("(Clone)","").Trim();
placedObjectTransform.rotation = Quaternion.Euler(0, rotation, 0);
placedObjectTransform.localPosition = worldPosition;
BuildableFreeObject buildableFreeObject = placedObjectTransform.GetComponent<BuildableFreeObject>();
if (activeGridSystem.gridAxis == GridAxis.XZ)
{
if (buildableFreeObject.IsRotateObjectForXZ())
{
Transform tempTransform = new GameObject("tempTransform").transform;
tempTransform.localPosition = worldPosition;
tempTransform.rotation = Quaternion.Euler(90, 0, 0);
placedObjectTransform.parent = tempTransform;
placedObjectTransform.localEulerAngles = new Vector3(0, 0, -rotation);
placedObjectTransform.parent = null;
Destroy(tempTransform.gameObject);
}
else
{
placedObjectTransform.rotation = Quaternion.Euler(0, rotation, 0);
}
}
else
{
if (buildableFreeObject.IsRotateObjectForXY())
{
Transform tempTransform = new GameObject("tempTransform").transform;
tempTransform.localPosition = worldPosition;
tempTransform.rotation = Quaternion.Euler(-90, 0, 0);
placedObjectTransform.parent = tempTransform;
placedObjectTransform.localEulerAngles = new Vector3(0, -rotation, 0);
placedObjectTransform.parent = null;
Destroy(tempTransform.gameObject);
}
else
{
placedObjectTransform.rotation = Quaternion.Euler(0, 0, rotation);
}
}
if (buildableFreeObjectTypeSO.setBuiltObjectLayer) SetLayerRecursive(placedObjectTransform.gameObject, LayerNumber(buildableFreeObjectTypeSO.builtObjectLayer));
buildableFreeObject.Setup();
return buildableFreeObject;
}
protected void Setup()
{
OnBuildableFreeObjectBuilt?.Invoke(this);
}
public void GridSetupDone(EasyGridBuilderPro gridSystem, bool isObjectBuilt, float rotation)
{
this.isObjectBuilt = isObjectBuilt;
ownGridSystem = gridSystem;
}
public bool GetIsObjectBuilt()
{
return isObjectBuilt;
}
public virtual void DestroySelf()
{
Destroy(gameObject);
}
public override string ToString()
{
return buildableFreeObjectTypeSO.objectName;
}
public EasyGridBuilderPro GetOwnGridSystem()
{
return ownGridSystem;
}
public BuildableFreeObjectTypeSO GetBuildableFreeObjectTypeSO()
{
return buildableFreeObjectTypeSO;
}
public Vector3 GetRawObjectScale()
{
return objectScale;
}
public Vector3 GetRawObjectCenter()
{
return objectCenter;
}
public bool IsRotateObjectForXY()
{
return rotateObjectForXY;
}
public bool IsRotateObjectForXZ()
{
return rotateObjectForXZ;
}
public Vector3 GetObjectPivotOffset()
{
return objectCustomPivot;
}
public Vector2 GetObjectScale()
{
if (ownGridSystem != null)
{
if (ownGridSystem.gridAxis == GridAxis.XZ)
{
if (rotateObjectForXZ)
{
return new Vector2(objectScale.x, objectScale.y);
}
else
{
return new Vector2(objectScale.x, objectScale.z);
}
}
else
{
if (rotateObjectForXY)
{
return new Vector2(objectScale.x, objectScale.z);
}
else
{
return new Vector2(objectScale.x, objectScale.y);
}
}
}
else
{
if (MultiGridManager.Instance.activeGridSystem.gridAxis == GridAxis.XZ)
{
if (rotateObjectForXZ)
{
return new Vector2(objectScale.x, objectScale.y);
}
else
{
return new Vector2(objectScale.x, objectScale.z);
}
}
else
{
if (rotateObjectForXY)
{
return new Vector2(objectScale.x, objectScale.z);
}
else
{
return new Vector2(objectScale.x, objectScale.y);
}
}
}
}
public void AutoCalculatePivotAndSize()
{
if (!gameObject.GetComponent<BoxCollider>())
{
gameObject.AddComponent<BoxCollider>();
hasCollider = false;
}
else
{
hasCollider = true;
}
bool hasBounds = false;
Bounds bounds = new Bounds(Vector3.zero, Vector3.zero);
if (gameObject.transform.childCount != 0)
{
for (int i = 0; i < gameObject.transform.childCount; ++i)
{
Renderer childRenderer = gameObject.transform.GetChild(i).GetComponent<Renderer>();
if (childRenderer != null)
{
if (hasBounds)
{
bounds.Encapsulate(childRenderer.bounds);
}
else
{
bounds = childRenderer.bounds;
hasBounds = true;
}
}
}
BoxCollider collider = gameObject.GetComponent<BoxCollider>();
collider.center = bounds.center - gameObject.transform.position;
collider.size = bounds.size;
}
objectScale = GetComponent<BoxCollider>().bounds.size;
objectCenter = GetComponent<BoxCollider>().bounds.center;
if (rotateForXY)
{
objectCustomPivot = new Vector3(objectCenter.x, objectCenter.y, (objectCenter.z + objectScale.z / 2));
}
else
{
objectCustomPivot = new Vector3(objectCenter.x, (objectCenter.y - objectScale.y / 2), objectCenter.z);
}
if (!hasCollider)
{
BoxCollider collider = gameObject.GetComponent<BoxCollider>();
DestroyImmediate(collider, true);
}
#if UNITY_EDITOR
UnityEditor.EditorUtility.SetDirty(gameObject);
#endif
}
private void OnDrawGizmos()
{
if (!Application.isPlaying)
{
Color color = Color.cyan;
Gizmos.color = color;
Gizmos.DrawWireCube(objectCenter, objectScale);
Vector3 startPos = objectCustomPivot;
Vector3 endPos;
if (rotateForXY)
{
endPos = new Vector3(objectCustomPivot.x, objectCustomPivot.y, objectCustomPivot.z - (objectScale.z));
}
else
{
endPos = new Vector3(objectCustomPivot.x, objectCustomPivot.y + (objectScale.y), objectCustomPivot.z);
}
Gizmos.color = Color.red;
Gizmos.DrawSphere(startPos, .2f);
Gizmos.DrawLine(startPos, endPos);
}
}
private static int LayerNumber(LayerMask builtObjectLayer)
{
int layerNumber = 0;
int layer = builtObjectLayer.value;
while(layer > 0)
{
layer = layer >> 1;
layerNumber++;
}
if (layerNumber > 1) return layerNumber - 1;
else return 0;
}
private static void SetLayerRecursive(GameObject targetGameObject, int layer)
{
targetGameObject.layer = layer;
foreach (Transform child in targetGameObject.transform)
{
SetLayerRecursive(child.gameObject, layer);
}
}
}
}