Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Rotating an object multiple times in one frame and checking for collsions?

Discussion in 'Scripting' started by UniversalGesture, Nov 24, 2019.

  1. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    Hi,
    I want to rotate an object some degrees multiple times and check if there is any collision, but I want to do all of this in one frame. Is this possible?
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    This is half-guessing, but since collisions are physics, which are updated in FixedUpdate(), even if you rotated and manually checked the collider, it shouldnt change anything. So unless i'm missing something, you'd need to write or approximate this functionality yourself.

    However, if you described why you need this, there may or may not be a more appropriate way of doing what you want. If you want to rotate something until it collides / or doesnt collide anymore between two frames, then the action itself is irrelevant (because it's an implementation detail the player wont ever see), and there may be other ways to get the result you are looking for.
     
  3. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    I want to do a quick calculation to see if a rotating object will have any obstacles. It's like a quick simulation and another non unity program will use the data. The goal is to control a robotic arm.
     
  4. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    If it's not a game but, as i understand, a physics simulation to control your physical robotic arm, why does the calculation need to happen between frames? Cant you just simulate the action before doing it (possibly in faster speed) and check for collisions that way?

    I dont know if there is a simpler way, but if not you could approximate the robotic arm shape by placing empty gameobjects at the joints (correctly rotated with the corresponding arm segment being its parent), and then cast a ray from there (you can potentially use multiple rays per segment, to better approximate its thickness, basically placing them around the arom segment). Then when you rotate the arm segment, its children also rotate, thus the ray direction changes and you can again check for collisions along that arm segment. You can also limit the length of the ray to only check for collisions that happen around the arm segment.
    While not perfect as far as approximating the shape of the arm goes, this would at least allow you to check / approximate collisions between frames.
     
    UniversalGesture likes this.
  5. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    That's actually a really good idea. I never thought about using both programs incrementally. The only problem is some possible solutions leads to dead ends similar to a maze. That's why I would like to find the solution in one frame.

    As far as the model its not a problem since I already have it.
     
  6. davidnibi

    davidnibi

    Joined:
    Dec 19, 2012
    Posts:
    424
    Try this for quick rotation (1440)

    Code (CSharp):
    1.     [SerializeField] Vector3 RotationPerSecond;
    2.     void FixedUpdate ()
    3.     {
    4.         Quaternion q = transform.rotation;
    5.         q.eulerAngles += RotationPerSecond * Time.fixedDeltaTime;
    6.         transform.rotation = q;
    7.     }
     
    UniversalGesture likes this.
  7. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    Just a thought, but similar to how you would solve a maze algorithmically, you could backtrack wrong rotations and continue with the next option until you either found one that worked, or went through all options.
    That said, i believe there is too much overhead in this approach so it may take a while, since rendering frames is unnecessary for what you want. Doing it purely using raycasts and rotations should be applicable, unless you need a perfect digital (collider) representation of the robotic arm.
    If raycasts are not a good enough approximation, then you could try creating your own "colliders" and calculate their collisions with other stuff yourself, thus making the entire process entirely calculatable between frames. Since you most likely dont need the Unity engine for this, you could also make it extremely efficient and fast using Jobs + Burst. But it's probably a bit more effort required for this approach.
     
    UniversalGesture likes this.
  8. Serinx

    Serinx

    Joined:
    Mar 31, 2014
    Posts:
    785
    I think what you're looking for is Rigidbody SweepTest.

    "Tests if a rigidbody would collide with anything, if it was moved through the Scene"

    https://docs.unity3d.com/ScriptReference/Rigidbody.SweepTest.html

    A response in this thread shows how to use it with a rotation.

    Basically it sets the rigidbody rotation before performing the sweeptest and then sets it back all in the same frame.

    Edit: Here's the code in the forum post link:


    Code (CSharp):
    1.     var rigidbodyCompoennt = GetComponent<Rigidbody>();
    2.     var initialRotation = rigidbodyCompoennt.rotation;
    3.     rigidbodyCompoennt.rotation = rotationForSweepTest;
    4.     var sweepHits = new List<RaycastHit>();
    5.     sweepHits.AddRange(rigidbodyCompoennt.SweepTestAll(new Vector3(0f, 0f, -0.01f), 0.01f, QueryTriggerInteraction.Ignore));
    6.     sweepHits.AddRange(rigidbodyCompoennt.SweepTestAll(new Vector3(0f, 0f, 0.01f), 0.01f, QueryTriggerInteraction.Ignore));
    7.     rigidbodyCompoennt.rotation = initialRotation;
    8.  
     
    UniversalGesture and Yoreki like this.
  9. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    As far as i remember, SweepTest only works with primitive shapes, like spheres or boxes, or combinations of those. But i guess it's still better than doing the raycasting manually if the width of the arm needs to be simulated approximately.
     
  10. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    Great suggestions guys! This is great. Thank you! I will try it out.
     
  11. Serinx

    Serinx

    Joined:
    Mar 31, 2014
    Posts:
    785
    @Yoreki

    Ah you're right sorry, I didn't see that part. It will only work if you've got a convex mesh collider. Although that might suffice!

    "this function only works when a primitive collider type (sphere, cube or capsule) or a convex mesh is attached to the rigidbody object - concave mesh colliders will not work"