With the release of Godot 4 and the improvements to 3D support, I have started testing out the 3D features by making a few small games. My first game has been a small camping scene with a first person character to explore with.

I started with a first person character controller which was mostly similar to how it is done in 2D Godot games except the camera movement requires a bit of extra logic to detect mouse movement and rotate the camera accordingly. The player also has a spotlight that can be turned on or off since the scene will be dark, and it will make it easier to see.

The scene I created consists of a tent and a campfire surrounded by taller trees, with some rocks and bushes scattered about. To start with, I followed a YouTube tutorial by DevLogLogan to learn some good practices for creating models in Blender and exporting to Godot. After I learnt the methods for creating low poly models with collision and applying textures, I created models for a rock and a bush to decorate the environment a bit more.

Using a low resolution style for the project meant the textures didn't need much detail and were easy to create by randomly adding some similar colours to a plain texture, then adding a layer of noise with a low opacity. Since the process for creating textures has been mostly the same except for using different colours, I created a shader that takes a base colour as an input along with a noise texture and some other variables to adjust strength and scale. This has sped up the process for creating new models, as I no longer need to create a whole new texture. It would also be a good method to use for larger games with a similar art style to reduce storage size, but this does come at the cost of having a slightly reduced performance.

At this point, I had a small scene with a tent and campfire. To add some more interactivity, I created an interaction component which extends Area3D. The player has a RayCast3D attached to the camera which scans for nodes with an interact method. When the player presses the interact button, it will call the function on the node. The interaction component has an on interact signal which is emitted when the interact function is called, this way any node can connect the signal to trigger some custom logic when interacted with.