using System; using System.Collections; using System.Collections.Generic; using BITKit; using BITKit.Entities; using Unity.Mathematics; using UnityEngine; using UnityEngine.AI; using UnityEngine.Animations; using UnityEngine.UI; namespace BITFALL.Scene { public interface IDoorConfig { string Name { get; } Transform Transform { get; } Axis Axis { get; } Vector3 OpenEuler { get; } Vector3 CloseEuler { get; } Vector3 OpenPosition { get; } Vector3 ClosePosition { get; } } [Serializable] public class BasicDoorConfig:IDoorConfig { [SerializeField] private string name; [SerializeField] private Transform transform; [SerializeField] private Axis axis; [SerializeField] private Vector3 openEuler; [SerializeField] private Vector3 closeEuler; [SerializeField] private Vector3 openPosition; [SerializeField] private Vector3 closePosition; public string Name => name; public Transform Transform => transform; public Vector3 OpenEuler => openEuler; public Vector3 CloseEuler => closeEuler; public Axis Axis => axis; public Vector3 OpenPosition => openPosition; public Vector3 ClosePosition => closePosition; } public sealed class BasicDoor : MonoBehaviour,IAction,IDescription,ISceneBlockArea,IScenePlayerImpact { [SerializeReference,SubclassSelector] private IReference objName; [SerializeField] private bool isOpened; [SerializeField] private bool isLocked; [SerializeField] private new Collider collider; [SerializeField] private NavMeshObstacle obstacle; [SerializeReference, SubclassSelector] private IDoorConfig[] doors; private bool initialized; public void Execute() { if (initialized is false) { initialized = true; } if(isLocked)return; isOpened = !isOpened; foreach (var door in doors) { door.Transform.localRotation = Quaternion.Euler(isOpened ? door.OpenEuler : door.CloseEuler); door.Transform.localPosition = isOpened ? door.OpenPosition : door.ClosePosition; } if(obstacle)obstacle.enabled = !isOpened; } public string Name => objName.Value; public bool IsBlocked =>isLocked || !isOpened; public bool InRange(float3 position)=>collider.bounds.Contains(position); public bool InRange(float3 position, float3 direction) { var ray = new Ray(position, ((Vector3)direction).normalized); return collider.Raycast(ray, out _, 1f); } public void OnPlayerImpact(IEntity entity, float4x4 matrix) { if (isOpened) return; isOpened = true; if (obstacle) obstacle.enabled = false; var playerPosition = ((Matrix4x4)matrix).GetPosition(); var dir = transform.InverseTransformPoint(playerPosition); foreach (var door in doors) { if (!door.OpenEuler.IsDefault() || !door.CloseEuler.IsDefault()) continue; var isForward = door.Axis switch { Axis.X => dir.x < 0, Axis.Y => dir.y < 0, Axis.Z => dir.z < 0, _ => false, }; var backEuler = door.OpenEuler; backEuler.y *= -1; door.Transform.localRotation = Quaternion.Euler(isForward ? door.OpenEuler : backEuler ); } } } }