You are on page 1of 16

Steering Behavior

Steering Behavior
• Steering behaviors extend the movement algorithms in the previous section
by adding acceleration. They are gaining larger acceptance in PC and console
game development. In some genres (such as driving games) they are
dominant; in other genres they are only just beginning to see serious use.
• Kita ketahui bahwa rumus perpindahan :
• 𝑠𝑡 = 𝑠0 + 𝑣Ԧ ∗ 𝑡
• position = position + velocity * time (perlu diingat time di unity engine menggunakan time.deltaTime)

• Velocity pada GLBB :


• Perubahan posisi menggunakan kecepatan rata2 sehingga velocity yg digunakan
adalah
• 𝑣𝑡 = 𝑣0 + 0.5 ∗ 𝑎Ԧ ∗ 𝑡
• Vt= Vt-1 + 0.5*a*t
• a= acceleration, t = time, Vt-1 = kecepatan pada frame sebelumnya
Steering Behavior GLBB
• 𝑠𝑡 = 𝑠0 + 𝑣Ԧ ∗ 𝑡
• 𝑣𝑡 = 𝑣0 + 0.5 ∗ 𝑎Ԧ ∗ 𝑡
sehingga
• 𝑠𝑡 = 𝑠0 + (𝑣0 +0.5 ∗ 𝑎Ԧ ∗ 𝑡) ∗ 𝑡

• Atau tidak jarang nilai 0.5 dihilangkan krn nilai deltatime yg sangat kecil
GLBB
Secara sederhana perpindahan dapat menggunakan : 1 struct Steering:
• 𝑣𝑡 = 𝑣0 + 0.5 ∗ 𝑎Ԧ ∗ 𝑡 2 _linear # is an vector acceleration
• 𝑠𝑡 = 𝑠0 + 𝑣Ԧ ∗ 𝑡 3 _angular # is an vector acceleration for rotation

1 class steeringSeek:
2 velocity = vector.zero #velocity awal adalah 0
3 ....
4 def update(steering, maxSpeed, time):
5
6 #the velocity
7 velocity += 0.5 * getSteering().linear * time #steering.linear is an acceleration
8 # Check for speeding and clip
9 if velocity.length() > maxSpeed:
10 velocity.normalize()
11 velocity *= maxSpeed
12
13 #Update the position and orientation
14 position += velocity * time
15 _character.orientation = getNewOrientation(_character.orientation,_velocity)
16
1 struct Steering:
2 _linear # is an vector acceleration
Seek-steering 3 _angular # is an vector acceleration for rotation

1 class SteeringSeek:
2 _character # Static data char.
3 _target # Static data target
4 _maxAcceleration # Holds the maximum acceleration of the character
5 def getSteering():
6 _SteeringOut = new Steering()
7 _SteeringOut._linear = _target.position - _character.position # direction
8 _SteeringOut._linear.normalize() #normalize membuat resultan vektor = 1.
9 _SteeringOut._linear*= maxAcceleration # Give full acceleration along this direction
10 Return _SteeringOut
11
12

Current Velocity Vt akan berangsur angsur menuju target


Vt = CurVelocity+steering
karena pengaruh steering linear
Target
Steer linear
Flee

7 _SteeringOut._linear = _character.position -_target.position # direction


Arriving

steering
- Current velocity

Steer = desiredVelocity - currentVelocity


