using UnityEngine; using Zenject; namespace DanroJump.Gameplay { [DisallowMultipleComponent] [RequireComponent(typeof(Collider2D))] public sealed class OneWayPlatformCollider : MonoBehaviour { [SerializeField] private JumpPlayerController player; [SerializeField] private float topBoundaryPadding; private Collider2D platformCollider; private Collider2D playerCollider; private bool isIgnoringPlayerCollision; public float TopY { get { if (platformCollider is BoxCollider2D boxCollider) { var localTop = boxCollider.offset + Vector2.up * (boxCollider.size.y * 0.5f); return boxCollider.transform.TransformPoint(localTop).y; } return platformCollider != null ? platformCollider.bounds.max.y : transform.position.y; } } [Inject] public void Construct(JumpPlayerController injectedPlayer) { player = injectedPlayer; ResolvePlayerCollider(); } private void Awake() { platformCollider = GetComponent(); platformCollider.usedByEffector = false; if (TryGetComponent(out PlatformEffector2D platformEffector)) { platformEffector.enabled = false; } RefreshColliderState(); } private void OnDisable() { SetPlayerCollisionIgnored(false); } private void FixedUpdate() { RefreshColliderState(); } private void RefreshColliderState() { if (player == null && !ResolvePlayer()) { return; } if (playerCollider == null && !ResolvePlayerCollider()) { return; } SetPlayerCollisionIgnored(!ShouldCollideWith(player)); } public bool ShouldCollideWith(JumpPlayerController targetPlayer) { return targetPlayer != null && targetPlayer.GroundCheckY >= TopY + topBoundaryPadding; } private bool ResolvePlayer() { return player != null; } private bool ResolvePlayerCollider() { if (player == null) { return false; } return player.TryGetComponent(out playerCollider); } private void SetPlayerCollisionIgnored(bool shouldIgnore) { if (platformCollider == null || playerCollider == null || isIgnoringPlayerCollision == shouldIgnore) { return; } Physics2D.IgnoreCollision(platformCollider, playerCollider, shouldIgnore); isIgnoringPlayerCollision = shouldIgnore; } } }