Подробные изменения: - Добавлены сцены Bootstrap, MainMenu и Game с текущей вертикальной 9:16 структурой проекта. - Добавлены runtime-скрипты gameplay-архитектуры: DI через Extenject, спавнер платформ, прогрессия этапов, one-way платформы, игрок, камера и оборудование JumpPad. - Добавлены ScriptableObject-этапы сложности, weighted-настройки платформ, оборудования, противников и collectibles. - Добавлены UI Toolkit ресурсы главного меню, preview-материалы, шрифты, спрайты, анимации и игровые prefab-ассеты. - Перенесена и оформлена новая COM-система для работы с аппаратными портами и StreamingAssets. - Обновлены проектные гайды, AGENTS.md, правила Git/Git LFS, .gitignore, Unity Packages и ProjectSettings. - Удалён локальный skill start-required-mcp-servers из репозитория.
109 lines
2.9 KiB
C#
109 lines
2.9 KiB
C#
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<Collider2D>();
|
|
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;
|
|
}
|
|
|
|
}
|
|
}
|