How can I apply steering behaviors to a car controlled with turning and acceleration? - Game Development Stack Exchange most recent 30 from gamedev.stackexchange.com 2019-12-16T10:47:20Z https://gamedev.stackexchange.com/feeds/question/149875 https://creativecommons.org/licenses/by-sa/4.0/rdf https://gamedev.stackexchange.com/q/149875 3 How can I apply steering behaviors to a car controlled with turning and acceleration? IanLarson https://gamedev.stackexchange.com/users/92307 2017-10-24T05:06:06Z 2018-04-26T05:06:05Z <p>I feel like I've got my head around <a href="https://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732" rel="nofollow noreferrer">steering behaviors</a>, but I've having trouble applying them to a car. The steering behaviors return forces that one could apply to an object that can move in any direction, but a car can essentially only move forward and turn. I'm having trouble determining how hard the car should turn or how much it should accelerate forward based on the steering force. How can I translate a steering force into the car's input?</p> https://gamedev.stackexchange.com/questions/149875/-/149882#149882 2 Answer by EvilTak for How can I apply steering behaviors to a car controlled with turning and acceleration? EvilTak https://gamedev.stackexchange.com/users/51745 2017-10-24T11:26:17Z 2018-04-26T05:06:05Z <p>You will have to calculate the desired input (steering and throttle) based on:</p> <ol> <li>The relative direction of the desired velocity when compared to the current velocity (for steering input)</li> <li>The relative magnitude of the desired velocity when compared to the current velocity (for throttle input)</li> </ol> <hr> <p>For calculating steering input, we need to calculate the amount of steering it will take to rotate the current velocity vector in the direction of the desired velocity vector based on the angle of steering at maximum lock in radians (<code>maxSteerAngleInRad</code>). </p> <p>Assuming full left and right lock is represented by <code>-1</code> and <code>1</code> respectively, the steering input can be calculated as follows (<code>desired</code> and <code>current</code> are the desired and current velocity vectors):</p> <pre><code>fullSteers = acos(dot(desired.normalized, current.normalized)) / maxSteerAngleInRad steer = sign(dot(leftperp(desired), current)) * fullSteers </code></pre> <p>where <code>leftperp</code> for a 2D vector <code>(x, y)</code> is given as <code>(y, -x)</code>. The <code>sign</code> expression serves to provide the direction (left or right) to steer in. If <code>desired</code> is to the left of <code>current</code>, the expression returns <code>-1</code> and <code>1</code> if it is to the right.</p> <p>If the steering input is reversed (i.e. positive values represent left and negative values represent right), simply use the right perpendicular (<code>(-y, x)</code>) instead of the left or simply negate the value of <code>steer</code>.</p> <p>To get rid of the <code>acos</code> call, you can use a more inaccurate albeit more performant approach wherein <code>fullSteers</code> is the quotient of the normalized <em>cross</em> products (where <code>cross(a, b) = a.x * b.y - a.y * b.x</code>) of the desired and current velocities, and the sine of <code>maxSteerAngleInRad</code> (which can be precalculated).</p> <p><code>steer</code> should also be clamped between <code>-1</code> and <code>1</code> if your vehicle input system does not do so.</p> <hr> <p>For calculating throttle input, we simply need to accelerate if <code>desired.magnitude</code> (desired speed) is more than <code>current.magnitude</code> (current speed), and brake if it is the other way around. You may also want to choose intermediary throttle values based on the speed difference and the vehicle throttle response.</p>