Slightly different approach

I was wondering if there is a way to make the grid system/visuals spawn on top of a terrain instead of predetermined height/floor??? Having floors is fine but I would rather have a single grid that is not confined by flat terrain. Is it doable? or should I say - How is it doable?

Yes. You’d probably want to look into decals. I suspect the visual would be a decal that can be projected onto the surface

Against a terrain, it’s rather tricky, as you’ll have to raycast for the true height so that you can set characters properly at various positions. There’s not really a good way to put the visuals on the Terrain. Bixarrio is right that the most likely best way is with a Decal, which is definitely out of scope for this course.

Thank you both for response. I have a feeling decals wont place my units properly on the top of terrain and they would rather clip into it, and raycasting was first thing that came to my mind aswell but I have no idea where to start. I will try to figure something out. Thank you again guys.

I was only answering for the visual because that’s what I read you wanted. Like Brain said, for the units you’d probably need to raycast down onto the terrain. You would perhaps also add a character controller on each unit so that they’d stay on top of the terrain as they move.

To raycast, you’d pick a spot above the terrain that is guaranteed to be higher than the terrain. It’s possible to calculate this, but probably easier to just pick a high number. Then shoot the ray down and use a mask that will only hit the terrain. So, the origin of the ray would be the world position of the grid position with the y-value updated to this high value, and the direction would be Vector3.down. This will then give you a new vector that would be the position.

I did not do the hex and multiple floors parts of this course so I am disregarding anything that happened in those, but here’s an extension method that could be useful

public static class GridSystemExtensions
{
    public static bool TryGetElevatedWorldPosition(this GridSystem gridSystem, GridPosition gridPosition, float maxHeight, LayerMask terrainMask, out Vector3 worldPosition)
    {
        var origin = gridSystem.GetWorldPosition(gridPosition);
        origin.y = maxHeight;
        var ray = new Ray(origin, Vector3.down);
        if (Physics.Raycast(ray, out var hit, maxHeight, terrainMask))
        {
            worldPosition = hit.point;
            return true;
        }
        worldPosition = Vector3.zero;
        return false;
    }
}
// Usage
if (gridSystem.TryGetElevatedWorldPosition(gridPosition, 1000, LayerMask.GetMask("Terrain"), out var worldPosition))
{
    // Move unit to worldPosition
}
1 Like

Privacy & Terms