I’m making the player a child of the platform as it moves so that the player is moved along with the platform.
Here is my script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectMove : MonoBehaviour
{
public float speed;
public bool playerOnBoard;
// Start is called before the first frame update
void Start()
{
playerOnBoard = false;
}
// Update is called once per frame
void Update()
{
if (playerOnBoard)
{
MovePlatform();
}
}
private void OnTriggerEnter(Collider other)
{
playerOnBoard = true;
other.transform.SetParent(transform);
}
private void OnTriggerExit(Collider other)
{
playerOnBoard = false;
other.transform.SetParent(null);
}
void MovePlatform()
{
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}
The result I’m getting is my player is still sliding off, and when I move the mouse it stretches the player out. In the inspector, I’m manipulating its rotation and doing this. In the hierarchy, my player is being added as a child of the platform, and removed from being a child when I jump (or slide) off.
My goal is to just jump on the platform and be carried along while still maintaining control of my character.
Edit: I want to add that I now remember I scripted my mouse to be the player’s rotation. This explains the stretching when the player is a child of the platform. I still do not see why my player continues to fall off the platform.
Edit 2:
This gave me the behavior I was looking for, but my player still stretches out. I’m not sure how to fix that?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectMove : MonoBehaviour
{
public float speed;
public bool playerOnBoard;
public GameObject player;
// Start is called before the first frame update
void Start()
{
playerOnBoard = false;
}
// Update is called once per frame
void FixedUpdate()
{
MovePlatform();
}
private void OnTriggerEnter(Collider other)
{
playerOnBoard = true;
}
private void OnTriggerExit(Collider other)
{
playerOnBoard = false;
other.transform.SetParent(null);
}
void MovePlatform()
{
if (playerOnBoard)
{
transform.Translate(Vector3.forward * speed * Time.deltaTime);
player.transform.SetParent(transform);
}
}
}
Here’s a very basic script for a character controller that doesn’t need to make itself a child of a platform. It works by moving itself and the platform in a given direction. The platform can be just a basic gameobject with a collider.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Platformer : MonoBehaviour
{
CharacterController cc;
Vector3 playerVelocity;
Vector3 platformVelocity;
public float friction=0.9f;
void Start()
{
cc=GetComponent<CharacterController>();
}
void Update()
{
// Move the player around:
Vector3 moveDirection=new Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
playerVelocity+=moveDirection;
if (cc.isGrounded==false)
playerVelocity.y-=7; // gravity
playerVelocity*=friction; // basic friction
cc.Move(playerVelocity*Time.deltaTime);
}
void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.gameObject.tag=="Platform")
{
Vector3 platformDirection=Vector3.right*0.2f; // direction and speed that the platform moves in when touched
platformVelocity+=platformDirection;
playerVelocity+=platformDirection; // We also want to move the player with the platform
if (platformVelocity.y>0.001f) // Is this a rising platform?
playerVelocity+=Random.insideUnitSphere*0.2f; // slightly jiggle the player's character controller to prevent it from going crazy (crap physics)
platformVelocity*=friction;
hit.transform.position+=platformVelocity*Time.deltaTime; // move the platform
}
}
}
I really appreciate that. I’m not at my computer at the moment; wouldn’t placing the code in FixedUpdate() take care of the craziness you mentioned? You may not need to juggle the controller.
ok. I would suggest using a Rigidbody. if you don’t like the acceleration of Rigidbody.AddForce(vector3) (like me), then (if your using unity 3d) then set the x and z of Rigidbody.velocity this way you can set add to velocity in lateupdate
I found a great way to do it, but you cannot use the CharacterController component.
Use the animation tab, and set up key frames at the different positions of the platform; mine is just going back and forth, so I made two and then copy and pasted the first one as the third one.
This sets the player as a child of the platform; it works wonderfully, but you cannot use the character controller; it will cause the player to slide off every time. I’m not sure why, but it doesn’t work at all.
// this function has to be called in Update().
protected void MovingPlatformSupport()
{
//_groundedTarget is the transform the player stands onto. this variable should be initialized by your grounded check sphere/raycast.
//_groundedTargetLastPosition has to be initialized whenever your _groundedTarget value changes.
// for example something like this:
//if(Physics.SphereCast(...))
//{
// if (hit.transform != m_groundedTarget)
// {
// _groundedTarget = hit.transform;
// _groundedTargetLastPosition = m_groundedTarget.position;
// }
//}
//{
// _groundedTarget = null;
//}
if (_groundedTarget != null)
{
Vector3 offsetVec = _groundedTarget.position - _groundedTargetLastPosition;
if (offsetVec.magnitude > 0.005f)
{
_controller.Move(offsetVec);
_groundedTargetLastPosition = _groundedTarget.position;
// if you are using iStep, tell iStep about the moving platform movement, otherwise uncomment the below line of code
_iStepFootIK.characterExternalMovingPlatformOffsetVec += offsetVec;
}
}
}