Arriving
1 class SteeringSeek:
2 ....
3 _maxSpeed
4 _targetSpeed
5 _targetRadius
6 _slowRadius
7 _timeTotarget
8 _targetVelocity
9
10 def getSteering():
11 _SteeringOut = new Steering()
12 _direction = _target.position - _character.position # direction
13 _distance = direction.length
14 if _distance > slowRadius: # If outside the slowRadius, then max speed
15 _targetSpeed = _maxSpeed
16 else if _distance < _targetRadius : #Check if we are there, _targetSpeed = 0
17 _targetSpeed = 0
18 else:
19 _targetSpeed = _maxSpeed * _distance / _slowRadius #slowing speed
20 _targetVelocity = _direction.normalize()*_targetSpeed
21 _SteeringOut._linear = _targetVelocity - _character._velocity #char._velocity dsni = currentVelocity
22 if _SteeringOut.linear.length() > maxAcceleration: # Check if the acceleration is too fast
23 _SteeringOut._linear.normalize() #normalize membuat resultan vektor = 1.
24 _SteeringOut._linear*= maxAcceleration # Give full acceleration along this direction
25
26 Return _SteeringOut
Collision Avoidance
• The basic idea behind collision avoidance is to generate a steering
force to dodge obstacles every time one is close enough to block the
passage.
• Obstacles ahead of the character are analyzed and the closest one
(most threatening) is selected.
Seeing Ahead
• The first step to avoid obstacles in the environment is to perceive them.
• The only obstacles the character must worry are the ones that are in front of it and
directly blocking the current route.
• the velocity vector describes the direction of the character. It will be used to produce a
new vector called ahead, which is a copy of the velocity vector, but with a different
length.
• The greater MAX_SEE_AHEAD is, the earlier the character will start acting to dodge an
obstacle,
Seeing Ahead
• ahead = position + normalize(velocity) *
MAX_SEE_AHEAD
• ahead2 = position + normalize(velocity) *
MAX_SEE_AHEAD * 0.5
check for collision
• One possible solution to check for collision is the line-sphere intersection - the
line is the ahead vector and the sphere is the obstacle.
• If the distance is less than or equal to the sphere radius, then the vector is inside
the sphere and a collision was found

1 struct Circle:
2 _center : vetor3D
_radius : integer

private function lineIntersectsCircle(ahead :Vector3D, ahead2 :Vector3D, obstacle :Circle) :Boolean


{
// the property "center" of the obstacle is a Vector3D.
return distance(obstacle.center, ahead) <= obstacle.radius || distance(obstacle.center, ahead2)
<= obstacle.radius;
}
Calculating the Avoidance Force

avoidance_force = ahead – obstacle.center


avoidance_force = normalize(avoidance_force) * MAX_AVOID_FORCE

• After avoidance_force is calculated it is normalized and scaled by MAX_AVOID_FORCE.


• The greater MAX_AVOID_FORCE is, the stronger is the avoidance force pushing the
character away from the obstacle.
Find Most Threatening Obstacle
private function findMostThreateningObstacle(ahead :Vector3D, ahead2 :Vector3D):Circle {
mostThreatening : Circle = null;

#cek semua objek yg perlu dihindari


for(var i:int = 0; i < Game.instance.obstacles.length; i++) {
var CircleObs :Circle = Game.instance.obstacles[i].getCircle;
var collision :Boolean = lineIntersecsCircle(ahead,ahead2,CircleObs);

#cek collision yang paling dekat


if(collision && (mostThreatening == null ||
distance(position, CircleObs) < distance(position, mostThreatening)))
{ mostThreatening = CircleObs; }
}
return mostThreatening;
}
collisionAvoidance

private function collisionAvoidance() :Vector3D {


ahead = position + normalize(velocity) * MAX_SEE_AHEAD;
ahead2 = position + normalize(velocity) * MAX_SEE_AHEAD * 0.5;
var mostThreatening :Obstacle = findMostThreateningObstacle(ahead,ahead2);
var steerLinear :Vector3D = new Vector3D(0, 0, 0);

if (mostThreatening != null) {
steerLinear = ahead - mostThreatening.center;
steerLinear = steerLinear.normalized*MAX_AVOID_FORCE;

} else {
steerLinear = vertor.zero; // nullify the avoidance force
}

return steerLinear;
}
Update : Seek plus collision avoidance
1 class steeringSeek:
2
3 _steering #variable vector untuk mengkalkulasi seluruh steering force
4 ....
5 def update(steering, maxSpeed, time):
6
7 #menggunakan steering hasil dari seek + collision avoidance
8 _steering = getSteering().linear + getCollisionAvoidance.linear
9
10 # and the velocity and rotation
11 velocity += _steering * time
12
13 # Check for speeding and clip
14 if velocity.length() > maxSpeed:
15 velocity.normalize()
16 velocity *= maxSpeed
17
18 # Update the position and orientation
19 position += velocity * time
20 _character.orientation = getNewOrientation(_character.orientation,_velocity)
21

You might also like