Edit: Abridged Version
I have a 3d platformer setup with a PlayerCharacter using CharacterController.Move and moving platforms with kinematic rigidbodies being moved by rigidbody.MovePosition.
If the PlayerCharacter is stationary, the platforms move through it without colliding. However, if the PlayerCharacter is moving, the collision is correctly detected.
Is this an appropriate setup for moving platforms? Have I overlooked something obvious? Does anyone have any tips for where to start when debugging this? Further details below - I've attempted to debug/fix this a number of ways, with no success so far.
I've been working on a 3d platformer. I have a Player object with a ThirdPersonController (using CharacterController.Move()) and SpringFollowCamera (harvested/modified from the 3D Platform Tutorial), and I've written generic platform movement code. The Player character is attached to the platform when it stands atop it, and can move around as the platform moves - based on the code given by Rune's answer to a similar question.
My initial implementation of the platforms was directly setting the transform.position, and I understood that it would clip through the character. However, I have changed to rigidbody.MovePosition(), and there are still clipping issues under some circumstances.
With the transform.position implementation:
- When the platform stops at either end, the Player cannot move through the platform. (intended)
- When both the platform and Player are moving, the Player can move through the platform.
- When the platform is moving but the Player is stationary, the platform will clip straight through the Player.
With the rigidbody.MovePosition implementation:
- When the platform stops at either end, the Player cannot move through the platform. (intended)
- When both the platform and Player are moving, the Player cannot move through the platform. (intended)
- When the platform is moving but the Player is stationary, the platform will clip straight through the Player.
The platform is a kinematic RigidBody with no drag or gravity applied, and scale of (2.0, 0.5, 2.0). The Player is a Cylinder with a CharacterController of 2 hieght and 0.5 radius.
I'm still fairly new to Unity, but fairly experienced with programming and game development. Is there something obvious that I've missed here? Is there an error with my implementation of the Rigidbody on the platform, or my use of MovePosition (as below)? My only other thoughts are that the collisionFlags are being ignored when the player is stationary, but I'm not sure how or why that would be set.
I've stripped out the unrelated code (where MoveObject is called, etc).
var startPosition : Vector3; // The starting WorldPosition of the platform (used if the platform must reset)
var endPosition : Vector3; // The ending WorldPosition of the platform
var moveTime : float = 2.5; // How long it takes to move from one end to another
var endMoveDelay : float = 0.5; // Time waited at each end without moving again
private var desiredPosition : Vector3;
function FixedUpdate()
{
if ( transform.position != desiredPosition )
{
transform.rigidbody.MovePosition(desiredPosition);
}
}
function MoveObject(startPos : Vector3, endPos : Vector3, moveTime : float)
{
var i = 0.0;
var rate = 1.0/moveTime;
while (i < 1.0)
{
i += Time.deltaTime * rate;
// transform.position = Vector3.Lerp(startPos, endPos, Mathf.SmoothStep(0.0, 1.0, i)); // was using this before rigidbody implementation
desiredPosition = Vector3.Lerp(startPos, endPos, Mathf.SmoothStep(0.0, 1.0, i));
yield;
}
}
Any insight is much appreciated! Cheers.