- Home /
Unitysteer 2.0 force output Vector
Hello,
I'm working on a top down shooter and created a player script that controls my air vehicle with input vales from -1 to 1 for both steering and acceleration. I want my AI to use the same Player script for enemy air vehicles. How can I transform the UnitySteer force Vector to a -1 to 1 output value for each axis. My guess to start inside the AutonomousVehicle class and calculate a -1 to 1 result from the resulting force vector. Which formula can I use the best for this calculation?
Should it be something like result.x = delta.x / MaxForce for the AI left right controls?
Are there more values that need to be handled for a better/accurate result.
Peter.
Answer by Ricardo · Jan 11, 2011 at 08:52 PM
The force vector will be the displacement that is applied to the object's position (or to move the rigidbody by, in case of non-kinematic rigidbody vehicles) for 1 second. I can't really say how to conver it to your [-1..+1] range, as that depends on how you're interpreting that value, but that should tell you how to calculate it. I can say that [-1..+1] is likely to mean movement only on one axis, while the least UnitySteer will return is two axes for planar vehicles (unless you meant that range for all axes involved).
Ricardo, First off thank you for this awesome Unity plugin :-). I have written a few player controls for my Vehicles. All axis input values (for x, y and z) are between -1 and 1. The values act as a force multiplier in that scripting. for example: value 0 = no force, 0.5 = half force, 1 = full force. The vehicles are rigidbody driven (non kinematic). $$anonymous$$y Idea was write an extra public function in the AutonomousVehicle class that can return a Vector3. I'm not sure which values are needed get a descend result.
Peter.
Well, again decent result will depend on your needs. :-) Since the value is already a displacement in a direction, it seems you would only need to do (force / $$anonymous$$axSpeed). However, the value that ends up being stored for the force is already balanced for the elapsed time, so I'd recommend caching the newVelocity from AutonomousVehicle. I'll add saving that value as a feature on 2.1
I've added this as read-only LastAppliedVelocity on AutonomousVehicle. It's currently only on b2.1, but you can get it here: https://github.com/ricardojmendez/UnitySteer/tree/b2.1 Fair warning: there are other changes and I haven't yet updated the change log.
Answer by TriplePAF · Jan 15, 2011 at 02:01 PM
Here is my current rigidbody implementation for Unitysteer 2.1b. I got already the same accuracy as with a simpler transform implementation :-) This line of code is clamping the max force value: Vector3 newForce = Vector3.ClampMagnitude (_smoothedAcceleration * MaxForce, MaxForce);
It works almost the same as clamping each value in _smoothedAcceleration between -1 and 1 and multiply it by MaxForce.
using UnityEngine; using UnitySteer;
/// <summary> /// Vehicle subclass which automatically applies the steering forces from /// the components attached to the object. /// </summary> public class AutonomousVehicle : Vehicle { #region Internal state values Vector3 _smoothedAcceleration; Rigidbody _rigidbody;
[SerializeField]
float _accelerationSmoothRate = 0.4f;
Vector3 _lastRawForce = Vector3.zero;
Vector3 _lastAppliedVelocity = Vector3.zero;
#endregion
/// <summary>
/// Gets or sets the acceleration smooth rate.
/// </summary>
/// <value>
/// The acceleration smooth rate. The higher it is, the more abrupt
/// the acceleration is likely to be.
/// </value>
public float AccelerationSmoothRate {
get { return this._accelerationSmoothRate; }
set { _accelerationSmoothRate = value; }
}
public Vector3 LastRawForce {
get { return this._lastRawForce; }
}
public Vector3 LastAppliedVelocity {
get { return this._lastAppliedVelocity; }
}
#region Methods
void Start ()
{
_rigidbody = GetComponent<Rigidbody> ();
}
void FixedUpdate ()
{
var force = Vector3.zero;
Profiler.BeginSample ("Calculating forces");
foreach (var steering in Steerings) {
if (steering.enabled) {
force += steering.WeighedForce;
}
}
Profiler.EndSample ();
// We still update the forces if the vehicle cannot move, as the
// calculations on those steering behaviors might be relevant for
// other methods, but we don't apply it.
//
// If you don't want to have the forces calculated at all, simply
// disable the vehicle.
if (CanMove) {
ApplySteeringForce (force, Time.fixedDeltaTime);
} else {
Speed = 0;
}
}
/// <summary>
/// Applies a steering force to this vehicle
/// </summary>
/// <param name="force">
/// A force vector to apply<see cref="Vector3"/>
/// </param>
/// <param name="elapsedTime">
/// How long has elapsed since the last update<see cref="System.Single"/>
/// </param>
private void ApplySteeringForce (Vector3 force, float elapsedTime)
{
if (MaxForce == 0 || MaxSpeed == 0 || elapsedTime == 0) {
return;
}
_lastRawForce = force;
// enforce limit on magnitude of steering force
Vector3 clippedForce = Vector3.ClampMagnitude (force, MaxForce);
// compute acceleration and velocity
Vector3 newAcceleration = (clippedForce / Mass);
if (newAcceleration.sqrMagnitude == 0 && !HasInertia) {
Speed = 0;
}
/*
Damp out abrupt changes and oscillations in steering acceleration
(rate is proportional to time step, then clipped into useful range)
The lower the smoothRate parameter, the more noise there is
likely to be in the movement.
*/
if (_accelerationSmoothRate > 0) {
_smoothedAcceleration = OpenSteerUtility.blendIntoAccumulator (_accelerationSmoothRate, newAcceleration, _smoothedAcceleration);
} else {
_smoothedAcceleration = newAcceleration;
}
// update Speed
Speed = _rigidbody.velocity.magnitude;
_lastAppliedVelocity = _rigidbody.velocity;
// Euler integrate (per frame) velocity into position
// TODO: Change for a motor
Profiler.BeginSample ("Applying displacement");
if (this.tag != "Player") {
Vector3 newForce = Vector3.ClampMagnitude (_smoothedAcceleration * MaxForce, MaxForce);
_rigidbody.AddForce (newForce);
//print (newForce);
// enforce speed limit
_rigidbody.velocity = Vector3.ClampMagnitude (_rigidbody.velocity, MaxSpeed);
}
Profiler.EndSample ();
// regenerate local space (by default: align vehicle's forward axis with
// new velocity, but this behavior may be overridden by derived classes.)
//if (this.tag != "Player")
// RegenerateLocalSpace (_rigidbody.velocity);
}
#endregion
}
Peter.
Your answer
Follow this Question
Related Questions
Help needed in UnitySteer 0 Answers
unitysteer with car model and ai 1 Answer
UnitySteer - Increase turning angle 0 Answers
Crowd of enemies with UnitySteer 1 Answer
Integrating UnitySteer with my wheeled collider based Rigidbody vehicles 0 Answers