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.

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.

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.

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.

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