using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; namespace WSMGameStudio.RailroadSystem { public class TrainAttachPassenger : MonoBehaviour { private Dictionary _onStopRuntimeEvents = new Dictionary(); private Dictionary _onLeaveRuntimeEvents = new Dictionary(); private List _passengerTags; private bool _kinematicWhileMoving; public List PassengerTags { get { return _passengerTags; } set { _passengerTags = value; } } public bool KinematicWhileMoving { get { return _kinematicWhileMoving; } set { _kinematicWhileMoving = value; } } /// /// Handles objects inside the train /// /// private void OnTriggerEnter(Collider other) { SetPassengerParent(other.gameObject, transform.parent); } /// /// Handles objects that starts the scene already inside the train /// /// private void OnTriggerStay(Collider other) { SetPassengerParent(other.gameObject, transform.parent); } /// /// Handles object exit from train /// /// private void OnTriggerExit(Collider other) { RemovePassengerParent(other.gameObject); } /// /// Set passenger parent transform /// /// /// private void SetPassengerParent(GameObject other, Transform parent) { if (IsPassenger(other.tag)) { other.transform.SetParent(parent); if (_kinematicWhileMoving) { TrainStationController trainStationController = parent.GetComponent(); if (trainStationController != null) { int objectId = other.gameObject.GetInstanceID(); UnityAction stopAction; UnityAction leaveAction; if (!_onStopRuntimeEvents.TryGetValue(objectId, out stopAction)) { stopAction = new UnityAction((delegate { GameObject localGameObject = other; SetPassengerKinematic(localGameObject, false); })); _onStopRuntimeEvents.Add(objectId, stopAction); trainStationController.onStop.AddListener(_onStopRuntimeEvents[objectId]); } if (!_onLeaveRuntimeEvents.TryGetValue(objectId, out leaveAction)) { leaveAction = new UnityAction((delegate { GameObject localGameObject = other; SetPassengerKinematic(localGameObject, true); })); _onLeaveRuntimeEvents.Add(objectId, leaveAction); trainStationController.onLeave.AddListener(_onLeaveRuntimeEvents[objectId]); } } } } } /// /// Remove passenger /// /// private void RemovePassengerParent(GameObject other) { if (IsPassenger(other.tag)) { if (_kinematicWhileMoving) { TrainStationController trainStationController = other.transform.parent.GetComponent(); if (trainStationController != null) { int objectId = other.gameObject.GetInstanceID(); UnityAction stopAction; UnityAction leaveAction; if (_onStopRuntimeEvents.TryGetValue(objectId, out stopAction)) { trainStationController.onStop.RemoveListener(_onStopRuntimeEvents[objectId]); _onStopRuntimeEvents.Remove(objectId); } if (_onLeaveRuntimeEvents.TryGetValue(objectId, out leaveAction)) { trainStationController.onLeave.RemoveListener(_onLeaveRuntimeEvents[objectId]); _onLeaveRuntimeEvents.Remove(objectId); } } } other.transform.SetParent(null); } } /// /// Set kinematic if game object as a ribidbody attached to it /// /// /// public void SetPassengerKinematic(GameObject gameObject, bool isKinematic) { if (isKinematic && gameObject.transform.parent == null) return; Rigidbody rb = gameObject.GetComponent(); if (rb != null) rb.isKinematic = isKinematic; } /// /// Check if object is configured as an valid passenger /// /// /// private bool IsPassenger(string tag) { if (_passengerTags == null) return false; return _passengerTags.Contains(tag); } } }