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
1
Question by StivArts · Nov 13, 2017 at 01:04 AM · collision detectioncollider2dplatform2.5d

Unity Platform Effector 2D doesn't work for me

Hello, i'm trying to do a 2.5D plaftormer, for that i'm using only 2d colliders. I have a player controller script that i copied from a Unity tutorial:

 public class PhysicsObject : MonoBehaviour
 {
     [HideInInspector]
     public float minGroundNormalY = .65f;
 
     public float gravedad = 1f;
 
     protected Vector2 targetVelocity;
     protected bool grounded;
     protected Vector2 groundNormal;
     protected Rigidbody2D rb2d;
     protected Vector2 velocity;
     protected ContactFilter2D contactFilter;
     protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
     protected List<RaycastHit2D> hitBufferList = new List<RaycastHit2D>(16);
 
 
     protected const float minMoveDistance = 0.001f;
     protected const float shellRadius = 0.01f;
 
     void OnEnable()
     {
         rb2d = GetComponent<Rigidbody2D>();
     }
 
     void Start()
     {
         contactFilter.useTriggers = false;
         contactFilter.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
         contactFilter.useLayerMask = true;
     }
 
     void Update()
     {
         targetVelocity = Vector2.zero;
         ComputeVelocity();
     }
 
     protected virtual void ComputeVelocity()
     {
 
     }
 
     void FixedUpdate()
     {
         velocity += gravedad * Physics2D.gravity * Time.deltaTime;
         velocity.x = targetVelocity.x;
 
         grounded = false;
 
         Vector2 deltaPosition = velocity * Time.deltaTime;
 
         Vector2 moveAlongGround = new Vector2(groundNormal.y, -groundNormal.x);
 
         Vector2 move = moveAlongGround * deltaPosition.x;
 
         Movement(move, false);
 
         move = Vector2.up * deltaPosition.y;
 
         Movement(move, true);
     }
 
     void Movement(Vector2 move, bool yMovement)
     {
         float distance = move.magnitude;
 
         if (distance > minMoveDistance)
         {
             int count = rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
             hitBufferList.Clear();
             for (int i = 0; i < count; i++)
             {
                 hitBufferList.Add(hitBuffer[i]);
             }
 
             for (int i = 0; i < hitBufferList.Count; i++)
             {
                 Vector2 currentNormal = hitBufferList[i].normal;
                 if (currentNormal.y > minGroundNormalY)
                 {
                     grounded = true;
                     if (yMovement)
                     {
                         groundNormal = currentNormal;
                         currentNormal.x = 0;
                     }
                 }
 
                 float projection = Vector2.Dot(velocity, currentNormal);
                 if (projection < 0)
                 {
                     velocity = velocity - projection * currentNormal;
                 }
 
                 float modifiedDistance = hitBufferList[i].distance - shellRadius;
                 distance = modifiedDistance < distance ? modifiedDistance : distance;
             }
 
 
         }
 
         rb2d.position = rb2d.position + move.normalized * distance;
     }
 
 }

The player script:

 public class PlayerPlatformerController : PhysicsObject
 {
     
     public int playerId;
     public float velocidadMax = 7;
     public float salto = 7;
 
     private SpriteRenderer spriteRenderer;
     private Animator animator;
 
     // Use this for initialization
     void Awake()
     {
         spriteRenderer = GetComponent<SpriteRenderer>();
         animator = GetComponent<Animator>();
     }
 
     protected override void ComputeVelocity()
     {
         Vector2 move = Vector2.zero;
 
         move.x = Input.GetAxis("Horizontal"+playerId);
 
         if (Input.GetButtonDown("Jump"+playerId) && grounded)
         {
             velocity.y = salto;
         }
         /*else if (Input.GetButtonUp("Jump"))
         {
             if (velocity.y > 0)
             {
                 velocity.y = velocity.y * 0.5f;
             }
         }*/
 
         /*bool flipSprite = (spriteRenderer.flipX ? (move.x > 0.01f) : (move.x < 0.01f));
         if (flipSprite)
         {
             spriteRenderer.flipX = !spriteRenderer.flipX;
         }*/
         if (move.x > 0.02f)
         {
             spriteRenderer.flipX = false;
         }
         if(move.x < -0.02f)
         {
             spriteRenderer.flipX = true;
         }
         animator.SetBool("grounded", grounded);
         animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / velocidadMax);
         animator.SetFloat("velocityY", velocity.y);
 
         targetVelocity = move * velocidadMax;
     }
 }

