This week we started a new game called Gem Search. Here are some of the key design points:
- The player can wander freely in a low-poly 3D environment with a first-person perspective
- There are random gems hidden around the environment
- Gems come in four levels
- Each level has several variants of gem
- The player holds a detector in their hands; a gauge and an indicator light show proximity to a hidden gem
- When very close to a gem, the user can dig to recover it and it will be placed in their inventory
- Each gem has a score value proportional to its level and scarcity
- The detector can initially only detect the lowest level gems
- Gems can be combined to make higher level gems
- Gem combination recipes are randomised each play-through
- When combining gems the original gems are destroyed.,
- If gem combination is successful, a single gem of the next level is produced
- Once a gem of a higher level is owned, it can be installed in the detector; the detector can then detect gems of that level
- The player is against the clock to get the highest possible score
Creating a New Project
We started first by creating a new project called “Gem Search”, using the 3D core template.
Asset Store
We took two free assets from the Unity Asset store as a basis for our game:
- Starter Assets – First Person Character Controller
- Author: Unity technologues
- Link: https://assetstore.unity.com/packages/essentials/starter-assets-first-person-character-controller-196525
- LowPoly Environment Pack
We logged into the Asset Store using the same login we use for Unity, searched for the above assets and on the web page for each one, chose “Add to my assets”.
After that, we returned to Unity and opened the Package Manager from the Window menu. In the package manager we changed the option from “Packages: In Project” to “My Assets”.

Our two packages from the Asset Store were then visible. We downloaded and imported them both. For the Starter Assets – First Person Character Controller package, there was an import warning about switching to the new input system, which we accepted.
We then spent a little time examining the assets we’d acquired; both asset packs have demo scenes in them.
Setting up our Main Scene
We opened the LowPoly Environment Pack\Demo\Demo 3 scene and, after creating a Scenes folder at the top-level of our project, saved a a copy of this scene there as “Main”.
We then did a few adjustments. First we deleted the existing Main Camera. Immediately the fog in the scene was apparent (settings on the camera was suppressing it). We looked at where the fog settings were specified (select Window | Rendering | Lighting and then look on the Environment tab of this panel) and saw how it was causing a problem for the Scene View if we were zoomed out far enough to see the entire scene. We disabled the fog in the Scene View (it will still be visible in the game) from this drop down:

We noted that the entire terrain was offset by -2.6m vertically and rotated by 100% around the vertical. It woulds suit us better if it was square to the world and at (0, 0, 0). The difficulty was the if we moved or rotated the terrain, nothing would move with it and all the trees, bushes, rocks, etc. would end up misplaced. The solution that we followed was as follows:
- Move the Terrain_2 GameObject out to the top-level of the hierarchy
- Move every other GameObject with a mesh (but not the empties they were previously children of) to be a child of the Terrain_2 GameObject
- Reset the transform on Terrain_2. As all other GameObjects are children, they move with it
- Move all the children from under Terrain_2 back under the empties that originally held them
- Move Terrain_2 itself back inside “Environment”
Now the environment is still organised as before, but everything is neat and square.
Raycasting and Defining the Ground
The ground isn’t level and we are going to be looking for the height of the ground at any point we want to position a gem using the something called Physics.Raycast(). A ray-cast shoots an invisible ray looking to see if it hits a collider of any sort. We can control many things about this operation including:
- The location that the ray starts from
- The direction the ray points in
- The maximum distance the ray can project
- Which Layers to look at
All GameObjects start out in the “Default” layer, but it’s often handy to put things in specific layers when we want to be specific about them. This is one of those times. With any GameObject selected, we can add a layer by clicking the Layer drop-down at the upper right of the Inspector and choosing “Add Layer”. We took the first non-assigned Layer and called it “Ground”.

We then filtered the hierarchy to isolate those GameObjects with a MeshCollider by typing “t:MeshCollider” in the box at the top of the hierarchy. This showed that terrain and the rocks were the only ones; this is exactly what we want. We used Shift to select all of them and then changed them to layer “Ground”. We then cleared the box at the top of the Hierarchy to remove the filter.
Creating a Prefab for Testing
We made a Prefabs folder at the top-level of the project, right-clicked and choose Create | Prefab. We renamed this prefab Lamp Post and combined a plane, a cylinder and a lamp, using some materials that came from the LowPoly Environment Pack, into a simple lamp-like shape 2m tall:

Creating the Item Scatterer
We set out to create something that could scatter gems across our ground surface, comprised of the terrain and the rocks.
We made a scripts folder and created as new C# script there called ItemScatterer.cs.
Editing this we added a single property to start:
public Vector3 size;
This is to represent the size of the area over which we’ll be scattering our gems. It would be nice to be able to see this area. Unity allows you to draw Gizmos which show up in the Scene View (but never in the game). We add the following code:
private void OnDrawGizmos()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireCube(transform.position, size);
}
This is going to draw a yellow wireframe box at the position of the GameObject this component is attached to at the requested size.
We add an empty to our game, and call it “Item Scatterer”. We then attach our latest script to it. Setting the size to something like (150, 150, 150) we can see a large yellow box outlining our area. I move the area slightly to centre it closer to where the most trees are on the environment.

We progressed the scatter code a little, but I’ll cover it fully in next weeks notes.
Code Download
The code for this week’s project is on our GitHub, as always.