Hello, when I move my CharacterController in Replicate and use TimeManager.TickDelta my Character moves correctly but I cannot get the correct horizontal velocity ( horizontalVelocity = new Vector3(controller.velocity.x, 0, controller.velocity.z).magnitude; ).
When using Time.deltaTime instead I get the correct velocity. Is there anyway I can get the right velocity using TimeManager.TickDelta?
#Get Current CharacterController Speed (CSP)
82 messages · Page 1 of 1 (latest)
You are setting the velocity directly to a rigidbody or translating the transform? What is the actual code?
I would expect something like rb.velocity = direction * velocity and I'm not sure where you'd be using time deltas
Hey @whole moat thanks for taking the time, I’m not actually using a rigidBody on the character, just using the character controller component. So I would use the time deltas when I move the character like so characterController.Move(movement * Time.delta time).
Gave +1 Rep to @whole moat
Instead of using Time.DeltaTime i use FN’s TimeManager.TickDelta as it is in Replicate. The character moves fine and the speed is correct just as it was before implementing networking except for getting the velocity for some reason its showing wrong values
Are you using prediction?
So lets say the speed is actually 3 it would show as 7 - if i inrease the time managers tickrate the velocity values change but the speed is the same and working correctly
Yes
I get the right velocity values if i use Time.deltaTime
What FN version are you on?
And what is the actual code? I don't know why you're getting the magnitude of a vector
Normally you would do eg
direction = new Vector2(Horizontal, Vertical).normalized;
Then direction * speed* TimeManager.tickDelta
I need to get the horizontal speed character is moving in to use it for something else
I'm still not sure how that achieves this
The vertical (speed) is normalizedDirection.y * speed * TickDelta
moving the character is fine its just the velocity values im trying to get are wrong
Therefore, why are you using Vector3.Magnitude?
Magnitude is for getting a distance between two vector
https://docs.unity3d.com/ScriptReference/Vector3-magnitude.html
ergo your vertical velocity is here ^
Once the Vertical is normalized, that is the value you need
its so i can get the speed the character is moving in on x and z axis
it returns correct values when using Time.deltaTime but not TimeManager.TickDelta
Horizontal is normalizedDirection.x * speed * TickDelta
The doc says the access would be called in Update, which mean it probably use a fake velocity by calculating currentPos - lastFramePos
Therefore it would match up with Time.deltaTime yes. I gave you the code repeatedly to try with OnTick
The normalized Y would be the correct factor for vertical and the normalized X of Vector 2/3 would be the correct factor for horizontal movement
Ergo normalizedHorizontal * TickDelta * speed is your velocity for horizontal
and normalizedVertical * TickDelta * speed is your velocity for vertical
(Actually I should not assume 4D movement so ignore the "static" part i typed earlier)
You should cache value normalizedDirection everytime you invoke move and use that whenever you need to figure out the current "velocity"
ok thank @whole moat ill try implementing what you typed and see if it returns the correct speed the character is moving in
Gave +1 Rep to @whole moat
Let me know if it does not. I just checked the example and that seem to be in-line with my recommendation
Example:
[Replicate]
private void Move(MoveData md, bool asServer, bool replaying = false)
{
Vector3 move = new Vector3(md.Horizontal, 0f, md.Vertical).normalized + new Vector3(0f, Physics.gravity.y, 0f);
_characterController.Move(move * _moveRate * (float)base.TimeManager.TickDelta);
}
Custom:
[Replicate]
private void Move(MoveData md, bool asServer, bool replaying = false)
{
// Move is your normalized direction
normalizedDirection = new Vector3(md.Horizontal, 0f, md.Vertical).normalized + new Vector3(0f, Physics.gravity.y, 0f);
_characterController.Move(normalizedDirection * _moveRate * (float)base.TimeManager.TickDelta);
}
private float GetTickHorizontalVelocity() {
return normalizedDirection.x * _moveRate * (float)base.TimeManager.TickDelta);
private float GetFrameHorizontalVelocity() {
return normalizedDirection.x * _moveRate * Time.deltaTime);
}
This should work as long as you always move at a "static" speed (no acceleration etc)
Now if you're running logic in update use GetFrameHorizontalVelocity(), if the math is in OnTick use GetTickHorizontalVelocity()
Gave +1 Rep to @whole moat
My pleasure, padawan
i think we were trying to achieve different things
but what u said here led me to the right way of getting the speed
I think you were trying to adapt an example from official docs. But it imply you're using Update()
float speed = (transform.position - lastPos).magnitude / deltaTime;
lastPos = transform.position;
deltaTime being TimeManager.TickDelta
That's a slightly more expensive way to deduct velocity
correct 🙂
ya have to find a better way of doing, for one i know that division is not recommended
It's something you do when you don't know your velocity, but you're not using physics. I actually use that in one of my project, but specifically because it also work for variable speed
Since you already calculated directionNormalized, you can use that but it only work if you always move at the same speed
I have fake accel/deccel in my project so I use your method above
Im using it for when the character is falling and at some points I need to get the x and z speed
thats the problem its not constant speed
but ya again thank you so much for your time and help 😄
In the prediction code we looked at, (total) speed is always constant
At least horizontal is. Vertical may be affected by gravity
how can i paste code like u did?
normalizedControlledFallDirection = new Vector3(playerStateMachine.Horizontal, 0f, playerStateMachine.Vertical);
normalizedControlledFallDirection = Vector3.ClampMagnitude(normalizedControlledFallDirection, 1f);
controlledFallMovement = new Vector3(normalizedControlledFallDirection.x, 0f, normalizedControlledFallDirection.z);
controlledFallMovement = transform.TransformDirection(controlledFallMovement);
finaControlledFallMovement = new Vector3(controlledFallMovement.x, 0, controlledFallMovement.z);
playerStateMachine.movementDirection = new Vector3(playerStateMachine.momentumDirection.x, 0, playerStateMachine.momentumDirection.z);
playerStateMachine.movementDirection = new Vector3(playerStateMachine.movementDirection.x + finaControlledFallMovement.x, 0f, playerStateMachine.movementDirection.z + finaControlledFallMovement.z);
The highlighting seem to be a bit meh when the code is out of the entire context lol
normalizedControlledFallDirection = new Vector3(playerStateMachine.Horizontal, 0f, playerStateMachine.Vertical);
normalizedControlledFallDirection = Vector3.ClampMagnitude(normalizedControlledFallDirection, 1f);
controlledFallMovement = new Vector3(normalizedControlledFallDirection.x, 0f, normalizedControlledFallDirection.z);
controlledFallMovement = transform.TransformDirection(controlledFallMovement);
finaControlledFallMovement = new Vector3(controlledFallMovement.x, 0, controlledFallMovement.z);
playerStateMachine.movementDirection = new Vector3(playerStateMachine.momentumDirection.x, 0, playerStateMachine.momentumDirection.z);
playerStateMachine.movementDirection = new Vector3(playerStateMachine.movementDirection.x + finaControlledFallMovement.x, 0f, playerStateMachine.movementDirection.z + finaControlledFallMovement.z);
xD
thats cool @whole moat thanks again
Gave +1 Rep to @whole moat
That make more sense, yeah. What matter is we got to the bottom of it lol, but next time lead with the code, especially when asked
Then I dont have to make assumptions like whether you're using the default code or not
^^ will do 😄
Happy hacking
Would just like to clear somethings up for anyone in a similar situation.
What I was trying to do is get the speed of 2 combined Vectors.
targetDirection = new Vector3(Horizontal, 0f, Vertical);
targetDirection = Vector3.ClampMagnitude(targetDirection, 1f);
movementDirection = new Vector3(targetDirection.x, 0f, targetDirection.z);
movementDirection = transform.TransformDirection(movementDirection);
momentumDirection = new Vector3(intialMomentumDirection.x, 0, intialMomentumDirection.z);
and Inside Replicate ```cs
timeDelta = (float)base.TimeManager.TickDelta;
Vector3 vMovement = data.MovementDirection;
Vector3 vMomentum = data.MomentumDirection;
if(something)
{
speed += 3f * timeDelta;
momentumSpeed -= 3f * timeDelta;
}
vMovement.x *= speed;
vMovement.z *= speed;
vMomentum.x *= momentumSpeed;
vMomentum.z *= momentumSpeed;
YVelocity -= gravity * deltaTime;
finalMovement = new Vector3(vMovement.x + vMomentum.x, YVelocity, vMovement.z + vMomentum.z);
characterController.Move(finalMovemnt * deltaTime);
So the problem I had was getting the final speed the character is moving in.
Before Networking I was getting the current speed the character is moving in like so ```cs
currentSpeed = characterController.velocity.magnitude;
This would not work now as we are moving the character in TimeManager.TickDelta instead of Time.deltaTime
and it turns out its as easy as ```cs
float currentSpeed = finalMovement.magnitude;
and if we just wanted the horizontal speed (horizontal here being x and z axis) ```cs
float currentHorizontalSpeed = new Vector3(finalMovement.x, 0f, finalMovement.z);
Get Current CharacterController Speed