# CharacterController movement with platform

Hello everyone.
I’m using asset library for character’s movement. It uses `Character Controller` component for the player movement. I want to add to my game some moving platforms, so that player will be able to jump to that platforms and move. I tried two approaches:

1. To make player’s game object child of moving platform, but it doesn’t work, I guess it’s because `Character Controller`’s position is changing in `Update` method.
2. To add platform’s velocity to the `Character Controller`’s calculated velocity, but now it moves faster than platform.

I know that there are some conditions related to the calculation logic, but my knowledge of mathematics is not enough to fix this.

Please help me to understand how to properly calculate and mix that two velocities, so the player will move along with the platform

This is the code, that reads user input and calculates movement velocity:

``````public void Move(Vector2 moveInput, float targetSpeed, Quaternion cameraRotation, bool rotateCharacter = true)
{
// note: Vector2's == operator uses approximation so is not floating point error prone, and is cheaper than magnitude
// if there is no input, set the target speed to 0
if (moveInput == Vector2.zero) targetSpeed = 0.0f;

// a reference to the players current horizontal velocity
float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;

float speedOffset = 0.1f;
float inputMagnitude = moveInput.magnitude; // _input.analogMovement ? _input.move.magnitude : 1f;

if (inputMagnitude > 1)
inputMagnitude = 1f;

// accelerate or decelerate to target speed
if (currentHorizontalSpeed < targetSpeed - speedOffset ||
currentHorizontalSpeed > targetSpeed + speedOffset)
{
// creates curved result rather than a linear one giving a more organic speed change
// note T in Lerp is clamped, so we don't need to clamp our speed
_speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude,
Time.deltaTime * SpeedChangeRate);

// round speed to 3 decimal places
_speed = Mathf.Round(_speed * 1000f) / 1000f;
}
else
{
_speed = targetSpeed * inputMagnitude;
}

_animationBlend = Mathf.Lerp(_animationBlend, targetSpeed * inputMagnitude,
Time.deltaTime * SpeedChangeRate);

// normalise input direction
Vector3 inputDirection = new Vector3(moveInput.x, 0.0f, moveInput.y).normalized;

// note: Vector2's != operator uses approximation so is not floating point error prone, and is cheaper than magnitude
// if there is a move input rotate player when the player is moving
if (moveInput != Vector2.zero)
{
_targetRotation = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg +
(_useCameraOrientation ? cameraRotation.eulerAngles.y : 0);
float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity,
RotationSmoothTime);

// rotate to face input direction relative to camera position
if (rotateCharacter)
transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
}

// update animator if using character
if (_hasAnimator)
{
_animator.SetFloat(_animIDSpeed, _animationBlend);
_animator.SetFloat(_animIDMotionSpeed, inputMagnitude);
}

Vector3 targetDirection = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;
_velocity = targetDirection.normalized * _speed + new Vector3(0.0f, _velocity.y, 0.0f);
_timeoutToResetVars = 0.5f;
}
``````

This is `Update` method:

``````void Update()
{
GravityControl();
GroundedCheck();

if (_timeoutToResetVars <= 0)
{
_speed = 0;
_animationBlend = 0;
_animator.SetFloat(_animIDSpeed, 0);
_timeoutToResetVars = 0;
}
else
_timeoutToResetVars -= Time.deltaTime;

if (_useRootMotion)
return;

if (!_controller.enabled) return;

_controller.Move(_velocity * Time.deltaTime);
}
``````

I think your second approach, to add the platform’s velocity to the player, would work with just a bit more logic. This is how I would do it:

1. When you get on/off a platform, update a value on the player itself to be the platform speed or 0.

2. When you’re going to move the player, run a check to see if that value is 0 or not. If it is 0, just move normally. If it is not 0, the player moves at that value instead of their normal value.

3. (2.5) However, I think you’d want them to move a bit while on the platform, right? So you could create a new variable for the player with a smaller speed variable that is just for platforms and then take the `platformSpeed + playerSpeedOnPlatform`, for example if they’re moving right. But then just `playerSpeedOnPlatform `by itself when moving left, since they’d be moving against the platform’s speed.

4. When the player leaves the platform, their speed returns to normal.

5. If your player jumps, think about how you want them it to work. Should their movement velocity in the air return to normal or stay with the platform until they land?