GameDev Blog: Goblin Rules Football #28: Creating My First Golf Hole

I did it. I followed through on what I said I’d do. I said I’d try and make it so you can play one hole in golf (which was misspelled in my post as “whole” until just a minute ago), and I did it! I drew out the entire thing in tiles! Created a gameplay manager that tracks whose turn it is and stuff! It keeps score! Penalties for hitting into the water.

And the best part? After testing it like 100 times, I decided to record a video of it and I got an EAGLE!

Amazing! What a shot from the fairway with a driver right into the hole! Maybe I need to balance the driver hits a bit! But, then, I tried it again with some wind and got a much worse double bogey…

I really got to learn to read the green better, especially considering that I programmed it.

At the beginning of the second video, you can see the whole hole. It’s pretty big! The hole is 350 unity units (meters? yards?) from the tee off position.

Making the hole took quite a bit of time. Drawing tiles, then deleting them, drawing them again. All the different terrain types. It was quite an ordeal! And while doing it, I was thinking, am I going to have to create a new scene for every hole? That seems annoying. But wait! What if I just saved the location of every tile so it can be loaded in whatever scene I wanted? And one scene can just load the next whole by placing new tiles? Well, to do that, I did the second thing I said I would do but hadn’t yet, I used scriptable objects!

To do it, I followed this tutorial by Tarodev called “How to save Unity Tilemaps.” They go through how to create the scritptable object(s) needed to do everything, save the tiles, clear all tiles, and then loading the scriptable object to read and place the tiles on the grid! Wow! I expanded on this a bit do save everything I wanted to know about a “hole.” Where the hole is, the tee off location, how many trees/obstacles there are and where to place them.

The scriptable object for a hole is pretty simple, it looks like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.Tilemaps;

public class ScriptableHole : ScriptableObject
    [Header("Hole Information")]
    public int HoleIndex;
    public string CourseName;
    public int HolePar;
    public List<Vector3> HolePositions;
    public Vector3 TeeOffLocation;
    public List<Vector3> TeeMarkerPositions;
    [Header("Saved Tiles")]
    public List<SavedTile> GreenTiles;
    public List<SavedTile> FairwayTiles;
    public List<SavedTile> RoughTiles;
    public List<SavedTile> DeepRoughTiles;
    public List<SavedTile> SandTrapTiles;
    public List<SavedTile> WaterTrapTiles;
    public List<SavedTile> EdgesTiles;
    public List<SavedTile> DirectionTiles;
    [Header("Saved Obstacles")]
    public List<SavedObstacle> SavedObstacles;
    [Header("Camera Bounding Box")]
    public Vector3 CameraBoundingBoxPos;
    public Vector2[] PolygonPoints;
    // Line camera should take in the "intro" video?
    // "Hit points" for the player to aim at when their turn starts. Have a few of the "intended route"
    [Header("Course Aim Points")]
    public Vector3 TeeOffAimPoint;

public class SavedTile 
    public Vector3Int TilePos;
    public Tile MyTile; 
public class SavedObstacle
    public Vector3 ObstaclePos;
    public ScriptableObstacle ObstacleScriptableObject;

Then in my “TileMapManager” I just have some options to save, clear, and load the tilemaps!

It was so nice and convenient! It worked perfectly in the Unity Editor! Then, I decided to make a built version no real reason, and error after error prevented the game from being compiled. Why??? There were no errors when running in the editor…oh, it’s because nice “Save/Clear/Load Map” buttons. They were used by a script including the UnityEditor namespace. A few #if UNITY_EDITOR #endif statements later and it all worked. Phew…

After that it was just creating the logic for the “flow” of the game. Making the player tee off. Then hit toward the hole. Make a putt. Keep track of strokes. Detect which player was furthest from the hole to see who goes next. +1 stroke penalties for hitting into the water AND finding the closest non-water spot to place the ball. Oh and trying to keep everything open to work with more than one player (and maybe holes with more than one hole!). Fun stuff!

I’m not sold on this hole design, but it is my first attempt at making a hole and perfectly good for testing all this right now.

Next Steps…

There are still A LOT of stuff I need to implement to make this a real “playable” one hole of golf. I need to implement how the gameplay manager sets the weather/wind. I need to deal with the player going out of bounds. Both when they hit out of bounds, and when they try and aim out of bounds. I want to be able to confine the aiming target to the camera bounds, and detect when the ball goes out of bounds to give the player a penalty + relocate the ball (similar to hitting into water). Sounds like it will be fun?

Smell ya later nerds!