- Home /
Moving Platforms
I'm writing a 2D Platformer and I'm trying to get the player to stay on a moving platform. I've done searching and tinkering for a day or two now, and I'm not having any luck.
Basically, I've been told to try to keep the character moving with the platform when they are touching. Firstly, if I use anything related to OnTriggerEnter(), the player goes right through the platform. If I do OnCollisionEnter() (with a CharacterController on the player and a BoxCollider on the platform), nothing happens at all. These are two things I've found suggested most. The other is parenting the player with the platform, but this apparently causes "problems" (frequently stated, never explained).
So, how can I get the player to stay on the moving platform? Here is the code for the moving platform:
public class MovingPlatform : MonoBehaviour
{
private float useSpeed;
public float directionSpeed = 9.0f;
float origY;
public float distance = 10.0f;
// Use this for initialization
void Start ()
{
origY = transform.position.y;
useSpeed = -directionSpeed;
}
// Update is called once per frame
void Update ()
{
if(origY - transform.position.y > distance)
{
useSpeed = directionSpeed; //flip direction
}
else if(origY - transform.position.y < -distance)
{
useSpeed = -directionSpeed; //flip direction
}
transform.Translate(0,useSpeed*Time.deltaTime,0);
}
AND here is the code for the Player's movement (in Update):
CharacterController controller = GetComponent<CharacterController>();
float rotation = Input.GetAxis("Horizontal");
if(controller.isGrounded)
{
moveDirection.Set(rotation, 0, 0); //moveDirection = new Vector3(rotation, 0, 0);
moveDirection = transform.TransformDirection(moveDirection);
//running code
if(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) //check if shift is held
{ running = true; }
else
{ running = false; }
moveDirection *= running ? runningSpeed : walkingSpeed; //set speed
//jump code
if(Input.GetButtonDown("Jump"))
{
//moveDirection.y = jumpHeight;
jump ();
}
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
Answer by Spy-King · Nov 01, 2015 at 01:27 PM
You can also use the code in this video. It will work for both 2D and 3D.
Answer by sarmth · Mar 26, 2013 at 05:01 AM
The best way to achieve this is by the use of unity's in built physics system. Using the Rigidbody feature you can achieve this easily.
See here for more information;
http://docs.unity3d.com/Documentation/Components/class-Rigidbody.html
Hi, I'm trying this right now, but it doesn't seem to be having any affect. I've added a rigidbody to both the player and the platform, and set the platform to be kinematic (but not to use gravity) and for the player to use gravity but not kinematic. The player doesn't always go through the platforms, but when the platform comes out of the ground from below, it doesn't pick the character up, and the player jiggles when I actually get it on the platform.
Have you added a collider (non-trigger) to the player object? Also make sure you have the collision detection set to constant / strict. Also, I think the second object (platform) should not be kinematic.
The reason I set it as $$anonymous$$inematic was because the rigidbody documentation you linked said "If enabled, the object will not be driven by the physics engine, and can only be manipulated by its Transform. This is useful for moving platforms or if you want to animate a Rigidbody that has a HingeJoint attached." Also, I have no individual collider on the player object because it has a character controller, which replaces the collider. How do I set the collision detection?
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
my 2d character is not going to next animation state from one 0 Answers
Transform.position assign attempt not valid, and position is infinity on an object? 1 Answer
Dynamic parenting to moving platform so object won't slide from it on it own doesn't work properly 1 Answer