0
\$\begingroup\$

Im making a top down game in unity. in my game there is a platform where the player can stand on. while this platform is moving the player moves with it. here is an example: enter image description here

This almost works like i want it to. The player moves together with the platform and is still able to move while on it. (note that currently the player will always follow the platform. there is no check to see if the player is on the platform or not. but that's done for testing.). What i want know is that when the platform rotates the player will also follow the rotation. currently it looks like this when the platform is rotating: enter image description here

here i move my character to show what i want to achieve: enter image description here

This is the code for moving my player and also the code that keeps me on the platform:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 5f;

    public Rigidbody2D rb;
    public Rigidbody2D platform;
    public Camera cam;

    Vector2 movement;
    Vector2 mousePos;
    // Update is called once per frame
    void Update()
    {
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");

        mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
    }
    Vector2 pos;
    private void FixedUpdate()
    {

        pos = pos + movement;
        rb.MovePosition(platform.position + pos  * moveSpeed * Time.fixedDeltaTime);

        Vector2 lookDir = mousePos - rb.position;
        float angle = Mathf.Atan2(lookDir.y,lookDir.x) * Mathf.Rad2Deg - 90f;

        rb.rotation = angle;
    }
}

this is the code for moving the platform:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Platform : MonoBehaviour
{
    public float moveSpeed = 5f;

    public Rigidbody2D rb;
    public Vector2 movement;

    private void Start()
    {
       rb = gameObject.GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        rb.MovePosition(rb.position + new Vector2(1f, 0) * Time.fixedDeltaTime);
        rb.MoveRotation(rb.rotation + 25f * Time.fixedDeltaTime);
    }
}

I know that is also possible to make the player a child of the platform and then move the platform by updating the transformation position. but i choose for a rigidbody for the platform movement because I want the player to be able to control the platform later on and then i will use things like addforce.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

On contact with the platform's trigger collide, store a reference to the platform and your position relative to the platform's coordinate system.

The next time you move, transform that local position by the platform's updated position and orientation. That's the location where you would be if you were "stationary".

Apply any player-induced movement relative to this shifted point. Then transform your resulting position back into the platform's local coordinate system to use next frame.

When you exit the platform's collider, clear the reference to it so you default back to full control of your movement relative to the stationary world coordinate system after that.

\$\endgroup\$
5
  • \$\begingroup\$ so i got the relative position towards the paltform with: localPos = platform.transform.InverseTransformPoint(rb.position); but then im stuck. how do i transform the local position with the platforms position and orientation? \$\endgroup\$ May 22, 2022 at 14:08
  • \$\begingroup\$ Exactly the opposite of what you just did: platform.transform.TransformPoint(localPos) \$\endgroup\$
    – DMGregory
    May 22, 2022 at 14:27
  • \$\begingroup\$ I tied to implement it the way you said but im probably doing something wrong. the player is not able to move and the platform just flies away without the player. this is the code: link i have set parts of what you said in the comments to show you where im trying to do what. i have not implemented a colider to detect when the player enters the platform yet so i just used Start to init the local coords instead so that it begins the moment the game starts. \$\endgroup\$ May 22, 2022 at 15:27
  • \$\begingroup\$ It is not appropriate to multiply the argument to Rigidbody2D.MovePosition by a speed or a time. This argument represents an absolute location, not a direction of travel. You want to multiply the movement variable, not the pos variable. \$\endgroup\$
    – DMGregory
    May 22, 2022 at 15:57
  • \$\begingroup\$ ok so i moved the * moveSpeed * Time.fixedDeltaTime; part to the line where i asign the movemnt so that it becomes this:pos = pos + movement * moveSpeed * Time.fixedDeltaTime; this is wat you mean with multiplying the movement and not the pos right ? I tested this and at first it looked like it works. but then everything started to shake. and the player was slowly drifting away. here is a video to it. but the shaking is way les visible in the video than it was onscreen. \$\endgroup\$ May 22, 2022 at 16:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .