Initial commit
This commit is contained in:
@@ -0,0 +1,324 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public enum PlaneAxis
|
||||
{
|
||||
XZ = 0, // Horizontal plane (Y = 0)
|
||||
XY = 1, // Front plane (Z = 0)
|
||||
YZ = 2 // Side plane (X = 0)
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class VirtualPlane
|
||||
{
|
||||
public PlaneAxis planeAxis;
|
||||
public GameObject canvasGrid; // The Canvas with grid visual
|
||||
[HideInInspector]
|
||||
public GameObject colliderObject; // The collider (generated dynamically)
|
||||
}
|
||||
|
||||
public class CanvasVirtualPlatformManager : MonoBehaviour
|
||||
{
|
||||
private static CanvasVirtualPlatformManager instance;
|
||||
|
||||
[Header("Plane Configurations")]
|
||||
[SerializeField] private VirtualPlane[] virtualPlanes;
|
||||
|
||||
[Header("Collider Settings")]
|
||||
[SerializeField] private float colliderThickness = 0.1f;
|
||||
[SerializeField] private string colliderLayer = "World";
|
||||
|
||||
[Header("Settings")]
|
||||
[SerializeField] private PlaneAxis currentPlane = PlaneAxis.XZ;
|
||||
[SerializeField] private bool platformVisible = true;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (instance == null) instance = this;
|
||||
else Destroy(this.gameObject);
|
||||
}
|
||||
|
||||
public static CanvasVirtualPlatformManager getInstance() => instance;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
GenerateColliders();
|
||||
UpdatePlaneVisibility();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate colliders for all planes based on their canvas sizes
|
||||
/// </summary>
|
||||
private void GenerateColliders()
|
||||
{
|
||||
foreach (var plane in virtualPlanes)
|
||||
{
|
||||
if (plane.canvasGrid == null) continue;
|
||||
|
||||
// Get the canvas component
|
||||
Canvas canvas = plane.canvasGrid.GetComponent<Canvas>();
|
||||
if (canvas == null) continue;
|
||||
|
||||
RectTransform rectTransform = canvas.GetComponent<RectTransform>();
|
||||
if (rectTransform == null) continue;
|
||||
|
||||
// Create collider object
|
||||
if (plane.colliderObject != null)
|
||||
{
|
||||
Destroy(plane.colliderObject);
|
||||
}
|
||||
|
||||
plane.colliderObject = new GameObject($"Collider_{plane.planeAxis}");
|
||||
plane.colliderObject.transform.SetParent(transform);
|
||||
|
||||
// Match canvas position
|
||||
plane.colliderObject.transform.position = plane.canvasGrid.transform.position;
|
||||
|
||||
// Set rotation based on plane axis (not canvas rotation)
|
||||
plane.colliderObject.transform.rotation = GetColliderRotation(plane.planeAxis);
|
||||
|
||||
// Add box collider
|
||||
BoxCollider boxCollider = plane.colliderObject.AddComponent<BoxCollider>();
|
||||
|
||||
// Calculate collider size based on canvas size and scale
|
||||
float width = rectTransform.rect.width * canvas.transform.localScale.x;
|
||||
float height = rectTransform.rect.height * canvas.transform.localScale.y;
|
||||
|
||||
// All colliders use the same size format (width, thickness, height)
|
||||
// Rotation handles the orientation
|
||||
boxCollider.size = new Vector3(width, colliderThickness, height);
|
||||
|
||||
// Set layer
|
||||
int layer = LayerMask.NameToLayer(colliderLayer);
|
||||
if (layer != -1)
|
||||
{
|
||||
plane.colliderObject.layer = layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Layer '{colliderLayer}' not found. Using default layer.");
|
||||
}
|
||||
|
||||
Debug.Log($"Generated collider for {plane.planeAxis}: Size = {new Vector3(width, colliderThickness, height)}, Rotation = {GetColliderRotation(plane.planeAxis).eulerAngles}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the rotation for the collider based on plane axis
|
||||
/// </summary>
|
||||
private Quaternion GetColliderRotation(PlaneAxis axis)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case PlaneAxis.XZ: // Horizontal plane (rotate to lay flat)
|
||||
return Quaternion.Euler(0, 0, 0);
|
||||
|
||||
case PlaneAxis.XY: // Front plane (vertical, facing forward)
|
||||
return Quaternion.Euler(90, 0, 0);
|
||||
|
||||
case PlaneAxis.YZ: // Side plane (vertical, facing sideways)
|
||||
return Quaternion.Euler(0, 0, 90);
|
||||
|
||||
default:
|
||||
return Quaternion.identity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Regenerate colliders (useful if canvas size changes at runtime)
|
||||
/// </summary>
|
||||
public void RegenerateColliders()
|
||||
{
|
||||
GenerateColliders();
|
||||
UpdatePlaneVisibility();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switch to a different plane axis
|
||||
/// </summary>
|
||||
public void SwitchToPlane(PlaneAxis plane)
|
||||
{
|
||||
currentPlane = plane;
|
||||
UpdatePlaneVisibility();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggle platform visibility (canvas and collider)
|
||||
/// </summary>
|
||||
public void TogglePlatformVisibility(bool visible)
|
||||
{
|
||||
platformVisible = visible;
|
||||
UpdatePlaneVisibility();
|
||||
}
|
||||
|
||||
private void UpdatePlaneVisibility()
|
||||
{
|
||||
foreach (var plane in virtualPlanes)
|
||||
{
|
||||
bool isActive = (plane.planeAxis == currentPlane) && platformVisible;
|
||||
|
||||
if (plane.canvasGrid != null)
|
||||
{
|
||||
plane.canvasGrid.SetActive(isActive);
|
||||
}
|
||||
|
||||
if (plane.colliderObject != null)
|
||||
{
|
||||
plane.colliderObject.SetActive(isActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggle only the canvas grid visibility, keep colliders active
|
||||
/// </summary>
|
||||
public void ToggleGridVisibility(bool visible)
|
||||
{
|
||||
foreach (var plane in virtualPlanes)
|
||||
{
|
||||
if (plane.planeAxis == currentPlane && plane.canvasGrid != null)
|
||||
{
|
||||
plane.canvasGrid.SetActive(visible && platformVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current active plane
|
||||
/// </summary>
|
||||
public PlaneAxis GetCurrentPlane() => currentPlane;
|
||||
|
||||
/// <summary>
|
||||
/// Check if platform is currently visible
|
||||
/// </summary>
|
||||
public bool IsPlatformVisible() => platformVisible;
|
||||
|
||||
/// <summary>
|
||||
/// Get the current active plane's collider object
|
||||
/// </summary>
|
||||
public GameObject GetCurrentCollider()
|
||||
{
|
||||
foreach (var plane in virtualPlanes)
|
||||
{
|
||||
if (plane.planeAxis == currentPlane)
|
||||
{
|
||||
return plane.colliderObject;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current active plane's canvas
|
||||
/// </summary>
|
||||
public GameObject GetCurrentCanvas()
|
||||
{
|
||||
foreach (var plane in virtualPlanes)
|
||||
{
|
||||
if (plane.planeAxis == currentPlane)
|
||||
{
|
||||
return plane.canvasGrid;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the canvas size for a specific plane and regenerate its collider
|
||||
/// </summary>
|
||||
public void SetCanvasSize(PlaneAxis planeAxis, float width, float height)
|
||||
{
|
||||
foreach (var plane in virtualPlanes)
|
||||
{
|
||||
if (plane.planeAxis == planeAxis && plane.canvasGrid != null)
|
||||
{
|
||||
Canvas canvas = plane.canvasGrid.GetComponent<Canvas>();
|
||||
RectTransform rectTransform = canvas.GetComponent<RectTransform>();
|
||||
|
||||
if (rectTransform != null)
|
||||
{
|
||||
rectTransform.sizeDelta = new Vector2(width, height);
|
||||
|
||||
// Regenerate only this plane's collider
|
||||
RegenerateSingleCollider(plane);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the canvas size for the current active plane
|
||||
/// </summary>
|
||||
public void SetCurrentCanvasSize(float width, float height)
|
||||
{
|
||||
SetCanvasSize(currentPlane, width, height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Regenerate collider for a single plane
|
||||
/// </summary>
|
||||
private void RegenerateSingleCollider(VirtualPlane plane)
|
||||
{
|
||||
if (plane.canvasGrid == null) return;
|
||||
|
||||
Canvas canvas = plane.canvasGrid.GetComponent<Canvas>();
|
||||
if (canvas == null) return;
|
||||
|
||||
RectTransform rectTransform = canvas.GetComponent<RectTransform>();
|
||||
if (rectTransform == null) return;
|
||||
|
||||
// Destroy old collider if exists
|
||||
if (plane.colliderObject != null)
|
||||
{
|
||||
Destroy(plane.colliderObject);
|
||||
}
|
||||
|
||||
// Create new collider
|
||||
plane.colliderObject = new GameObject($"Collider_{plane.planeAxis}");
|
||||
plane.colliderObject.transform.SetParent(transform);
|
||||
|
||||
// Match canvas position
|
||||
plane.colliderObject.transform.position = plane.canvasGrid.transform.position;
|
||||
|
||||
// Set rotation based on plane axis (not canvas rotation)
|
||||
plane.colliderObject.transform.rotation = GetColliderRotation(plane.planeAxis);
|
||||
|
||||
BoxCollider boxCollider = plane.colliderObject.AddComponent<BoxCollider>();
|
||||
|
||||
float width = rectTransform.rect.width * canvas.transform.localScale.x;
|
||||
float height = rectTransform.rect.height * canvas.transform.localScale.y;
|
||||
|
||||
// All colliders use the same size format (width, thickness, height)
|
||||
// Rotation handles the orientation
|
||||
boxCollider.size = new Vector3(width, colliderThickness, height);
|
||||
|
||||
int layer = LayerMask.NameToLayer(colliderLayer);
|
||||
if (layer != -1)
|
||||
{
|
||||
plane.colliderObject.layer = layer;
|
||||
}
|
||||
|
||||
// Update visibility based on current state
|
||||
plane.colliderObject.SetActive((plane.planeAxis == currentPlane) && platformVisible);
|
||||
|
||||
Debug.Log($"Regenerated collider for {plane.planeAxis}: Size = {new Vector3(width, colliderThickness, height)}, Rotation = {GetColliderRotation(plane.planeAxis).eulerAngles}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current canvas size
|
||||
/// </summary>
|
||||
public Vector2 GetCurrentCanvasSize()
|
||||
{
|
||||
GameObject canvas = GetCurrentCanvas();
|
||||
if (canvas != null)
|
||||
{
|
||||
RectTransform rectTransform = canvas.GetComponent<RectTransform>();
|
||||
if (rectTransform != null)
|
||||
{
|
||||
return rectTransform.sizeDelta;
|
||||
}
|
||||
}
|
||||
return Vector2.zero;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user