alt text

alt text

So when i try to pass-trought the platform I can't, it detects it like a normal collision. What am i doing wrong?

(This is my first question, sorry if i am breaking some rule)

screenshot-5.jpg (13.2 kB)
screenshot-3.jpg (35.4 kB)
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 codemite · Nov 23, 2017 at 08:24 PM

You'll have to manually check for the platform, since you're not relying on the inner physics engine. Something like this might work before adding the collisions

 PlatformEffector2D platform = hitBuffer[i].collider.GetComponent<PlatformEffector2D>();
 if (!platform || 
     (hitBuffer[i].normal == Vector2.up 
     && velocity.y < 0 && yMovement)) //only when going down
 { 
     hitBufferList.Add(hitBuffer[i]); // get the colliding objects
 }
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 davidson27 · May 18, 2018 at 09:52 PM 1
Share

I used the same tutorial as the OP and this solution works. I made the following changes to the $$anonymous$$ovement function in the PhysicsObject script

 void $$anonymous$$ovement(Vector2 move, bool y$$anonymous$$ovement){
         float distance = move.magnitude;
         if(distance>$$anonymous$$$$anonymous$$oveDistance)
         {
             int count = rb2d.Cast(move, contactFilter, hitBuffer, distance+shellRadius);
             hitBufferList.Clear();
 
             for (int i = 0; i<count;i++){
 
                 // This line and the if statement will check if a platform has a PlatformEffector2D.
                 // If it does, it will allow the player to jump up from underneath, but not fall through
                 // the top surface
                 PlatformEffector2D platform =hitBuffer[i].collider.GetComponent<PlatformEffector2D>();
                 if(!platform||(hitBuffer[i].normal == Vector2.up && velocity.y < 0 && y$$anonymous$$ovement)){
 
                     hitBufferList.Add (hitBuffer[i]);
 
                 }
 
 
             }
 
             for (int i = 0; i<hitBufferList.Count; i++)
             {
 
                 Vector2 currentNormal = hitBufferList[i].normal;
                 if(currentNormal.y>$$anonymous$$GroundNormalY)
                 {
                     grounded = true;
                     if(y$$anonymous$$ovement){
                         groundNormal = currentNormal;
                         currentNormal.x=0;
                     }
                 }
                 float projection = Vector2.Dot(velocity, currentNormal);
                 if(projection < 0){
 
                     velocity = velocity - projection * currentNormal;
 
                 }
                 float modifiedDistance = hitBuffer[i].distance - shellRadius;
                 distance = modifiedDistance < distance ? modifiedDistance : distance;
             }
 
         }
         rb2d.position = rb2d.position + move.normalized * distance;
     }



Also I made a further edit because didn't want to add platformeffectors to everything I had made already. If you change this line

 PlatformEffector2D platform = hitBuffer[i].collider.GetComponent();


to this line.

 BoxCollider2D platform = hitBuffer[i].collider.GetComponent ();


you do not have to add PlatformEffectors to every platform and you can still jump through the bottom, without falling through the top. Which might be easier on your computer computationally.

avatar image Beks_Omega davidson27 · Jul 31, 2018 at 05:53 PM 0
Share

I found that switching:

 if (!platform||(hitBuffer[i].normal == Vector2.up && velocity.y < 0 && y$$anonymous$$ovement))
 {
     hitBufferList.Add (hitBuffer[i]);
 }

to:

 if(!platform||(hitBuffer[i].normal == Vector2.up && velocity.y <= 0))
 {
      hitBufferList.Add (hitBuffer[i]);
 }

. kept the character from falling through platforms

avatar image
0

Answer by Cuttlas-U · Apr 27, 2020 at 07:41 AM

For some reason the comparing part didnt work for me ! I mean this :

 hitBuffer[i].normal == Vector2.up 

so i ended up using vector2.distance < 0.01f instead ,

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

125 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 avatar image avatar image avatar image avatar image avatar image

Related Questions

2D colliders doesnt work with Gravity Scale = 0 0 Answers

Camera for 2.5D 2P Platformer 0 Answers

How to kill player (and or end game) when enemy hits the ground? JAVASCRIPT 1 Answer

Unity 2D does not detect collisions 0 Answers

Enemies spawning on top of each other,Enemies spawn on top of each other 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