Saturday, May 31, 2014

Unreal Engine 4: Oculus Rift Outdoor Environment Work In Progress

I had thought about making this post somewhat of a step-by-step tutorial about using the Landscape tool in UE4, but upon researching there are already way too many great Landscape tutorials out there both in writing and on youtube.  In fact, Epic does have some amazing write-ups on the Landscape tool already like this one https://docs.unrealengine.com/latest/INT/Engine/Landscape/index.html.  If you are new to the Landscape tool in general, I suggest that you visit that link before continuing to read this post.  If you are already familiar with Landscape from UE3, you are in luck, because UE3 and UE4 landscape tools are extremely similar and most of the tools go by the same naming conventions, building a Landscape Materials and Landscape Layer Blend Materials are also the same in UE4 as they were in UE3.
So for post I would like to share how I utilized the tools in UE4 to make an environment for the Oculus Rift game that I am making.  Stylistically I am trying to go for something that is between photo-real and cartoonish by way of mixing less realistic sculpting with more realistic textures or vice versa… Upon starting my Landscape I had decided to begin with a fairly large Landscape, one that would cover the entire map and implement some realistic textures by way of layering textures with LandscapeLayerWeight nodes in the material editor.  So I started by making some realistic  textures, and porting them to UE4.  UE4 is more forgiving with texture file formats than UE3 was, but for portability and quality reasons I suggest to always stick with .png or .tga files for your textures in almost every scenario. 
After porting the materials, making the material itself works the same way it does in UE4, in your content browser you can just make a new Material and just drag and drop your textures into the material.  Making a LandscapeLayerWeight chain is the same as it is in UE3 as well, my results looked like so (again if you are new to this, my suggestion is to visit the like to the UE4 docs that I provided above).

As you can see from the photo above, I daisy chained the LandscapeLayerWeights, named each layer, and copied the layers over when adding spec maps and normal maps. 
After creating the material I decided to add them to my Landscape by just dragging and dropping the material onto the Landscape (if you create your material prior to making the Landscape, you can just add the material in the material slot before committing to the creation of the Landscape), but either way, they will not show up by default as you can see here.


You will see a little plus button to the right of each texture, there you will need to press it so that you can add a new Landscape Layer Info for each Landscape Layer (in this case it would be all of your textures since each texture is a layer).   Once this is done, painting textures is now possible on the terrain by simply selecting any material layer and using the paint tools to paint the materials onto the terrain.

It is at this point hard to judge if the textures are tiling too much or too little at this point, but the tiles from far away are pretty unattractive.  One can easily fix the tiles by going into the material editor, adding a Texture Coordinate material expression to each UV that I would like to adjust tiling to and simply change the tiling, but we will cover that a bit later in this post.
In addition to painting I decided to also start creating some topology here by using the sculpt tools.  I also wanted to see what the surfaces would look like with proper lighting.  In an outdoor scenario I always choose to use a strong Directional light (especially when casting daytime lighting) because it matches what outdoor lighting is in real life which is light covering a massive amount of area, moving in a single direction ie. The sun or the moon.

There are a few things I started to dislike about my environment other than the fact that the realistic materials that are tiled multiple times may not be what I want… I would have liked more ridged surfaces which could be done by use of the Noise sculpting tool… I also do not like the shiny surfaces, which part of the blame is my spec map, but the other part of the blame is that the default material shader in UE4 has some specular shader to look reflective, this can be corrected which I will show how to do a bit later on… Having reflective surfaces like this aren’t bad especially for wet surfaces, but in my case, I have an environment that looks like plastic.  Stylistically, I decided that this is not what I want, so I decided to start over and try an opposite style which is realistic surfaces with cartoonish, single tiled textures.  Moreover I decided to use a height map which can be created in a number of programs like Photoshop (which is what I often do), but there are other programs out there like World Machine, which allows a user to built topology within the program and be given 2D views of their color map and height map, along with 3D views of their color map and height map applied onto a plane, this is a major step up from programs like Photoshop.  So I created a height map in World Machine with textures that I liked, and ended up with height, color, normal and spec maps that look like this.
Height
Color
Normal
Specular

I then ported all of these into UE4, and this time upon creating my Landscape, I created it through importing a height map…. Note that your height map must be either a grayscale 16-bit PNG, or an 8-bit .RAW file.
I also created a new Material which only had my Texture Sample, Normal Map and Spec map.


But upon applying the material to the Landscape, the material for my Landscape looked like this.


