PathPlatform¶
A platform that moves on a set path defined by multiple absolute position vectors called nodes and can conditionally be stopped depending on the hit
value of other NPCControl present on the map. Can be operated in loop mode using only 2 nodes or with multiple nodes in path mode with more options.
Data Arrays¶
data
: The map entities ids to check for theirhit
being true and if any are, it will tell the platform to set itshit
to true and to start moving along its path in path mode. This is optional, the platform is considered as continually moving as normal without any elementsvectordata
: The nodes the platform will travel in absolute positioningdialogues[0].x
:The meaning depends on the mode:- In path mode, this is the starting node after truncating to int
- In loop mode, this is the starting
speedmultiplier
(the starting node index) after truncating to int. This means only [0.0, 2.0[ are valid values
dialogues[0].y
: The speed multiplier at which the platform moves.dialogues[1].x
: if it's 1, it means to place the platform in loop mode by only using the first 2vectordata
and disregard thecurrentnode
logicdialogues[1].y
: Theactioncooldown
to apply when the platform has reached the end of its path and it should go inactive.dialogues[2].x
: The local scale of the entity.model
will be multiplied by the 1/10 of this, but this is optional and the scale will not change if it is 0.1 or belowdialogues[2].y
: If not 0, theelectime
of the GlowTrigger when the entity.originalid
is theElectroPlatform
AnimID. This is optional and the value defaults is 260.0
Additional data¶
speedmultiplier
: OVERRIDEN (this is used as a value between 0.0 and 1.0 that represents the lerp factor of the platform position between 2 nodes as it moves)boxcol
: If entity.originalid
is theLilypad
AnimID, theboxcol
is created manually, but it doesn't remove the existing one meaning under these circumstances, the entity shouldn't be specified that it has one since it would make it so there's 2boxcol
with the loaded version not being accessible by the game
Setup¶
- entity.
rigid
gets effectively locked by disabling gravity, making it kinematic and freezing all constraints - isStatic on the gameObject is set to false
nointeract
is set to true- entity.
soundonpause
is set to true - entity.
model
scale is multiplied by a 1/10 ofdialogues[2].x
- If
dialogues[1].x
is 1 (loop mode) anddialogues[0].x
is 1 (the starting node is the second one), thespeedmultiplier
is set to 1.0 - If
dialogues[1].x
is 0 (path mode):currentnode
is set todialogues[0].x
- The position is set to the
vectordata
at thecurrentnode
- entity.
startpos
is set to the new position
- If the entity.
originalid
is theLilypad
AnimID:- The
scol
is disabled - the
boxcol
is recreated with trigger and a size of (5.0, 1.0, 5.0) which overrides all theboxcol
fields obtained when loading the data.
- The
- entity.
alwaysactive
is set to true - entity.
model
tag is set toPlatformNoClock
- If entity.
originalid
is theElectroPlatform
AnimID, a GlowTrigger is added on the first child of themodel
:getactivecolorfromstart
is set to trueparent
is set to this NPCControlglowparts
is initialised to a single element corresponding to the MeshRenderer of the first child of themodel
electime
is initialised to 260.0 unlessdialogues[2].y
exists and isn't 0 where it will take that value instead
Update¶
If entity.originalid
is the Lilypad
AnimId, the boxcol
if present is kept enabled, otherwise, its enabled will bet set to the hit
value.
From there, the platform can operate in 2 distinct modes: forever loop between the first 2 vectordata
where the current one is tracked by speedmultiplier
or follow a series of nodes defined in vectordata
where the current one is tracked by currentnode
. The former is done if dialogues[1].x
is 1, the latter is done otherwise.
Loop mode¶
This is a much simpler mode where only the first 2 vectordata
are used as nodes.
In this mode, hit
is set to true and it is never toggled back. This means the platform will continually move according to the speedmultiplier
field which serves as the factor of the position lerp to perform between vectordata[0]
and vectordata[1]
.
On the first update, if dialogues[0].x
isn't negative (which it shouldn't be on the first Update), it will be the starting value of speedmultiplier
. This is a one off: after setting the field, it is reset to -1. It should be noted that the value set is a cast to int meaning it can only be [0.0, 2.0[ which coresponds to the starting node chosen among the 2.
The platform is considered active when either data
is empty or any of its elements refers to a map NPCControl whose hit
is true. If it is active, speedmultiplier
gets incremented by the game's frametime * dialogues[0].y
/ 1000.0. If it's inactive, it gets decremented instead. Basically, the platform moves forward when active and backward when inactive.
The position set portion starts by clamping speedmultiplier
from 0.0 to 1.0 and then setting the position using a Vector3.Lerp from vectordata[0]
to vectordata[1]
with a factor of speedmultiplier
.
Unless entity.originalid
is the Lilypad
AnimId, speedmultiplier
is below 1.0 and the entity.sound
is playing, then PlaySound is called on the entity with the PlatformMove
clip set to loop.
Path mode¶
What happens each updates depends on the value of hit
which gets toggled on and off in a very systematic manner. The details involves many different fields that interacts with each other:
actioncooldown
: The cooldown used to stop movement whenever the platform reaches its last node AND it is considered deactivated. This is refreshed to bedialogues[1].y
each time the platform goes to a new node withhit
being set to true.speedmultiplier
: The factor to use when lerping the platform positions between nodes. It's set to 0.0 when going to a new node until it reaches 1.0+. It progressively increases by the frametime of the game *dialogues[0].y
/ 1000.0.bounces
: The previous node index visited which will be used as thefrom
vector when lerping.currentnode
: The next node index to visit which will be used as theto
vector when lerping.
When hit
is false¶
Before anything happens, the entity's sound
is set to not loop and its model
tag is set to Platform
.
The platform is considered active when either data
is empty or any of its elements refers to a map NPCControl whose hit
is true. When a platform is active, it will have its hit
set to true on the first update in which it was false. This will cause the fields to be set in such a way that bounces
will always lag behind by 1 from currentnode
when going forward. When the platform reaches the end and it's still active, it will set currentnode
to 0 which will make the platform go back to its starting point, but ignoring all the nodes, it simply moves straight towards the start and continues from there.
But it is possible for the platform to go inactive during its forward path. When this happens, this is where the actioncooldown
comes into play. It will be exhausted which will make the platform stationnary until it expires. When it does expire, if the platform's currentnode
is higher than 0 (it's further than the starting node), it will decrement it, but have bounces
be one node above. This essentially makes the platform go backwards from the nodes list, but following its movement path until the start (with cooldown applied) and it also sets hit
to true.
When hit
is true¶
There is a special case before anything happens: whenever hit
goes to true, it is possible that currentnode
and bounces
points to the same node. It can happen if there's only one node defined in vectordata
. If this occurs, the update logic just ends abrutply because there is no need to move the platform and it will remain stationnary forever.
The entity.model
tag is set to PlatformNoClock
. Unless entity.originalid
is the Lilypad
AnimId and the entity's sound
is playing, then PlaySound is called on the entity with the PlatformMove
clip set to loop.
From there, this is where the movement is done until speedmultipiler
reaches 1.0 or above in which case, it's reset to 0.0 and hit
is set to false again.
When moving the platform, the lerping using will be the standard Vector3.Lerp, but there is a special case if there's only 2 nodes in vectordata
. When this happens, the game's SmoothLerp is used instead which is a much slower and spread out lerping procedure.
OnTriggerEnter if the other collider is the player¶
There is some dead logic here where nothing happens, but the conditions are all of these being true:
- The current area is
WildGrasslands
- The entity
originalid
is theLilypad
animid - The player entity is
onground
Hazards.OnObjectStay¶
If the NPCControl passed has this type, it returns true which allows it to stay in collision with the Hazards.
Effects of the Platform
and PlatformNoClock
¶
There are some special logic implicated by the platform having these tags. Mainly, the game will often child GameObjects of interests to the platform when they are getting on it and child them back to where they were when no longer being on it.
Specififcally, the GroundDetector's OnTriggerStay will check if the other collider has either of these tags and do the childing of the entity if it does. Additionally, the entity.noclock
is set to true if the tag is PlatformNoClock
and to false if it's Platform
. On the component's OnTriggerExit, this is all undone, but there's a special case for the player or PFolower
where it's parented to the root instead of the map.
The Hornable component also does this which is related to the ice cube of a Dropplet. If the other collider has either tag, OnTriggerEnter / OnCollisionEnter will child the other transform to the platform. This is undone on the component's OnTriggerExit if the other collider has either of the tags.
As for what the entity.noclock
does, normally, on MainManager.DoClock, the method RefreshPlayer is called when the player is free and it would normally set the onground
to false and root all playerdata entities (this incidentally has a known issue where the frictions gets toggled off for one frame every second). noclock
is a field that will prevent this logic from happening so it prevents the rooting of the player to the scene. In the case of the PathPlatform, it means that this logic doesn't happen as long as the player is on the platform AND it is active (the logic is free to do its thing when the platform goes inactive).