Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
avatar image
1
Question by Catlard · Oct 16, 2011 at 07:14 AM · collisionontriggerenternormalsignorecollisioncontact.point

Using Contact Point normals to allow for player jumping through platforms?

Anybody know a better way to do this? I'd love to hear your idea. Here's how I'm doing it:

I've got a script that causes my player object's rigidbody to be able to pass through platforms that he's jumping up to. Basically, it works by checking to see if the player's y position is less than or greater than the platform. It's a simple fix. But because a platform's position is technically at the center of it's bounding box, and a rigidbody's position is technically the center of ITS bounding box, my script doesn't work properly when my player attempts to jump into the platform from the upper corner--since the script detects that the y position of the rigidbody is higher, and therefore the platform should be solid.

So, I think my problem is that I can't use contact point normals to detect a player's point of entry to a trigger because you can't get those when you're just using OnTriggerEnter. Is this correct?

Help!

Here's my script:

 var floorOfPlatform;
 var playerObject;
 function Start()
 {
          if(gameObject == "puzzlePlatformTrigger")
     {
         floorOfPlatform = gameObject.transform.parent.gameObject.transform.Find("puzzleFloor");
     }
     if(gameObject == "jumpThroughTrigger")
     {
         floorOfPlatform = gameObject.transform.parent.gameObject.transform.Find("basicPlatform");
     } 
     if(floorOfPlatform == null)
     {
         floorOfPlatform = gameObject.transform.parent.gameObject.transform.Find("Puzzle Platform Floor");
     }
     playerObject = GameObject.Find("playerRigidBody");
 }
 
 function OnTriggerEnter(other: Collider)
 {
     if(playerObject.transform.position.y < floorOfPlatform.transform.position.y) 
     {
         Physics.IgnoreCollision(playerObject.collider, floorOfPlatform.collider, true);
     }
 }
 
 function OnTriggerExit()
 {
     Physics.IgnoreCollision(playerObject.collider, floorOfPlatform.collider, false);
 }
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
Best Answer

Answer by kromenak · Oct 16, 2011 at 09:13 AM

I'm a little confused from the code whether your platform is using a solid collider or a collider set as a trigger. If it is a solid collider, you could use OnCollisonEnter/Exit to get the contact points and normals. The problem I see there is that the collision itself would slow down the moving character, so you'd probably have to manually adjust the rigidbody velocity to account for that.

Another possibility might be, assuming you have this script attached to all your platforms, is to have the platform script check in Update or FixedUpdate what the current bounds of the player is and, if they are above the platform, make it solid. This way, all platforms above the player will always be possible to jump through. You could have a flag for platforms without this characteristic or vise-versa.

(Sorry for the C#, but my Javascript is very rusty. Concepts are the same.)

 GameObject player;
 void Update()
 {
     /* if the player is made up of more than one collider, you'd
        need to iterate over the colliders and use playerBounds.Encapsulate()*/
     Bounds playerBounds = player.collider.bounds;

     //check bottom of player to see if it is above the platform
     if(playerBounds.min.y >= collider.bounds.max.y)
     {
         //make the platform solid
     }
     else
     {
         //turn off platform collision
     }
 }

This code is untested, just me thinking through the problem, but I think it would work.

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 Matt-Downey · Mar 24, 2012 at 12:05 AM

A good way to do this would be to collide if Vector3.Dot (or Vector2.Dot) of Player.velocity && rayInfo.normal (for a simple raycast) is less than 0. In order for this to work you need to go into Edit-->Project Settings-->Physics and turn on the toggle for "raycast hits triggers."

 var Trans : Transform;
 
 //or alternatively use:
 
 private var Trans : Transform;
 
 Trans = transform; //will not work with #pragma strict
 
     function FixedUpdate ()
         {
         var rayInfo : RaycastHit;
         var halfHeight : float = 1; //One half the player's height
         if(Physics.Raycast(Trans.position + (0.05 - halfHeight)*Vector2.up, -Vector2.up, rayInfo, 0.05)
             {
             Collide(Vector2(0,0)); //collide with a motionless platform if the dot is zero
             //INSERT Disable gravity code here
             }
         }

My collide code will help. It takes in a platform relative velocity variable, so if you want moving platforms, you can.

You can not just plug in these functions and see everything magically work. Personally, I think you should work to understand this code. I presume you are working in 2D, if not then should read up on 3D dot products.

Learn Dot Products, they essentially check if two vectors (such as velocity vectors and normal vectors (in this case) are facing in the same direction). For two normalized vectors, if the dot product is 1, they are parallel (0 degrees), dot product of -1 means the vectors are going away from each other (180 degrees)[which is what we are checking for], 0 means perpendicular (90 degrees or 270 degrees)

         function Collide (relVel : Vector2)
             {
             Cross(controller.perceivedNormal);
             if(Vector2.Dot(controller.perceivedNormal,Vector3(controller.velocity.x - relVel.x,controller.velocity.y -relVel.y,0)) < 0)
                 {
                 controller.velocity = relVel + Vector3.Project(Vector3(controller.velocity.x - relVel.x,controller.velocity.y  - relVel.y,0),Vector3(controller.moveDir.x,controller.moveDir.y,0));
                 }
             }
     
     function Cross () //this is a Cross Product that is optimized for 2D
 //it finds "rightward" and thus might be irrelevant in your game
 //if platforms are not slanted
         {
         controller.moveDir = Vector2(normal.y,-normal.x);
         }

This is a makeshift post which has not been catered to the variables in the OP, so you will have to change the functions a little (who knows maybe a lot).

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Collision with no contact? 2 Answers

How to only delete one of two collided objects? 1 Answer

Overlap point of 2 kinematic colliders 1 Answer

OnTriggerEnter not firing if rigidbody is on its side 0 Answers

OnTriggerEnter detection too late 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