- Home /
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: https://youtu.be/RblzWRGa13c
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!
Player controllers are one of the most frustrating things to code (in my opinion) and have a vast array of possible issues at any given time. In your case, I would try to check the following to get more information:
Does your player move totally normally on a non-moving platform? Does the player ground properly on a non-moving platform? Try, just for kicks and giggles, setting your players base velocity to the same as the movement of the platform, and not childing the player to the platform.
Lots of things can go wrong with a rigidbody player controller, but I personally find them to be the superior player controller, so all the more to you. I would be most worried about how rigidbodies act as children of non-rigidbody objects. So maybe investigate the things I said above, I sort of feel like a non-parenting approach might solve the issue, but I think you'll just have to investigate it yourself.
Hope I could help!
Answer by MyNameAintCodex · Mar 17, 2021 at 10:34 PM
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.
Answer by CodesCove · Mar 14, 2021 at 05:17 PM
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).
Hello, I have moved the platform object under another gameobject, which has the scale (1, 1, 1) and I parent the player to that object (the object has the platform controller on it, so it moves and the model inside moves with it). Sadly, the problem persists. The player has the same scale when it's parented to the object as when it's not. If the platform is still, I can move around freely, but as you could see in the video, when the platform is moving, it's just super slow and janky. Is there possibly something else I could try?
Answer by prokiller7880 · Mar 14, 2021 at 05:25 PM
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, I changed the script to use MoveTowards (I think that in my old platform script, I used to have this from the beginning), but it sadly didn't help the with the jiterring and slow movement of the player when the platform is moving.
Thank you for your answer anyway.
Your answer
Follow this Question
Related Questions
Child object not moving with parent 3 Answers
Character on Moving and Rotating Platform 0 Answers
Platform Mover continued 1 Answer
Slowly move a GameObject on 1 axis, then destroy it. 1 Answer
2D Topdown Character Contoller 0 Answers