The fp system is a project template fit for any first-person game, it's quite advanced and easy to use
the interaction system works by doing a raycast from the camera every frame, if it detects a hit
it moves the ui elements to the hit entity's position.
The ui element's position is calculated by using the world_to_viewport
function on
the player camera's Camera
component.
If the hit entity has a Name
component it will set the "name" ui element's text to
the name.
If the hit entity has an Interactable
component, it will iterate thru the
interactions listed in that component and spawn ui texts with the correct text as children in
the "interactions" ui node.
The interactable component is defined like this
This system has a global resource called Interactions
wich holds an array of
SystemId<Entity>
.
based on what the action: Int
enum and the key: KeyCode
are set to,
when the system detects that it needs to run the interaction code, it gets the
usize
from the action: Int
, and indexes into the array in the
ESystems
and gets a
SystemId<Entity>
, wich it runs using the
commands.run_system_with_input
function, with the input set to the
Entity
id of the interacted entity.
The one_handed: bool
is used for held objects, wich is explained later.
the indexes for the systems are stored as contants, so I don't have to remember the numbers.
Here's an example of how this interaction system is used
The holdable system allows for holding objects, and using them.
The system uses the interactable system to hold objects.
The system allows for holdables to have three systems at max: a primary, a secondary, and a
reload.
The holdable component is defined like this:
The takes: Hands
, determines how a holdable can be held
if it's Two
, the holdable will only be able to be held if both arms are free.
if it's OneAndHalf
or One
, the holdable will be able to be used with
one hand.
the way the primary
and secondary
systems are called is basically the
same as in the interaction system, except the functions are located in the HSystems
resource, wich holds SystemId<(Entity, bool)>
The bool in the input to the systems represents if the holdable is being held improperly.
A holdable is held incorrectly when it's takes
is OneAndHalf
and there
is another object held in the other hand, or when it's either OneAndHalf
or
Two
and the player is interacting with something.
if the thing being interacted with has the one_handed: bool
set to
false
, then none of the held objects will be useable while the player is
interacting.
the visibility: Vis
shows how a holdable should be shown:
None
means that the object will be invisible when heldTransform
means that the held object will be shown at the specified transform
as a child of the player's "held entites", with it's X coordinate negated when it's in the
other handTransformD
means that the held object will be shown at the first transform if
it's the only currently held object, otherwise it'll do the same thing as
Transform
, with the second specified transform
the oscilate: bool
tells the code, if there's two held objects that have the same
primary sould the primary interactions oscillate between the left and the right hand, or should
they run at the same time.
the sound: Option<Handle<AudioSource>>
is a handle that tells the code what
sound to play when the object is picked up.
the sound is spawned using the AudioBundle
, with, in it's
PlayBackSettings
, the mode set to PlaybackMode::Despawn
Here's an example holdable object; the M9 Beretta
Here's how the system works in practice:
This page is not fully finished.