Working on teleporation manager to teleport

This commit is contained in:
Hazim Bin Ijaz 2025-08-30 22:01:55 +05:00
parent 7962b96976
commit 59f11a4b6f
7 changed files with 236 additions and 0 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e1e704e47ac357c43a1c55af30b5e432
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5dce2a4efa47e2f4aaa40c0820a478ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6cd2ca85a22ffb642bb124e4b6d6b716
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf0f714f4603da745855c8b18be4de59
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: