Reputation: 9
I have implemented the following tutorial in Unity (2D) attempting to create a rope swinging platformer: https://gamedevelopment.tutsplus.com/tutorials/swinging-physics-for-player-movement-as-seen-in-spider-man-2-and-energy-hook--gamedev-8782
void FixedUpdate()
{
Vector2 testPosition = playerRigidbody.position + playerRigidbody.velocity * Time.deltaTime;
Hooked(testPosition);
}
private void Hooked(Vector2 testPosition)
{
Vector2 t = new Vector2(tetherPoint.position.x, tetherPoint.position.y);
Debug.DrawLine(tetherPoint.position, playerRigidbody.position);
float currentLength = (testPosition - t).magnitude;
if (currentLength < tetherLength)
{
currentLength = (playerRigidbody.position - t).magnitude * Time.deltaTime;
}
else
currentLength = tetherLength;
if ((testPosition - t).magnitude > tetherLength)
{
Vector2 x = (testPosition - t).normalized;
testPosition = new Vector2(x.x * currentLength, x.y * currentLength);
playerRigidbody.velocity = (testPosition - playerRigidbody.position) * Time.deltaTime;
playerRigidbody.position = testPosition;
}
}
It seems to function correctly on the downward swing but when the player begins to travel upwards they become stuck floating in the air and don't drop to the middle of the arc. The swing also does not propel them very high on the other side even when dropped from height.
EDIT (Further clarification): Interestingly When the player is dropped from the other side of the tetherPoint it stops in the same spot, this time only half-way down. It's as if the player is being pulled toward a single position even when manually moved in the editor while playing no matter the direction.
EDIT: User John cleared up my concerns about deltaTime.
I've tried examining the change in variables during play but I just can't figure out why it's not working correctly. I think the issue lies somewhere in my interpretation of the original psudeo-code to C#.
Another question on the same tutorial has been asked previously but unfortunately that users implementation was very different than mine: Game rope swing physics acting weird
EDIT: Since posting I've updated the code to use AddForce and MovePosition instead but it's still the same.
playerRigidbody.AddForce((testPosition - playerRigidbody.position) * Time.deltaTime);
playerRigidbody.MovePosition(testPosition);
Upvotes: 0
Views: 540
Reputation: 728
It looks like you're using Time.deltaTime
from a method that is called from FixedUpdate
. What you want to use instead is Time.fixedDeltaTime
.
FixedUpdate
is called at a set interval (eg. 50fps) for physics updates, but regular Update
is called at a different varying frequency (up to hundreds of times a second if you've got a fast computer/simple game).
Time.deltaTime
is used for the Update
method, and so the value of it can be different each time Update
is called, as the time between Update
calls varies.
However, because FixedUpdate
is called at the same interval each time, Time.fixedDeltaTime
is constant and (normally) much larger than Time.deltaTime
. Your code doesn't work well with Time.deltaTime
, as it doesn't represent the actual difference in time between each FixedUpdate
call, but Time.fixedDeltaTime
should work.
As a side note, you're correct that you should be multiplying by the time delta rather than dividing. the time delta should be multiplied when calculating positions (eg. for the Vector2 testPosition
assignment and the currentLength
calculation), but for calculating the velocity you should be dividing the time delta (because velocity = distance/time).
Upvotes: 0