2.Potion With Detachable Stopper
Creating a potion with a detachable stopper (reproduction of the potion in the example). For the purposes of this example I will be using engine default shaped and not the actual potion bottle.
First thing first you will want to create a GrippableStaticMeshActor in your editor and assign it a relevant name. The grippable base classes are already all setup for the plugins gripping interface and have gripping properties embedded into their properties list.
Assign a static mesh to the root component (and scale it appropriately), this will visualize our potion body. (using the cube mesh is has been scaled to 0.1f.
As this Potion is intended to be used with one hand while the other can grab the stopper, as well as be physically held so it cannot be pushed through geometry, the following grip settings will be chosen. Being a grippable actor, the grip settings exist on the actor itself and not the root component.
Slot/Free Default Grip Type: Interactive Collision with Physics
The grip will be physics based and collide with the enviroment.
Grip Movement Type: ForceClientSideMovement
The object is expected to sit in the level and have multiple users able to interact with it, we will be selecting the ForceClientSideMovement as it is a server authoritative grip mode that has client sided movement for no latency after the grip. Server authoritative is important with multiple possible interacting persons as it ensures that a single connection has authority over when/how the object is gripped and it prevents multiple users grabbing it at the same time.
Secondary Grip Type: SG_None
Disallow secondary attachments on the object, it will not have two handed rotation applied.
bAllowMultipleGrips: False
Don’t allow multiple full grips on the object as the same time
These already being the default settings for a grippable actor, there is actually nothing to change. Constraint Stiffness and Damping may have to be tweaked based on the mass of the mesh.
Now we need to add two additional components to the actor.
- A Collision shape of some sort (I chose a sphere), this will act as our attachment location specifier as well as overlap detection for when to attach to the object.
- A GrippableStaticMeshComponent, this will be our stopper.
Make sure that the collision shape is set to the same relative height as the stopper.
For this example I set the stopper mesh to a red material and a scale of 0.3f on all axis’s.
Grippable components have some different default grip settings and for this purpose the stopper needs to be tweaked to match the same grip settings as the potion body. The default of ManipulationGrip is generally used for objects constrained with physics constraints ( a common use for grippable components over grippable actors ).
As of this moment you now have a potion that is grippable and moveable, as well as a stopper that is separately grippable and moveable. The only real thing to add in would be the ability to re-attach the stopper to the bottle after it has been removed.
To start lets ensure that the collision shape doesn’t block our grip query (in the example there is a specific trace channel used for grip queries, we are going to ignore this channel).
To start, lets add in the begin overlap event of the stopper collision sphere and hook up some basic logic to it.
This graph is fairly simple and covers several important concepts for the plugin.
Step 1:
First check if we are the server or not (authority), since both of these grippables are set to ServerAuthed grip types we only want to run this logic on the server. You could also check HasGripAuthority from the motion controller later in the graph.
Step 2:
Then the graph checks if the stopper is the object overlapping our collision zone, it also checks if the stopper is already attached to our potion or not.
Step 3:
We get the list of currently holding controllers for the stopper, given the stoppers grip type being server authoritative we can assume that if there is a holding controller that is is the only one.
Step 4:
We call the grip controllers DropAndSocketObject function, this will not only drop the object from being gripped, but also attach it to the body of the potion. Its an important function not just for convenience, but also for utility as it specifically works around potential order of operations issues and the physics thread.
Relative transform to parent is attained by getting the collision spheres relative location and rotation (remember we synced these up earlier) this makes it very straight forward. The scale is hard set to the stoppers relative transform to the potion body, you could calculate this instead from the two but we currently know what it should be so its hard set.
Object to drop is the stopper, since we already have the GripID from the grip information we technically don’t need this but I provided it anyway.
Grip ID to drop is the actual information the function is going off of here, if it was empty the ObjectToDrop would be used instead to find the correct grip.
SocketingParent is the parent we want to attach too.
If following this tutorial in UE5.1 there is a chaos physics bug preventing the body instance from being created after the stopper has been welded on to the potion body, I assume this will be fixed later on. You can attach the stopper to the collision sphere instead to work around this (though worse as it will not collide with the enviroment when the body is moved).