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 mStep · Sep 27, 2012 at 08:48 PM · iosmobilecollision detection

Distance-based collision detection not accurate

I'm making a pretty simple mobile 2D puzzle game that requires a lot of collision detection between perfect circles. I had figured this would let me skip physics altogether, as they tend to bog down mobile projects, and detecting collisions between circles shouldn't be difficult to accomplish without it.

Basically the user is able drag a circle around the screen via touch. At certain time intervals, a disc (also perfectly circular) is spawned and shot across the screen; when the user-controlled circle comes in contact with the disc, the disc sticks to the circle and becomes a part of it (basically, the disc is parented to the circle). Not complicated.

In my update function I'm checking the distance between the spawned disc and the closest child of the user-controlled object, all of which are circles. Here's what it looks like:

 var closest : float = 999;
     var circ : Transform;
     
     // Check for collision with main or children of main
     for (var circle : Transform in main)
     {
         // Get the distance from this child object to the child
         var nextDist = Vector3.Distance (circle.position, transform.position);
         
         // If it is closer than the previous one, update closest circle
         if (nextDist < closest)
         {
             closest = nextDist;
             circ = circle;
         }
         
         // If the circle and the closest transform overlap...
         if (closest <= ((transform.localScale.x / 2) + (circ.localScale.x / 2)))
         {
             // Stop movement and parent the circle to the main
             EndLife ();
         }
     }

It works pretty well, but there's a problem - when the user moves the main object too fast, the collision detection seems to "lag", meaning discs won't detect a collision until they're partly inside an object. If the player moves the main object REALLY fast, sometimes discs won't detect anything at all and will just phase through the object, as if they never collided.

Is there a way around this? How is it possible that a distance check in the Update loop can be "slower" than the movement of an object that is also controlled through the Update loop? I feel like I'm misunderstanding something pretty fundamental here.

Any help would be greatly appreciated!

Comment
Add comment · Show 3
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 Fattie · Sep 27, 2012 at 08:54 PM 2
Share

it looks like the last clause should be outside the loop, rather than inside it. did you make a typo? i think you've just accidentally put it in the wrong place

Just FWIW ...... "as they tend to bog down mobile projects" .. PhysX is incredibly fast, probably faster than anything one can write by hand. and it's hard to see that physics bogs down "mobile projects" as what 50% (80%? more?) of ifone games use physics

avatar image mStep · Sep 27, 2012 at 09:03 PM 0
Share

Yeah, it is outside the loop, I guess I just somehow copied it wrong.

And physics absolutely adds significant overhead to a project, mobile or not. It probably wouldn't be too big of a deal here, as the project is relatively small-scale, but it's always good to be as efficient as possible. It's entirely possible I'm being dumb with this particular problem though - I just can't wrap my head around why the distance check seems to not work at high speeds.

avatar image Fattie · Sep 28, 2012 at 06:43 AM 0
Share

Just FWIW

"it's always good to be as efficient as possible"

The central thrust of all modern computing is that you engineer for reliability and ease of development.

You often hear the saying "don't optimize early."

"physics absolutely adds significant overhead to a project"

The resources usage added by PhysX is $$anonymous$$uscule compared to many (two dozen? four dozens?) other systems that grind away constantly in the modern hardware/software assembly.

To make an extreme analogy, it would be like program$$anonymous$$g for $$anonymous$$ac and saying, oh, I don't want to to use these lame systems Cocoa supplies for rendering type on a monitor, I will calculate the antialiasing myself in my own code.

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Bunny83 · Sep 27, 2012 at 09:30 PM

Well, keep in mind objects don't really "move". They always jump to their next position. The movement "speed" and the framerate determine how much the object will "jump" each frame.

For example, when you have a monitor 1600 pixel wide and you move your mouse quickly from the left side to the right side, the cursor won't pass each of the 1600 pixels. It will probably stop / e visible at 5 to 30 positions in between even when it's 30 that means each "update" the cursor moved ~50 pixels.

To prevent those big jumps you can increase the sample rate, so you would move the objects several times in one Update step to reach the new position. This will decrease the move step size. This is sometimes called oversampling or interpolation. However this requires a lot more cpu power.

The second solution is to calculate the trajectory of the two objects and calculate if and where they meet. It's the search for the closest point of aproach. All those solutions are quite heavy to calculate.

The best fix is probably to do a dynamic oversampling so no movement gets larger then half of the smalles circle radius. That means when the user moved the mouse / touch very quickly the difference between the old position and the new position would be greater than the max allowed movement step. In this case you would run a while loop and interpolate between the old and the new position in smaller steps (our max allowed step size) until we reach the new postion.

There's still a problem when you need oversampling for both objects. In this case you have to interpolate both in the same loop or it's quite pointless.

edit
An example. If you have a movement code like this:

 // C#
 public float speed = 2000;
 void Update()
 {
     transform.position += transform.forward * speed * Time.deltaTime;
     CheckCollisions();
 }

You would do something like this instead :

 // C#
 public float speed = 2000.0f;
 public float maxMovementStep = 2.0f;
 void Update()
 {
     float amount = speed * Time.deltaTime;
     while (amount > 0)
     {
         float step = Mathf.Min(maxMovementStep, amount);
         amount -= step;
         transform.position += transform.forward * step;
         CheckCollisions();
     }
 }
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 mStep · Sep 28, 2012 at 02:46 AM 0
Share

Thanks for the answer. What I wound up doing was, after the movements were applied, I checked to see if the disc overlapped with one of the children of the main object. If it did, I simply moved the disc away from the center of the object it overlapped with by the distance that they overlapped. It seems to work pretty well, and it looks natural enough. Your explanation was very helpful.

Thanks again!

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

11 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

Related Questions

Game won't run on iPhone even with the device selected 0 Answers

IOS GUI slider 1 Answer

Getting a more accurate lat lng coordinate on mobile devices 0 Answers

GL ES1 vs ES2 (for iOS) 1 Answer

Third party patching software for mobile? 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