102 lines
3.3 KiB
C#

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using RR.Common.Interfaces;
namespace RR.Game2D.Entities
{
[RequireComponent(typeof(Collider2D))]
public class Lever : MonoBehaviour, IActionable
{
[Header("Управление")]
[SerializeField] protected InputActionReference activateKey;
[Header("Настройки частей рычага")]
[SerializeField] protected Transform stick;
[SerializeField] protected Transform leverBase;
[Header("Настройки поворота рычага")]
[SerializeField] protected float rotationAngle = -90f;
[SerializeField] protected float rotationSpeed = 5f;
[Header("События после активации")]
[SerializeField] protected UnityEvent onActivate;
protected Quaternion _initialRotation;
protected Collider2D _collider;
protected bool _isActivated;
protected bool _canBeActivated = false;
protected void Start()
{
_isActivated = false;
// onActivate = new UnityEvent();
if (_collider == null) _collider = GetComponent<Collider2D>();
if (_collider == null) _collider = gameObject.AddComponent<Collider2D>();
if (!_collider.isTrigger) _collider.isTrigger = true;
if (stick == null)
{
Debug.LogError("Lever: Stick transform is not assigned!", this);
}
else
{
_initialRotation = stick.rotation;
}
// activateKey.action.performed += OnActivateKey;
activateKey.action.started += OnActivateKey;
activateKey.action.Enable();
}
protected void OnTriggerEnter2D(Collider2D other)
{
if (!other.CompareTag("Player")) return;
_canBeActivated = true;
}
protected void OnTriggerExit2D(Collider2D other)
{
if (!other.CompareTag("Player")) return;
_canBeActivated = false;
}
public virtual void Activate()
{
if (_isActivated) return;
StopAllCoroutines();
StartCoroutine(RotateLever(_initialRotation, _initialRotation * Quaternion.Euler(0f, 0f, rotationAngle)));
onActivate?.Invoke();
}
protected virtual IEnumerator RotateLever(Quaternion initialRotation, Quaternion targetRotation)
{
float elapsedTime = 0f;
_isActivated = initialRotation == _initialRotation;
float speedModifier = Mathf.Abs(Quaternion.Angle(initialRotation, targetRotation) / rotationAngle);
while (elapsedTime < rotationSpeed)
{
stick.rotation = Quaternion.Slerp(initialRotation, targetRotation, elapsedTime / (rotationSpeed * speedModifier));
elapsedTime += Time.deltaTime;
yield return null;
}
stick.rotation = targetRotation;
}
protected virtual void OnActivateKey(InputAction.CallbackContext obj)
{
if (!_canBeActivated) return;
if (_isActivated) return;
Activate();
}
}
}