Ride the Platform
Part of the Building Real Games section of Coddy's Unity journey. Lesson 51 of 60.
A CharacterController is not carried by what it stands on: on a moving platform it stays put, and the platform slides away under it. Moving its transform.position does not help, because the next Move starts from where the physics last saw it and undoes the change.
So the player adds the platform's move to its own. OnControllerColliderHit(ControllerColliderHit hit) runs for each collider a Move touches; a hit from below has hit.normal.y near 1. A ferry that carries a crate the same way:
private Ferry ferry;
void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.normal.y > 0.7f && hit.gameObject.TryGetComponent(out Ferry f))
{
ferry = f;
}
}Challenge
MediumMake the player ride the moving platform.
- In
Player, addprivate MovingPlatform platform;andOnControllerColliderHit: whenhit.normal.y > 0.5fand the object has aMovingPlatform, keep it inplatform. - In
Update(), put(move + velocity) * Time.deltaTimeinVector3 motion. Ifplatform != null, addplatform.deltaand setplatform = null. - Call
controller.Move(motion).
Press Play and jump onto the platform: it carries you. Then Check.
Try it yourself
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
[SerializeField] private float speed = 5f;
[SerializeField] private float jumpHeight = 1.5f;
[SerializeField] private float gravity = -9.81f;
private CharacterController controller;
private InputAction moveAction;
private InputAction jumpAction;
private Vector3 velocity;
void Start()
{
controller = GetComponent<CharacterController>();
moveAction = InputSystem.actions.FindAction("Move");
jumpAction = InputSystem.actions.FindAction("Jump");
}
void Update()
{
if (controller.isGrounded && velocity.y < 0f)
{
velocity.y = -2f;
}
Vector2 input = moveAction.ReadValue<Vector2>();
Vector3 move = new Vector3(input.x, 0f, input.y) * speed;
if (jumpAction.WasPressedThisFrame() && controller.isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move((move + velocity) * Time.deltaTime);
}
}
All lessons in Building Real Games
10Project: 3D Platformer
The CourseMoving Platforms2Buttons and Screens
Buttons and onClickLambdasWiring in the InspectorPanels On and OffHealth BarsRecap: Upgrade Shop5Saving with PlayerPrefs
Save a NumberLoad with a DefaultHigh ScoreSave SettingsRecap: Coins in the Bank3The Game Manager
One Script Runs the GameThe SingletonGame StatesSwitching on the StateRecap: Round Manager6Project: Endless Runner
Three LanesObstacles Ahead9The New Input System
Two Input SystemsKeyboard and MousePressed This FrameInput ActionsRecap: Input SwapPractice on your own: Unity playground