# Portals

I wanted to make a portal that teleports the player to another portal upon collision. A portal is either for souls or for inhabited bodies and only becomes visible if the player is in the correct state. The portals will get their visual looks by a shader that Tirso has written.

## Portal

The first thing that I needed to do was track if the player was a soul or if they had inhabited a body. I wrote a script that kept track of the players' states.

```
public class PlayerData : MonoBehaviour
{
    public bool isSoul;
    public bool inRoom;
}
```

I used that state in the Portal script to determine if the player could teleport. A soul can go through a soul portal and an inhabited body can go through non-soul portals. In the TeleportPlayer function I position and rotate the player to a spawnPosition gameObject, which is a child of the portal that the player needs to teleport to. I had a bit of help with calculating the rotations from Tirso.

```
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.layer == LayerMask.NameToLayer("Player"))
        {
            PlayerData playerData = other.gameObject.GetComponent<PlayerData>();
            if (playerData)
            {
                if (soulPortal)
                {
                    if (playerData.isSoul)
                        TeleportPlayer(other.gameObject, playerData);
                }
                else
                {
                    if (!playerData.isSoul)
                        TeleportPlayer(other.gameObject, playerData);
                }
            }
        }
    }

    private void TeleportPlayer(GameObject player, PlayerData playerData)
    {
        player.transform.position = linkedPortalSpawnPosition.position;
        playerData.inRoom = !playerData.inRoom;
        player.transform.localRotation = Quaternion.Euler(0, linkedPortalSpawnPosition.localEulerAngles.y - player.GetComponentInChildren<Camera>().transform.localEulerAngles.y, 0);
    }
```

This solution caused me to have to set up each spawnPosition rotation mannualy, which was quite bothersome because I had to test it in VR take the headset off change some variables and see if the rotation was correct. I had to do that for a total of 6 portals, so that took a bit of time. It was a better solution than calculating the rotation based on the player forward, because the player rotations were set up quite badly. There were multiple child objects in the player that had different rotations, which made it quite difficult to calculate.

## Minor adjustments

With the addition of the portals, there was no reason anymore for the player to be able to exit every room with the press of a button. Previously you could press the B button and leave your inhabited body and you would be teleported to the position where you inhabited the body. I changed it so you can only exit a body when you're inside of the HUB.

```
    public void ExitBody(InputAction.CallbackContext obj)
    {
        if (!playerData.inRoom)
        {
```

## Final result

This is how the portal effect looked, without the Tirso's shader on it while entering the echolocation room.

![](https://708397551-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MjnIU3pkRtiaeZ6PEEt%2Fuploads%2FYFIGiUwVIElM1AEcbmbR%2FEchocavePortal.gif?alt=media\&token=3a2c7ab8-0551-47a1-8232-9b20c8342c66)

And here is how it looks with the shader:

![](https://708397551-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MjnIU3pkRtiaeZ6PEEt%2Fuploads%2FrTYaWW2Y8XwG0qxBPIBX%2FPortalGIF.gif?alt=media\&token=e17d765e-0fc6-44b5-83aa-3776508d2c34)
