• 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 /
avatar image
1
Question by saberboy117 · Apr 26, 2011 at 12:27 AM · physics

Portal Physics Effect.

Is there anyway to make a portal Effect in the physics engine, like in the Valve game, so things just move on through them? probably not, but just wondering.

thanks

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

4 Replies

· Add your reply
  • Sort: 
avatar image
6

Answer by DavidDebnar · Mar 28, 2013 at 01:46 PM

To create a Portal like visual effect, you unfortunately need Unity Pro because of render textures. To do this, you'd create a camera pointing outwards from Portal B, save it to a render texture and apply it as the texture of Portal A and vise versa.

To allow objects to pass trough the portal, you need to place a trigger collider on both portals. A script would then detect if an object hit the portal and create a second duplicate of the object, to create an illusion of smoothly walking trough the portal.

Then it needs to preserve the velocity of the object, make it point out of the second portal and pass it to the duplicate.

An example:

 var velocity = rigidbody.velocity;
 velocity = Vector3.Reflect(velocity,currentPortal.forward);
 velocity = currentPortal.InverseTransformDirection(velocity);
 velocity = otherPortal.TransformDirection(velocity);
 rigidbody.velocity = velocity;

In this example I take the original object's velocity, reflect it to the forward direction of the portal using the Vector3.Reflect function, inverse it, align it to otherPortal's direction and assign it.

Also make sure that the position is updated correctly. The code for it is very similar to the code that preserves the velocity.

 var pos : Vector3 = currentPortal.position - transform.position;
 pos = Vector3.Reflect(pos, currentPortal.forward);
 pos = otherPortal.TransformDirection(pos);
 pos += otherPortal.position;
 myDuplicate.position = pos;

It takes the direction between the object and the portal. Reflects it to the second portal and moves it to the second portal.


Simple example

Both examples work with Unity Free and don't need Unity Pro, because the code handling render textures isn't included.

Before using the either of these following scripts create tags "PortalA" and "PortalB" - apply them to the portals and assign the script to a rigidbody entity.

 public var ignoreTime : float = 1;
 
 function OnTriggerStay(c : Collider) {
     if(c.CompareTag("PortalA") || c.CompareTag("PortalB")) {
         var otherPortal : Transform = GameObject.FindGameObjectWithTag(c.CompareTag("PortalA")?"PortalB":"PortalA").transform;
         transform.localEulerAngles += Quaternion.LookRotation(otherPortal.forward).eulerAngles;
         transform.position = otherPortal.TransformDirection(Vector3.Reflect(c.transform.position - transform.position, c.transform.forward)) + otherPortal.position;
         rigidbody.velocity = otherPortal.TransformDirection(c.transform.InverseTransformDirection(Vector3.Reflect(rigidbody.velocity,c.transform.forward)));
         Physics.IgnoreCollision(collider,otherPortal.collider,true);
         yield WaitForSeconds(ignoreTime);
         Physics.IgnoreCollision(collider,otherPortal.collider,false);
     }
 }


Full example [TeleportableEntity.js]

 class TeleportableEntity extends MonoBehaviour {
     
     public var myDuplicate : Transform;
     public var currentPortal : Transform;
     public var otherPortal : Transform;
 
     private var shouldUpdate : boolean = false;
     private var initialPosition : Vector3;
 
     function UpdateDuplicate() {
         shouldUpdate = true;
 
         while(myDuplicate != null && shouldUpdate) {
             if(!shouldUpdate) break;
             ForceUpdateDuplicate();
             yield;
         }
     }
 
     function ForceUpdateDuplicate() {
         var rot : Vector3 = Quaternion.LookRotation(otherPortal.forward).eulerAngles;
         rot += transform.localEulerAngles;
         myDuplicate.localEulerAngles = rot;
         
         var pos : Vector3 = currentPortal.position - transform.position;
         pos = Vector3.Reflect(pos, currentPortal.forward);
         pos = otherPortal.TransformDirection(pos);
         pos += otherPortal.position;
         myDuplicate.position = pos;
     }
 
     function CreateDuplicate () {
         myDuplicate = Instantiate(transform, transform.position, transform.rotation) as Transform;
         Destroy(myDuplicate.GetComponent(TeleportableEntity));
         Destroy(myDuplicate.collider);
         UpdateDuplicate();
     }
 
     function OnTriggerEnter (c : Collider) {
         if(myDuplicate != null || shouldUpdate) return;
 
         if(c.CompareTag("PortalA"))
             otherPortal = GameObject.FindGameObjectWithTag("PortalB").transform;
         else if(c.CompareTag("PortalB"))
             otherPortal = GameObject.FindGameObjectWithTag("PortalA").transform;
         else return;
 
         currentPortal = c.transform;
 
         initialPosition = transform.position;
 
         CreateDuplicate();
     }
 
     function OnTriggerExit (c : Collider) {
         if(currentPortal != null && c == currentPortal.collider) {
             shouldUpdate = false;
 
             if((currentPortal.position - transform.position).magnitude < (initialPosition - transform.position).magnitude) {
 
                 ForceUpdateDuplicate();
 
                 transform.position = myDuplicate.position;
                 transform.rotation = myDuplicate.rotation;
                 
                 var velocity = rigidbody.velocity;
                 velocity = Vector3.Reflect(velocity,currentPortal.forward);
                 velocity = currentPortal.InverseTransformDirection(velocity);
                 velocity = otherPortal.TransformDirection(velocity);
                 rigidbody.velocity = velocity;
             }
 
             DestroyDuplicate();
         }
     }
 
     function DestroyDuplicate () {
         Destroy(myDuplicate.gameObject);
 
         myDuplicate = null;
 
         currentPortal = null;
         otherPortal = null;
     }
 }


