Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by Greenie · Nov 12, 2017 at 01:19 AM · architectureportallevel design

Impossible Architecture

Hey everyone,


So I've been playing a lot of Davey Wreden and William Pugh's games over the last week or so and love their clever use of "impossible architecture". By this I mean hallways that twist without ever crossing back over themselves, rooms that endlessly repeat, areas that are bigger on the inside etc.


"Bigger on the inside" hallway
Endless Hallway


Now I assume that this is just using well hidden portals of sorts where you have a camera moving relative to the player rendered on a plane and a trigger collider to teleport you to another place. Is there a better way to do this or should I follow that route?


Cheers in advance!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Nov 12, 2017 at 01:18 PM

In general the main solution is teleporting as you already mentioned. Visual portals are not necessarily required if you have a clever map design. However in certain situations you just don't have enough room to only use map design as you would have to duplicate large portions of the map or you can't have the transition points too close together.


So your first example video would be hard / almost impossible without visual portals.

The second one (from what we have seen) would be possible just by level design + teleport. Though since it's made with source they might also simply use portals.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Greenie · Nov 14, 2017 at 04:38 AM

Ok so I have made myself a little game where you can wander around and in one direction there is an endless hallway, in the other is a "bigger on the inside" corridor. I didn't use any portals for the hallway, a simple teleport was far easier. However for the corridor of course a teleport was necessary. Works ok but is quite obvious there is a plane there.


Firstly there's a slight white tint to it. not sure where it's coming from but it looks like you're looking through a window.


Secondly, when facing one direction the camera rotation seems to be a frame out and so you see outside the hallway. I have no idea why this is happening though.


Here is a video demonstrating what I have so far and the issues with it


