itch.io is community of indie game creators and players

Devlogs

Between the Folds #008 - Abilities: Glove

WHALIEN - Unexpected Guests
A downloadable game

In the next few weeks, we are finally going to talk you through the core mechanics of our game. WHALIEN is all about pushing and pulling. For this, our protagonist Ernest Hemingwhale owns a set of gloves to grab and push away objects in his vicinity. Later, he also finds two magnetic pearls that can be thrown and suspended anywhere in the level and thereby push and pull objects located farther away. We can make any object influenceable for our gloves and pearls by adding a WhaliumComponent to it.

This first post is going to give insight on the idea and inner workings behind the glove ability.

Glove

CollisionBox

At its core, our Glove consists of a collision box that overlaps with all objects that have a WhaliumComponent. Each frame, it iterates over all overlapped WhaliumComponents and applies a force towards the box’ center if we want to pull the object, or away from the center if we want to push it. 

PhysicsHandleComponent

This approach already allowed us to properly push objects away from the player, but when pulling them, the objects would oscillate around the center, constantly overshooting it and never coming to a full stop. This effect was magnified whenever the player was moving or turning.

(Objects oscillating around the box center)

We fixed this by introducing a PhysicsHandleComponent at the center of our overlap box. The function GrabComponentAtLocationWithRotation() constrains a PrimitiveComponent to a desired location while the PrimitiveComponent retains its physical properties and collision. When the first object reaches the box’ center, we no longer apply any force to that object and attach it to the PhysicsHandleComponent at the box’ center. Additional pulled objects then collide with the grabbed component in the center and can therefore no longer oscillate around it.

Weld Together

While the PhysicsHandleComponent fixed most of the oscillating, the objects around the center would still slide along the surface of the attached object and lag behind a bit when the player moved and turned. Moreover, this solution still required applying a force to every influenced WhaliumComponent each frame, which we wanted to prevent. Therefore, we introduced a flag in our WhaliumComponent to check if it had already been picked up.

The first WhaliumComponent is set to bPickedUp once it’s attached to the PhysicsHandleComponent. Whenever a non picked up WhaliumComponent hits a bPickedUp WhaliumComponent, that component is also set to bPickedUp and welded to the hit component using AttachToComponent() and SetSimulatePhysics(false).

(Left: Objects lagging behind the grabbed component because they are not frozen in place. Right: Objects are welded to the grabbed component and follow the player's movement without lag.)

All bPickedUp components are released when the player disables their glove. The objects are detached from one another and SetSimulatePhysics(true) is called. Additionally, the component attached to the PhysicsHandle is released. 

Alternatively, objects are released when they have been outside of the overlap box for too long. This generally happens when the carried objects get stuck on colliding geometry. We determine if the object has been outside of the overlap box for too long by setting a timer on EndOverlap with the overlap box. If the timer runs out and the object hasn’t had another BeginOverlap event with the box in that duration, we release it.

Iterations

Initially, the push glove behaved like a leaf blower that pushed away everything once it entered the overlap box. The pull glove worked similar to a vacuum cleaner, which meant that as long as the glove was active all objects inside the box were pulled towards its center.

Our first few playtests yielded that many players weren’t yet satisfied with the feeling of our gloves. They felt that the push glove was too weak and the pull glove was found to be unsuited for precise grabbing and placing of objects, e.g. for building a tower or stairs.

Therefore, we decided to implement a strong initial impulse for the push and pull glove, where the objects snap towards or are pushed away with a lot of power when the glove is activated. After that initial impulse, the gloves have less power for as long as the corresponding key is held down.

For the push glove, we handle this by applying a large impulse once the ability key is pressed, launching objects away at a high speed. The continuous force applied each following frame is set to a lower value to provide more control if the player wants to push objects in a precise direction.

(Left: Initial push impulse exerting an explosive burst of power. Right: Continuous push force exerting far less force.)

For the pull glove, we decided that it can only pick up new objects during the initial impulse. Once this impulse is over, it can comfortably keep the carried objects in its center, but it can never attract additional objects. This way, the player can for example choose a single object to pick up and place it on top of another. If no objects are in range during the initial impulse, the glove is deactivated again. 

(Left: Trying to pick up a single cube and placing it on top of another. Right: Managing to pick up a single cube and placing it on top of another.)

Improvements

We made a series of improvements to our glove to make picking up and carrying items more comfortable. For one, this involved moving the attachment point a bit higher - we don’t actually attach the objects to the box’ center, but to a separate SceneComponent (grabLocation). This has the effect that objects don’t scrape the ground as much when they are carried. 

We also introduced the ability to define a PickUpSocket per mesh that defines where the mesh is attached and grabbed by the glove. This is especially useful for bulky objects and the ones whose pivot is in the wrong place.

(Left: Grabbing a bulky object at its original pivot, making it unwieldy to carry. Right: Grabbing the object at its PickUpSocket, making it easier to carry around.)

We also decided to lift up the grabLocation of the glove whenever something gets in the way of the carried objects, to prevent knocking those things over. For this, we calculate the bounding box of all carried objects and perform a shape trace each frame on whether the carried objects are about to collide with objects in the level. If so, we adjust the grabLocation up. If no objects are hit anymore by the shape trace, we move the grabLocation down to its original position again.

(The carried object is being lifted up when it gets close to other, potentially interfering, objects.)

Stay tuned until next time, when we are going to uncover the mysteries of the PearlMagnet!

- Andi, Ralf

Leave a comment