The issues here are that the spec map is causing even more shininess and the textures are being tiled over too many times, only a single tiling should cover the surface… So to fix these issues I added more material expressions, like Texture Coordinate and I set the U and the V to something very low like .00045, so the material stretches across the entire surface.  I also added a constant to the specular and made the constant 0 so I have absolutely no shininess covering my surface.


Looks much better!
I also needed to play with things like lighting, fog and the sky.  I first added my directional light again, but this time I did add a little bit of a yellow tint to the color of the lighting because generally outdoor lighting in real life is not a straight white color, you can determine what color your lights should be when creating your levels.. Lighting should not be overlooked or rushed in any way since it determines the mood of your levels. 

Also, I added some exponential height fog to my level because I am planning on having a very foggy valley but I also do not want the player to see the lower edges of the Landscape when they look out into the distance, fog is a great way to cover up these spots.  With Exponential Height fog and Directional lighting, a ground view of my environment looks like this.

Next I added an Atmospheric Fog and adjusted the rotation of the fog.  This Fog is awesome because it not only creates a fog that can set a color gradient which can be displayed in the sky, but it also comes with the ability to enable a disc which can act as a sun.  For my level there is really no need to have a sky dome, the Atmospheric Fog does everything that I want it to do.

Upon looking around my environment I did start to notice many areas that needed touching up, particularly areas that had some flat plateaus that I wanted smoothed out.


By use of the Erosion sculpting tool I was easily able to smooth these out, but upon a lit environment some stretching showed.  No worries, the Smoothing tool does the trick here!  So these are final results by use of working with a small area by use of a conjunction of various sculpting tools like the Erosion and Smooth tools…


Note the plateaus are okay and can be rather realistic, in fact I chose to keep many of them in different areas of my level, there were just some areas where I wanted these plateaus and other areas where I wanted more of a smooth surface.
These are my final results.

Later on this week, I will be adding water into the valley and I may be revisiting some alternative textures for my level.  In addition to this I will be adding the music that I would like to use for this particular area in the game and post a video that includes all of this.  I may be showing off some alternate screenshots and/or videos which may include various gameplay speeds, textures, lighting and water.  So I will be looking for input on all of these things via blog responses or social networking.  Stay tuned!




Monday, May 26, 2014

Unreal Engine 4: Come Fly With Me, an Oculus Flying Rail Shooter

Those who have already migrated from Unreal Engine 3 to Unreal Engine 4 know that Unreal Engine 4 is vastly different and that there is a lot to learn… Over last summer I had acquired an Oculus Rift for the purpose of development in UDK.  The project has been just a personal side-project where I had been focused on developing a first-person Star Fox style rail shooter.  Many parts of the project I would like to keep secret until development is in more complete stages.  Since the public release of Unreal Engine 4, I am now focused on migrating my project to Unreal Engine 4, this does mean starting the framework of the project over since Unreal Script is no more, but the logic behind my game will remain the same, so it is a matter of working with different syntax and a different (yet in some ways similar) editor. 
Those who have dove into Unreal Engine 4 know that we have full access to C++, and all the coding can be done in Visual Studio through C++.  For many programmers C++ can be daunting but I assure you Epic Games has done an excellent job with providing an initial framework and many helpful functions which can be used by developers like us.  So let’s get started…
My first steps in redeveloping my game in C++ is to set up my player, controls, physics ect.  For me, a great starting point was the Code First Person which was provided as a starting point by Epic. 


The defaults for this project is a character mesh in first person view which holds a weapon and can walk around in full 3D space.  We of course need to change this up quite a bit if we are to make a Star Fox style rail shooter.



The first steps I will do is change the way in which the player pawn is controlled.  In your newly made Visual Studio Project (note, I am using Visual Studio 2013 for this), you will need to go into your source directory within your project, and find your Character.cpp and Character.h files (this would normally be named [the name of your project]Character).  I will first notice that functions for MoveForward, MoveRight, and turning are already written for us, but I will need the player to move up, a simple way to do this is to copy the contents of an existing movement ( MoveRight), and modify it so that it uses up and down directions.  The MoveRight function looks like this.
void AOculusGameCharacter::MoveRight(float Value)
{
       if (Value != 0.0f)
       {
              // find out which way is right
              const FRotator Rotation = GetControlRotation();
              const FRotator YawRotation(0, Rotation.Yaw, 0);

              // Get right vector
              const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

              // add movement in that direction
              AddMovementInput(Direction, Value);
       }
}
I will copy it over and modify it by declaring a new function in  the Character header file.
void MoveUp(float Val);

