Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
7
Question by demize2010 · Apr 06, 2012 at 01:11 PM · collisionphysicsplatformer

One Way Collider

Hey guys,

I was wondering if anyone had any incite on doing a 1 way collider.

The effect we're trying to imitate is akin to old 2D platformers - eg you can jump up onto a platform from below but when coming from on high the platform gives you collision and stops you.

We are using physics for the character control (custom actor motors) and have tried a plane collider (where collision is given based on the direction of the normals) and this works but is a bit messy - characters have a habbit to "pop" up through it at a non even rate.

Any bright chaps have an idea or two?

Muchley appreciated.

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

5 Replies

· Add your reply
  • Sort: 
avatar image
10

Answer by Bunny83 · Apr 18, 2012 at 12:48 PM

Just in addition to Kleptomaniacs answer:

I've just written a small script that takes the Mesh of the GameObjects MeshFilter, create a duplicate and removes all faces which facenormals have a greater angle to the upvector than maxAngle. This mesh is assigned to the MeshCollider.

Setting maxAngle to 0 will remove all faces. Setting it to 45 it will just keep the faces that points upwards and aren't steeper than 45°

I've tested it with the buildin cube mesh. I've just created a cube object, replaced the boxcollider with a meshcollider and attached my script. Turn of the meshrenderer at runtime and select the object to see the collision mesh.

 //C#
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class PlatformCollision : MonoBehaviour
 {
     public float maxAngle = 45.0f;
     void Start ()
     {
         float cos = Mathf.Cos(maxAngle);
         MeshFilter MF = GetComponent<MeshFilter>();
         MeshCollider MC = GetComponent<MeshCollider>();
         if (MF == null || MC == null || MF.sharedMesh == null)
         {
             Debug.LogError("PlatformCollision needs a MeshFilter and a MeshCollider");
             return;
         }
         Mesh M = new Mesh();
         Vector3[] verts = MF.sharedMesh.vertices;
         List<int> triangles = new List<int>(MF.sharedMesh.triangles);
         for (int i = triangles.Count-1; i >=0 ; i -= 3)
         {
             Vector3 P1 = transform.TransformPoint(verts[triangles[i-2]]);
             Vector3 P2 = transform.TransformPoint(verts[triangles[i-1]]);
             Vector3 P3 = transform.TransformPoint(verts[triangles[i  ]]);
             Vector3 faceNormal = Vector3.Cross(P3-P2,P1-P2).normalized;
             if (Vector3.Dot(faceNormal, Vector3.up) <= cos)
             {
                 triangles.RemoveAt(i);
                 triangles.RemoveAt(i-1);
                 triangles.RemoveAt(i-2);
             }
         }
         M.vertices = verts;
         M.triangles = triangles.ToArray();
         MC.sharedMesh = M;
     }
 }
Comment
Add comment · Show 6 · 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 demize2010 · Apr 22, 2012 at 10:36 PM 0
Share

Looks like some serious work you've done there! Thank you! Will give this a go ASAP!

avatar image Kleptomaniac · Apr 23, 2012 at 10:41 AM 0
Share

Wow @Bunny83! A very nice answer! $$anonymous$$akes my link seem inferior! :D

avatar image Bunny83 · Apr 23, 2012 at 10:49 AM 0
Share

I just thought duplicating and editing meshes in an external application is not a very fast workflow. The solution is yours, i've just automated it ;)

btw: I don't remove the vertices since they could be shared by other tirangles. Finding isolated vertices is possible but needs some more fiddling ;)

avatar image aldonaletto · May 20, 2012 at 01:40 AM 0
Share

Nice solution!

avatar image Bunny83 · May 20, 2012 at 01:50 AM 0
Share

Thanks ;) Just realized that i have a newer version on my pc. I will update the script. The old one doesn't have the maxangle variable.

Show more comments
avatar image
2

Answer by Kleptomaniac · Apr 06, 2012 at 02:34 PM

May be a bit of a hacky solution but this may help ... there has got to be a better way to do it though ...

Hope that helps, Klep

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 demize2010 · Apr 22, 2012 at 10:35 PM 0
Share

Thanks man, that's kinda what I tried but I found that my capsule collider got stuck half way :(

avatar image Bunny83 · Apr 23, 2012 at 10:34 AM 0
Share

@demize2010 do you use a CharacterController? I've tested it with rigidbodies and it works fine. The CharacterController is not a real physics object. I haven't tested it yet but i thing it should work as well.

avatar image
0

Answer by jasperstocker · Apr 06, 2012 at 02:04 PM

I think your best option is to disable the platform when your character is below it and enable it only when you know he is able to stand on it. You could use his Y coordinate to work out if he is high enough. A really easy solution if your character origin is at his feet - you can test the point is above the platform collider box. Or use a capsule collider trigger to test if it's above and not inside the platform.

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 demize2010 · Apr 06, 2012 at 02:20 PM 0
Share

Thanks man, problem is that the platforms need to provide constant projectile and NPC collision detection, so switching them on and off isn't really an option :(

avatar image jasperstocker · Apr 18, 2012 at 10:42 AM 0
Share

what about separating out the collisions for NPC/Bullets and the player.Have one box only for the player using layers in the physics settings and the other is always on and collides with everything but the player. A bit complex but it would work.

avatar image
0

Answer by jimmay · Oct 12, 2012 at 04:59 PM

Slight modifications to Bunny83's great example. This allows collisions from top or bottom and only requires a mesh collider. I am using this for sprites, so I set the meshCollider mesh field to use a cube.

 using UnityEngine;
 using System.Collections.Generic;
 
 [RequireComponent (typeof (MeshCollider))]
 public class PlatformCollision : MonoBehaviour
 {
     public bool topCollision = true;
     public float maxAngle = 45.0f;
     
     void Start ()
     {
         float cos = Mathf.Cos(maxAngle);
         MeshCollider MC = GetComponent<MeshCollider>();
         if (MC == null)
         {
             Debug.LogError("PlatformCollision needs a MeshCollider");
             return;
         }
         Mesh M = new Mesh();
         Vector3[] verts = MC.sharedMesh.vertices;
         List<int> triangles = new List<int>(MC.sharedMesh.triangles);
         for (int i = triangles.Count-1; i >=0 ; i -= 3)
         {
             Vector3 P1 = transform.TransformPoint(verts[triangles[i-2]]);
             Vector3 P2 = transform.TransformPoint(verts[triangles[i-1]]);
             Vector3 P3 = transform.TransformPoint(verts[triangles[i  ]]);
             Vector3 faceNormal = Vector3.Cross(P3-P2,P1-P2).normalized;
             if ( (topCollision && Vector3.Dot(faceNormal, Vector3.up) <= cos) ||
                  (!topCollision && Vector3.Dot(faceNormal, -Vector3.up) <= cos) )
             {
                 triangles.RemoveAt(i);
                 triangles.RemoveAt(i-1);
                 triangles.RemoveAt(i-2);
             }
         }
         M.vertices = verts;
         M.triangles = triangles.ToArray();
         MC.sharedMesh = M;
     }
 }
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 sattri99 · Dec 30, 2013 at 09:22 AM

I've made a tutorial recently of how to make efficient one way collider for d game with source code (project folder) on my physicist3d.blogspot.com . It's the best way of making effeicient one way collided. Link to my tutorial --- link text

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

9 People are following this question.

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

Related Questions

2D 360 degress platformer example needed 0 Answers

How to prevent Character Controller from falling through moving Platforms? 4 Answers

Character falling through moving object using iTween 1 Answer

How to deal the 2d platform physics? 0 Answers

Collision impact force 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