weird player movement when parented to moving platform
Hey guys! I am having problems with moving platforms in my 2D game and i can't figure out what is causing the issue.
I have a gameobject that is moved via script. It contains the actual platform. The platform itself has a box collider2d, a rigidbody2d (set to isKinematic) and a script attached to it. Objects that land on top of it are parented to the parent of the platform. All things are doing what i want them to do. If the player jumps onto the platform he is parented to the platform container, same goes for boxes. However if the player moves on the platform the movement is slower than usual. The player is moved using
float move = Input.GetAxis ("Horizontal");
myRigidbody2D.velocity = new Vector2(move*maxSpeed, ySpeed);
If i debug.log the velocity, the numbers are the same whether i walk on the platform or on normal ground but on the platform the player is only about half as fast.
How the hell is that possible? What is going on?
------------------ EDIT -----------------------
so i am still going mad about this issue. I have found a way to move my objects with the platform without parenting them because i read on several threads that parenting to moving platforms is bad practise and can cause problems. The strange phenomenas are still happening though.
If you want to look into any of my code i will gladly share it. At the moment my next guesses for a potential origin of the problem are:
a) The player movement is manipulated in the FixedUpdate of the characterController script (with Input.GetAxis and then setting the velocity) and in the update function of my platform-Script (with transform.Translate). However when i parented the player in my old approach i didnt manipulate the movement anywhere but in the player's FixedUpdate. In my platform script i only set a parent for it.
b) To detect wether or not the player is standing on the platform i am using OnCollisionEnter2D and OnCollisionExit2D. I am not sure how and why this would cause such an behaviour but i guess ill change this anyway since they do not seem to be called reliantly when the player hits the platform and i hope i can achieve a better result using raycasts.
I have already invested an incredible amount of time to get this fixed (around 20 hours of coding, testing, etc) so i hope i can get this fixed soon. Any help is highly apprecciated.
If you are using rigidbodies you shouldn't have to parent the object to the platform, but you do need to make the platform move and accelerate smoothly.
If i understand you correctly you suggest that i accelerate the platform at a speed where the player never loses contact to the platform (since the reason why i started parenting was that the player moved differently than the platform resulting in the player losing contact to the platform and falling back on it when moving down and the player kinda "vibrating" when moving up). However since i have different objects on the platform that can have different mass they are moving at different speed. Also i dont know which speed the platform will have in the end - it might be kinda fast. Won't this lead to problems when trying your approach? Also the player could jump while the platform is accelerating...
Answer by DavidWatts · Sep 08, 2016 at 09:21 PM
here is a script I wrote while trying this myself a while back just attach it to the player. hope this helps.
using UnityEngine;
using System.Collections;
public class SimpleCharacterController : MonoBehaviour {
Transform lastParent;
CharacterController character;
// Update is called once per frame
float cosSlopeLimit;
Vector3 platformVelocity;
void Start () {
character = GetComponent<CharacterController>();
lastParent = transform.parent;
cosSlopeLimit = Mathf.Cos( character.slopeLimit * Mathf.Deg2Rad );
}
void LateUpdate () {
if( transform.parent != lastParent && character.collisionFlags == CollisionFlags.None )
transform.SetParent( lastParent, true );
}
void OnControllerColliderHit ( ControllerColliderHit hit ) {
if( hit.gameObject.GetComponent<MovingPlatform>() ) {
if( hit.normal.y >= cosSlopeLimit )
transform.parent = hit.transform;
else if( transform.parent != lastParent )
transform.parent = lastParent;
}
else if( transform.parent != lastParent )
transform.parent = lastParent;
}
}
thank you for your answer.
As it seems you are using a CharacterController on your character that i don't have so i can't attach it to my player since i dont have "collisionFlags" etc defined.
However i found it interesting that you set the parent in LateUpdate ins$$anonymous$$d of Update. I tried it out but it didnt seem to make a difference.
I have now started to completly rewrite my character script and i wont make it physics based again. It's pretty sad that unity does not have a documented solution for something so basic as moving platforms imo.