Home > Enterprise >  Is there any way to stop raycasts from going through objects?
Is there any way to stop raycasts from going through objects?

Time:12-19

Im making a grappling gun, that pulls an object towards the player if the layer is LightWeight, and pull the player towards the object if the layer is Ground

            int groundLayer_mask = LayerMask.GetMask("Ground");
            int lightWeightLayer_mask = LayerMask.GetMask("LightWeight");

            //Shoots a raycast, and only works if layer is Ground
            if (Physics.Raycast(Shoulder.transform.position, cam.transform.forward, out raycastHit, float.PositiveInfinity, groundLayer_mask))
            {
                //Hit Something
                debugHitpointTransform.position = raycastHit.point;
                hookshotPosition = raycastHit.point;
                hookShotSize = 0f;
                HookShotTransform.gameObject.SetActive(true);
                HookShotTransform.localScale = Vector3.zero;
                layerHit = 0;

                state = State.HookShotThrown;
            }
            //Shoots a raycast, and only works if layer is LightWeight
            else if (Physics.Raycast(Shoulder.transform.position, cam.transform.forward, out raycastHit, float.PositiveInfinity, lightWeightLayer_mask))
            {
                //Hit Something
                debugHitpointTransform.position = raycastHit.point;
                hookshotPosition = raycastHit.point;
                hookShotSize = 0f;
                HookShotTransform.gameObject.SetActive(true);
                HookShotTransform.localScale = Vector3.zero;
                layerHit = 1;

                state = State.HookShotThrown;
            }

But if im looking in the direction of an object with Ground layer, even if there is one with the layer LightWeight closer than the one with Ground, it goes for the one with Ground cuz i have it's if statement first. Any way to make it either not go through the object infront just cuz the first if is looking for one behind, or to make it prioritize the one infront?

CodePudding user response:

Both your raycast cases basically do the exact same thing, except for the value of layerHit. So either way this is a waste of resources ;)

So in order to be more efficient and also achieve what you want simply include both layers in your layer mask and make only one single raycast against both layers -> it will use whatever it hits first from the given layers.

You can then still check what layer you actually have hit inside the if block.

So I would expose the field to be configurable in the Inspector

// Configure this via the Inspector
// it will be a drop-down from which you can select multiple entries
public LayerMask layers;

private void Awake ()
{
    // if you really want to keep getting these by code
    layers = LayerMask.GetMask("Ground", "LightWeight");
}

And also in general I would also use an enum in order to have some meaningful names like e.g.

public enum HitType
{
    None = -1,
    Ground,
    Lightweight
}

and then use a single ray cast like

int groundLayer_mask = LayerMask.NameToLayer("Ground");
int lightWeightLayer_mask = LayerMask.NameToLayer("LightWeight");

var hitType = HitType.None;

if (Physics.Raycast(Shoulder.transform.position, cam.transform.forward, out raycastHit, float.PositiveInfinity, layers))
{
    //Hit Something
    debugHitpointTransform.position = raycastHit.point;
    hookshotPosition = raycastHit.point;
    hookShotSize = 0f;
    HookShotTransform.gameObject.SetActive(true);
    HookShotTransform.localScale = Vector3.zero;

    if(raycastHit.collider.gameObject.layer == groundLayer_mask) hitType = HitType.Ground;
    else if(raycastHit.collider.gameObject.layer == lightWeightLayer_mask) hitType = HitType.Lightweight;

    state = State.HookShotThrown;
}
  • Related