Search Unity

Sword colliers physics

Discussion in 'Physics' started by Sword111, May 19, 2017.

  1. Sword111

    Sword111

    Joined:
    Feb 28, 2016
    Posts:
    20
    Hi maybe someone can help me, with a sword collision problem that ive been battling with for a long time .Tried every forum but with out success .So the problem is at speed the colliders are able to pass through each other . I've tried every type of collider and combination of multiple staged collider to all of the rigid body collision types to time step, scaling up and add force script (but that only works in one direction), so it has to be a physics answer to work in all directions and location up and down the length of the blade . I need to be able to manipulate the blade to any angle while the lesson animation is operating using the proper physics and angle of contact ! ANY IDEAS on what i may be able to do to solve this conundrum with such small thin colliders ? I enclose a link to show you what i mean first ok slow .. then not second .

    Thanks
     
  2. kritoa

    kritoa

    Joined:
    Apr 21, 2017
    Posts:
    60
    Quick sanity check, you mentioned you had but just making sure you tried setting all the various rigidbodies' Collision Detection to Continuous Dynamic or Continuous? I am not sure, but I assume that only works when the Rigidbodies are not kinematic, and perhaps yours are since they are attached to your controllers(?).

    In any case I also have a similar problem in my game (very thin kinematic swordy things that need to collide, and I don't actually have rigidbodies on the blades anyways), and I ended up solving it by writing my own collision method, which you might have to do as well.

    I don't have access to my code right now (and the code is dirty and horrible anyway), but the general approach is to

    1) Find the points on each sword which are closest to the other sword. For me this was easy because both of my swords are straight lines, but yours might be more difficult since they bend? Call those points PointClosest1 and PointClosest2. Google will find you quick methods if you don't know how to do that.

    2) use cross product of sword 1 and sword 2 (or the sword segments closest to each other in your case with bending swords, which you should have from step #1) to find the vector that is perpendicular to both swords (call it VectorPerp or something) - (note that the vector between PointClosest1 and PointClosest2 should be aligned with this VectorPerp. *

    3) Find the Vector from PointClosest1 to PointClosest2: e.g. VectorPC1ToPC2 = PointClosest2 - PointClosest1

    4) if you use dot product dot(VectorPC1ToPC2, VectorPerp) and keep track of the sign (negative or positive) from frame to frame, when the sign flips from positive to negative or vice versa, then the swords passed through each other and should have collided, and then you can take appropriate action. **

    * - you have to update this VectorPerp every frame, but there are some edge cases - if you, say, have both swords facing each other up at 45 degrees, sword 1 to the right of sword 2, and let both swords droop so that both swords are facing down at 45 degrees, sword 1 still to the right of sword 2, the VectorPerp will switch from left to right side, so the sign of the dot product in step 4 will flip even thought to swords didn't cross, so you have to handle that appropriately - I forget how I did that - but I tested to see if VectorPerp flipped more than 180 degrees in one frame and did something smartish (reset the signs of the dot product that I was keeping track of in step 4, or something like that).

    ** - you also have to make sure that not only did the infinite lines that represent the swords cross sides, but also that the finite sword line segments actually passed. So you check to see if your PointClosest1 and PointClosest2 are actually on the sword segments (and not beyond the tip or closer than the hilt).
     
    Last edited: May 25, 2017
  3. Sword111

    Sword111

    Joined:
    Feb 28, 2016
    Posts:
    20
    HI Kritoa thank for your reply ! Unfortunately my rift is in for repair,so even if i could understood your message, its one of those thing where you need to be in the game to trial ! As im not a coder, but use playmaker, which has been great till now ! I will have to try to unravel what exactly you mean and get back to you . I was hoping i would be able to use the Unity physics engine some how.
    The blade bends are effected by the trigger colliders, they are graduated animations now , so the colliders stay rigid , but am working on a pure skeletal physic type... the next evolution .You have given me food for thought so will start from scratch, double checking every thing again !! If any one has ideas about whippy blade ideas please do tell !!
     
    BrandyStarbrite likes this.
  4. Sword111

    Sword111

    Joined:
    Feb 28, 2016
    Posts:
    20
    Here is a simple view exposed . There must be a simple answer ?

     
  5. kritoa

    kritoa

    Joined:
    Apr 21, 2017
    Posts:
    60
    The only other thing I can think of is: set the blades to continuous dynamic collision detection, and then, most importantly, make then non-kinematic, and attach them to a dummy gameobject using a FixedJoint. I haven't tried this myself - I am just assuming that continuous dynamic collisions will work correctly if the swords are non-kinematic.
     
  6. eXonius

    eXonius

    Joined:
    Feb 2, 2016
    Posts:
    207
    Continus collision detection shouldn't pass through. I think the problem is that you're not using forces to control it. If not it must be a bug.
     
  7. Taorcb

    Taorcb

    Joined:
    Mar 15, 2015
    Posts:
    39
    Try increasing the solver frequency, and do what kritoa said and make sure continuous collision is on. That looks to me like the rigidbodies are just not registering collisions because they're moving too fast. Increasing the solver frequency should fix that, but it can be a drag on framerates if it goes too low.
     
  8. eXonius

    eXonius

    Joined:
    Feb 2, 2016
    Posts:
    207
    But "not registrering collisions because of moving too fast" is what continuous dynamic collision detection is supposed to prevent so I think there has to be something more to it.

    Anyhow, here's from the docs:

    Continuous Collision Detection
    Continuous collision detection is a feature to prevent fast-moving colliders from passing each other. This may happen when using normal (Discrete) collision detection, when an object is one side of a collider in one frame, and already passed the collider in the next frame. To solve this, you can enable continuous collision detection on the rigidbody of the fast-moving object. Set the collision detection mode to Continuous to prevent the rigidbody from passing through any static (ie, non-rigidbody) MeshColliders. Set it to Continuous Dynamic to also prevent the rigidbody from passing through any other supported rigidbodies with collision detection mode set to Continuous or Continuous Dynamic. Continuous collision detection is supported for Box-, Sphere- and CapsuleColliders. Note that continuous collision detection is intended as a safety net to catch collisions in cases where objects would otherwise pass through each other, but will not deliver physically accurate collision results, so you might still consider decreasing the fixed Time step value in the TimeManager inspector to make the simulation more precise, if you run into problems with fast moving objects.

    https://docs.unity3d.com/Manual/class-Rigidbody.html

    But I am not so sure that it can work properly when he doesn't use forces to move his colliders.
     
  9. Taorcb

    Taorcb

    Joined:
    Mar 15, 2015
    Posts:
    39
    I see no reason why not using physics to move stuff should cause collisions to not register. He/you (depending on who's reading this) mentioned that the blade is being controlled by triggers and animations, perhaps using continuous collision detection doesn't work with triggers. I'm grasping at straws here, 'cause I'm just as confused.

    One other thing to try is controlling the blade's bending with joints and colliders rather than triggers and animations. If animations are the way it needs to happen, perhaps use a pseudo-collision method that calculates the distance from the two closest points on the swords and does animation based on that, rather than using physics.
     
  10. kepesh

    kepesh

    Joined:
    Dec 29, 2017
    Posts:
    92
    I have the exact problem right now. Did you ever solve this?

    Thanks!
     
  11. cwBAH

    cwBAH

    Joined:
    Nov 2, 2021
    Posts:
    1
    I've been working on a similar problem for awhile, and thought it was enough of a pain in the ass to necro this thread so others can solve. In fact I'll probably make a blog about it because its more complex than what I can write here, but there are some pretty silly pitfalls that will completely prevent this from working.

    Its not really an issue of solver iterations or even collision detections. I had the same issue and tested collision count and it would tunnel (teleport) even when it hit the other sword.

    The cause of the tunneling error was that I had my sword rigidbodies parented to its moving configurable joint anchor (kinematic player vr hands), which caused a conflict between parenting movement and physics calculations. By insuring that the sword rigidbody was not parented to any moving object it allowed the physics to calculate correctly. I'm using continuous dynamic for both weapons.

    I would definitely recommend using a configurable joint - however there are hangups here as well that I was able to resolve with very strict testing. I would start with setting up everything as free and control with spring only (I use around 3000 for Slerp but I make it dynamic) ; just to get started. Then work you way to setting angles to certain limits. Locking any component on the config joint can result in some really wear physics solutions. I would also disable preprocessing as it can prevent physics solutions from resolving (not really sure what its for other than breaking stuff).

    Anyways, I know its several years late, but hope this helps somebody.
     
  12. Number-3434

    Number-3434

    Joined:
    Dec 31, 2022
    Posts:
    13
    The easiest fix is to attach a tracer / trail renderer to the sword, and add the collider to the tracer instead. Then set the time of the tracer to a small value, e.g. 0.2
     
  13. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,928
    Continuous collision detection generally uses object's velocities to calculate collisions. If you move a rigidbody by directly setting its transform values (be it through animations, scripts, or other means), it has zero velocity as far as the physics engine is concerned. All the engine "sees" are objects teleporting around, and it will only register a collision during frames where the colliders physically overlap each other. If the colliders are thin and are moving fast, the chances of this happening are slim, so they won't collide.

    You must either use rigidbody.MovePosition/MoveRotation, or AddForce(), joints, or some other means of moving the object that actually involves the physics engine.
     
    Last edited: Jan 10, 2023