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

Question CapsuleCast radius fine tuning needed

Discussion in 'Scripting' started by Falcoshin, May 11, 2021.

  1. Falcoshin

    Falcoshin

    Joined:
    May 31, 2017
    Posts:
    168
    I'm trying to get the unit with the blue circle under it to move towards its destination and have it stop when it meets another unit (the one with the red circle under it in this case) and have it stop just short of where they intersect. As you can see based on the picture, though, the markers end up intersecting which is not suppose to happen (it's suppose to stop just short of that happening).

    Code (csharp):
    1.  
    2. //Set angle and magnitude
    3.             float angle = AngleBetween(transform.position, destination);
    4.             float magnitude = Time.deltaTime * speed;
    5.             if (magnitude > Vector3.Distance(transform.position, destination))
    6.             {
    7.                 magnitude = Vector3.Distance(transform.position, destination);
    8.             }
    9.  
    10.             //Obstacle check
    11.             float radius = cc.radius * transform.localScale.x + MARKER_RADIUS * 2;
    12.             RaycastHit[] hits = Physics.CapsuleCastAll(transform.position, Top(transform.position), radius, AngleToVector(angle), magnitude);
    13.             bool moveLock = false;
    14.             foreach (RaycastHit hit in hits)
    15.             {
    16.                 if (hit.collider != GetComponent<Collider>() && hit.collider.GetComponent<CharacterController>() != null)
    17.                 {
    18.                     moveLock = true;
    19.                 }
    20.             }
    21.  
    22.             //Move
    23.             if (!moveLock)
    24.             {
    25.                 if (magnitude == Vector3.Distance(transform.position, destination))
    26.                 {
    27.                     transform.position = destination;
    28.                 }
    29.                 else
    30.                 {
    31.                     cc.Move(AngleToVector(angle) * magnitude);
    32.                 }
    33.             }
    Capture.JPG

    What I know for sure is that the radius variable is too small, but I'm not sure what it's SUPPOSE to be to get it to work properly. Past iterations have added character controller skin width to it and, while it helps tremendously, it still has problems for what I ultimately want to do. So the question is "What is the real value I should add to the radius to get it to work properly?"
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,758
    I'm guessing this is an internal threshold value of the physics solver, and perhaps even related to how rapidly the two objects are brought together for the solver to consider. Obviously things can't collide if they are just barely kissing against each other, since this is identical to not touching at all, so I assume there is a built-in band of overlap allowed.

    Since these appear to be circles, you could just use your own geometric expression to set the actual object centers apart the correct distance so that the graphics don't overlap.
     
  3. Falcoshin

    Falcoshin

    Joined:
    May 31, 2017
    Posts:
    168
    So how would I get these values? I can only assume that the "how rapidly the two objects are brought together" value you're talking about has to do with the magnitude, but I'm not sure how I'd use that value to determine what I need to add onto the radius.
     
  4. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,921
    I don't know -- I've done lots of ray and sphere casts and never gotten things that far off. I think it's a problem with the radius calculation. I'm not sure what cc.radius and MARKER_RADIUS are. I almost always want to use the real radius of the moving object. It seems as if you're adding to that, which should flag collisions well before you actually touch, making that small overlap an even bigger mistake.

    I'd almost want to put that all inside a keypress check to step it out. The part where you calculate the distance needed seems as if it won't overshoot, but there are a lot of things going on.
     
  5. Falcoshin

    Falcoshin

    Joined:
    May 31, 2017
    Posts:
    168
    MARKER_RADIUS is an extension value (0.5) used to create the markers beneath the units (As in their radius is equal to the collider radius plus this extension). As such, the bounds of those circles are suppose to be a representation of the collider bounds I want to pretend exist. As they don't actually exist, though, I added the other unit's MARKER_RADIUS into the radius preemptively hoping that it will be big enough to catch that unit's REAL collider, but it's not. Historically I've had to add the skinWidth values of both unit colliders in as well and it helps a lot, but there are still times where these circles will still overlap when they're not suppose to. Clearly this means I'm suppose to STILL add something more to it, but I can't think of what other value I would need.
     
  6. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,921
    So cc.radius is the actual temporary small collider the blocking objects have, and MARKER_RADIUS is the eventual one. Should you be adding (MARKER_RADIUS-cc.radius)? In other words, subtracting cc.radius instead of adding it as you are now?

    I'd add that whenever I've got a temporary hack just to get it running, and it has some minor issues, I don't bother trying to fix them -- it's often an artifact of the hack which goes away when it's done the real way. It's even helpful to look bad as part of a big fat "this is not done yet".
     
  7. Falcoshin

    Falcoshin

    Joined:
    May 31, 2017
    Posts:
    168
    cc.radius is the actual radius of the character controller minus the skin width. MARKER_RADIUS merely extends that far enough to create a marker that isn't obscured by the unit model. As such, the radius of the marker is cc.radius + MARKER_RADIUS. The idea is that, in order to try and penetrate the character controller of the unit in the way, I preemptively add its MARKER_RADIUS to the CapsuleCast radius.
     
  8. Falcoshin

    Falcoshin

    Joined:
    May 31, 2017
    Posts:
    168
    It's seeming the magic number is 0.2, but I have no idea where it comes from. Fortunately it seems to be constant as changing the magnitude of the moving unit doesn't seem to cause any overlaps what so ever, but I still want to know where it comes from since I wager this information alone isn't going to help me for the other problems I've been having.
     
  9. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,921
    In that case, get rid of cc.radius altogether. I'll bet it's size is 0.2. cc exists and is an actual collider, right? Only add extra for the colliders you're pretending to have, which is your (wanted-current) value MARKER_RADIUS (and maybe consider renaming it MARKER_RADIUS_EXTEND)?
     
  10. Falcoshin

    Falcoshin

    Joined:
    May 31, 2017
    Posts:
    168
    It's not. cc.radius is 1 and the MARKER_RADIUS is 0.5 so overall the radius of the circle is 1.5. This goes for both of them.
     
    Last edited: May 11, 2021
  11. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,921
    But you realize that the math is still wrong? You already have a collider of size 1 for cc. You want to add only the missing 0.5. Adding cc.radius again makes it too big. You have an imaginary radius of 2.5 instead of 1.5.

    This means you're collisions are actually _way_ off -- there must be something big wrong somewhere else. I'm seeing cc.radius*transform.localScale.x. I've used that trick -- it's round, localScale.xyz are all the same, so just pick one. But shouldn't that be cc.radius*cc.transform.localScale.x? (but again, i don't think cc should even be there).