Follow¶
Follow is a private method called during LateUpdate that manages following the following
entity if it exist, we aren't overriding followers, the entity overridefollow
isn't active and the entity isn't dead
or iskill
.
Follow logic¶
There are 3 ways to follow: player and their followers, tempfollower
and everything not in the first 2 categories. The default follow logic is actually contained in DoFollow described later, but the player and their followers may not call it under some conditions.
Player and their followers¶
This branch is applicable if it's not a tempfollower
and the following
has the tag Player
or PFollower
with the player being present.
The default logic is to set leiffly
to false, call Return from action and then call DoFollow. However, there are 3 special cases where this logic isn't performed.
Digging¶
This only applies if the player is digging or started digging. backsprite
is set to false with a spin
of 30.0 on the y and the spritetransform
's scale is set to be lerped towards 0 with a factor of 0.075. The transform
's position is changed directly towards following
+ the forward direction of the camera / 2.0. This is done because it bypasses the physics engine. The rigid
is actually set to kinematic without gravity and the ccol
is disabled so the physics engine no longer can control the follower when digging. The shadow
is disabled if it wasn't and finally, StopMoving is called with the default basestate
(-1) which completely stops any velocity.
Flying¶
This only applies if the player is flying. First, backsprite
is set to false, same with overrridejump
and overrideanim
to get back control on the flying animations. StopForceMove is called with no animstate and no smoothing which halts any current coroutine force move if one existed.
From there, if the AnimIDs was Beetle
, his animstate is changed to 102, his position changed directly to be the player's + the forward direction of the camera * 0.2 and his flip
changed to the player's. This forces Kabbu to face the same direction and to be positioned where the player is. On the other hand, if it's not Beetle
, then it is assumed to be Moth
and as such, his rigid
gets its gravity disabled, overrideanim
becomes true, his animstate becomes 101, his flip
becomes the player's and leiffly
becomes true. This is needed during FixedUpdate to update his position smoothly towards the player.
Shielding¶
During bubble shield, the follow logic is managed differently by ShieldMove (tempf to false since this is a player follower). It forces the entity to face towards the player, StopForceMove is called with walkstate
and no smoothing before the position is set directly via a lerp to the player's + an offset with a factor of framestep * 0.25. This offset is calculated by using the AnimID number as an offset in 0.5 units in x and 0.2 units in z which makes the entity go very close to the player, but with enough spacing to prevent z fighting.
Default¶
If none of the above applies, then the default logic mentioned earlier applies which ends with a DoFollow call.
Temp followers¶
There are 3 starting logic branches for a tempfollower
:
- The player is shielding: then ShieldMove with tempf to true is called. The only change with the player follower version is that the offset is now the player's
spritetransform
right direction * 0.75 + the camera foward direction * 0.5. - The player is flying: the animstate is set to
basestate
, therigid
gravity is disabled,flip
is set to to the last player in playerdata'sflip
(basically the last party member in the follow chain) and the position is set directly to be the last party member's position + (+-0.35, 0.75, 0.1) *tempfollowerid
+ 1 which will offset the position to be up forward and left/right. The x sign is determined by the player'sflip
. - Everything else: DoFollow is called
After this is done, the rigid
gravity is enabled, nodigpart
is set to true and digging
is set to whether the player is digging or has started digging. If we are indeed digging
, the position is set directly to the player's + the forward direction of the camera * 0.1.
Default logic¶
If none of the other 2 branches applies, DoFollow is called as the only execution for this follow.
DoFollow¶
DoFollow is a private method that houses the default logic of a typical follow that entities will use most of the time. It applies unless the game's overridefollower
is enabled, overridefollow
is true, the entity is dead
or iskill
.
From there, unless there's a springcooldown
and jumpcooldown
is above 15.0, the rigid
velocity is set to to the current one in x/z and in y to the clamp of the current one from -20.0 to jumpheight
. After, FaceTowards is called with the following
position. The rest of the method only happens every 2 frames so if we're in an odd frame, this is done.
If we aren't however, this is where the actual follow management is handled.
Movement logic¶
We first gather the horizontal square distance between the transform
and the following
which will be used to decide what to do for this follow.
Too far handling¶
The first thing that is checked is if the entity is too far from following
which it is if the square distance in x/z is higher than followlimit
(20.0 by default) OR we aren't in a minipause and the y actual distance is higher than the map's followerylimit. In that case, the position is changed directly to the following
's + the forward direction of the camera * 0.1 and the velocity is zeroed out.
Decide whether to move¶
From there, we can now check the if entity should not move or move towards following
. The entity will attempt to move towards it only if the square distance is higher than followdistance
(by default 2.0). However, this check changes to half of the followdistance
if CloseMove returns true. This method only returns true under the following conditions:
- The player is present and not dashing
- One or more of the following is true:
- We are currently in a stealth section (flags 401), the map's closemove is true and this entity is part of the
mainparty
- This entity is part of the
mainparty
and the player has a parent - The player has forceclosemove to true
- We are currently in a stealth section (flags 401), the map's closemove is true and this entity is part of the
The result is that the entity will attempt to be twice as close than normal under these conditions.
Follow movement¶
If we decided to move towards following, MoveTowards is called which starts a forcemove
to following
+ the forward direction of the camera * followoffset
. This is however halved if CloseMove returned true earlier. The forcemove
is done with a multiplier of 1.25 unless CloseMove returned true which makes it (the square distance - 1) / 2.0. The rest are left default with ignore_y
to true.
From there we go into determining if we should Jump, but only if detect
is present. If it is, DetectDirection is called which aligns the wall detector. From there, there are 2 potential scenario that will make the entity jump (only one of them needs to be true):
- The entity is
onground
and a raycast hit occurs fromtransform
.position +detect
.transform.forward.normalized + Vector3.up * 0.3 directed down with a max distance of 2.5 only hitting layers Ground and NoDigGround. This raycast basically ensures that there is a wall that can be jumped over by the entity, but it doesn't make use ofhitwall
to check this and rather by raycasting manually using thedetect
direction. - The entity is
onground
, it hashitwall
and the actual distance between thetransform
andfollowing
is higher than 0.5 and the horizontal square distance between the 2 is higher thanfollowjump
(0.3 normally). This basically means both detector reports ground and wall while the horizontal and vertical distance are high enough to warrant jumping.
Jump is not called if neither applies or detect
isn't present.
Follow stop movement¶
If we decided to not move towards following
, StopForceMove is called with the basestate
with smoothing. After, the deltavelocity
is zeroed out if the animstate isn't Walk
.