Working on teleporation manager to teleport
This commit is contained in:
parent
7962b96976
commit
59f11a4b6f
8
Assets/Scripts/Teleportation.meta
Normal file
8
Assets/Scripts/Teleportation.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e1e704e47ac357c43a1c55af30b5e432
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
104
Assets/Scripts/Teleportation/TeleportManager.cs
Normal file
104
Assets/Scripts/Teleportation/TeleportManager.cs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.AI;
|
||||||
|
|
||||||
|
public class TeleportManager : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static TeleportManager Instance { get; private set; }
|
||||||
|
|
||||||
|
[Header("Optional fade (CanvasGroup with RaycastBlock)")]
|
||||||
|
public TeleportScreenFader screenFader; // drag a CanvasGroup-based fader (below)
|
||||||
|
[Range(0f, 2f)] public float fadeDuration = 0.25f;
|
||||||
|
|
||||||
|
// Prevent immediate re-triggering after arrival
|
||||||
|
private readonly Dictionary<GameObject, float> _entityCooldownUntil = new();
|
||||||
|
private readonly Dictionary<GameObject, string> _entityLastPortalId = new();
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
|
||||||
|
Instance = this;
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanUsePortal(GameObject entity, string portalId, float cooldownSeconds)
|
||||||
|
{
|
||||||
|
if (cooldownSeconds <= 0f) return true;
|
||||||
|
|
||||||
|
var now = Time.time;
|
||||||
|
if (_entityCooldownUntil.TryGetValue(entity, out float until) && now < until)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If just came out of this portal pair, block one frame of re-trigger
|
||||||
|
if (_entityLastPortalId.TryGetValue(entity, out string lastId) && lastId == portalId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkUsed(GameObject entity, string portalId, float cooldownSeconds)
|
||||||
|
{
|
||||||
|
if (cooldownSeconds > 0f)
|
||||||
|
_entityCooldownUntil[entity] = Time.time + cooldownSeconds;
|
||||||
|
|
||||||
|
_entityLastPortalId[entity] = portalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Teleport entity to destination. Handles CharacterController, Rigidbody, and NavMeshAgent safely.
|
||||||
|
/// </summary>
|
||||||
|
public void Teleport(GameObject entity, Transform destination, bool matchRotation = true)
|
||||||
|
{
|
||||||
|
if (entity == null || destination == null) return;
|
||||||
|
StartCoroutine(TeleportRoutine(entity, destination, matchRotation));
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator TeleportRoutine(GameObject entity, Transform destination, bool matchRotation)
|
||||||
|
{
|
||||||
|
// Fade out (optional)
|
||||||
|
if (screenFader != null && fadeDuration > 0f)
|
||||||
|
yield return screenFader.FadeTo(1f, fadeDuration);
|
||||||
|
|
||||||
|
// Disable common movers safely
|
||||||
|
var cc = entity.GetComponent<CharacterController>();
|
||||||
|
var rb = entity.GetComponent<Rigidbody>();
|
||||||
|
var agent = entity.GetComponent<NavMeshAgent>();
|
||||||
|
|
||||||
|
bool ccWasEnabled = false;
|
||||||
|
bool agentWasEnabled = false;
|
||||||
|
|
||||||
|
if (cc != null) { ccWasEnabled = cc.enabled; cc.enabled = false; }
|
||||||
|
if (agent != null) { agentWasEnabled = agent.enabled; agent.enabled = false; }
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
rb.isKinematic = true; // pause physics for an instant
|
||||||
|
rb.velocity = Vector3.zero;
|
||||||
|
rb.angularVelocity = Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move + rotate
|
||||||
|
if (agent != null)
|
||||||
|
{
|
||||||
|
agent.Warp(destination.position);
|
||||||
|
if (matchRotation) entity.transform.rotation = destination.rotation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entity.transform.position = destination.position;
|
||||||
|
if (matchRotation) entity.transform.rotation = destination.rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Small frame delay to settle
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// Re-enable components
|
||||||
|
if (rb != null) rb.isKinematic = false;
|
||||||
|
if (cc != null) cc.enabled = ccWasEnabled;
|
||||||
|
if (agent != null) agent.enabled = agentWasEnabled;
|
||||||
|
|
||||||
|
// Fade in (optional)
|
||||||
|
if (screenFader != null && fadeDuration > 0f)
|
||||||
|
yield return screenFader.FadeTo(0f, fadeDuration);
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Scripts/Teleportation/TeleportManager.cs.meta
Normal file
11
Assets/Scripts/Teleportation/TeleportManager.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5dce2a4efa47e2f4aaa40c0820a478ee
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
62
Assets/Scripts/Teleportation/TeleportPoint.cs
Normal file
62
Assets/Scripts/Teleportation/TeleportPoint.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[RequireComponent(typeof(Collider))]
|
||||||
|
public class TeleportPoint : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Destination")]
|
||||||
|
public Transform destination; // set this to SkyCity_Spawn or any target
|
||||||
|
|
||||||
|
[Header("Filtering")]
|
||||||
|
public string requiredTag = "Player"; // only teleport objects with this tag
|
||||||
|
|
||||||
|
[Header("Behavior")]
|
||||||
|
public bool matchRotation = true;
|
||||||
|
[Tooltip("Shared ID for A<->B portals to avoid instant ping-pong.")]
|
||||||
|
public string portalId = "SkyCityGate";
|
||||||
|
[Tooltip("Seconds the entity cannot re-trigger a portal after using one.")]
|
||||||
|
public float reentryCooldown = 0.5f;
|
||||||
|
|
||||||
|
private void Reset()
|
||||||
|
{
|
||||||
|
var c = GetComponent<Collider>();
|
||||||
|
c.isTrigger = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTriggerEnter(Collider other)
|
||||||
|
{
|
||||||
|
if (!IsAllowed(other.gameObject)) return;
|
||||||
|
|
||||||
|
var tm = TeleportManager.Instance;
|
||||||
|
if (tm == null) { Debug.LogWarning("[TeleportPoint] No TeleportManager in scene."); return; }
|
||||||
|
|
||||||
|
if (!tm.CanUsePortal(other.gameObject, portalId, reentryCooldown)) return;
|
||||||
|
|
||||||
|
tm.MarkUsed(other.gameObject, portalId, reentryCooldown);
|
||||||
|
tm.Teleport(other.gameObject, destination, matchRotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsAllowed(GameObject go)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(requiredTag) && !go.CompareTag(requiredTag))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (destination == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[TeleportPoint] '{name}' has no destination assigned.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (destination == null) return;
|
||||||
|
Gizmos.color = Color.cyan;
|
||||||
|
Gizmos.DrawWireSphere(transform.position, 0.3f);
|
||||||
|
Gizmos.DrawLine(transform.position, destination.position);
|
||||||
|
Gizmos.DrawWireSphere(destination.position, 0.3f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
11
Assets/Scripts/Teleportation/TeleportPoint.cs.meta
Normal file
11
Assets/Scripts/Teleportation/TeleportPoint.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6cd2ca85a22ffb642bb124e4b6d6b716
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
29
Assets/Scripts/Teleportation/TeleportScreenFader.cs
Normal file
29
Assets/Scripts/Teleportation/TeleportScreenFader.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[RequireComponent(typeof(CanvasGroup))]
|
||||||
|
public class TeleportScreenFader : MonoBehaviour
|
||||||
|
{
|
||||||
|
private CanvasGroup _cg;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
_cg = GetComponent<CanvasGroup>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator FadeTo(float targetAlpha, float duration)
|
||||||
|
{
|
||||||
|
float start = _cg.alpha;
|
||||||
|
float t = 0f;
|
||||||
|
_cg.blocksRaycasts = targetAlpha > 0.01f;
|
||||||
|
|
||||||
|
while (t < duration)
|
||||||
|
{
|
||||||
|
t += Time.unscaledDeltaTime;
|
||||||
|
_cg.alpha = Mathf.Lerp(start, targetAlpha, t / duration);
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
_cg.alpha = targetAlpha;
|
||||||
|
_cg.blocksRaycasts = targetAlpha > 0.01f;
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Scripts/Teleportation/TeleportScreenFader.cs.meta
Normal file
11
Assets/Scripts/Teleportation/TeleportScreenFader.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bf0f714f4603da745855c8b18be4de59
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
x
Reference in New Issue
Block a user