-1

I have this piece of script that I made and I get this error and I don't understand why

RaycastHit HitFL, HitFR, HitBL, HitBR;

grounded = CastRayFrontLeft(out HitFL) || CastRayFrontRight(out HitFR) ||
           CastRayBackLeft(out HitBL) || CastRayBackRight(out HitBR);
VehiculeNormal = ((  HitFL.normal
                   + HitFR.normal
                   + HitBL.normal
                   + HitBR.normal) / 4).normalized;

enter image description here

as you can witness, .net thinks the HitFR BL and BR are not assigned but they are just above.

I came to think that the execution of the boolean expression is stopped after CastRayFrontLeft(out HitFL) because it's the only one that does not throw an error but I don't understand why it should work that way.

any answer to this problem I found could not help since, in their's, they did not assign a value which I do in mine.

if some boy can help me I would highly appreciate it.

EDIT:

following is the code related to the custom functions

private bool CastRayFrontRight(out RaycastHit hit)
{
    return Physics.Raycast(RayCasterFrontRight.position, -transform.up, out hit, .5f);
}

public bool CastRayFrontLeft(out RaycastHit hit)
{
    return Physics.Raycast(RayCasterFrontLeft.position, -transform.up, out hit, .5f);
}

private bool CastRayBackRight(out RaycastHit hit)
{
    return Physics.Raycast(RayCasterBackRight.position, -transform.up, out hit, .5f);
}

public bool CastRayBackLeft(out RaycastHit hit)
{
    return Physics.Raycast(RayCasterBackLeft.position, -transform.up, out hit, .5f);
}
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • 2
    You're using the short-circuiting `||` operator - if `CastRayFrontLeft(out HitFL)` returns true, none of the other methods will be called... so what values do you expect to be assigned to `HitFR`, `HitBL` and `HitBR` in that case? If you wanted *all* the methods to be called, you should use `|` instead of `||`. I'd add this as an answer, but it's not clear what you actually want to happen. – Jon Skeet Apr 28 '21 at 18:32
  • I'll try that, what I wanted is to set grounded if one of the four rays hits something. thanks for that I did not know about this behaviour. – Louis BERTRAND Apr 28 '21 at 18:34
  • 2
    In general: What if any of these raycasts fails? Why would you try and use a normal of a Raycast that didn't hit anything and therefore possibly returns `null`? ... Also I never saw that someone would sum up normal vectors and take an average ... doesn't make sense in my eyes .. you rather would want to use only the one normal of the one hit of the one Raycast that actually hit something ... – derHugo Apr 28 '21 at 18:43
  • @derHugo for now i think i’ll get a null pointer exception or something like this, i’ll add security or even rework the script as a whole, i was simply very surprised to see an error of that kind before i had any thought of the effectiveness of the expression – Louis BERTRAND Apr 28 '21 at 19:00

1 Answers1

1

The problem is the short-circuit evaluation of C#. When terms are combined with || (OR), the second term is only evaluated, if the first one returns false, because otherwise, the outcome is known without evaluating it.

Therefore, change the code to:

var castFL = CastRayFrontLeft(out HitFL);
var castFR = CastRayFrontRight(out HitFR);
var castBL = CastRayBackLeft(out HitBL);
var castBR = CastRayBackRight(out HitBR);
grounded = castFL || castFR || castBL || castBR;
VehiculeNormal = ((  HitFL.normal
                   + HitFR.normal
                   + HitBL.normal
                   + HitBR.normal) / 4).normalized;

As an alternative, you can also combine the terms with the bitwise OR operator |:

grounded = CastRayFrontLeft(out HitFL) | CastRayFrontRight(out HitFR) | 
           CastRayBackLeft(out HitBL) | CastRayBackRight(out HitBR);
VehiculeNormal = ((  HitFL.normal
                   + HitFR.normal
                   + HitBL.normal
                   + HitBR.normal) / 4).normalized;

However, as @derHugo pointed out, there is a fundamental issue with your geometrical logic. If a ray doesn't hit, the resulting normal will be (0, 0, 0). Therefore you should only consider rays that did actually hit.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • thanks, vs does not return any error now, therefore is this behaviour (for the ||) common to every programming language or is it just for c#? – Louis BERTRAND Apr 28 '21 at 18:37
  • There are thousands of programming languages out there. Some do, some do not. Note that this very practical in cases like these: `if (i < a.Length && a[i] == x)`, where the first part ensures that the array index is within the bounds. The second term is only evaluated when the first returns `true`. Otherwise, this would blow up. – Olivier Jacot-Descombes Apr 28 '21 at 18:41
  • This might still not work as expected though! See comment on the question – derHugo Apr 28 '21 at 18:41
  • Yes. One issue solved. Next one appears! :-( – Olivier Jacot-Descombes Apr 28 '21 at 18:51