For starters there was a lot wrong in the scene.
-
The collider’s that acted as the portals were not set to be ‘trigger’. So instead they were solid and you couldn’t walk through them.
-
The render plane’s had colliders on them as well, so those too blocked you from walking through.
-
Your player was not tagged ‘Player’, which your code required.
-
Everything was rotated really weird.
Once that was all said and fixed. Your script worked.
Well… it technically worked. It teleported you, and at the positions of your portals as they are it worked. Because there was no rotational difference between them.
BUT, if you oriented the doors differently it broke since your rotation code doesn’t do what you assume it does.
I also don’t think you should use Update like that though…
So I rewrote it:
using UnityEngine;
using System.Collections.Generic;
public class Portal : MonoBehaviour
{
[Tooltip("Tag mask to test for, leave blank if dont' want to filter.")]
public string TagMask;
public Transform TargetLocation;
public Camera PortalCamera;
public Renderer PortalVisualSurface;
#region Messages
private void Start()
{
if(this.PortalCamera.targetTexture != null)
{
this.PortalCamera.targetTexture.Release();
}
this.PortalCamera.targetTexture = new RenderTexture(Screen.width, Screen.height, 24);
this.PortalVisualSurface.material.mainTexture = this.PortalCamera.targetTexture;
}
private void LateUpdate()
{
var cam = Camera.main; //get the main rendering camera... we're going to be positioning based off this
var q = Quaternion.LookRotation(-this.TargetLocation.forward, this.TargetLocation.up);
var dq = Quaternion.Inverse(this.transform.rotation) * q;
//update pos
var dv = cam.transform.position - this.transform.position;
dv = dq * dv;
this.PortalCamera.transform.position = this.TargetLocation.position + dv;
//update rot
this.PortalCamera.transform.rotation = dq * cam.transform.rotation;
//make sure camera projection matches
this.PortalCamera.projectionMatrix = cam.projectionMatrix;
}
private void OnTriggerEnter(Collider other)
{
if (string.IsNullOrEmpty(this.TagMask) || other.CompareTag(this.TagMask))
{
var targ = other.transform;
float dotProduct = Vector3.Dot(transform.forward, targ.position - transform.position);
if (dotProduct > 0f)
{
var q = Quaternion.LookRotation(-this.transform.forward, this.transform.up);
var dq = Quaternion.Inverse(q) * this.TargetLocation.rotation;
//update position
var dv = targ.position - this.transform.position;
dv = dq * dv;
targ.position = this.TargetLocation.position + dv;
//update rot
targ.rotation = dq * targ.rotation;
UnityEngine.EventSystems.ExecuteEvents.Execute<ITeleportMessageReceiver>(targ.gameObject, null, (x, y) => x.Teleported(this));
}
}
}
#endregion
public interface ITeleportMessageReceiver : UnityEngine.EventSystems.IEventSystemHandler
{
void Teleported(Portal portal);
}
}
Note - when I fixed the rotations, I made the portal’s forward be the forward of its transform rather than up.
I also scrapped your PortalTextureSetup, PortalCamera, and PortalTeleporter. Instead putting everything in the ‘Portal’ class I wrote.
-
PortalTextureSetup, this was a generic adhoc class that you set globally. The way you had it, you’d have to have edit this PortalTextureSetup with every portal you added. And you’d have to have a adhoc version for every scene.
-
PortalCamera - I could have left this a separate class from Portal. It’s effectively the ‘LateUpdate’ portion of my Portal class. I just stuck it in one place, because a Portal will always have a PortalCamera. It’s part of what makes it a Portal. You can’t have one with out the other.
I also made some major changes to how the portal is rendered… see the code.
- PortalTeleporter - basically became Portal, and was cleaned up.
Also the MouseLook of the FirstPersonController is not directly compatible. You need to add a public method that allows updating the current rotations of MouseLook. This came from the stanard assets I presume… but yeah, it wasn’t made with portals in mind.
I use the ITelepoertMessageReceiver to do this, by attaching this script to the Player:
using UnityEngine;
using System.Collections.Generic;
public class FirstPersonTeleportReceiver : MonoBehaviour, Portal.ITeleportMessageReceiver
{
public UnityStandardAssets.Characters.FirstPerson.FirstPersonController Controller;
void Portal.ITeleportMessageReceiver.Teleported(Portal portal)
{
this.Controller.MouseLook.Init(this.transform, Camera.main.transform);
}
}
Note - this requires that m_MouseLook on FirstPersonController is uncovered with a public property.
…
I tried sending you a pull request for a branch with my changes, but you have your github configured to block pull requests. (I get a permission denied error)