I was having some fun with 3DS Max and created an air ship. I’ve been spending the past weeks getting it flying in the Unreal engine, and getting some basic AI to see if I can get it to navigate in 3D space.
I used to play a lot of Garry’s mod when I was younger. Whenever you wanted to make something fly you would give it hover balls to lift it at certain points. This whole thing reminded me a lot of the buoyancy spheres I used when creating my ocean, except in reverse. So I created a hover ball game objects that would split the weight of the object among them and then apply equal force to get them the object to float perfectly on the spot. This was way more successful than I original thought it would be and I was even able to split the distribution of force among them to create a sort of procedural animation. I also stuck some fans onto the airship that would speed up or slow down depending on the amount of force being applied to its respective hover ball.
I also had to sort out some AI for the cannons on the side of the airship. This was harder than I thought it would be, but proved an interesting math puzzle. In the end I got it to aim perfectly at the target regardless of the turrets orientation.
Lastly I got some AI onto the airship to get it to follow patrol points, attack the player, or flee. The end result was really cool, as the airship would instinctively perform a 3 point turn to turn around. This was because instead of having the AI move the ship, it moves a virtual joystick that moves the ship. Creating a more natural and less clunky movement system. The video below shows me setting up a patrol route and letting the airship navigate it.
It has been fun programming this ocean, and I want to optimise its use. What I want to use is a method projecting a flat plane from the camera and its frustum onto the ocean, and then use this plane to create my ocean. This would mean that in terms of the mesh i use for the ocean I will be making use of all of its vertices. A really cool method that was also mentioned in the article about the tech behind assassins creeds oceans that inspired me to start this (Assassins Creed Tech Article).
In the image below you can see what i have to do to get this method to work, not only to i have to project onto this invisible plane, but have to account for what to do if the projection does not hit the plane. So all i have to do is reflect the vector off the roof and fire it back down, some fun little math to get this working.
Accidentally left my music on during the video posted below, so enjoy the Persona 3 sound track.
I even managed to take this further by using a really cool site called Desmos to form some equations to force vertices to cluster around the point of focus on the ocean, making even more efficient use of the vertices, meaning i no longer have half of them rendering parts of the mesh being projected onto the horizon. Below you can see the equations on the site and the effect of the clustering.
I wanted to implement buoyancy in order to get object floating on my ocean. The way I implemented this was through buoyancy spheres. This is what was used in Assassins creed to implement buoyancy in an efficient and accurate manner. Multiple buoyancy spheres are attached to objects in order to provide an approximation of the objects shape. Below I have attached some buoyancy spheres onto a cube. I can then check the height of the ocean at each point of each sphere and determine how much of it is submerged to determine the amount of upwards force.
I factoring in 3 forces into these physics, gravity, buoyancy, and drag. I was having a few issues initially with reaching an equilibrium that would have the objects settle and float normally on the ocean. In the video below you can a real propulsion of objects out of the water.
I added some debug arrows to my buoyancy spheres to represent how much of each force was being applied to each one. This helped me find where the issue was in my math and find the point of equilibrium in my buoyancy. The green arrows is the force of gravity, blue is buoyancy, and yellow is drag, and purple is the overall force.
In the end I got some good results, I was really happy with the approach of buoyancy spheres. They provide great results with a low cost and a flexible application.
I love games which can change the entire mechanics of its self by creating a world that is something different. This is what the Mario Galaxy games did by creating planetary bodies to open up a variety of new mechanics that otherwise would not have been available. And this is also something Assassins Creed Black Flag did with its ocean, creating a non-static world that was something I had never experienced before. It was a world with a personality, that could work with or against you.
Ever since I played the game I wanted to figure out how there ocean worked and create it. Lucky for me I came across an article that interviews an Ubisoft employee who explains how the ocean works entirely (Assassins Creed Tech Article).
One of the first thing I wanted to get right before anything else was getting the waves procedurally animating on a plane. With a series of values that I could adjust to change the size, speed, or shape of waves. Before I could do any of this I had to study into Gerstner waves. A Gerstner wave is a wave that forms peaks and troughs. And the collective Gerstner waves is a summation of multiple individual Gerstner waves of different amplitudes and wave lengths to form a fractal implementation.
I decided to work with the Unreal Engine, because I enjoy working with its Blueprint system for creating shaders. The implementation of Gerstner waves into a shader also went rather well with the use of this GPU gems chapter of water simulation (GPU Gems Water simulation Article). Helpful laying out all the equations I need to implement this functionality. Though I came across an annoying issue that I have never seen before. For some reason Unreal Engine shaders do not use radians or degrees. Instead they use a normalised value between 0 and 1. So 2pi (Radians) = 360 (degrees) = 1 (Unreal). I do not understand why it does this, but it took a long time to debug.
I managed to get the shader set up, and a manager that could send down values to the shader in order to control the shape, speed, or size of the waves being created. The end result was very effective, and am quite happy with this first step.
I was digging through my old USB and found my old Unreal Tournament 3 level I made years ago. I love making levels in games, and loved this game to death. Though it would be cool to post some level images here. The level I made was built for the scavenger vehicle, with a nice Japanese style village. I also got some Majora’s Mask references in there, with a working clock tower that ticks around and spawns a vehicle after a full rotation of the clock face. Download link below for .ut3 and .upk files.