Then calling the function in the Character cpp file.
void AOculusGameCharacter::MoveUp(float Value)
{
}
 Then following the logic of the MoveRight function to find which way is up and down using pitch as a rotator instead of yaw.
const FRotator Rotation = GetControlRotation();
              const FRotator PitchRotation(0, Rotation.Pitch, 0);
Followed by setting the direction vector to the Z direction instead of Y.
const FVector Direction = FRotationMatrix(PitchRotation).GetUnitAxis(EAxis::Z);
And then setting the input to move that direction when the input is pressed.
AddMovementInput(Direction, Value);
You can then encapsulate this logic in an  if condition which finds if the value of the input is not equal to 0.0, then do the movement logic.  Note, this function listens for an input and that input gives us a value depending on a scalar that we can give that input, so in theory we can have the Up key scale the value parameter by 1.0f which will set the Z direction positive which is up, and we could have a Down key scale the value parameter by -1.0f which will make the Z value negative thus moving the character in the down direction.  When we are done writing our function we can make the inputs for this.  In the end my MoveUp function looks like this.
void AOculusGameCharacter::MoveUp(float Value)
{
       if (Value != 0.0f)
       {
              // find out which way is right
              const FRotator Rotation = GetControlRotation();
              const FRotator PitchRotation(0, Rotation.Pitch, 0);

              // Get right vector
              const FVector Direction = FRotationMatrix(PitchRotation).GetUnitAxis(EAxis::Z);

              // add movement in that direction
              AddMovementInput(Direction, Value);
       }
}
Now we need to have button inputs scale the Value parameter as I mentioned in the paragraph above.  So head into your Config folder and open DefaultInput.ini.  You will of course notice ActionNames and AxisNames, since we are scaling a parameter and applying it to a scalar, we will be using AxisNames.  Since we have 2 keys to use, I we will need to have two AxisNames both equal to Move Up.  So to have W equal to the up direction this would be the input for up.
+AxisMappings=(AxisName="MoveUp", Key=W, Scale=1.f)
And if we were wanting the character to move the down direction by pressing the S key, we would simply change the Key to S and change the Scale to -1.f so it can set the Value of the MoveUp parameter to -1.  Additionally, if you already have W and S movements for functions like MoveForward, you should comment these out or delete them.
+AxisMappings=(AxisName="MoveUp", Key=S, Scale=-1.f)
Lastly, you will need to head back into the Character.cpp file and set the key binding for MoveUp within the SetupPlayerInputComponent so that when the player does press one of the MoveUp buttons, it calls the function which sets the direction and character movement.
InputComponent->BindAxis("MoveUp", this, &AOculusGameCharacter::MoveUp);
This should compile with no warnings or errors, but the character will not move up or down at will because by default the character’s physics is set to Walking, which won’t allow a player to move freely into the air.  We need to set the character’s physics to Flying.  In theory you can set this wherever you want, but logically you will want to place this in a spot where it most logically will start.  Since I want flying to start upon player interaction with the game and player starts controlling the game upon firing, I will put a calling to Flying right at the top of the OnFire function.  I may change the way in which the player starts on a future date, but for right now having the player Fire and start will work out for what I am trying to do.  Below is the code that sets the players physics to Flying.  As opposed to Unreal Engine 3, Unreal Engine 4 will use SetMovementMode rather than SetPhysics, inherently this is very similar, since SetMovemementMode contains an enumerator that has various character movement modes such as MOVE_Flying, MOVE_Walking, MOVE_None, ect.
CharacterMovement->SetMovementMode(EMovementMode::MOVE_Flying);
If you play test this you should notice that upon firing, the player will be able to freely fly in all directions… But I want to allow our character to move on a rail and again, similar to Star Fox.  So the easiest way to do that would be to go back to the Character.cpp file and change the MoveFoward function to automatically MoveFoward.  To do that I will eliminate the need to press a button by removing the if condition that checks to see if the Value is not equal to 0.  I will then zero out the YawRotation variable, because forward will just be whichever direction the player spawns at, we no longer care about direction other than what forward is.
FRotator YawRotation(0, 0, 0);
Then I can set the value of AddMovementInput to some constant (note, the higher the constant the faster the player will move forward, I am setting mine to 1).
 AddMovementInput(Direction, 1);
