- Home /
Dynamic parenting to moving platform so object won't slide from it on it own doesn't work properly
I've got theory covered - reparent player object dynamically to object it's on, so he'll stick to moving platform, but for some reason it doesn't work.
Both platform and player are physics-based rigidbodies. I'm not sure if problem lies in parenting or moving platform itself (debugging showed that it parents to correct object).
Player object just doesn't stick to moving platform.
Here's my platform code:
using UnityEngine;
using System.Collections;
public class SimpleMovingPlatform : MonoBehaviour {
public Vector3 velocity;
// Use this for initialization
void Start () {
}
void OnCollisionEnter(Collision other) {
velocity.x = -velocity.x;
velocity.y = -velocity.y;
velocity.z = -velocity.z;
}
// Update is called once per frame
void Update () {
this.rigidbody.velocity = velocity;
}
}
and this is character control script:
using UnityEngine;
using System.Collections;
public class PhysicBasedCharacterController : MonoBehaviour {
private bool isGrounded;
public float movementForce = 30;
public float jumpForce=20;
public float normalLimit =0;
public bool parentToColliders = true;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetAxisRaw("Vertical")>0){
this.rigidbody.AddForce(this.transform.forward * movementForce);
} else if (Input.GetAxisRaw("Vertical")<0){
this.rigidbody.AddForce(-this.transform.forward * movementForce);
}
if (Input.GetAxisRaw("Horizontal")>0){
this.rigidbody.AddForce(this.transform.right * movementForce);
} else if (Input.GetAxisRaw("Horizontal")<0){
this.rigidbody.AddForce(-this.transform.right * movementForce);
}
if ((isGrounded)&& (Input.GetButtonDown("Jump"))) {
this.rigidbody.AddForce(this.transform.up * jumpForce);
}
}
void OnGUI(){
//GUI.Box(new Rect(400,0,200,50),"isGrounded = "+isGrounded.ToString()+"\n"+"Jump = "+Input.GetButton("Jump").ToString());
}
void OnCollisionStay(Collision other) {
foreach(ContactPoint temp in other.contacts) {
if((temp.normal.y>normalLimit)) {
isGrounded=true;
}
}
if ((parentToColliders) && (isGrounded)){ //check for isGrounded, so player won't get parented to insane things like walls or ceiling and thus won't glitch out of level.
this.transform.parent = other.gameObject.transform;
}
}
void OnCollisionExit(Collision other) {
isGrounded=false;
}
}
Can you help me?
If it does matter, character is using Capsule collider and platform uses box collider.
Answer by clunk47 · Sep 24, 2013 at 01:11 AM
Have you tried childing a non-rendered trigger collider to you platform? Try this, and use OnTriggerStay, which uses Collider instead of Collision. Parent your player to this trigger object's transform, perhaps use a bool and set the player's position to the transform's position while the bool is true. This is a simpler approach, and doesn't require anything too fancy to work.
Re-read OP. Parenting actually work, when on platform and paused game, player objects shows as parented to platform. It just doesn't "stick" to it.
Have you tried making the rigibody kinematic while parented?
Then player won't be able to step away from platform or jump. One of reason of making physics-based movement script was to make movement entirely force driven so it feels more natural than character controller that is bundled with Unity.
That's why I say use a bool. $$anonymous$$ake the bool true or false, depending if the player has pressed the jump or walk buttons. If no buttons are pressed, the rigidbody would be kinematic, and you would freeze the player's position to the position of the transform in your platform (the trigger). Then when you press jump or walk buttons, make the rigidbody non-kinematic, unparent it, and re enable any movement that way.
I've got it mostly, but can't get jumping to work.
Here's my current update function:
void Update () {
kinematic = (!((Input.GetAxisRaw("Vertical")>0) || (Input.GetAxisRaw("Vertical")<0) || (Input.GetAxisRaw("Horizontal")>0) || (Input.GetAxisRaw("Horizontal")<0) || (Input.GetButtonDown("Jump")))) && (isGrounded);
if (Input.GetAxisRaw("Vertical")>0){
this.rigidbody.AddForce(this.transform.forward * movementForce);
} else if (Input.GetAxisRaw("Vertical")<0){
this.rigidbody.AddForce(-this.transform.forward * movementForce);
}
if (Input.GetAxisRaw("Horizontal")>0){
this.rigidbody.AddForce(this.transform.right * movementForce);
} else if (Input.GetAxisRaw("Horizontal")<0){
this.rigidbody.AddForce(-this.transform.right * movementForce);
}
if ((isGrounded)&& (Input.GetButtonDown("Jump"))) {
this.rigidbody.is$$anonymous$$inematic=false;
kinematic=false;
isGrounded = false;
this.rigidbody.AddForce(this.transform.up * jumpForce);
}
this.rigidbody.is$$anonymous$$inematic=(kinematic) && (onPlatform);
}
onPlatform is a bool set via messages. Here is part of platform movement object that triggers them:
void OnCollisionEnter(Collision other) {
if (other.gameObject.Equals(Player)){
Player.Send$$anonymous$$essage("setOnPlatform",true);
} else
{
velocity.x = -velocity.x;
velocity.y = -velocity.y;
velocity.z = -velocity.z;
}
}
void OnCollisionExit(Collision other) {
if (other.gameObject.Equals(Player)){
Player.Send$$anonymous$$essage("setOnPlatform",false);
}
}
The problem is that I'm not being able to jump as high as I can out from normal ground.