using NewHorizons.Components; using NewHorizons.External.Modules.Props; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace NewHorizons.Builder.Props { public static class ShapeBuilder { public static Component AddShapeOrCollider(GameObject go, ShapeInfo info) { if (info.useShape.HasValue) { // Explicitly add either a shape or collider if specified if (info.useShape.Value) return AddShape(go, info); else return AddCollider(go, info); } else { // Prefer colliders over shapes if no preference is specified if (info.type is ShapeType.Sphere or ShapeType.Box or ShapeType.Capsule) return AddCollider(go, info); else return AddShape(go, info); } } public static Shape AddShape(GameObject go, ShapeInfo info) { if (info.hasCollision) { throw new NotSupportedException($"Shapes do not support collision; set {info.hasCollision} to false and use a supported collider type (sphere, box, or capsule)."); } if (info.useShape.HasValue && !info.useShape.Value) { throw new NotSupportedException($"{info.useShape} was explicitly set to false but a shape is required here."); } switch (info.type) { case ShapeType.Sphere: var sphereShape = go.AddComponent(); sphereShape._radius = info.radius; sphereShape._center = info.offset ?? Vector3.zero; return sphereShape; case ShapeType.Box: var boxShape = go.AddComponent(); boxShape._size = info.size ?? Vector3.one; boxShape._center = info.offset ?? Vector3.zero; return boxShape; case ShapeType.Capsule: var capsuleShape = go.AddComponent(); capsuleShape._radius = info.radius; capsuleShape._direction = (int)info.direction; capsuleShape._height = info.height; capsuleShape._center = info.offset ?? Vector3.zero; return capsuleShape; case ShapeType.Cylinder: var cylinderShape = go.AddComponent(); cylinderShape._radius = info.radius; cylinderShape._height = info.height; cylinderShape._center = info.offset ?? Vector3.zero; return cylinderShape; case ShapeType.Cone: var coneShape = go.AddComponent(); coneShape._topRadius = info.innerRadius; coneShape._bottomRadius = info.outerRadius; coneShape._direction = (int)info.direction; coneShape._height = info.height; coneShape._center = info.offset ?? Vector3.zero; return coneShape; case ShapeType.Hemisphere: var hemisphereShape = go.AddComponent(); hemisphereShape._radius = info.radius; hemisphereShape._direction = (int)info.direction; hemisphereShape._cap = info.cap; hemisphereShape._center = info.offset ?? Vector3.zero; return hemisphereShape; case ShapeType.Hemicapsule: var hemicapsuleShape = go.AddComponent(); hemicapsuleShape._radius = info.radius; hemicapsuleShape._direction = (int)info.direction; hemicapsuleShape._height = info.height; hemicapsuleShape._cap = info.cap; hemicapsuleShape._center = info.offset ?? Vector3.zero; return hemicapsuleShape; case ShapeType.Ring: var ringShape = go.AddComponent(); ringShape.innerRadius = info.innerRadius; ringShape.outerRadius = info.outerRadius; ringShape.height = info.height; ringShape.center = info.offset ?? Vector3.zero; return ringShape; default: throw new ArgumentOutOfRangeException(nameof(info.type), info.type, $"Unsupported shape type"); } } public static Collider AddCollider(GameObject go, ShapeInfo info) { if (info.useShape.HasValue && info.useShape.Value) { throw new NotSupportedException($"{info.useShape} was explicitly set to true but a non-shape collider is required here."); } switch (info.type) { case ShapeType.Sphere: var sphereCollider = go.AddComponent(); sphereCollider.radius = info.radius; sphereCollider.center = info.offset ?? Vector3.zero; sphereCollider.isTrigger = !info.hasCollision; go.GetAddComponent(); return sphereCollider; case ShapeType.Box: var boxCollider = go.AddComponent(); boxCollider.size = info.size ?? Vector3.one; boxCollider.center = info.offset ?? Vector3.zero; boxCollider.isTrigger = !info.hasCollision; go.GetAddComponent(); return boxCollider; case ShapeType.Capsule: var capsuleCollider = go.AddComponent(); capsuleCollider.radius = info.radius; capsuleCollider.direction = (int)info.direction; capsuleCollider.height = info.height; capsuleCollider.center = info.offset ?? Vector3.zero; capsuleCollider.isTrigger = !info.hasCollision; go.GetAddComponent(); return capsuleCollider; default: throw new ArgumentOutOfRangeException(nameof(info.type), info.type, $"Unsupported collider type"); } } } }