Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Spherecast sometimes stops detecting object

Discussion in 'Physics' started by Ahzenrei, Nov 29, 2020.

  1. Ahzenrei

    Ahzenrei

    Joined:
    Mar 13, 2017
    Posts:
    1
    Hello,
    I'm making a two players game where I have to aim at objects to highlight them, then hold a button to attract them and then I have to shoot them on the other player to inflict him damage.

    I'm using SphereCast to detect objects. First I start with small sphere and then I gradually increase the radius of the spheres if it don't collide. It works well but sometimes, and I can't understand why, it stops working. I'm not able to reproduce it constantly. Here the part of the code that handle it :

    Code (CSharp):
    1.  
    2. public Player player;
    3. public Camera cameralinked;
    4. public Vector3 raycastOffset = new Vector3(0f, 0f, 0f);
    5. public float maxDistance = 10f;
    6. public float[] spheresSizes = { 0.01f, 0.1f, 0.2f, 0.3f, 0.5f };
    7. private LayerMask layerMask;
    8.  
    9. //Debug values
    10. private Color[] palette = new Color[5];
    11. private float maxSphereTried = 0f;
    12.  
    13. [ColorUsage(true, true)]
    14. public Color highlightColor;
    15.  
    16. // Start is called before the first frame update
    17. void Start()
    18. {
    19.     //Debug values initialisation
    20.     layerMask = LayerMask.GetMask("Projectiles");
    21.     UnityEngine.Accessibility.VisionUtility.GetColorBlindSafePalette(palette, 0.5f, 1.0f);
    22. }
    23.  
    24. void Update()
    25. {
    26.     if (player.projectile != null) return;
    27.     //We search for projectiles in the center of the screen
    28.     bool projectileFound = false;
    29.     foreach (float i in spheresSizes)
    30.     {
    31.         maxSphereTried = i;
    32.         RaycastHit hitInfo;
    33.         if (Physics.SphereCast(cameralinked.transform.position + raycastOffset, i,
    34.                              cameralinked.transform.forward,
    35.                              out hitInfo, maxDistance + i, layerMask))
    36.         {
    37.             Projectile newProjectile = hitInfo.collider.GetComponent<Projectile>();
    38.  
    39.             // We don't want to allow player to steal the projectile of other player
    40.             if (newProjectile.target != null)
    41.             {
    42.                 break;
    43.             }
    44.  
    45.             if (newProjectile != player.viewProjectile && player.viewProjectile != null)
    46.             {
    47.                 player.viewProjectile.Highlight(highlightColor, false);              
    48.             }
    49.  
    50.             if (newProjectile == null)
    51.             {
    52.                 Debug.LogError("The projectile Vision Select Script has detected an object which is not a Projectile : check if the object "
    53.                                + hitInfo.collider.gameObject + " is missing a Projectile script or isn't in the good layer.");
    54.             }
    55.             else
    56.             {
    57.                 newProjectile.Highlight(highlightColor, true);
    58.                 player.viewProjectile = newProjectile;
    59.                 projectileFound = true;
    60.             }
    61.  
    62.             break;
    63.         }
    64.     }
    65.     if (!projectileFound)
    66.     {
    67.         if (player.viewProjectile != null)
    68.         {
    69.             player.viewProjectile.Highlight(highlightColor, false);
    70.         }
    71.         player.viewProjectile = null;
    72.     }
    73.   }
    player.projectile is the projectile that hold the player and player.viewProjectile is the projectile that the player is highlighting.

    When it occurs player.projectile is null so it doesn't return at the beggining. sphereSize is still the same so the foreach still behave the same.

    I have Gizmos that shows me how SphereCast is fired

    Code (CSharp):
    1.     public void OnDrawGizmosSelected()
    2.     {
    3.         foreach (float i in spheresSizes)
    4.         {
    5.             if (i <= maxSphereTried)
    6.             {
    7.                 Gizmos.color = palette[((int)(i * 10f)) % 5];
    8.                 for (float j = 0f; j < maxDistance; j += 1)
    9.                     Gizmos.DrawWireSphere((cameralinked.transform.position + raycastOffset + (cameralinked.transform.forward * (j + i))), i);
    10.                 Gizmos.DrawWireSphere((cameralinked.transform.position + raycastOffset + (cameralinked.transform.forward * (maxDistance + i))), i);
    11.             }
    12.         }
    13.     }
    and I can see that it is fired in the right direction and at the right position. The layer of the objects in the scene doesn't change and are still correct when the bug occurs.
    About the colliders of my projectile, I'm using a convex mesh collider or multiple box collider, and they all have a rigidbody set with continous collision and interpolate.
    The last times it happened, it was after I shot a projectile but it get expulsed from the map by some weird collision because he was too fast I guess. And after that, objects near the zone where it happened were not detected but others objects farther were.
    It's a nasty bug that follows me for a week now and I just don't know what causes it, do you have any leads ?

    Thanks for your attention, and sorry if I wasn't clear in my explanations, tell me and I'll try to be more precise

    [EDIT]
    It appears to be the origin of the sphereCast that causes the problem, I can't detect objet when I'm inside a certain zone which seems to be relate to the position where the projectile glitched the first time.
    Here a little scheme
    upload_2020-11-29_13-58-46.png
     
    Last edited: Nov 29, 2020