Hello there. I’m working on improving my game, and decided to use moving platforms (and all sorts of other moving terrain). I’ve gotten the platform to move so far with something simple like this:
where targetA and targetB are Transforms. It works very well, but my player’s ball doesn’t move with it.
I’ve looked this up for a while now, and the two common solutions I’ve found either needs a character controller (which is what the 2D platformer tutorial uses, if I recall correctly) or makes the player a child of the platform. However, the latter won’t work correctly (I’m assuming) as my player is a child of another (empty) gameobject. Are there any other solutions? I’ve also read about adding the two velocities together, but my platform moves directly by editing the transform.
Thank you, and I’m sorry if I missed the answer somewhere out in easy reach there.
Give your platform a kinematic rigidbody and use rigidbody.MovePosition instead - It simulates what would happen with the physics between the origin and position you move it to, as opposed to simply snapping when you set transform.position. I used it in a ball rolling game and it turned out how you would expect, though the documentation warns it will behave the same as transform.position if you’re using small values.
Hmm… Not sure exactly how/when to use it. For example, this is what I last tried:
void LateUpdate(){
if(riding)
{
this.transform.position = rideOffset;
}
} // end of FixedUpdate()
void OnTriggerEnter(Collider hit){ // when entering an object with a Trigger...
Control_Terrain terrainType = hit.gameObject.GetComponent<Control_Terrain>();
if(terrainType != null)
{
switch(terrainType.thisTerrain)
{
case Control_Terrain.TerrainType.PlatformMover:
print("On a platform!");
riding = true;
Vector3 ride2Offset = this.transform.position - hit.transform.position;
rideOffset = hit.transform.position + ride2Offset;
break;
}
}
}
void OnTriggerExit(Collider hit){
print("Got off a trigger");
riding = false;
}
This is on my player (for having all my trigger action centered on my player), and what happens is that the ball enters the platform’s trigger, and the rideOffset is then calculated. However, that rideOffset is pretty much permanent and the ball won’t be able to move at all.
Actually, now that I look at it, I may have to move this code onto the platform, cache the player at the Start(), and do that. However, I’d still need to edit it so the ball can easily move… Hm, not sure exactly how to let the ball move (with forces) and add on the dynamic change in position of the platform at the same time…
Sorry for the double post, but I guess I got it to work. I’ll change the transform.position to rigidbody.MovePosition soon enough, but here’s what it took me a ton of research and testing to do:
void Start ()
{
if(player == null)
{
player = GameObject.Find("Player");
}
}
void FixedUpdate()
{
if(thisTerrain == TerrainType.PlatformMover)
{
float weight = Mathf.Cos (Time.time*speed*2*Mathf.PI)*0.5f+0.5f;
Vector3 newPosition = targetA.position *weight + targetB.position*(1-weight);
Vector3 changeRate = -this.transform.position + newPosition;
this.transform.position = newPosition;
// Following code for moving the player
if(riding){
player.transform.position += new Vector3(changeRate.x, 0, changeRate.z);
}
}
}
void OnTriggerEnter(Collider hit)
{
if(hit.gameObject == player)
{
print("Player is riding the platform!");
riding = true;
}
}
void OnTriggerExit(Collider hit)
{
if(hit.gameObject == player)
{
print("Player is off the paltform =/");
riding = false;
}
}
Works as it should! I actually had to step back from the computer and write the steps out, as I couldn’t figure out how to apply the change of the platform’s position to the ball- which is really simple when you write out the words and figure out you got all the information you need, you just need to sort through it.
Thanks for the tip, Josh707! Hopefully this post will save a bunch of others time.
Edit: Just for clarification, this script lies on the platform itself. Also, I guess I won’t use MovePosition as the change in position isn’t that great, thus rendering it not as useful. Maybe if I increase the speed I’ll implement it.
Also, no need for a rigidbody on the platform (still need one of the ball, of course) as the platform itself isn’t using any of the features of a rigidbody.
Your idea seems like it’ll work fine, if what you have works then there’s no reason to change it to a rigidbody, but I guess I could have explained that a little better - If you give the platform a kinematic rigidbody it won’t react to collisions/gravity but MovePosition will cause the physics engine to calculate all collisions/forces on rigidbodies that are in it’s way, e.g. if there is a rigidbody cube on top of a horizontally moving platform it will sit on top with friction like you would expect. The code would be simpler, you wouldn’t need to adjust the players position as the physics engine would just do that for you.
If your player is just a traditional rigidbody it should stay in place on the platform without needing any code to adjust the position, as long as the friction isn’t low enough to let you slide around. If you do decide to use this you might want to set the platform’s rigidbody to interpolate or it could appear to stutter as it moves, but it’s good you got it figured out regardless.
I tried using rigidbodies and physics materials, but none of them worked in my case. I even tried to increase the friction as high as it could go without much progress. Thanks for the input though.
Also, isn’t it recommended to only use interpolation on the player, for speed reasons?
Oh, you’re using a sphere/ball right? Like rolling it around? This way will kind of cause a sphere to roll on the spot rather than just move with it unless you apply some torque to keep it still, which is how the player controlled the ball with input in my game, I wanted that kind of physics in mine. If you just want it to move with the platform rather than with accurate physics your method is probably the way to go, it’s basically the thing you see when you move a surface underneath a ball and the ball rolls backwards or in place rather than moving with the surface. If you’re not using a sphere I can still understand how it wouldn’t work how you want, the change in direction wouldn’t instantly change the players velocity either.
I’m not 100% sure about the interpolation and it’s performance, but without it the platforms stutter quite a bit when you’re riding with them, my player rigidbody is set to interpolate as well. The docs say it smooths the transform based on the previous frame’s transform, it doesn’t sound like a heavy operation so it’s probably not an issue (unless on mobile perhaps), until you’re using like hundreds of them at once. It is recommended for just the player but I think it’s also meant for situations like this, it probably means don’t set every rigidbody in the scene to interpolate.
I think that guys issue could be solved the same way here, but he seems to be going for the same movement you want. When the platform changes direction the player will continue in the same direction until friction slows him down/pulls to the the same velocity as the platform, with the sizes he’s using it might be difficult to stay on. I think your method could help him with that
Actually, my ball moves perfectly with the platform. I can roll the ball around the platform, and it will move sideways to the same degree as the platform, but I can still accelerate off of it.
If you’re talking about making the ball act as if the platform was scraping against it and thus turning it, it wasn’t the sort of behavior in mind. Honestly, can’t see how a platform doing that would be useful, but now I’m thinking if I can get it to work
I sort of wanted to throw in platformer elements into my game, since that’s… essentially what it is xD
Hehe yeah, I meant if you decided to use the rigidbody it would behave like that, when I made my project I needed the platform to make the ball react with physics rather than carry it around. Anyways, glad you got it figured out!
This is a pretty old thread, but in case anyone needs a way to do this without parenting for objects with rigidbody, here is a solution that works for me:
Create a platform object that moves.
Create a child object with box collider trigger that covers most of the platform surface and attach this script:
Hi, I have just found this as having a problem myself trying to get my player to stay on the platform without parenting, I have tried your code and attached the script to the platform but when my player jumps onto the moving platform he still doesn’t stay on it and slides off, also with box collider as a trigger the player falls through it, I would appreciate any help trying to solve this as its really puzzling me.