Recently I started attempting to make a teleporting mechanic which creates a red and blue portal if Q or E is pressed.
When the player enters this portal he gets teleported to the other portal as expected. However when the Player teleports, its children/attached objects don’t teleport aswell. I’m sure there is a simple solution like adding an if statement to an Update function that constantly repositions the children but I am unable to figure it out fully. If anybody has any suggestions I’d greatly appreciate it!
The code that teleports the character is as follows:
(This code is attached to each portal)
(collision = The Player/Parent Object)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class telePortal : MonoBehaviour {
private Transform destination;
public bool isOrange;
private void Start()
{
if (!isOrange)
{
destination = GameObject.FindGameObjectWithTag("OrangePortal").GetComponent<Transform>();
}
else
{
destination = GameObject.FindGameObjectWithTag("BluePortal").GetComponent<Transform>();
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (Vector2.Distance(transform.position, collision.transform.position) > 0.5f)
{
collision.transform.position = new Vector2(destination.position.x, destination.position.y);
}
}
}
Hey there,
if i understand your setup correctly you can not guarantee that the collider that hits the portals collider is your player-parent-objects collider.
So it might be good to check if the object that hits your portal is actually the one you are expecting.
Something like Debug.Log("Transform entering Portal: " + collision.transform.name);
If this actually is a problem you might be able to fix it by changing your code to:
collision.root.transform.position = new Vector2(destination.position.x, destination.position.y);
though this will only work if your player object is actually the root of the moving player.
Maybe an alternative would be destroying and Instantiate your gameobject
public class telePortal : MonoBehaviour
{
private Transform destination;
public bool isOrange;
public GameObject Thingyouwanttoteleport;
private void Start()
{
if (!isOrange)
{
destination = GameObject.FindGameObjectWithTag("OrangePortal").GetComponent<Transform>();
}
else
{
destination = GameObject.FindGameObjectWithTag("BluePortal").GetComponent<Transform>();
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (Vector2.Distance(transform.position, collision.transform.position) > 0.5f)
{
Destroy(collision.gameObject);
Instantiate(Thingyouwanttoteleport, destination.transform.position , Quaternion.identity);
}
}
}
Something like this? This could work as long as there isn’t any important data in the said Game object. If there is you could store the data on something else.
Your script is checking not checking if the collision is happening with parent or child object. It could be that a child object (if you have sprite as a child of the player gameobject) is the one colliding. I’d suggest adding a “Player” tag to the player and check collision based on that.
On the parent object, change tag to Player, then use this code inside onTriggerEnter2D
private void OnTriggerEnter2D(Collider2D collision) {
if (collison.gameobject.tag == "Player") {
collision.transform.position = new Vector2(destination.position.x, destination.position.y);
}
}
One method that works but I feel isn’t the best solution is that I found a way of storing the local position of the players children to its parent in a Start() function and constantly making sure that the children stay there by using an Update() that’s on the player.
public Vector3 child1;
public Vector3 child2;
private void Start()
{
ledgeDetector = gameObject.GetComponent<BoxCollider2D>();
coinSound = Resources.Load<AudioClip>("CoinPickupSound");
myrigidbody2D = this.GetComponent<Rigidbody2D>();
anim = gameObject.GetComponent<Animator>();
gravityStore = myrigidbody2D.gravityScale;
child1 = this.transform.GetChild(0).transform.position - this.transform.position;
//Local position to parents
child2 = this.transform.GetChild(1).transform.position - this.transform.position;
}
void Update()
{
if (facingRight)
{
this.transform.GetChild(0).transform.position = this.transform.position + child1;
this.transform.GetChild(1).transform.position = this.transform.position + child2;
}
else if(!facingRight)
{
this.transform.GetChild(0).transform.position = new Vector3(this.transform.position.x - child1.x, this.transform.position.y + child1.y, child1.z);
this.transform.GetChild(1).transform.position = new Vector3(this.transform.position.x - child2.x, this.transform.position.y + child2.y, child2.z);
}
This solution makes everything work perfectly yet I feel like this is not the intended way or most efficient way.