Telekinesis System
Combat Design Solo Project
Inspired by such systems as telekinesis in Control (2019), force powers in Jedi Knight: Jedi Academy (2003), and the gravity gun in Half-Life 2 (2004).
Developed in Unreal Engine 4 & 5 using Blueprints
My system aims to explore an implementation of telekinesis in which the object the player selects in the environment is launched towards the player’s target from its initial position rather than being called to the player’s position first.
This seemingly simple difference has many design implications, foremost of which is the player’s ability to hit a target from a variety of angles rather than just head on.
I gave myself two main constraints while designing this system:
First, I want players to be able to catch speedy objects and projectiles out of the air without requiring a high skill-level.
Second, I want to play this system on a controller, so point-precision aiming must not be required to play well.
The solutions to these constraints that I implemented were time-dilation and aim-assist, explained in detail later on.
BASE SYSTEM
Design & Implementation
The basics of my telekinesis system is pretty simple. The player will aim at and “shoot” a throwable object in the environment to select it. Once the player has a selected object, the next time they “shoot” that object will be launched at the point or object where the player is aiming. Using some vector arithmetic and a couple line traces, it was pretty easy to implement launching an object in this way.
Problems & Solutions
However, the basic implementation brought to light a few issues that I had not considered previously. Many throwable objects are lying on the ground when they are selected and launched. Contact with the ground caused some collision issues and awkwardness in using the ability. To solve this, the system checks if an object is close to the ground when selected, and if it is, will hover the object a bit off the ground to avoid these issues.
Another problem is with speedy projectiles flying through the air. When selected, an object would continue to move at speed, making precise aiming near impossible. To solve this, I tweaked the system to reduce an object's velocity by some fraction when selected. After some playtesting, I settled on a 90% reduction to give a good feeling of control for the objects over which the player has power.
The final issue was that it was difficult to know which objects the player was interacting with at any given time. In my whitebox testing, all the throwable objects were identical little spheres, and there were often dozens on screen at once. There was no visual indicator of what object was being aimed at or selected. To solve this, I added a simple highlight system that gives an outline to an object while the player is aiming at it. The object the player currently has selected has an outline of a different color. This fix helped immensely with readability and made the experience much more enjoyable.
Time-Dilation
Design & Implementation
Because I wanted players to be able to catch speeding projectiles out of the air without a high level of skill, adding a time-dilation (bullet-time) feature was a no-brainer. My implementation slows down time in-game while the player is aiming, letting even an unskilled player feel fast and powerful.
However, a time-dilation feature needs some constraints to prevent it from being game-breaking. There needs to be a limit to the amount of time a player can spend in the time-dilation state, otherwise a player might never leave it. This would remove the necessity for the player to make quick on-the-fly decisions, remove any sense of difficulty, and all around be pretty boring.
The solution I implemented was a simple mana bar that would deplete while the player is in the time-dilation state, and recharge while out of it. With some balancing of the depletion/recharge rate and maximum amount, the mana system gives the player access to time-dilation when needed, but retains much of the exciting and challenging aspects that the telekinesis system provides.
Aim-Assist (With Custom-Made Cone-Trace)
Design & Implementation
One design constraint was to make this system playable on a controller without requiring a high skill-level to play well. Since precise aiming can often be difficult with joysticks, I wanted to implement an aim-assist feature to help players on controller get past this issue.
The aim-assist I wanted to implement is fairly simple in concept. If the point at which the player is aiming is close to but not directly on a desirable target, just rotate the camera slightly towards that target each frame.
The rotating part was done using interpolation with a “strength” variable that can be adjusted until the aim-assist feels good (i.e. not too overpowering but still helpful).
Finding the point towards which to rotate the camera was much more difficult. My first attempt used a basic sphere trace that would just use the first target hit as the interpolation target. This method had some problems. For objects at a close distance to the player, tracing with a large sphere would cause the camera to simply gravitate to whatever object is closest, making selection of a specific target difficult. A small sphere works well and gives the player the ability to precisely choose the object they want. However, at far distances (where aim-assist is most important) a small sphere is not very effective and a large sphere would be better.
The ideal shape for the trace would be a cone that has a small radius near to the player and a large radius at a distance. But, as there is no cone-trace native to Unreal Engine, I had to make my own.
My custom cone-trace solution involves approximating a cone using a series of short sphere traces with progressively larger radii.
The cone-trace takes an argument for angle and number of segments, and then performs several sphere traces using the number of segments to determine where each individual trace should start and end, and the angle to determine how large the radius of each trace should be.
This system works pretty well. The player is able to aim precisely at both close and far range with the aim-assist providing the needed help for aiming on a controller.