Sunday, September 27, 2015

Unreal Engine Diaries #5: GPU Profiling & Rendering Optimizations

  • The 'profilegpu' console command can be used to profile the GPU for a single frame.
  • The 'r.xxxxx ?' command can be used to get the tool tip for the particular rendering command that is being passed on as parameter.
  • Shaders can get really expensive when using World Position Offset and Tessellation. And speaking of World Position Offset, it can be used to manipulate the vertices of a mesh from it's material.
  • If there are lots of skeletal meshes in a game, the 'SkinnedMeshComp Tick' can get expensive. Reducing the number of bones of the skeletons or the complexity of the anim blueprints can help improve the performance in these scenarios. Also if you do not need the animation to update when you can't see the skeletal mesh consider setting the 'Mesh Component Update Flag' in the details panel of skeletal mesh component to 'Only Tick Pose when Rendered'.
  • The 'Smoothed Frame Rate' option in the Project Settings [under General Settings category] is used to render a No VSync frame capped version of the rendering. While doing GPU Profiling, it's a good practice to test it out without using this Smoothed Frame Rate.

Friday, September 25, 2015

Unreal Engine Diaries #4

Material Editor: In the material editor, we can add the 'Noise' node to display noisy patterns on the surface of a mesh. However it's very expensive and hence best used for prototyping or in rare scenarios where using an actual texture isn't justified.

Material Editor: The 'Particle Position' node can be used to get the location of a particle in space.

AI: The 'Bind Event to ReceiveMoveCompleted' in the AI controller can be used to automatically receive the status of a bot once it has completed it's movement order. It's got different states like success, aborted, blocked, invalid, etc and these can be used to have the AI respond to different situations with different behaviors. But if we have multiple events waiting for it's reply from different places, like say from different tasks in a Behavior Tree, all these bound events will start executing. And that might not be a desirable outcome. So in order to work around such a scenario, it would be a good idea to have a check on the current state of the bot in all these events and proceed based on that result. This could help ensure that even thought multiple events maybe fired, only the one that is suitable for the current state of the AI will see through to it's completion.

AI Perception: When using the 'OnPerceptionUpdated' event to detect potential targets, you may have noticed it does not give any details regarding the location of the source of the stimuli. But there is actually a method to retrieve this data. Just loop through this array of actors and for each actor, get it's actors perception ['Get Actors Perception' node], then break down it's output 'info' struct and loop through the 'Info Last Sensed Stimuli' to get all the necessary details like stimulus location, age, tag, etc.

Editor: Press 'Alt+C' in the map editor to see the collision data for all the meshes.

General: In Unreal Engine, most of the physics calculations are done by the CPU.

Wednesday, September 23, 2015

Unreal Engine Diaries #3

  • If we're displaying the game over screen as a widget that's added on to the viewport while the game is running, make sure that the game is paused using the 'Set Game Paused' command. Not doing this would mean that the actors in the level are continuously being updated in the background. Now sometimes it's fine to have the enemy actors move around the screen in the background, but even in those scenarios, it'd be a good practice to make sure that any constantly updating game element that's part of the player character/controller are turned off. An easy example to think of would be an actor in the level that is responding to the mouse cursor. So it might move around the screen, even while we're trying to click that restart button.
  • When creating a widget from within a task in a Behavior Tree, it's a good idea to make sure that it's not being called continuously. It's generally better to create widgets outside the task flow, within normal blueprints, but certain situations might demand widget construction from within Behavior trees in order to use some of it's functionalities that are not natively available in the blueprints. In such situations, there is a way to handle UI changes from the behavior tree tasks. Just add a 'Do Once' node inside the task before calling the widget construction logic. This makes sure that the subsequent iterations of the task don't create the widget unless explicitly specified. In my project, I've used this only in an end game scenario as one of the conditions for it was handled from within a Behavior tree task. It has since been replaced with a game pause call. So this makes sure that the Behavior Tree stops executing altogether, but the 'Do Once' node might be useful in other situations where you can't pause the game.
  • The world rotation of actors in a level, when broken down into their  x,y,z components lie within the range of (0,180) & (-180,0). When doing calculations based on actor rotation, this change in the values from positive to negative have to be taken into account. If we treat it like normal repeating cycles of (0,360), it might yield strange results in certain types of calculations.
  • When aborting a subtree in Behavior Trees, any task within that subtree that is actively running at that moment will not be aborted midway. It will see through to it's completion and if the task has delay conditions or code that changes some important data, this could lead to unexpected results if not taken care of. However it is possible to shut down these tasks at runtime through the use of conditional checks that gauge the current state of the game based on some external variable or blackboard values. Once we have determined that the task is to be aborted, we just call the 'Finish Execute' node to stop and get out of the task.

Monday, September 21, 2015

Unreal Engine Diaries #2

  • Useful Material Editor Hotkeys [Press these keys & click anywhere on the mat editor]: B = Bump Offset; E = Power; I = If condition; O = OneMinus; P = Panner; S = Scalar Parameter; U = Texture Coordinates; V = Vector Parameter
  • If you change any of the member names of a Struct in the Content Browser, the connections from the aforementioned members in all blueprints will get cut. As a result, you'll have to go around each of these blueprints and manually connect them again. So it helps to actually note down where you need to reconnect before making changes to a Struct.

    Also note that in v4.8 of Unreal Engine, these renamed members will have their input pins invisible the next time you check out those structs in your blueprints. In order to make make them visible again, click on the struct >> go to the details panel >> tick the checkbox next to the changed element to see it again. You'll however have to do this for every instance of the said struct.
  • An Unlit material means that we are only dealing with the Emissive and Opacity inputs.
  • Useful Material Nodes:

    The 'Radial Gradient Exponential' node can be used to create a circular gradient.

    The 'Particle Color' node provides data about the current color of a particle.

    The 'Depth Fade' node can be used in materials of particle emitters like Fire to have them smoothly fade away when they come in contact with any meshes. This node when connected to the opacity helps remove the hard edges which would be otherwise evident when a mesh obstructs the emitter.

Wednesday, September 16, 2015

Unreal Engine Diaries #1

  • When you're calling the function 'Get Random Point in Navigable Radius' [see link below], make sure that you store the vector return value inside a variable if you intend to use it in multiple scenarios later down the line. Otherwise, it ends up creating different randomized vectors each time it's used even though you're taking the same return value. It's kind of obvious as those are different function calls, but sometimes in the heat of the battle, it's easy to overlook small things like these.
  • Blackboards can be cleared from within blueprints using the 'Clear Value' function [see link below]. This is especially useful in scenarios where you're dealing with vector blackboards. Setting it to zero in this case is not ideal as it actually represents a location in the game space. 
  • Basic workflow for creating splines: Create a spline component in your blueprint >> Set it's world points by passing in the vector data [see link below] >> Add a spline mesh component >> Set static mesh >> Set material for the mesh >> Get the location (and tangents, if necessary) at the stored spline points [see link below] and use this data to set start/end points as well as tangent vectors for the spline mesh. [Do a for loop with the spline points data, if you have more than two points]
  • Select a group of blueprint nodes, right click and select 'Collapse to function' to have the editor automatically create a function encompassing those nodes.
  • It is possible to increase or decrease the rate at which an animation is run, by adjusting the Rate Scale in the details panel of the anim sequence.

Documentation Links: