Danro/Assets/Scripts/Entities/Props/Platforms/TriggeringPlatform.cs
Danil Iarosh bd57b74d8b level 1-3 updates, bug fixes etc
- улучшил структуру уровня 1-3
- пофиксил баг с застреванием персонажа на уровне 1-3
- пофиксил баг с прилипанием игрока к платформе сбоку
- изменил логику платформ
- добавил больше динамичности в уровень 1-3
2025-11-28 16:48:31 +03:00

117 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Linq;
using UnityEngine;
using RR.Game2D.Core;
namespace RR.Game2D.Entities.Platforms
{
public class TriggeringPlatform : MonoBehaviour
{
[Header("Настройки движения платформы")]
[SerializeField] private float moveSpeed = 3f;
[SerializeField] private float pathLength = 5f;
[SerializeField] private Direction2D moveDirection = Direction2D.Right;
[Header("Прикрепление игрока")]
[SerializeField] private bool attachPlayer = true;
[Tooltip("Минимальный угол нормали контакта к вертикали для прикрепления (0.7 ≈ 45°)")]
[SerializeField, Range(0f, 1f)] private float normalThreshold = 0.7f;
private Vector3 _startPosition;
private Vector3 _endPosition;
private void Awake()
{
_startPosition = transform.position;
_endPosition = moveDirection switch
{
Direction2D.Down => _startPosition + Vector3.down * pathLength,
Direction2D.Left => _startPosition + Vector3.left * pathLength,
Direction2D.Right => _startPosition + Vector3.right * pathLength,
Direction2D.Up => _startPosition + Vector3.up * pathLength,
_ => _startPosition
};
}
private void OnCollisionEnter2D(Collision2D other)
{
if (!attachPlayer) return;
if (!other.gameObject.CompareTag("Player")) return;
// Проверяем, что игрок стоит на верхней части платформы
if (IsPlayerOnTop(other))
{
other.transform.SetParent(transform);
}
}
private void OnCollisionStay2D(Collision2D other)
{
if (!attachPlayer) return;
if (!other.gameObject.CompareTag("Player")) return;
// Если игрок уже прикреплён, но больше не на верхней части - отсоединяем
if (other.transform.parent == transform && !IsPlayerOnTop(other))
{
other.transform.SetParent(null);
}
// Если игрок не прикреплён, но теперь на верхней части - прикрепляем
else if (other.transform.parent != transform && IsPlayerOnTop(other))
{
other.transform.SetParent(transform);
}
}
private void OnCollisionExit2D(Collision2D other)
{
if (!attachPlayer) return;
if (!other.gameObject.CompareTag("Player")) return;
if (other.transform.parent == transform)
{
other.transform.SetParent(null);
}
}
/// <summary>
/// Проверяет, находится ли игрок на верхней части платформы
/// </summary>
/// <param name="collision">Данные о столкновении</param>
/// <returns>True, если игрок стоит сверху</returns>
private bool IsPlayerOnTop(Collision2D collision)
{
// Проверяем нормали всех контактных точек
// Нормаль направлена от другого объекта (игрока) к платформе,
// поэтому если игрок сверху, нормаль будет направлена вниз
return collision.contacts.Any(contact => Vector2.Dot(contact.normal, Vector2.down) > normalThreshold);
}
public void Move()
{
StopAllCoroutines();
StartCoroutine(MovePlatform(_endPosition));
}
public void MoveBack()
{
StopAllCoroutines();
StartCoroutine(MovePlatform(_startPosition));
}
private IEnumerator MovePlatform(Vector3 targetPosition)
{
while (transform.position != targetPosition)
{
transform.position = Vector3.MoveTowards(
transform.position,
targetPosition,
Time.deltaTime * moveSpeed);
yield return null;
}
transform.position = targetPosition;
}
}
}