- Home /
MRUA implementation optimization issues
I am implementing the MRUA formulas as an extension method in the rigidbody class, the main porpuse is to try and make the rigidbodys to move from pose A to pose B just using velocitys so i dont have problems with collisions. the code works fine it ismply calculates the time needed to stop the object, get the distance calculated in that time and compare if the distance from the player is lower than the distance to stop the object. but now i want to go a step forward, i am trying to create a coroutine method for moving the objects when both pose A and pose B are fixed, the code used in the other method for calculating each iteration when to start slowing down would work, but doesnt seem like the most efficient way of doing this. here is the code used as an example
public static void MoveByForces(this Rigidbody body, Vector3 target, float maxSpeed, float acceleration, float deceleration, float offset = 0.0f)
{
float distance = Vector3.Distance(target, body.position);
if(distance <= offset)
{
body.velocity = Vector3.zero;
body.MovePosition(target);
return;
}
float currentVelocity;
float decelerationDistance = DistanceCalculation(body, deceleration, out currentVelocity);
if (distance < decelerationDistance)
{
currentVelocity -= deceleration;
}
else
{
if (currentVelocity < maxSpeed)
{
currentVelocity += acceleration;
}
}
body.velocity = (target - body.position).normalized * currentVelocity / Time.fixedDeltaTime;
}
and what exactly is it you're asking for? "doesnt seem like the most efficient way" is actually the wrong assumption here. Use the Profiler. Does this code use a lot of CPU time? how many Rigidbodies does it need to get bad performance? Is the amount of rigidbodies you have an acceptable amount performance wise? Don't optimize until you need to. This code is short enough that it's easy to do later if necessary and there is never a perfect solution to a single problem besides maybe adding two numbers on the assembly level.
sorry english is not my first language and i have not expressed myself well. i need to optimise the code because the plan is to release it as a pack of free extra tools for the comunity, and even the code is short, is the type of code that would be call in the fixedupdate of each body, and calling methods like Vector3.Distance every iteration is a big overhead.i know this is not the best performance code at all, i am calculaing the distance from A - B every iteration because the distance each iteration might change, but, what i want to do know is create a coroutine so that it makes the object go to 2 fixed points, so calculating the distance of each iteration doesnt seem like a good practice, because there must be a way to calculate when to start brake if the points are fixed, but my physics knowledge isnt the best, so i was hoping maybe someone would suggest me a path or formulas to look into
Answer by lgarczyn · Oct 17, 2019 at 11:52 PM
Your code has multiple problems.
First, if the target moves, the object will turn instantly at full speed. This might look jarring in an otherwise realistic movement.
Second, performance wise, Distance
, magnitude
and normalized
are the biggest problem, as they involve a square root and three multiplications.
Without the DistanceCalculation I can only do so much, but here I reduced the amount of square roots from 2 to 1, and the amount of float multiplications from 12 to 9.
public static void MoveByForces(this Rigidbody body, Vector3 target, float maxSpeed, float acceleration, float deceleration, float offset = 0.0f)
{
float dir = target - body.position;
float distance = dir.magnitude;
if(distance <= offset)
{
body.velocity = Vector3.zero;
body.MovePosition(target);
return;
}
float currentVelocity;
float decelerationDistance = DistanceCalculation(body, deceleration, out currentVelocity);
if (distance < decelerationDistance)
{
currentVelocity -= deceleration;
}
else
{
if (currentVelocity < maxSpeed)
{
currentVelocity += acceleration;
}
}
body.velocity = dir * (currentVelocity / distance / Time.fixedDeltaTime);
}
thanks a lot for your time, but i have some questions,
float distance = dir.magnitude;
as far as i know you cant calculate the distance between 2 points just getting the maginuted from the vector AB, or i am missing something?
also, you said that it would get the max velocity if i move the target, why is that? if i am only adding a acceleration or deceleration, it is not posible unless there is a bug i have not seen
i have tested your approach and i am not being able to get 100% accurate velocities, the object doesnt reach the destination point with a velocity of 0
Dir is the difference of the two points, it's magnitude is by definition the distance. Dir divided by it's magnitude is by definition the normalized direction vector to the target.
In real life, and object needs three floats to describe it's velocity. To make a 90° turn you need to completely cancel your velocity and accelerate again. It's not a real problem here though, I tried to implement my own solution with 3d velocity and it's harder than I thought.
Your answer
Follow this Question
Related Questions
Best way to handle LOTS of potential rigidbodies? 2 Answers
Is a collider that enables/disables considered stationary? 2 Answers
Broadphase CD in Unity - pile of rigid bodies unsolved 0 Answers
Add 2d rigidbodies to moving objects to increase performance or not? 1 Answer
Rigidbody.MovePosition performance 1 Answer