'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....>>
}
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 |