I'm trying to make a portal, but I don't understand why the code:
playerControl.transform.position = new Vector3(destination.position.x, destination.position.y, destination.position.z);
only works on certain positions and angles.
This is the set up for the code
public class Teleport : Interactable
{
public Transform destination;
private GameObject playerControl;
private PortalAnimationController portalController;
// Start is called before the first frame update
void Start()
{//get the player information
playerControl = PlayerManager.instance.player;
portalController = PortalAnimationController.instance;
}
public override void interact()
{
//base.interact();
//run the teleport method
StartCoroutine("teleport");
//Debug.Log(playerControl.GetInstanceID());
}
/*
1. trigger the panel
2. stop the time
3. teleport the player
*/
private IEnumerator teleport()
{
Time.timeScale = 0f;//stop the time
portalController.fadeOut();
//wait for seconds realtime can avoid stopping when timescale is 0
yield return new WaitForSecondsRealtime(portalController.duration);//wait for the transition
Debug.Log("wait finish");
//after the the wait
Debug.Log(playerControl.transform.position + "before");
playerControl.transform.position = new Vector3(destination.position.x, destination.position.y, destination.position.z);
if(playerControl.transform.position!= destination.position)
{
Debug.Log(playerControl.transform.position);
}
else
{
Debug.Log(playerControl.transform.position+"pass");
}
portalController.fadeOut();
Time.timeScale = 1f;
}
}
The interactable class only contains a "public virtual void interact()" method for teleport to override it. The way to trigger is through the code below:
void Update()
{
RaycastHit hit;
if (Input.GetButtonDown("Interact"))
{
if (Physics.Raycast(cam.transform.position, cam.transform.forward, out hit, interactableRange))
{
Interactable interactable = hit.collider.GetComponent<Interactable>();
//if the player is looking at the interactable
//Debug.Log("Interact with " + hit.transform.name);
if (interactable != null)
{
//highlight the object
interactable.interact();
//if player press the interact key, then pick it up
Debug.Log("Interact with " + hit.transform.name);
}
}
}
}
It shoots a ray when the e key is pressed, then hit a collider box to retrieve the interactable component and call the interact() immediately.
I have tested it hundreds of times, and there are only 3 results. 1. player actually get teleported.(success) 2. player flashes to the destination in 1 frame then back to where it was.(failed) 3. player does not move at all.(failed)

if (Input.GetButtonDown("Interact") && canTeleport) { canTeleport = false, Of cource, you need to press interact button only once, when you look directly to teleporter. - Mykhailo Khadzhynov