- Home /
How can I stop a box sliding off a platform when the platform is moved?
What would be the best way to stop a box sliding off a platform when the platform is moved?
I have a moving platform which is a kinematic rigid body with a box collider. I've tried a couple of ways of controlling it (it moves in and out, rotates on its axis and moves up and down) - see method 1 and 2 at the bottom of my post.
Both methods result in the box sliding off the platform when the platform moves.
The platform is a kinematic rigid body with a box collider. The box is a non-kinematic body with a mesh collider. The platform and box both use a physics material.
Any pointers or suggestions would be helpful. By the way, I have played around with the physics material, and the mass/ drag settings of both the platform and the box, with little success.
Kinematic rigid body controller Method 1:
function Update () { transform.Translate(Input.GetAxis("Horizontal") *Time.deltaTime*10, 0, Input.GetAxis("Vertical") *Time.deltaTime*10);
if (Input.GetButton ("platform_up"))
transform.Translate(0,Time.deltaTime*3,0, Space.World);
if (Input.GetButton ("platform_down"))
transform.Translate(0,-Time.deltaTime*3,0, Space.World);
}
Kinematic rigid body controller Method 2:
var speed : float = 10.0; var rotationSpeed : float = 100.0;
function Update () { // Get the horizontal and vertical axis. // By default they are mapped to the arrow keys. // The value is in the range -1 to 1 var translation : float = Input.GetAxis ("Vertical") speed; var rotation : float = Input.GetAxis ("Horizontal") rotationSpeed;
// Make it move 10 meters per second instead of 10 meters per frame... translation = Time.deltaTime; rotation = Time.deltaTime;
// Move translation along the object's z-axis transform.Translate (0, 0, translation); // Rotate around our y-axis transform.Rotate (0, rotation, 0);
if (Input.GetButton ("platform_up"))
transform.Translate(0,Time.deltaTime*3,0, Space.World);
if (Input.GetButton ("platform_down"))
transform.Translate(0,-Time.deltaTime*3,0, Space.World);
} //can I limit the amount the platform can go up and down by in world space - say a lower limit of 0,0.5,0 and upper limit 0,9,0
//}
Update of this main question as pointed out by Joshua. Many thanks for your help. RESOLVED
Description of my scene:
I have a plane with a mesh collider serving as a "ground".
I have a box, tagged as box.
I have a platform, tagged as platform with "Kinematic rigid body controller Method 2": script from above controlling its movement.
I have a platform box collider set to trigger as a child of the platform. This has the following script attached:
public var Platform: GameObject;
function OnTriggerEnter (col : Collider) { var box = GameObject.FindWithTag ("box"); box.transform.parent = Platform.transform;
}
function OnTriggerExit (col : Collider) { var box = GameObject.FindWithTag ("box"); box.gameObject.transform.parent = null;
}
Result:
When the platform is moved under the box and collides with it, the box becomes a child of the platform, and follows it around exactly. This is what I wanted!
When I lower the platform to the ground the box then ceases to become a child of the platform and sits on the ground, and the platform can be moved away.
Please note this doesn't work perfectly, as there are errors and pops when the box comes to rest on the ground, but I can live with these as I'm just prototyping at the moment.
All workings out and problems, workarounds follow on the next few questions.
SM.
Answer by Joshua · Apr 29, 2011 at 09:31 AM
Ah, sounds like you simply need to add a trigger to the platform (an empty gameObject, parented and with it's transform reset with a sphere collider - trigger). If your box is inside this trigger it will be kinematic, when it leaves the trigger it will be non-kinematic again.
Alternatively you could use OnCollisionEnter and check if the box collided with the platform. Then, if the collision object is indeed the platform parent the box to the platform, so all movements of the platform will be applied to it's own transform as well. That would look something like
function OnCollisionEnter (hit : Collision) {
if (hit.gameObject.tag == "platform") {
transform.parent = hit.gameObject;
}
}
function OnCollisionExit (hit : Collision) {
transform.parent = null;
}
alternatively you could also exit the parenting when jumping. You have to attach this to the box/the upper parent of the box.
Thanks Joshua. I've tried adding a trigger to the platform - it doesn't make the box become kinematic. I also tried the OnCollisionEnter whihch I added as a script to the box - it doesn't become a child of the platform - perhaps I need to add something else to the box? The platform has been tagged as "platform" by the way.
I also tried animating the platform to see if it was anything to do with the speed/ accelaration of it affecting the box - but the same thing happens - the box slides off the platform.
Could you tell my why the trigger doesn't make it kinematic? It does if you tell it to through script.. (OnTriggerEnter/Exit). And the second method should definitely work. You're probably doing some simple small step wrong. Please try again and think about each stap, because the solutions I posted work.
Answer by SM · Apr 29, 2011 at 02:03 PM
So I've created an empty gameobject which I've made a child of the platform. Then I've Reset its transform and added a box collider.
I've Made the size of this collider slightly bigger than the box (which is a fair bit bigger than the platform).
Enabled "Is Trigger" on this BoxCollider.
To the box I've added the following script:
function OnTriggerEnter (col : Collider) {
this.rigidbody.isKinematic = true;
}
function OnTriggerExit (col : Collider) {
this.rigidbody.isKinematic = false;
}
Result: The box becomes kinematic when it touches/ is inside the box collider. When the box collider is moved, the box stops becoming kinematic.
However, when I move the platform, the box slides off of it. Perhaps it may be slightly stickier, but it still slides off quite easily.
Ok try this: At the top of that script add var platform : GameObject; and in the inspector drag the platform gameObject onto it.
Now replace the line inside your OnTriggerEnter with col.gameObject.transform.parent = platform.transform;
And replace the line insode the OnTriggerExit with col.gameObject.transform.parent = null;
This shouldn't make it sticky, this should make it move 100% with the platform while still allowing for it to also move indipendently.
Answer by SM · Apr 29, 2011 at 02:54 PM
Thanks Joshua for the reply. I've done what you suggest. Here is my code:
public var platform: GameObject;
function OnTriggerEnter (col : Collider) {
col.gameObject.transform.parent = platform.transform;
}
function OnTriggerExit (col : Collider) {
col.gameObject.transform.parent = null;
}
I put the platform trigger in the scripts variable slot in the inspector.
I notice that the box doesn't become a child of the platform and it still slides off the platform when the platform moves.
However, I do notice that the platform trigger ceases to become a child of the platform though, if that helps. So tried changing the game object in the public variable to the actual platform, rather than its child, the trigger. The result is that the box still falls off the platform, but all hierarchies remain unchanged.
Answer by SM · Apr 29, 2011 at 06:24 PM
I seem to have got something working, with one problem.
Description of my scene:
I have a plane with a mesh collider serving as a "ground".
I have a box.
I have a platform, tagged as platform with Kinematic rigid body controller Method 2: script from above controlling its movement.
I have a platform box collider set to trigger as a child of the platform. This has the following script attached:
public var Platform: GameObject;
function OnTriggerEnter (col : Collider) {
col.gameObject.transform.parent = Platform.transform;
}
function OnTriggerExit (col : Collider) {
col.gameObject.transform.parent = null;
}
The platform object is set as the platform GameObject in the inspector.
Result:
When the platform is moved under the box and collide with it, the box becomes a child of the platform, and follows it around exactly. This is what I wanted!
However, when I lower the platform to the ground the ground plane then also becomes a child of the platform as well as the box!
So partial success, which I can live with for now. Thanks for your helps Joshua.
If anyone would like to give me pointers on how to clean this up or make it more workable then I'd be grateful.
(I'm guessing it's something to do with the col : Collider being a generic statement and picking up anything with a collider.)
SM
I have to stress: please update your main question and do not post answers as addition to the question if they are not answers. This makes it unreadable for others who might have the same problem and could benefit.
You're right about OnTriggerEnter (col : Collider) will name everything that enters it's trigger col. You can specify if(col.gameObject.tag == "player") { before the making it parented. Of course give the player the tag player.
Your answer
Follow this Question
Related Questions
Increasing dynamic friction 1 Answer
Stop character sliding? 1 Answer
Unity 5 - Sliding Rigidbodies with maximum friction 2 Answers