So I have been reading and editing the default mobile sidescroller script to accept moving platforms. There are other scripts out there that do this, but I want to learn how to do this myself. Here is what I have edited so far. I do not wish to do this with parenting as I want to get the velocity of the platform eventually and add to my character.
//////////////////////////////////////////////////////////////
// SidescrollControl.js
//
// SidescrollControl creates a 2D control scheme where the left
// pad is used to move the character, and the right pad is used
// to make the character jump.
//////////////////////////////////////////////////////////////
#pragma strict
@script RequireComponent( CharacterController )
// This script must be attached to a GameObject that has a CharacterController
var moveTouchPad : Joystick;
var jumpTouchPad : Joystick;
var forwardSpeed : float = 4;
var backwardSpeed : float = 4;
var jumpSpeed : float = 16;
var inAirMultiplier : float = 0.25; // Limiter for ground speed while jumping
private var thisTransform : Transform;
private var character : CharacterController;
private var velocity : Vector3; // Used for continuing momentum while in air
private var canJump = true;
//These are for platform support
private var activePlatform : Transform;
private var activeLocalPlatformPoint : Vector3;
private var activeGlobalPlatformPoint : Vector3;
private var lastPlatformVelocity : Vector3;
// If you want to support moving platform rotation as well:
private var activeLocalPlatformRotation : Quaternion;
private var activeGlobalPlatformRotation : Quaternion;
function Start()
{
// Cache component lookup at startup instead of doing this every frame
thisTransform = GetComponent( Transform );
character = GetComponent( CharacterController );
// Move the character to the correct start position in the level, if one exists
var spawn = GameObject.Find( "PlayerSpawn" );
if ( spawn )
thisTransform.position = spawn.transform.position;
}
function OnEndGame()
{
// Disable joystick when the game ends
moveTouchPad.Disable();
jumpTouchPad.Disable();
// Don't allow any more control changes when the game ends
this.enabled = false;
}
function Update()
{
var movement = Vector3.zero;
if (Application.platform == RuntimePlatform.Android)
{
// Apply movement from move joystick
if ( moveTouchPad.position.x > 0 )
{
movement = Vector3.right * forwardSpeed * moveTouchPad.position.x;
}
else
{
movement = Vector3.right * backwardSpeed * moveTouchPad.position.x;
}
}
else
{
if (Input.GetKey("d"))
{
movement = Vector3.right * forwardSpeed * -1;
}
else if (Input.GetKey("a"))
{
movement = Vector3.right * backwardSpeed * 1;
}
else
{
movement = Vector3.right * 0;
}
}
// Check for jump
if ( character.isGrounded )
{
var jump = false;
var touchPad = jumpTouchPad;
if ( !touchPad.IsFingerDown() )
canJump = true;
if ( canJump touchPad.IsFingerDown() || Input.GetKeyDown("space"))
{
jump = true;
canJump = false;
}
if ( jump )
{
// Apply the current movement to launch velocity
velocity = character.velocity;
velocity.y = jumpSpeed;
}
}
else
{
// Apply gravity to our velocity to diminish it over time
velocity.y += Physics.gravity.y * Time.deltaTime;
// Adjust additional movement while in-air
movement.x *= inAirMultiplier;
// movement.z *= inAirMultiplier;
}
// Moving platform support
if (activePlatform != null) {
var newGlobalPlatformPoint = activePlatform.TransformPoint(activeLocalPlatformPoint);
var moveDistance = (newGlobalPlatformPoint - activeGlobalPlatformPoint);
//moveDistance = Vector3(moveDistance.x, moveDistance.y, 0);
if (moveDistance != Vector3.zero)
{
character.Move(moveDistance);
}
lastPlatformVelocity = (newGlobalPlatformPoint - activeGlobalPlatformPoint) / Time.deltaTime;
// If you want to support moving platform rotation as well:
var newGlobalPlatformRotation = activePlatform.rotation * activeLocalPlatformRotation;
var rotationDiff = newGlobalPlatformRotation * Quaternion.Inverse(activeGlobalPlatformRotation);
// Prevent rotation of the local up vector
rotationDiff = Quaternion.FromToRotation(rotationDiff * transform.up, transform.up) * rotationDiff;
transform.rotation = rotationDiff * transform.rotation;
}
else {
lastPlatformVelocity = Vector3.zero;
}
activePlatform = null;
if(movement.z != 0)
{
movement.z = 0;
}
movement += velocity;
movement += Physics.gravity;
movement *= Time.deltaTime;
// Actually move the character
character.Move( movement );
if ( character.isGrounded )
// Remove any persistent velocity after landing
velocity = Vector3.zero;
// Moving platforms support
if (activePlatform != null) {
activeGlobalPlatformPoint = transform.position;
activeLocalPlatformPoint = activePlatform.InverseTransformPoint (transform.position);
// If you want to support moving platform rotation as well:
activeGlobalPlatformRotation = transform.rotation;
activeLocalPlatformRotation = Quaternion.Inverse(activePlatform.rotation) * transform.rotation;
}
}
function FixedUpdate()
{
// //This makes sure we are always at z 0
// if(character.transform.position.z !=0)
// {
// character.transform.position.z = 0;
// }
}
function OnControllerColliderHit (hit : ControllerColliderHit) {
// Make sure we are really standing on a straight platform
// Not on the underside of one and not falling down from it either!
if (hit.moveDirection.y < -0.9 hit.normal.y > 0.5) {
activePlatform = hit.collider.transform;
}
}
The code works, however if I am walking left or right on the platforms while they are moving, I fall through them. Or if I try to jump while on the platforms when they move, I fall through them. If I slow the platform down, I can walk left or right, but when I jump, it still falls through. I am thinking that it is because this script has to constantly be on the top of the platform to work and when the update function is called, the platform moves before the character so I am not longer on top of the platform. Don’t know how to fix that. Is there a better way to do platforms than this? This is from the lerpz tutorial. I would also appreciate any ideas for better handling of me not being able to move in the Z direction at all.
Thanks!