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 helios · Apr 19, 2012 at 02:02 PM · pixelcollisionsraycasts

Pixel Perfect Collision Possible?

Hello, I have been trying for a little while now to achieve precise collision for a 2D platforming game with an orthographic camera, but I just can't seem to get it to behave how I want. The only way I have been able to get perfect collision is by using a CharacterController, which I can't use because of the limitations of the capsule shape. Also, I don't like the reactions by adding forces, so I am trying to manually set the velocity, or manually translate the object.

The Problem:

When landing from a jump, the character sometimes dips below into the ground, before snapping back up to ground level. This happens randomly, maybe 60% of the time. This is visually not good.

What I've Tried:

I have tried setting the velocity manually and then using Raycasts to detect the ground, and if the ground is present, just set the Y velocity to zero. I have also tried just translating the object and using Raycasts to detect the ground. Here is a real quick example you can test to demonstrate I am talking about:

1) Add another cube , make it smaller to use as the player. Add a rigidbody, disable gravity, constrain Z position and X,Y,Z rotation

2) Add a cube to use as the ground and stretch it out. Change the material to anything so you can differentiate from the player

3) Make your camera orthographic

4) Add this script to the player cube:

 using UnityEngine;
 using System.Collections;
 
 public class TestBox : MonoBehaviour {
 
     // Use this for initialization
     private Rigidbody thisRigidbody;
     private Transform thisTransform;
     
     public float gravity = 500.0f;
     public float upSpd = 300.0f;
     private Vector3 movement = Vector3.zero;
     private float rayLength;
     
     void Start () {
         thisRigidbody = GetComponent<Rigidbody>();
         rayLength = collider.bounds.extents.y + 0.1f;
         thisTransform = GetComponent<Transform>();
     }
     
     // Update is called once per frame
     void Update () 
     {
         if( Input.GetMouseButtonDown(0) )
         {
             movement.y = upSpd;    
         }
         if( IsGrounded() && movement.y < 0 ) 
             movement.y = 0;    
         else 
             movement.y -= gravity * Time.deltaTime;
     }
     
     bool IsGrounded()
     {
         RaycastHit hit;
         if (Physics.Raycast(thisTransform.position, -Vector3.up, out hit, rayLength))
         {
              return true;
         }
         return false;
     }
     
     void FixedUpdate()
     {
         thisRigidbody.velocity = movement;
     }
 }


You can adjust the gravity and upSpd depending on the scale of your objects. If you run it and click the mouse you'll see if the gravity is high enough, the dipping will occur.

I have no idea why the results are so inconsistent. The problem appears to be in the Raycast itself, where it returns true at slightly different times in code execution. The "dipping" doesn't happen when the Y speed is slow enough, but under any normal speed, the temporary dip happens.

Does anyone have ANY idea as to why this is happening? Am I going about this the wrong way? Is there a way for me to ensure that the Raycast always returns true at the right time? I don't know how the CharacterController works, but whatever it does, it seems to not suffer from this problem.

Thanks in advance!

Comment
Add comment · Show 4
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 Kryptos · Apr 19, 2012 at 03:09 PM 0
Share

You should consider using the forces and the built-in gravity. The main advantage is that the physics engine run several cycles between two fixed update, so that it remains (almost) always consistent.

In your case, between two updates your character can have pass through the ground, thus the dips. Setting the position/rotation of a non-kinematic rigidbody is disregarded.

avatar image helios · Apr 19, 2012 at 03:30 PM 0
Share

Thanks for your reply. Unfortunately, I've tried using forces and built-in gravity, but the movement just isn't the same or desirable as the other methods. Surely there must be another way?

avatar image helios · Apr 20, 2012 at 04:22 PM 0
Share

Even using forces and built-in gravity, the same issue happens. Any other solutions?

avatar image James1992 · Feb 12, 2016 at 10:57 AM 0
Share

1 alternative you can do is make it use mesh colliders, and generate a mesh for things like slopes, and boxes, making a physics engine to support slopes should be easy enough

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by jellybit · Dec 16, 2012 at 02:38 PM

I found the answer for my particular project. Go to Edit->Project Settings->Physics. In here, you can set the Min Penetration For Penalty Force. The larger the number is, the more it will sink into objects. The smaller the number is, the less it will allow penetration. I used this in my game, and it resolves the character beautifully, however it does dip below for a single frame. Not bad though.

The only issue is that the smaller this number is, the more jitter you can experience. I haven't had that problem yet with how I've set things up, and you can always adjust the bounce threshold to try to compensate. There's more info here. Another thing you could try if that fails is to increase the scale of everything. That way, you won't likely see the issue.

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 AriesT · Aug 04, 2013 at 08:40 AM

As of my experience, it is not possible to have Super Mario World-like precise collision detection in Unity using the Character Controller or a Ridigbody+BoxCollider combo. Unless, you write your collision detection by yourself.

Using a Character Controller causes the object to fall off edges if you try to jump at the very edge because the CC already thinks it is falling - due to the capsule collider. Especially if you have a rather fast moving player / object. Using the standard Unity update speed causes fast objects to fall through triggers without triggering them or even falling through walls.

I never achieved a REALLY precise Super Mario World-like collision detection with Unity. It is just not possible without coding it from scratch.

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

7 People are following this question.

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

Related Questions

Use RayCasting and simulate collision physics 1 Answer

Detect when CharacterController is not colliding? (SOLVED) 1 Answer

OnCollisionEnter not working for bullet 2 Answers

Collision with Plane fails 0 Answers

Best way to implement an advanced collision system? 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