The lag on the other cameras is the biggest issue, how can I stop that? Induced all my code for reference.


 using System;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.SceneManagement;
 
 public class portal : MonoBehaviour {
 
     public RenderTexture rt;
     public GameObject thisPortal;
     public GameObject otherPortal;
     public Shader cropShader;
     public Boolean inPortal;
     public float distance;
     public float clipping;
 
     private GameObject thisPlane;
     private GameObject otherPlane;
     private GameObject player;
     private Material mat;
 
     // Use this for initialization
     void Start () {
         thisPortal = this.gameObject;
         thisPlane = thisPortal.transform.GetChild(0).gameObject;
         otherPlane = otherPortal.transform.GetChild(0).gameObject;
         player = Camera.main.transform.parent.gameObject;
         rt = new RenderTexture(Screen.width, Screen.height, 16, RenderTextureFormat.ARGB32);
     }
 
     // Update is called once per frame
     void Update () {
         MoveCamera();
         Clip();
         if (IsOnScreen(thisPlane))
         {
             //Debug.Log("is on screen");
             CreateRenderTexture();
             
         }
         else
         {
             //Debug.Log("is not on screen");
 
             DestroyRenderTexture();
         }
 
         if (Input.GetKeyDown("r"))
             SceneManager.LoadScene(0);
     }
 
 
     // When you look at the portal, switch on the camera and create the renderTexture
     private void CreateRenderTexture()
     {
 
         if (rt.IsCreated() == false)
         {
             //Debug.Log("Render texture doesn't exist... Creating");
             rt.Create();
             transform.GetChild(1).gameObject.GetComponent<Camera>().targetTexture = rt;
             transform.GetChild(1).gameObject.GetComponent<Camera>().enabled = true;
 
             mat = new Material(cropShader);
             mat.mainTexture = rt;
             thisPlane.GetComponent<MeshRenderer>().material = mat;
         }
     }
 
     // When you are not looking at the portal, delete the texture and turn off the camera to save resources
     private void DestroyRenderTexture()
     {
 
         if (rt.IsCreated())
         {
             //Debug.Log("Render texture exists... Releasing");
             rt.Release();
             transform.GetChild(1).gameObject.GetComponent<Camera>().enabled = false;
             transform.GetChild(1).gameObject.GetComponent<Camera>().targetTexture = null;
             thisPlane.GetComponent<MeshRenderer>().material = null;
             
         }
     }
 
     // Moves the exit portals camera so it matches the mainCamera's relative position and rotation to the entry portal
     private void MoveCamera()
     {
         var portalPos = thisPlane.transform.position;
         var otherPortalPos = otherPlane.transform.position;
         var mainCamPos = Camera.main.transform.position;
 
         var playerOffset = mainCamPos - otherPortalPos;
         otherPortal.transform.GetChild(1).position = portalPos + playerOffset;
 
         otherPortal.transform.GetChild(1).rotation = Camera.main.transform.rotation;
     }
 
     // Checks if any point of an object is on screen
     private bool IsOnScreen(GameObject obj)
     {
         // Defining top left, top right, bottom left, bottom right and middle
         Vector3 TL;
         Vector3 TR;
         Vector3 BL;
         Vector3 BR;
         Vector3 mid;
 
         // Assigning each of the above a point in world space based off the objects bounding box
         BL = Camera.main.WorldToScreenPoint(obj.GetComponent<BoxCollider>().bounds.min);
         TR = Camera.main.WorldToScreenPoint(obj.GetComponent<BoxCollider>().bounds.max);
         BR = Camera.main.WorldToScreenPoint(new Vector3(obj.GetComponent<BoxCollider>().bounds.max.x, obj.GetComponent<BoxCollider>().bounds.min.y, obj.GetComponent<BoxCollider>().bounds.max.z));
         TL = Camera.main.WorldToScreenPoint(new Vector3(obj.GetComponent<BoxCollider>().bounds.min.x, obj.GetComponent<BoxCollider>().bounds.max.y, obj.GetComponent<BoxCollider>().bounds.min.z));
         mid = Camera.main.WorldToScreenPoint(obj.GetComponent<BoxCollider>().bounds.center);
 
         // Checking if any of these points are on the screen
         if (IsBetween(BL) || IsBetween(TR) || IsBetween(BR) || IsBetween(TL) || IsBetween(mid))
         {
             return true;
         }
 
         // There is a possibility that the player is standing so close to the wall that all the points are outside their cone of vision, so we check if they are within 3 units of the portal
         else if (Vector3.Distance(transform.position, Camera.main.transform.position) < 10)
         {
             return true;
         }
 
         else
         {
             return false;
         }
     }
 
     // This method just neatens up the IsOnScreen method by doing all the repetative working
     private bool IsBetween(Vector3 v3)
     {
         // Defining the min and max width and height with a 1/3 buffer so you don't catch an untextured plane when you turn too fast
         var minWidth = 0 - Screen.width * 0.3;
         var minHeight = 0 - Screen.height * 0.3;
         var maxWidth = Screen.width + Screen.width * 0.3;
         var maxHeight = Screen.height + Screen.height * 0.3;
 
         if (v3.x > minWidth && v3.x < maxWidth && v3.y > minHeight && v3.y < maxHeight && v3.z > 0)
         {
             return true;
         }
         else
         {
             return false;
         }
     }
 
     private void Clip()
     {
         var cam = transform.GetChild(1).gameObject;
         var dist = Vector3.Distance(transform.position, Camera.main.transform.position);
         
         if(dist >= 9)
         {
             cam.GetComponent<Camera>().nearClipPlane = dist - 5.8f;
         }
         else if (dist < 9 && dist > 3)
         {
             cam.GetComponent<Camera>().nearClipPlane = dist * 0.75f;
         }
         else
         {
             cam.GetComponent<Camera>().nearClipPlane = dist * 0.5f;
         }
         distance = dist;
         
     }
 
     private void OnTriggerEnter(Collider other)
     {
         Debug.Log("in");
         if (inPortal == false)
         {
             inPortal = true;
             otherPortal.GetComponent<portal>().inPortal = true;
             player.transform.position = otherPortal.transform.position - (thisPortal.transform.position - player.transform.position);
         }
     }
 
     private void OnTriggerExit(Collider other)
     {
         Debug.Log("out");
 
         StopCoroutine("Wait");    // Interrupt in case it's running
         StartCoroutine("Wait");
         
     }
 
     IEnumerator Wait()
     {
         yield return new WaitForSeconds(1);
         inPortal = false;
         otherPortal.GetComponent<portal>().inPortal = false;
     }
 }
 


Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

120 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Creating an Auto-Restart 2 Answers

Architectural help for 2D sprite-layered animations, re: customizable characters 1 Answer

infinity walking track 0 Answers

Rotating a direction vector 0 Answers

How to structure FTL-like events? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges