I hover a unit above the ground (a grid). The ground highlights/changes the shader if the raycast is hitting it. How do I reset that specific grid’s shader when the raycast leaves it?
My initial thought was to track the last grid that was highlighted, then do a compared of the current one and the last one. If they don’t match, turn the last one’s shader back to normal.
After some testing I implemented it successfully as I mentioned above. Logic is simple:
If I’m hovering over a grid (raycast hitting it), change its shader
If the grid I just hit is different than the last grid, change the last grid’s shader back to normal
The main gotcha is that you need to instantiate the lasthit variable to ANYTHING (in start) because if it’s empty, the first comparison breaks the whole chain. Nothing is there to compare it to after all.
So here it is, a “OnTriggerExit” for raycast, at least in my use case:
RaycastHit raycasthit;
Ray placementray;
Transform lasthit;
Shader shader1;
Shader shader2;
// This lets me choose the "grid" layer in the inspector so that the raycast only hits that
public LayerMask activelayers;
void Start()
{
// Get some shaders ready, as well as a plceholder for lasthit so it isn't null later on for the first comparison
shader1 = Shader.Find("Standard");
shader2 = Shader.Find("Diffuse");
lasthit = gameObject.transform;
}
// Drag a unit around in the air. Place him on a grid if possible when you let go.
void OnMouseDrag()
{
// Do dragging things...
...
// Point raycast down from unit so it hits the grid
placementray = new Ray(transform.position, Vector3.down);
Debug.DrawLine(transform.position, transform.position + Vector3.down * raydistance, Color.green);
// If the unit's raycast is hitting a grid object, turn that grid object a stronger shade and make the placement feel snappy
if (Physics.Raycast(placementray, out raycasthit, 50, activelayers))
{
// If current grid object isn't the same as the last one, turn the last one's shader back to normal.
// This lets us know when we've moved onto another grid
if (raycasthit.transform.name != lasthit.transform.name)
{
lasthit.transform.GetComponent<Renderer>().material.shader = shader1;
}
// Debug line for testing
Debug.Log("Ray is hitting: " + raycasthit.transform.name);
// Make the unit feel "snappy" when hovering above the grid so it's easier to place
transform.position = new Vector3(Mathf.Round(objposition.x),
Mathf.Round(objposition.y),
Mathf.Round(objposition.z));
// Finally, actually change the current grid that is hitting the raycast to the stronger shade
raycasthit.transform.GetComponent<Renderer>().material.shader = shader2;
// Now that we are on the current grid and have already compared to the lasthit (above), update lasthit to the new grid
lasthit = raycasthit.transform;
}
}