'Why does hit.point reset to 0,0,0 within the same raycast?

I'm super confused. I am making a 3D fishing minigame with Unity. When I raycast at a water plane, I move a lure object to the point the raycast hits the water, which hit.point should provide. I had this previously working a few weeks ago and checked today to find that hit.point resets to 0,0,0 midway through the coroutine.

IEnumerator handleFishing()
{
    if (Physics.Raycast(rayOrigin, myCam.transform.forward, out hit, gunRange, layermaskWater) && hit.transform.tag == "fishingWater")
    {
        print("You can fish");
        print(hit.point);
        print(hit.transform.gameObject);

        yield return StartCoroutine(playerScript.fishingStart());

        // throw lure into water
        float normalizedTime = 0;
        float height = 10f;
        gunRecoil.enabled = false;

        Vector3 startPosition = this.transform.position;
        Vector3 destination = hit.point;
        print(hit.point);
<<Code to move gun....>>
}

Here is the resulting output

Why does hit.point change partway through?

You can see that the first print at the start of the coroutine is a coordinate that I want the lure to end up at, but after the coroutine partway through, hit.point becomes 0,0,0, causing my lure to always end up somewhere off the map. The final print is 0,0,0 regardless if I print "hit.point" or "destination." Weirder still, printing hit.transform.gameObject after the coroutine will result in a null exception, so hit became null somewhere along the way.

The easy fix is to set "destination" at the start of the if statement, but I don't understand why hit changes in the first place. What's happening?



Solution 1:[1]

Issue

As mentioned from your description and comment it sounds like you have a class field

private RaycastHit hit;

and use this in shared locations for all your raycasts.

Therefore while your Coroutine is waiting it might happen that any other method is doing a raycast which apparently fails and thereby overwrites the hit with the default values (therefore hit.position = Vector3.zero; and hit.transform = null etc).


Solution

As said don't use a class field at all! Remove the

private Rigidbody hit;

from your class and rather use local variables like

if (Physics.Raycast(rayOrigin, myCam.transform.forward, out var hit, gunRange, layermaskWater) && hit.gameObject.CompareTag("fishingWater"))

which basically equals writing

Rigidbody hit;
if (Physics.Raycast(rayOrigin, myCam.transform.forward, out hit, gunRange, layermaskWater) && hit.gameObject.CompareTag("fishingWater"))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 derHugo