--David

Comment
Add comment · Show 22 · 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 luniac · Mar 28, 2013 at 11:48 PM 0
Share

If i didn't have unity pro but at least want the portal to act like a portal, the magic is these lines right?

  var velocity = rigidbody.velocity;
 velocity = Vector3.Reflect(velocity,currentPortal.forward);
 velocity = currentPortal.InverseTransformDirection(velocity);
 velocity = otherPortal.TransformDirection(velocity);
 rigidbody.velocity = velocity;
   
avatar image luniac · Mar 29, 2013 at 12:04 AM 0
Share

Actually that code didn't do anything at all... I could have just as easily did trigger.gameObject.transform.position = otherPortal.transform.position;

Using your code, if i drop an object into the portal and the other portal is flat on the floor, the ball wont jump out into the air... it just keeps falling down.

avatar image luniac · Mar 29, 2013 at 12:07 AM 0
Share

Oh wait a $$anonymous$$ute, i didn't realize i have to put the exit portal upside down locally, so when the y axis is pointing down the object flies out into the opposite direction. It appears to work if i just drop the ball in, im going to try some angles.

avatar image luniac · Mar 29, 2013 at 12:12 AM 0
Share

Yea angles work, heres the simple version for people with INDI$$anonymous$$

 //Teleport.js
 
 #pragma strict
 var otherPortal : GameObject;
 
 function OnTriggerEnter(trigger : Collider) 
 { 
     if(trigger.gameObject.tag == "Player")
     {
         trigger.transform.position = otherPortal.transform.position; 
         var velocity : Vector3 = trigger.rigidbody.velocity;
         velocity = Vector3.Reflect(velocity,trigger.transform.forward);
         velocity = transform.InverseTransformDirection(velocity);
         velocity = otherPortal.transform.TransformDirection(velocity);
         trigger.rigidbody.velocity = velocity;
                 
     }
avatar image DavidDebnar · Mar 29, 2013 at 07:46 AM 0
Share

no, actually, you need the whole thing for it to work properly. I didn't include the code that handles the render textures, so my code is indie too ;)

Show more comments
avatar image
1

Answer by Joshua · Apr 26, 2011 at 12:34 AM

Do you mean create two portals, have the view as if looking out of the other portal when looking into the one portal and have objects go through the portal and come out the other one?

For the visible effect use two cameras that go to the portals position, for the teleportation effect use a trigger and transform position. To render a cameras view as a texture you'd need Unity pro though, I think.

Comment
Add comment · Show 1 · 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 Flafla2 1 · Apr 26, 2011 at 01:09 AM 0
Share

Yeah, you need unity pro. If you want to make a simple effect though, you should be fine.

avatar image
1

Answer by taoa · May 05, 2011 at 12:15 PM

Try this for the closest 'visual effect' of portal you can do in Unity.

Comment
Add comment · Show 2 · 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 fireDude67 · Aug 21, 2011 at 10:24 PM 0
Share

QATO seemed to have broken your link.

avatar image AlucardJay · Mar 28, 2013 at 05:34 AM 0
Share

The above link is broken, here it is : http://answers.unity3d.com/questions/39509/portal-2-how-to-make-a-portal-in-unity-3d.html

avatar image
0

Answer by Peter G · Apr 26, 2011 at 01:15 AM

It is very doable. But it could become a somewhat complicated procedure. If you want to keep it simple, I would try this. Find the magnitude of the velocity as an object enters the portal, then move the object to the portal and set its velocity to the portal's normal times the magnitude we just recorded:

var otherPortal : Transform; var normal : Vector3; //You can get this various ways, but you will need a surface normal //transform.forward would probably work.

function OnTriggerEnter (col : Collider) { var velocity : float = col.rigidbody.velocity.magnitude; //var velocity : float = col.GetComponent<CharacterController>().velocity.magnitude; col.transform.position = otherPortal.position;

  col.rigidbody.velocity = otherPortal.GetComponent.&lt;ThisScript&gt;().normal * velocity;
  //col.GetComponent&lt;CharacterController&gt;().Move(otherPortal.GetComponent.&lt;ThisScript&gt;().normal * velocity * Time.deltatime);

}

This is a really simple script. It takes the velocity an object enters the first portal at and shoots it out the second portal along its normal at the same velocity. The only thing you lose is the possibility of entering the portal at an angle. That can be solved but requires some more math that I can try to replicate if you would like.

Comment
Add comment · Show 4 · 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 CHPedersen · May 05, 2011 at 01:18 PM 0
Share

Agreed, achieving an instant teleport isn't very hard. Here's a real challenge, though. :)

How would you teleport fluidly, i.e. teleport only the part of character model that has entered the portal? (Enabling you to "stick your head through", and the head appears at the other portal, but the body remains)

avatar image Peter G · May 05, 2011 at 01:41 PM 0
Share

Through blood sweat and $$anonymous$$rs. It would take some major procedural mesh generation or you could instantiate a new object at the portal and delete the old one when it is entirely through the hole.

avatar image luniac · Mar 28, 2013 at 01:46 AM 0
Share

So did you get it working at angles?

avatar image Aurelio_hl2 · Nov 20, 2013 at 01:47 AM 0
Share

If a "portal" rotates and the other not, rotate the object. How would the scrip?, To turn Portal and the other not, without affecting the position of the object, between portals.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

7 People are following this question.

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

Related Questions

2D 360 degress platformer example needed 0 Answers

Help with orbits 1 Answer

make addforce ignore player controller? 1 Answer

Would it be possible to record animations in playmode? 1 Answer

OnCollisionEnter isn't working between two RigidBodies 1 Answer


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