Hello everyone, I’ve been working on a portal system that retains the player’s physics when teleporting. For example, if the player comes falling down into one portal, they’ll come flying out the other.
This is what I go so far, but it’s buggy. I used a coroutine to have more control over the parameters surrounding the teleport, but the physics is messed up, as if the player is weighted down.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Portal : MonoBehaviour
{
public Portal otherPortal;
[SerializeField] Transform destination;
[SerializeField] float distance = 0.4f;
[SerializeField] float secondsBeforeTeleport;
Rigidbody2D playerRB;
Vector2 entryVelocity; // Store the velocity when entering the portal
private void OnTriggerEnter2D(Collider2D player)
{
playerRB = player.GetComponent<Rigidbody2D>();
if (player.CompareTag("Player"))
{
if (Vector2.Distance(player.transform.position, transform.position) > distance)
{
entryVelocity = playerRB.velocity; // Store the velocity upon entering the portal
StartCoroutine(TeleportDelay(player, secondsBeforeTeleport));
}
}
}
IEnumerator TeleportDelay(Collider2D player, float seconds)
{
yield return null;
yield return new WaitForSeconds(seconds);
player.transform.position = destination.position;
// Calculate the negative entry velocity
Vector2 negativeEntryVelocity = -entryVelocity;
// Check if the player is moving upward or downward
float verticalVelocity = Mathf.Sign(entryVelocity.y);
// If moving upward, launch downward from the destination portal, and vice versa
playerRB.velocity = new Vector2(negativeEntryVelocity.x, verticalVelocity * Mathf.Abs(negativeEntryVelocity.y));
yield return new WaitForSeconds(seconds);
}
private void OnTriggerExit2D(Collider2D player)
{
playerRB = player.GetComponent<Rigidbody2D>();
if (player.CompareTag("Player"))
{
// Apply the stored entry velocity when exiting the second portal
playerRB.velocity = entryVelocity;
}
}
}