Friday, November 22, 2019

Week 8 and 9.1 - Making a Robot Companion

Going into the final 3 week project I wanted to work a bit more with Blueprints, so I chose one idea from the VFX Brief:
  • Small flying drone that follows player, orientation controlled by velocity.
However, depending on the time, I would like to experiment with some other features for the drone/robot.

EDIT: The video's were made during week 3 of the project, so they have the current model instead of my placeholder one.

Placeholder Robot vs. Semi-finished Robot


1 - Location
I broke down updating the Robot's location into 3 parts, making seperate functions for each to keep it more organized, however, they still use each others results.

  1. X/Y Location
  2. Z Location
  3. Avoiding Obstacles

1.1 X/Y Location
The way I currently update the XY-Location needs some improvement, I will go into the reasons whilst explaining, how it currently works.


Update XY-Location Overview
When updating the Location the function is currently checking, if the robot is supposed to follow the player. If not, then it decelerates from its current speed to 0 and waits until follow is enabled again.
If follow is set to true it checks, whether the distance to the player is below a certain threshold or an obstacle is in the way. Since I only want it to accelerate when both are false, using the logical "or" was the only way. I added a table to hopefully make this a bit more clear.

UE4 Logical OR
The logical OR only returns false, if both inputs are false, otherwise, since at least one input is true it, returns true.

Conditions
The acceleration is currently linear, I might see if I can change it to be exponential, maybe by using time passed since starting to accelerate or something similar.
For quite some time I also had the problem that I used a set value for acceleration, so depending on the maximum speed the robot wasn't able to stop in time and would get stuck in the player.
I was able to circumvent that by changing it from just adding a certain amount of acceleration per Tick to first of all multiplying acceleration by World Delta Seconds ( to make it frame rate independent ) and then by Maximum Speed squared ( which is then multiplied by 2 for deceleration, it seemed to work quite well ). That way the acceleration and especially the deceleration is exponentially greater, when the speed is higher.


Sorry about the bad quality, I will try to make a better video at a later point. The video also doesn't show the slower acceleration, that I changed to later.

Acceleration, Deceleration Setup
After figuring out the acceleration and changing the current speed, the current speed then gets clamped between 0 and Maximum Speed to prevent it from speeding up infinitely. I then multiply the normalized direction vector ( Magnitude = 1) by the current speed to get the velocity and update the Location by adding the velocity to the current world location.
Another small feature I added is adding the player velocity multiplied by an Alignment Multiplier to the Robot's velocity, so that it not only moves towards the player, but based on the player's velocity also head in the player's movement direction, which is quite nice, if the player is making sharp turns.

1.2 Z Location
Updating the Z Location has 2 parts as well. The first one is just a general up and down motion, to give a nicer floating effect. It uses two layered sine waves with different "wavelengths" and "waveheights" to create a slightly irregular Z motion.

Z Sine Motion
Furthermore I needed to make sure, that the robot stays above the ground at a more or less consistent height, so I made another function specifically for that.
It works, by linetracing straight down from the robot's location plus some offset on the Z Axis, so that it can move up terrain higher than its current Z location. However, depending on the current velocity the starting position moves along the velocity vector adapt to terrain height changes in time.

Stay above ground - Line Trace
Stay above ground Setup
Once the Line Trace hits something I can get the current distance from Robot to ground, compare it to the desired distance and adjust the Z location based on that.

1.3 Avoid Obstacle
The avoid obstacle section is definitely still a weak point in the movement system and needs quite a bit of polishing. Here I essentially had to make a choice between a 2D and a 3D approach, 2D meaning looking for unobstructed paths on the XY-Plane, whereas in the 3D approach the search happens in the XYZ Space. In the end I chose the 3D approach, because the 2D one requires at least one Direction on the XY-Axis to be unobstructed, because otherwise the Robot is more likely to get stuck.
After some research I found a thread on Stackoverflow, that explained several ways of equally distributing points on a sphere.
Link: https://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere/44164075#44164075

Stackoverflow Code Examples
Also I found a great video on Youtube going into simulating swarm behavior, that used a similar approach in Unity, called "Coding Adventure - Boids" by Sebastian Lague.
Link: https://www.youtube.com/watch?v=bqtqltqcQhw

Points on Sphere Blueprint
Points on Sphere Visualisation


Essentially this function returns a set of vectors, that I can use to define the Line Trace Direction to check for unobstructed paths.
Per Frame the Robot goes through the following queries:

In Blueprint it looks like this:
Avoid Obstacle Blueprint Overview

Check for Obstacle

Find unobstructed path

As I said the system is not perfect by any means. Yes, it works in most cases, but sometimes the Robot's movement gets quite jittery, so I will have to see, if I can fix that somehow.


2 - Rotation
At the same time I was figuring out, how to update the Robot's Rotation. I decided to handle the rotation towards the player in World Space purely on the Z Axis and then I could handle the leaning/banking (X and Y Axis) based on velocity separately in Local Space. I also want the Robot to stop rotating once the distance to the player is below a certain threshold, I tried without it and crazy things happened.

Robot Rotation Blueprint Overview
 2.1 Z Rotation
For the World Space Rotation I get the Rotation by using Find Look at Rotation on the with the Robot's Location and the Player Location ( again plus the Player's velocity multiplied by the Alignment multiplier ). I then use RInterp to update the Rotation over time for a smoother transition.

Z Rotation
2.1 XY Rotation
To create the banking/leaning into turns I compare the Z Rotation from the previous with the current Tick (X Axis Rotation).
For the Robot to lean forward when moving I compare Current speed with Maximum Speed and adjust the angle accordingly (Y Axis Rotation).

XY Rotation


No comments:

Post a Comment