|
entity - the character that follows target - the entity to follow, such as the player or a leader; it needn't be a NavWalker distance# (optional) - how close to keep, in metres across the ground; -1 for two of the follower's radii, 0.7 m for a person (default) run (optional) - True to run after it; False to walk (default) |
|
Walks an entity after another one, keeping within a distance of it. FollowEntity is for a dog at its owner's heels, a squire behind a knight, a zombie after the player, or an escort that keeps up. It makes the entity a NavWalker, as WalkEntity does, and heads for the target along the walkable map, round walls and through doors. As the target moves, the follower plans its way again: whenever the target is more than a metre from where it was heading (or a tenth of the distance between them, when that is more), at most four times a second. Once it is within the distance, it stops: WalkState says WALK_ARRIVED, and it sends the world event "arrived". It waits there until the target is farther away than the distance and half a metre more, then sets off again, WALK_ON_WAY, so a follower doesn't shuffle each time its target takes a step. If there is no way to the target, it goes as near as it can. Following goes on until you give the walker another order (WalkEntity, WanderEntity, StopWalking, or FollowEntity again, perhaps with a new distance), or the target is freed, when the follower stops and stands. Following itself, or a target in another world, is a runtime error. Running is the way to keep up: a follower walking at 1.4 m/s falls behind anything faster, as the dog in the example does until you press R. Walkers don't step round the target unless it is a NavWalker itself or NavWalkersAvoid marks it, so mark the player with NavWalkersAvoid, and its followers keep out from under its feet. See also: WalkEntity, WalkState, NavWalkersAvoid, WalkSpeed, StopWalking. |
; FollowEntity Example
; --------------------
Graphics3D 640,480,0,2
SetBuffer BackBuffer()
; A raised camera looking down on the courtyard
camera=CreateCamera()
PositionEntity camera,0,13,-12
RotateEntity camera,50,0,0
light=CreateLight()
RotateEntity light,45,45,0
; A 20 x 20 m courtyard, one unit to a metre: the floor's top is at y=0
floor=Block(0,-0.5,0,20,0.5,20)
EntityColor floor,60,80,55
; Walls round the edge, and a hut in the middle
Block 0,0,-10,20,1.5,0.5
Block 0,0,10,20,1.5,0.5
Block -10,0,0,0.5,1.5,20
Block 10,0,0,0.5,1.5,20
Block 0,0,0,5,2.5,5
; A sheep the program walks round the hut, and a dog that follows it
sheep=Character(0,6,230,230,220)
dog=Character(-7,-7,150,100,60)
distance#=2
run=False
FollowEntity dog,sheep,distance,run
angle#=0
grazing=False
While Not KeyDown(1)
; + / - change how close the dog keeps, R walk / run: each gives the dog
; its orders again
If KeyHit(13) And distance<6 Then
distance=distance+0.5
FollowEntity dog,sheep,distance,run
EndIf
If KeyHit(12) And distance>1 Then
distance=distance-0.5
FollowEntity dog,sheep,distance,run
EndIf
If KeyHit(19) Then
run=Not run
FollowEntity dog,sheep,distance,run
EndIf
; Space stops the sheep to graze, or sets it off again
If KeyHit(57) Then grazing=Not grazing
; The sheep trots round the hut, 6 m from its middle, at 1.6 m/s
If Not grazing Then
angle=angle+0.25
PositionEntity sheep,6*Sin(angle),0.9,6*Cos(angle)
RotateEntity sheep,0,-angle-90,0
EndIf
; Arrow keys move the camera (turning round the world's up axis)
If KeyDown(200) Then MoveEntity camera,0,0,0.1
If KeyDown(208) Then MoveEntity camera,0,0,-0.1
If KeyDown(203) Then TurnEntity camera,0,1,0,True
If KeyDown(205) Then TurnEntity camera,0,-1,0,True
; UpdateWorld moves the dog after the sheep
UpdateWorld
RenderWorld
pace$="walking"
If run Then pace="running"
doing$="following"
If WalkState(dog)=WALK_ARRIVED Then doing="close enough, waiting"
Text 0,0,"+ / - : distance R: walk / run Space: sheep Arrows: camera Esc: exit"
Text 0,20,"FollowEntity dog,sheep,"+distance+" ("+pace+")"
Text 0,40,"The dog is "+doing+", "+Int(EntityDistance(dog,sheep))+" m from the sheep"
Flip
Wend
End
; A stone block standing on y, centred on x,z
Function Block(x#,y#,z#,width#,height#,depth#)
b=CreateCube()
ScaleEntity b,width/2,height/2,depth/2
PositionEntity b,x,y+height/2,z
EntityColor b,125,110,90
Return b
End Function
; A character 0.6 m across and 1.8 m tall, with a visor on its face, kept out
; of the walkable map it walks on
Function Character(x#,z#,red,green,blue)
c=CreateCube()
ScaleMesh c,0.3,0.9,0.3
PositionEntity c,x,0.9,z
EntityColor c,red,green,blue
visor=CreateCube(c)
ScaleMesh visor,0.2,0.08,0.06
PositionEntity visor,0,0.6,0.32
EntityColor visor,30,30,40
Return c
End Function