Moving platform script makes my player unable to move

Hello,

I presume that my problem is probably something fundemental about how transforms/parents work in Unity, but as I’m not very familliar with the inner workings of the engine, I’ll ask for help here.

I have a platform script, which updates the platform transform every Update using transform.Translate and an OnTriggerEnter/OnTriggerExit system to make the platform my players parent when it touches the platform.

Here are the scripts:
PlatformController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlatformController : MonoBehaviour
{
    public Transform[] platformPoints;
    public float speed = 200f;
    public float distance = 0.1f;
    public float waitTime = 1f;

    private int curPoint;
    private float stopTime = 0f;

    void Start()
    {
        curPoint = 1;     
    }

    void Update()
    {
        if (Vector3.Distance(transform.position, platformPoints[curPoint].position) > distance)
        {
            Vector3 dir = platformPoints[curPoint].position - transform.position;
            dir = dir.normalized;
            transform.Translate(dir * speed * Time.deltaTime);
            stopTime = 0f;
        } else
        {
            if(stopTime >= waitTime)
            {
                curPoint++;
                if (curPoint == platformPoints.Length) curPoint = 0;
                stopTime = 0f;
            } else
            {
                stopTime += Time.deltaTime;
            }
        }
    }

    void OnTriggerEnter(Collider other)
    {
        if(other.transform.gameObject.layer == 9 && other.transform.parent == null)
        {
            other.transform.parent = transform;
        }    
    }

    void OnTriggerExit(Collider other)
    {
        if (other.transform.gameObject.layer == 9)
        {
            other.transform.parent = null;
        }
    }
}

PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 10f;
    public float moveAccel = 50f;
    public float moveDeaccel = 0.15f;
    public float jumpForce = 250f;
    public float inAirMoveAccel = 35f;
    public float maxAngle = 75f;

    private Rigidbody rb;

    private Vector3 input;
    private Vector2 refVel = Vector2.zero;

    private bool isGrounded;
    
    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        input = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical"));
        input = input.normalized;
    
        if(isGrounded && Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(Vector3.up * jumpForce);
        }
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        Vector2 vel = new Vector2(rb.velocity.x, rb.velocity.z);
        if(vel.magnitude > moveSpeed)
        {
            vel = vel.normalized;
            vel *= moveSpeed;
        }

        vel = Vector2.SmoothDamp(vel, Vector2.zero, ref refVel, moveDeaccel);

        rb.velocity = new Vector3(vel.x, rb.velocity.y, vel.y);


        float curMoveAccel = moveAccel;
        if (!isGrounded) curMoveAccel = inAirMoveAccel;

        rb.AddRelativeForce(input* curMoveAccel);
    }

    private void OnCollisionStay(Collision collision)
    {
        foreach(ContactPoint contact in collision.contacts)
        {
            if (Vector3.Angle(contact.normal, Vector3.up) < maxAngle)
            {
                isGrounded = true;
            }
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        isGrounded = false;
    }
}

My problem is that when my players gets parented to the platform, the players movement is slowed down to a crawl and it cant jump very high (almost not at all).

I will link a video below to show what I mean:

This only happens when the platform is moving, as you can see in the video.

Thank you in advance for any answer or pointer to where the problem might be.

Have a great day!

One possible reason:

Is your Player object scaled in any way when the parenting is done? If so, try how the movements works if the platform will have 1,1,1 scale. This is because scaling will effect also to the physics.

If this seems to be your root cause of the problem then you need to use intermediate object with 1,1,1 scale btw the platform and the player… It will take a few tries to get it to work right (the parenting sequence order is important).

If youre platform had a fixed start and end position, I would look into using Vector3.MoveTowards. at least thats how I do it most of the time. It Neede a startingposition, target(endposition) and a speed.

Hi, so I have been able to solve this by implementing a if statement, in which I check if the player’s input magnitude whilst on the platform is 0 or if they are not jumping.
The platform controller now looks like so:
public class PlatformController : MonoBehaviour
{
public Transform platformPoints;
public float speed = 5f;
public float distance = 0.1f;
public float waitTime = 1f;

    private int curPoint;
    private float stopTime = 0f;

    private PlayerController player;
    private bool onPlatform;

    void Start()
    {
        curPoint = 1;
        onPlatform = false;
        player = null;
    }

    void Update()
    {
        if (Vector3.Distance(transform.position, platformPoints[curPoint].position) > distance)
        {
            transform.position = Vector3.MoveTowards(transform.position, platformPoints[curPoint].position, speed*Time.deltaTime);
            if (onPlatform && player.input.magnitude > 0) player.transform.parent = null;
            else if (onPlatform && (player.input.magnitude <= 0 || Input.GetKeyDown(KeyCode.Space))) player.transform.parent = transform;
            stopTime = 0f;
        } else
        {
            if(stopTime >= waitTime)
            {
                curPoint++;
                if (curPoint == platformPoints.Length) curPoint = 0;
                stopTime = 0f;
            } else
            {
                stopTime += Time.deltaTime;
            }
        }
    }

    private void FixedUpdate()
    {
        
    }

    void OnTriggerEnter(Collider other)
    {
        if(other.transform.gameObject.layer == 9 && other.transform.parent == null)
        {
            other.transform.parent = transform;
            player = other.transform.GetComponent<PlayerController>();
            onPlatform = true;
        }    
    }

    void OnTriggerExit(Collider other)
    {
        if (other.transform.gameObject.layer == 9)
        {
            other.transform.parent = null;
            player = null;
            onPlatform = false;
        }
    }
}

There is still a certain amount of wonkiness going on, but it generally works as it should.
So if anybody needs a solution for this and the answers of the other great people who posted here didn’t help, you can try this.

Thank you all for your pointers, they helped me to get to this.