wastland cont..
This commit is contained in:
@@ -1,173 +1,216 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Beyond
|
||||
{
|
||||
[RequireComponent(typeof(Collider))]
|
||||
public class DestinationPoint : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private DestinationPoint nextPoint; // Nast<EFBFBD>pny punkt docelowy
|
||||
[SerializeField] private Collider triggerCollider; // Collider, kt<6B>ry wyzwala zmian<61> punktu
|
||||
[SerializeField] private AudioClip destinationSound; // D<>wi<77>k do odtworzenia
|
||||
[SerializeField] private AudioSource audioSource; // <20>r<EFBFBD>d<EFBFBD>o d<>wi<77>ku
|
||||
[SerializeField] private UnityEvent onTriggerEnter;
|
||||
[SerializeField] private DestinationPoint nextPoint; // Następny punkt
|
||||
[SerializeField] private Collider triggerCollider;
|
||||
[SerializeField] private AudioSource audioSource;
|
||||
[SerializeField] private AudioClip destinationSound;
|
||||
|
||||
[Header("Settings")]
|
||||
[Header("Events")]
|
||||
[SerializeField] private UnityEvent onPointReached;
|
||||
|
||||
[Header("Detection Settings")]
|
||||
[SerializeField] private LayerMask playerLayer; // Lepsze niż Tag
|
||||
[Tooltip("Jeśli true: zalicza punkt natychmiast, jeśli gracz już w nim stoi w momencie aktywacji.")]
|
||||
[SerializeField] private bool autoSkipIfInside = false;
|
||||
[Tooltip("Jeśli true: punkt nie włączy się, dopóki gracz nie oddali się na bezpieczną odległość.")]
|
||||
[SerializeField] private bool waitForExitIfInside = true;
|
||||
[SerializeField] private float minActivationDistance = 5.0f; // Dystans wymagany do uzbrojenia punktu
|
||||
|
||||
[Header("General Settings")]
|
||||
[SerializeField] private bool activateOnStart = true;
|
||||
[SerializeField] private bool switchOnParentDeactivation = false; // Czy prze<7A><65>cza<7A> na nast<73>pny punkt, gdy obiekt nadrz<72>dny jest dezaktywowany
|
||||
|
||||
private bool isActive = false; // Czy punkt jest aktywny
|
||||
private bool isDestroyed = false;
|
||||
private bool wasParentActive = true;
|
||||
|
||||
//private void OnEnable()
|
||||
//{
|
||||
// Upewnij si<73>, <20>e widoczno<6E><6F> jest poprawnie ustawiona zanim wszystko si<73> zainicjalizuje
|
||||
// UpdateVisibility();
|
||||
//}
|
||||
private bool isActive = false; // Czy punkt logicznie jest "tym aktualnym"
|
||||
private bool isArmed = false; // Czy punkt jest fizycznie włączony (collider + marker)
|
||||
private Transform playerTransform;
|
||||
private Coroutine activationCoroutine;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Upewnij si<73>, <20>e collider jest ustawiony jako trigger
|
||||
if (triggerCollider != null)
|
||||
{
|
||||
triggerCollider.isTrigger = true;
|
||||
}
|
||||
if (triggerCollider == null) triggerCollider = GetComponent<Collider>();
|
||||
if (triggerCollider != null) triggerCollider.isTrigger = true;
|
||||
|
||||
// Upewnij si<73>, <20>e audioSource jest przypisany
|
||||
if (audioSource == null)
|
||||
{
|
||||
audioSource = gameObject.AddComponent<AudioSource>();
|
||||
}
|
||||
|
||||
// Sprawd<77>, czy obiekt nadrz<72>dny jest aktywny na pocz<63>tku
|
||||
if (switchOnParentDeactivation && transform.parent != null)
|
||||
{
|
||||
wasParentActive = transform.parent.gameObject.activeInHierarchy;
|
||||
}
|
||||
if (audioSource == null) audioSource = GetComponent<AudioSource>();
|
||||
if (audioSource == null && destinationSound != null) audioSource = gameObject.AddComponent<AudioSource>();
|
||||
}
|
||||
/*
|
||||
|
||||
private void Update()
|
||||
private void Start()
|
||||
{
|
||||
// Sprawd<77>, czy obiekt nadrz<72>dny zmieni<6E> sw<73>j stan
|
||||
if (switchOnParentDeactivation && transform.parent != null)
|
||||
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
|
||||
if (playerObj) playerTransform = playerObj.transform;
|
||||
|
||||
if (activateOnStart)
|
||||
{
|
||||
bool isParentActive = transform.parent.gameObject.activeInHierarchy;
|
||||
if (wasParentActive && !isParentActive)
|
||||
{
|
||||
// Obiekt nadrz<72>dny zosta<74> dezaktywowany
|
||||
HandleParentDeactivated();
|
||||
}
|
||||
wasParentActive = isParentActive;
|
||||
Activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Upewnij się, że na starcie jest wyłączony, jeśli nie ma być aktywny
|
||||
UpdateVisualState(false);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
// Zak<61>adamy, <20>e gracz ma tag "Player"
|
||||
if (isActive && other.CompareTag("Player"))
|
||||
{
|
||||
// Odtw<74>rz d<>wi<77>k, je<6A>li jest przypisany
|
||||
if (destinationSound != null && audioSource != null)
|
||||
{
|
||||
audioSource.PlayOneShot(destinationSound);
|
||||
}
|
||||
|
||||
// Prze<7A><65>cz na nast<73>pny punkt
|
||||
//DestinationTargetManager.Instance.SwitchToNextPoint(nextPoint);
|
||||
|
||||
// Dezaktywuj ten punkt
|
||||
Deactivate();
|
||||
onTriggerEnter?.Invoke();
|
||||
}
|
||||
}
|
||||
// --- Logika Włączania/Wyłączania (Unity Lifecycle) ---
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Aktywuj punkt, gdy skrypt jest w<><77>czony
|
||||
if (activateOnStart)
|
||||
Activate();
|
||||
// Jeśli obiekt został włączony ponownie (np. po dezaktywacji rodzica),
|
||||
// a logicznie ten punkt nadal powinien być aktywny -> wznów działanie.
|
||||
if (isActive)
|
||||
{
|
||||
TryArmPoint();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
|
||||
// Dezaktywuj punkt, gdy skrypt jest wy<77><79>czony
|
||||
Deactivate();
|
||||
}
|
||||
/*
|
||||
// Funkcja sprawdzaj<61>ca, czy obiekt nadrz<72>dny jest aktywny i czy wska<6B>nik powinien by<62> widoczny
|
||||
private void UpdateVisibility()
|
||||
{
|
||||
if (isActive && IsParentActive() && DestinationTargetManager.Instance != null)
|
||||
{
|
||||
DestinationTargetManager.Instance.SetTargetVisibility(true);
|
||||
}
|
||||
else if (DestinationTargetManager.Instance != null)
|
||||
{
|
||||
DestinationTargetManager.Instance.SetTargetVisibility(false);
|
||||
}
|
||||
// Kiedy obiekt jest wyłączany, zawsze chowamy marker i wyłączamy logikę
|
||||
// Ale NIE zmieniamy 'isActive', bo quest nadal jest na tym etapie.
|
||||
if (activationCoroutine != null) StopCoroutine(activationCoroutine);
|
||||
UpdateVisualState(false);
|
||||
}
|
||||
|
||||
// Sprawdza, czy obiekt nadrz<72>dny jest aktywny
|
||||
private bool IsParentActive()
|
||||
{
|
||||
return transform.parent == null || transform.parent.gameObject.activeInHierarchy;
|
||||
}
|
||||
*/
|
||||
// --- Główna Logika ---
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
if (!isActive)
|
||||
if (isActive) return; // Już jest aktywny
|
||||
isActive = true;
|
||||
|
||||
TryArmPoint();
|
||||
}
|
||||
|
||||
private void TryArmPoint()
|
||||
{
|
||||
// 1. Sprawdź, czy gracz jest w środku
|
||||
if (IsPlayerInsideOrTooClose())
|
||||
{
|
||||
isActive = true;
|
||||
if (triggerCollider != null)
|
||||
if (autoSkipIfInside)
|
||||
{
|
||||
triggerCollider.enabled = true;
|
||||
Debug.Log($"[DestinationPoint] Gracz wewnątrz {name}, automatyczne zaliczenie.");
|
||||
HandleDestinationReached();
|
||||
return;
|
||||
}
|
||||
else if (waitForExitIfInside)
|
||||
{
|
||||
Debug.Log($"[DestinationPoint] Gracz za blisko {name}, czekam na dystans...");
|
||||
if (activationCoroutine != null) StopCoroutine(activationCoroutine);
|
||||
activationCoroutine = StartCoroutine(WaitForSafeDistance());
|
||||
return;
|
||||
}
|
||||
Compass.Instance.AddQuestMarker(transform, null);
|
||||
}
|
||||
|
||||
// 2. Normalna aktywacja (Marker + Collider)
|
||||
UpdateVisualState(true);
|
||||
}
|
||||
|
||||
public void Deactivate()
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
isActive = false;
|
||||
if (triggerCollider != null)
|
||||
{
|
||||
triggerCollider.enabled = false;
|
||||
}
|
||||
Compass.Instance.RemoveQuestMarker(transform);
|
||||
if (nextPoint)
|
||||
{
|
||||
nextPoint.Activate();
|
||||
}
|
||||
|
||||
// Ukryj wska<6B>nik, gdy skrypt jest wy<77><79>czony
|
||||
//if (DestinationTargetManager.Instance != null)
|
||||
//{
|
||||
// DestinationTargetManager.Instance.SetTargetVisibility(false);
|
||||
// DestinationTargetManager.Instance.SwitchToNextPoint(nextPoint);
|
||||
//}
|
||||
}
|
||||
isActive = false;
|
||||
UpdateVisualState(false);
|
||||
if (activationCoroutine != null) StopCoroutine(activationCoroutine);
|
||||
}
|
||||
|
||||
/*
|
||||
// Funkcja wywo<77>ywana, gdy obiekt nadrz<72>dny zostaje dezaktywowany
|
||||
private void HandleParentDeactivated()
|
||||
// Metoda pomocnicza do zarządzania stanem wizualnym/fizycznym
|
||||
private void UpdateVisualState(bool state)
|
||||
{
|
||||
if (switchOnParentDeactivation && !isDestroyed)
|
||||
isArmed = state;
|
||||
|
||||
if (triggerCollider != null)
|
||||
triggerCollider.enabled = state;
|
||||
|
||||
if (Compass.Instance != null)
|
||||
{
|
||||
isDestroyed = true;
|
||||
// Prze<7A><65>cz na nast<73>pny punkt, je<6A>li obiekt nadrz<72>dny zosta<74> dezaktywowany
|
||||
DestinationTargetManager.Instance.SwitchToNextPoint(nextPoint);
|
||||
// Dezaktywuj ten punkt
|
||||
Deactivate();
|
||||
if (state)
|
||||
Compass.Instance.AddQuestMarker(transform, null);
|
||||
else
|
||||
Compass.Instance.RemoveQuestMarker(transform);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (!isActive || !isArmed) return;
|
||||
|
||||
// Sprawdzamy LayerMask lub Tag
|
||||
if (IsInLayerMask(other.gameObject, playerLayer) || other.CompareTag("Player"))
|
||||
{
|
||||
HandleDestinationReached();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDestinationReached()
|
||||
{
|
||||
// Dźwięk
|
||||
if (destinationSound != null && audioSource != null)
|
||||
audioSource.PlayOneShot(destinationSound);
|
||||
|
||||
// Eventy
|
||||
onPointReached?.Invoke();
|
||||
|
||||
// Logika następnego punktu
|
||||
// Najpierw wyłączamy obecny, żeby nie wywołał się dwa razy
|
||||
Deactivate();
|
||||
|
||||
if (nextPoint != null)
|
||||
{
|
||||
nextPoint.Activate();
|
||||
}
|
||||
}
|
||||
|
||||
// --- Pomocnicze (Dystans i Coroutine) ---
|
||||
|
||||
private bool IsPlayerInsideOrTooClose()
|
||||
{
|
||||
if (playerTransform == null) return false;
|
||||
|
||||
// Sprawdzenie 1: Czy jest fizycznie w Triggerze
|
||||
if (triggerCollider != null && triggerCollider.bounds.Contains(playerTransform.position))
|
||||
return true;
|
||||
|
||||
// Sprawdzenie 2: Czy jest za blisko (zabezpieczenie jeśli collider jest mały)
|
||||
return Vector3.Distance(transform.position, playerTransform.position) < 2.0f;
|
||||
}
|
||||
|
||||
private IEnumerator WaitForSafeDistance()
|
||||
{
|
||||
// Upewnij się, że marker i collider są wyłączone podczas czekania
|
||||
UpdateVisualState(false);
|
||||
|
||||
while (playerTransform != null &&
|
||||
Vector3.Distance(transform.position, playerTransform.position) < minActivationDistance)
|
||||
{
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
}
|
||||
|
||||
// Gracz odszedł wystarczająco daleko -> włącz punkt
|
||||
UpdateVisualState(true);
|
||||
activationCoroutine = null;
|
||||
}
|
||||
|
||||
private bool IsInLayerMask(GameObject obj, LayerMask layerMask)
|
||||
{
|
||||
return (layerMask.value & (1 << obj.layer)) > 0;
|
||||
}
|
||||
|
||||
// --- Debug w Edytorze ---
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
Gizmos.color = isActive ? (isArmed ? Color.green : Color.yellow) : Color.gray;
|
||||
Gizmos.DrawWireSphere(transform.position, 0.5f);
|
||||
|
||||
if (nextPoint != null)
|
||||
{
|
||||
Gizmos.color = Color.white;
|
||||
Gizmos.DrawLine(transform.position, nextPoint.transform.position);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user