Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved Player Not Moving With Platforms

Discussion in 'Scripting' started by SinkingSun, Jul 6, 2023.

  1. SinkingSun

    SinkingSun

    Joined:
    Feb 14, 2022
    Posts:
    13
    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:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ObjectMove : MonoBehaviour
    6. {
    7.     public float speed;
    8.  
    9.     public bool playerOnBoard;
    10.  
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.         playerOnBoard = false;
    15.     }
    16.  
    17.     // Update is called once per frame
    18.     void Update()
    19.     {
    20.         if (playerOnBoard)
    21.         {
    22.             MovePlatform();
    23.         }
    24.     }
    25.  
    26.     private void OnTriggerEnter(Collider other)
    27.     {
    28.         playerOnBoard = true;
    29.         other.transform.SetParent(transform);
    30.     }
    31.  
    32.     private void OnTriggerExit(Collider other)
    33.     {
    34.         playerOnBoard = false;
    35.         other.transform.SetParent(null);
    36.     }
    37.  
    38.     void MovePlatform()
    39.     {
    40.         transform.Translate(Vector3.forward * speed * Time.deltaTime);
    41.     }
    42. }
    43.  
    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?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ObjectMove : MonoBehaviour
    6. {
    7.     public float speed;
    8.  
    9.     public bool playerOnBoard;
    10.  
    11.     public GameObject player;
    12.  
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         playerOnBoard = false;
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void FixedUpdate()
    21.     {
    22.         MovePlatform();
    23.     }
    24.  
    25.     private void OnTriggerEnter(Collider other)
    26.     {
    27.         playerOnBoard = true;
    28.     }
    29.  
    30.     private void OnTriggerExit(Collider other)
    31.     {
    32.         playerOnBoard = false;
    33.         other.transform.SetParent(null);
    34.     }
    35.  
    36.     void MovePlatform()
    37.     {
    38.         if (playerOnBoard)
    39.         {
    40.             transform.Translate(Vector3.forward * speed * Time.deltaTime);
    41.             player.transform.SetParent(transform);
    42.         }      
    43.     }
    44. }
     
    Last edited: Jul 6, 2023
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,862
    How are you moving the player? Via transforms, or rigidbodies? That dictates the method you use to make the player follow moving objects.

    For example the above code won't work if you're using physics.
     
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    541
    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.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Platformer : MonoBehaviour
    6. {
    7.     CharacterController cc;
    8.  
    9.     Vector3 playerVelocity;
    10.     Vector3 platformVelocity;
    11.     public float friction=0.9f;
    12.  
    13.     void Start()
    14.     {
    15.         cc=GetComponent<CharacterController>();
    16.     }
    17.  
    18.     void Update()
    19.     {
    20.         // Move the player around:
    21.         Vector3 moveDirection=new Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
    22.         playerVelocity+=moveDirection;
    23.         if (cc.isGrounded==false)
    24.             playerVelocity.y-=7;    // gravity
    25.         playerVelocity*=friction;   // basic friction
    26.         cc.Move(playerVelocity*Time.deltaTime);
    27.     }
    28.  
    29.     void OnControllerColliderHit(ControllerColliderHit hit)
    30.     {  
    31.         if (hit.gameObject.tag=="Platform")
    32.         {
    33.             Vector3 platformDirection=Vector3.right*0.2f; // direction and speed that the platform moves in when touched
    34.             platformVelocity+=platformDirection;
    35.             playerVelocity+=platformDirection; // We also want to move the player with the platform
    36.             if (platformVelocity.y>0.001f) // Is this a rising platform?
    37.               playerVelocity+=Random.insideUnitSphere*0.2f;  // slightly jiggle the player's character controller to prevent it from going crazy (crap physics)
    38.             platformVelocity*=friction;
    39.             hit.transform.position+=platformVelocity*Time.deltaTime; // move the platform
    40.         }
    41.     }
    42. }
    43.  
     
    SinkingSun likes this.
  4. SinkingSun

    SinkingSun

    Joined:
    Feb 14, 2022
    Posts:
    13
    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.
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,862
    FixedUpdate is for physics. Are you using physics?
     
  6. Sooly123

    Sooly123

    Joined:
    Aug 24, 2022
    Posts:
    90
    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
     
  7. SinkingSun

    SinkingSun

    Joined:
    Feb 14, 2022
    Posts:
    13
    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.

    Now, I can just use:

    Code (CSharp):
    1. private void OnTriggerEnter(Collider other)
    2.     {
    3.         playerOnBoard = true;
    4.         player.transform.parent = transform;
    5.     }
    6.  
    7.     private void OnTriggerExit(Collider other)
    8.     {
    9.         playerOnBoard = false;
    10.         player.transform.parent = null;
    11.     }
    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.
     
  8. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    433
    Use a solution like this:

    Code (CSharp):
    1. // this function has to be called in Update().
    2.         protected void MovingPlatformSupport()
    3.         {
    4.             //_groundedTarget is the transform the player stands onto. this variable should be initialized by your grounded check sphere/raycast.
    5.             //_groundedTargetLastPosition has to be initialized whenever your _groundedTarget value changes.
    6.             // for example something like this:
    7.             //if(Physics.SphereCast(...))
    8.             //{
    9.             //  if (hit.transform != m_groundedTarget)
    10.             //  {
    11.             //      _groundedTarget = hit.transform;
    12.             //      _groundedTargetLastPosition = m_groundedTarget.position;
    13.             //  }
    14.             //}
    15.             //{
    16.             //  _groundedTarget = null;
    17.             //}
    18.  
    19.             if (_groundedTarget != null)
    20.             {
    21.                 Vector3 offsetVec = _groundedTarget.position - _groundedTargetLastPosition;
    22.  
    23.                 if (offsetVec.magnitude > 0.005f)
    24.                 {
    25.                     _controller.Move(offsetVec);
    26.                     _groundedTargetLastPosition = _groundedTarget.position;
    27.  
    28.                     // if you are using iStep, tell iStep about the moving platform movement, otherwise uncomment the below line of code
    29.                     _iStepFootIK.characterExternalMovingPlatformOffsetVec += offsetVec;
    30.                 }
    31.             }
    32.         }
     
    zulo3d likes this.
  9. Sooly123

    Sooly123

    Joined:
    Aug 24, 2022
    Posts:
    90
    hi, I see you are still having trouble. here's my script for the player:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerScript : MonoBehaviour
    6. {
    7.     Vector3 force;
    8.     public Rigidbody rb;
    9.  
    10.     public float mouseSensitivity = 1000f;
    11.     public Transform playerCamera;
    12.  
    13.     public float playerSpeed = 7f;
    14.     private float playerSpeedNormal;
    15.     public float slowDownMultiplier = 30f;
    16.     public float speedAtRunMultiplier = 2.5f;
    17.     public float jumpSpeed;
    18.     private bool onBoard;
    19.     private Transform onBoardTransform;
    20.     private Vector3 lastobPos;
    21.  
    22.     private Vector3 addToForce;
    23.     private bool onGround;
    24.    
    25.     void Start()
    26.     {
    27.         playerSpeedNormal = playerSpeed;
    28.         Cursor.visible = true;
    29.     }
    30.  
    31.     void Update()
    32.     {
    33.         if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
    34.         {
    35.             playerSpeed += ((playerSpeedNormal*speedAtRunMultiplier)-playerSpeed)/slowDownMultiplier;
    36.         }
    37.         else
    38.         {
    39.             playerSpeed += (playerSpeedNormal-playerSpeed)/slowDownMultiplier;
    40.         }
    41.  
    42.         LookAround(mouseSensitivity);
    43.         if (onBoard)
    44.         {
    45.             TrackOnBoard();
    46.         }
    47.         Movement();
    48.     }
    49.     void LookAround(float sensitivity)
    50.     {
    51.         float mouseX = Input.GetAxis("Mouse X");
    52.         float mouseY = Input.GetAxis("Mouse Y");
    53.  
    54.         mouseY = Mathf.Clamp(mouseY, -90f,90f);
    55.  
    56.         playerCamera.eulerAngles -= new Vector3(mouseY,0,0);
    57.  
    58.         transform.eulerAngles += new Vector3(0,mouseX,0);
    59.     }
    60.  
    61.     void Movement()
    62.     {
    63.         float horizontal = Input.GetAxis("Horizontal")*playerSpeed;
    64.         float vertical = Input.GetAxis("Vertical")*playerSpeed;
    65.  
    66.         if (Input.GetButtonDown("Jump") && onGround)
    67.         {
    68.             rb.AddForce(new Vector3(0,jumpSpeed,0));
    69.         }
    70.  
    71.         force = ((transform.right * horizontal) + (transform.forward * vertical));
    72.         force.y = rb.velocity.y;
    73.         rb.velocity = force;
    74.         transform.position += addToForce;
    75.     }
    76.  
    77.     void TrackOnBoard()
    78.     {
    79.         addToForce = onBoardTransform.position - lastobPos ;
    80.         lastobPos = onBoardTransform.position;
    81.     }
    82.  
    83.     void OnCollisionEnter(Collision other)
    84.     {
    85.         Ray ray = new Ray(transform.position, Vector3.down);
    86.         Physics.Raycast(ray, out RaycastHit hitInfo);
    87.         if (hitInfo.transform != null)
    88.         {
    89.             if (hitInfo.distance > 0.9f)
    90.             {
    91.                 onGround = true;
    92.             }
    93.             else
    94.             {
    95.                 Debug.Log("NOT ON GROUND: " + hitInfo.distance);
    96.             }
    97.         }
    98.  
    99.         if (other.transform.TryGetComponent<IMove>(out IMove i))
    100.         {
    101.             onBoard = true;
    102.             onBoardTransform = other.transform;
    103.             lastobPos = onBoardTransform.position;
    104.             Debug.Log("IS A MOVING OBJECT");
    105.         }
    106.         else
    107.         {
    108.             Debug.Log("NOT A MOVING OBJECT");
    109.             onBoard = false;
    110.         }
    111.     }
    112.  
    113.     void OnCollisionExit(Collision other)
    114.     {
    115.         onGround = false;
    116.         onBoard = false;
    117.         addToForce = Vector3.zero;
    118.     }
    119. }
    120.  
    my hierarchy looks like this:
    upload_2023-7-8_15-37-13.png
    platform has a script called "IMove" which looks like this:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class IMove : MonoBehaviour
    6. {
    7. //ye I move
    8. }
    9.  
    just make sure to not set the "isTrigger" option on any colliders, and everything should work