When finished, my MoveFoward function looks like this.
void AOculusGameCharacter::MoveForward(float Value)
{
              // find out which way is forward
              const FRotator Rotation = GetControlRotation();
              FRotator YawRotation(0, 0, 0);

              // Get forward vector
              const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);

              // add movement in that direction
              AddMovementInput(Direction, 1);
       }

Upon play testing we get closer to the results we need, but the player will now rush forward immediately before the player presses fire to actually start playing.  So I figured the best thing to do is to encapsulate the movement logic into a bool.  If the bool is true, we MoveFoward, if not we do nothing.  So you would need to declare a bool variable and define it as false somewhere outside of your function.
bool started = false;
Then upon firing (since firing starts the game at this point), set started equal to true. I set this at the top of my OnFire function.
void AOculusGameCharacter::OnFire()
{
       CharacterMovement->SetMovementMode(EMovementMode::MOVE_Flying);
       started = true;
       // try and fire a projectile
       if (ProjectileClass != NULL)
       {
              const FRotator SpawnRotation = GetControlRotation();
              // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
              const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

              UWorld* const World = GetWorld();
              if (World != NULL)
              {
                     // spawn the projectile at the muzzle
                     World->SpawnActor<AOculusGameProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);
              }
       }

       // try and play the sound if specified
       if (FireSound != NULL)
       {
              UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
       }

       // try and play a firing animation if specified
       if(FireAnimation != NULL)
       {
              // Get the animation object for the arms mesh
              UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
              if(AnimInstance != NULL)
              {
                     AnimInstance->Montage_Play(FireAnimation, 1.f);
              }
       }

}
Lastly, I encapsulated the logic within my MoveFoward function in an If started equals true.
void AOculusGameCharacter::MoveForward(float Value)
{
       if (started == true)
       {
              // find out which way is forward
              const FRotator Rotation = GetControlRotation();
              FRotator YawRotation(0, 0, 0);

              // Get forward vector
              const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);

              // add movement in that direction
              AddMovementInput(Direction, 1);
       }
}
So the logic is basically, started equals false at the start of the program.  When the player presses fire, start is set to true which also begins to move the player forward.  Upon testing the game now, you should notice that the player moves freely up, down left and right, and gets pushed forward.  You will notice that the player can still turn their view with the mouse button, since we are constantly moving forward, when the player turns the player will not switch directions which is exactly what I want.  If for whatever reason you did not want that, for instance if you did not want “head turning”, you can eliminate the functions and function calls of turning (or the keybinds that allow for turning , which is even easier).  Since we are building this for the Oculus, I want the player to freely be able to turn their head as they are flying through the air, again this is a pure design call…
I also want my game to work with the Xbox 360 controller.  By default most of the keybinds are in the DefaultInput.ini file for these controls, but MoveFoward is set to the left stick Y direction (up and down),  we need to set MoveUp to be in the Left stick Y direction instead.
+AxisMappings=(AxisName="MoveUp", Key=Gamepad_LeftY, Scale=1.f)
The right analog stick is set well for the Y direction, (LookUpRate), but not set for the X direction, so to do that I will make the X direction to call turning.
+AxisMappings=(AxisName="Turn", Key=Gamepad_RightX, Scale=1.f)
Since the logic for these functions are already set up, we do not need to do anything else.  If you are doing this all from scratch just note that the logic is very similar to the logic that we did above for MoveUp, we will just be calling and utilizing different axis. If you play test this, you should notice that your Xbox360 controller should work well with the left thumbstick moving the character around, right thumbstick allowing the character to look in 360 degrees, and right trigger allowing the player to fire.
In accordance to my design, I also do not want the player to actually see the character mesh, however upon later testing I may decide to use a character mesh.  So for now one of the tricks that I utilized within the inlitization of my player character in the Character.cpp file is SetOwnerNoSee() which is a function call that can be set to true or false.  If it is true, the player cannot see their own mesh, and if it is false the player can see their own mesh, so I set this to true.
Mesh1P->SetOwnerNoSee(true);
We will now be able to test out the Oculus Rift with this and see if everything with the Oculus Rift works with our likings.  Lucky for us, Oculus Rift for Unreal Engine 4 is plug and play so we may not have to do anything in order to get it to work.


 Just kidding, the Star Fox music is just for fun.  I have something much better in mind for the real game.  In the next Unreal 4 blog I will show what I have done with Landscape.  So I will take a little break with coding and play around with creating an environment that fits the game.