156 lines
4.7 KiB
C#
156 lines
4.7 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
[RequireComponent(typeof(AudioSource))]
|
|
public class DoorSystem : MonoBehaviour
|
|
{
|
|
public enum MotionType { Rotate, Slide }
|
|
|
|
[Header("G³ówne Ustawienia")]
|
|
public MotionType motionType = MotionType.Rotate;
|
|
public bool isAutomatic = true; // Czy maj¹ siê same otwieraæ?
|
|
public string playerTag = "Player";
|
|
|
|
[Header("Skrzyd³a Drzwi")]
|
|
public Transform doorWing1;
|
|
public Transform doorWing2;
|
|
public bool invertWing2 = true;
|
|
|
|
[Header("Parametry Ruchu")]
|
|
public Vector3 actionAxis = Vector3.up;
|
|
public float amount = 90f; // K¹t/Dystans bazowy
|
|
public float springStrength = 10f;
|
|
public float springDamper = 4f;
|
|
|
|
[Header("Audio")]
|
|
public AudioClip openSound;
|
|
public AudioClip closeSound;
|
|
public AudioClip slamSound;
|
|
|
|
private float currentValue = 0f;
|
|
private float targetValue = 0f;
|
|
private float velocity = 0f;
|
|
private float currentDirectionMult = 1f; // 1 lub -1 w zale¿noœci od strony
|
|
|
|
private Vector3 wing1StartPos, wing2StartPos;
|
|
private Quaternion wing1StartRot, wing2StartRot;
|
|
private AudioSource audioSource;
|
|
private bool playedSlam = true;
|
|
private bool isOpen = false;
|
|
|
|
// Lista obiektów wewn¹trz triggera (Safety System)
|
|
private List<Collider> objectsInTrigger = new List<Collider>();
|
|
|
|
void Start()
|
|
{
|
|
audioSource = GetComponent<AudioSource>();
|
|
if (doorWing1) { wing1StartPos = doorWing1.localPosition; wing1StartRot = doorWing1.localRotation; }
|
|
if (doorWing2) { wing2StartPos = doorWing2.localPosition; wing2StartRot = doorWing2.localRotation; }
|
|
}
|
|
|
|
// Wywo³ywane przez Raycast lub przycisk interakcji
|
|
public void Interact(Vector3 interactorPosition)
|
|
{
|
|
if (isOpen)
|
|
{
|
|
TryClose();
|
|
}
|
|
else
|
|
{
|
|
SetDirection(interactorPosition);
|
|
Open();
|
|
}
|
|
}
|
|
|
|
private void Open()
|
|
{
|
|
isOpen = true;
|
|
targetValue = amount * currentDirectionMult;
|
|
playedSlam = false;
|
|
if (openSound) audioSource.PlayOneShot(openSound);
|
|
}
|
|
|
|
private void TryClose()
|
|
{
|
|
// Safety check: nie zamykaj, jeœli ktoœ stoi w przejœciu
|
|
if (objectsInTrigger.Count > 0) return;
|
|
|
|
isOpen = false;
|
|
targetValue = 0f;
|
|
if (closeSound) audioSource.PlayOneShot(closeSound);
|
|
}
|
|
|
|
// Sprawdza, z której strony jest gracz wzglêdem osi Z (Forward) drzwi
|
|
private void SetDirection(Vector3 position)
|
|
{
|
|
Vector3 directionToPlayer = position - transform.position;
|
|
float dot = Vector3.Dot(transform.forward, directionToPlayer);
|
|
|
|
// Jeœli gracz jest z przodu (dot > 0), drzwi otwieraj¹ siê do ty³u (-1)
|
|
// Jeœli gracz jest z ty³u (dot < 0), drzwi otwieraj¹ siê do przodu (1)
|
|
currentDirectionMult = (dot > 0) ? -1f : 1f;
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
if (other.CompareTag(playerTag))
|
|
{
|
|
if (!objectsInTrigger.Contains(other)) objectsInTrigger.Add(other);
|
|
|
|
if (isAutomatic && !isOpen)
|
|
{
|
|
SetDirection(other.transform.position);
|
|
Open();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnTriggerExit(Collider other)
|
|
{
|
|
if (other.CompareTag(playerTag))
|
|
{
|
|
if (objectsInTrigger.Contains(other)) objectsInTrigger.Remove(other);
|
|
|
|
if (isAutomatic && isOpen)
|
|
{
|
|
TryClose();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
float dt = Time.deltaTime;
|
|
float force = (targetValue - currentValue) * springStrength;
|
|
float damping = velocity * springDamper;
|
|
float acceleration = force - damping;
|
|
|
|
velocity += acceleration * dt;
|
|
currentValue += velocity * dt;
|
|
|
|
if (!isOpen && !playedSlam && Mathf.Abs(currentValue) < 0.05f)
|
|
{
|
|
if (slamSound) audioSource.PlayOneShot(slamSound);
|
|
playedSlam = true;
|
|
currentValue = 0; // Hard stop
|
|
velocity = 0;
|
|
}
|
|
|
|
UpdateDoorVisuals(currentValue);
|
|
}
|
|
|
|
void UpdateDoorVisuals(float val)
|
|
{
|
|
if (doorWing1) ApplyTransform(doorWing1, val, wing1StartPos, wing1StartRot, false);
|
|
if (doorWing2) ApplyTransform(doorWing2, val, wing2StartPos, wing2StartRot, invertWing2);
|
|
}
|
|
|
|
void ApplyTransform(Transform target, float val, Vector3 startPos, Quaternion startRot, bool invert)
|
|
{
|
|
float finalVal = invert ? -val : val;
|
|
if (motionType == MotionType.Rotate)
|
|
target.localRotation = startRot * Quaternion.AngleAxis(finalVal, actionAxis);
|
|
else
|
|
target.localPosition = startPos + (actionAxis.normalized * finalVal);
|
|
}
|
|
} |