CharlieMalphas
@CharlieMalphas

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

動く床とプレイヤーキャラクターが同調しない

解決したいこと

Unityでキャラクターコントローラを使ったアクションゲームを作っています。プレイヤーキャラを動く床に乗せた時、床を動かすとプレイヤーキャラが落ちていくことがあります。解決方法を教えてください。

発生している問題・エラー

該当するソースコード

PlayerController.cs

using System.Collections;
 using System.Collections.Generic;
 using UnityEditor.Presets;
 using UnityEngine;
 
 public class PlayerController : MonoBehaviour
 {
     [Header("Script Connecting")]
     public static PlayerController instance;
 
     [Header("Player's Core")]
     public CharacterController controller;
 
     [Header("Option")]
     public bool AutoRun;
 
     [Header("Speed Meter")]
     public Vector3 velocity;
     public float gravityScale;
 
     [Header("Movement")]
     public float maxRunX;
     public float maxWalkX;
     public float walkAcc;
     public float runAcc;
 
     public float skidPower;
     public float releaseDeAcc;
 
     public float airStrafeBorder;
     public float airStrafeFast;
 
     public bool fastAirStraff;
 
     [Header("Jump")]
     public float jumpForce;
     public float jumpTime;
     public float jumpTimeCounter;
     public bool isJumping;
     public bool jumpPressed;
 
     [Header("Crouch")]
     public bool Crouch;
     public bool CrouchPressed;
     public bool CrouchGrounded;
 
     void Awake()
     {
         instance = this;
     }
     // Start is called before the first frame update
     void Start()
     {
         controller = GetComponent<CharacterController>();
     }
 
     // Update is called once per frame
     void Update()
     {
         Gravity();
         Ground();
         Key();
         Jump();
         CrouchKey();       
     }
 
     void FixedUpdate()
     {
         Movement();
         Sliding();
         BIPWC();
     }
 
     #region Gravity Processing
     void Gravity()
     {
 
         if (controller.isGrounded == false)
         {
             velocity.y = velocity.y + (Physics.gravity.y * gravityScale * Time.deltaTime);
         }
 
         controller.Move(velocity * Time.deltaTime);
     }
     #endregion
 
     #region Ground Processing
     void Ground()
     {
         if (controller.isGrounded == true)
         {
             controller.stepOffset = 0.5f;
         }
 
         if (controller.isGrounded == false)
         {
             controller.stepOffset = 0f;
         }
     }
     #endregion
 
     #region Key Processing
     private bool Right, Left, Sprint;
     void Key()
     {
         Right = Input.GetAxisRaw("Horizontal") > 0;
         Left = Input.GetAxisRaw("Horizontal") < 0;
         Sprint = Input.GetButton("Sprint");
     }
     #endregion
 
     #region Movement Processing
     void Movement()
     {
         #region Basic Movement Setting
         bool moving = false;
         bool skidding = false;
         #endregion
 
         #region Right Moving
         if (Right && CrouchGrounded == false)
         {
             if(!controller.isGrounded)
             {
                 if(velocity.x >= 0)
                 {
                     if(velocity.x >= airStrafeBorder)
                     {
                         velocity.x += runAcc;
                     }
                     else
                     {
                         velocity.x += walkAcc;
                     }
                 }else if(velocity.x < 0)
                 {
                     if (-velocity.x >= airStrafeBorder)
                     {
                         velocity.x += runAcc;
                     }
                     else
                     {
                         if (fastAirStraff)
                         {
                             velocity.x += releaseDeAcc;
                         }
                         velocity.x += walkAcc;
                     }
                 }
             }
             else
             {
                 moving = true;
                 if(velocity.x >= 0)
                 {
                     if (Sprint)
                     {
                         velocity.x += runAcc;
                     }
                     else velocity.x += walkAcc;
                 }else if(velocity.x < 0)
                 {
                     velocity.x += skidPower;
                     skidding = true;
                 }
             }
         }
         #endregion
         #region Left Moving
         if (Left && CrouchGrounded == false)
         {
             if (!controller.isGrounded)
             {
                 if (velocity.x <= 0)
                 {
                     if (velocity.x >= airStrafeBorder)
                     {
                         velocity.x -= runAcc;
                     }
                     else
                     {
                         velocity.x -= walkAcc;
                     }
                 }
                 else if (velocity.x > 0)
                 {
                     if (-velocity.x >= airStrafeBorder)
                     {
                         velocity.x -= runAcc;
                     }
                     else
                     {
                         if (fastAirStraff)
                         {
                             velocity.x -= releaseDeAcc;
                         }
                         velocity.x -= walkAcc;
                     }
                 }
             }
             else
             {
                 moving = true;
                 if (velocity.x <= 0)
                 {
                     if (Sprint)
                     {
                         velocity.x -= runAcc;
                     }
                     else velocity.x -= walkAcc;
                 }
                 else if (velocity.x > 0)
                 {
                     velocity.x -= skidPower;
                     skidding = true;
                 }
             }
         }
         #endregion
         #region Movement Engine
         if (!moving && controller.isGrounded)
         {
             if (velocity.x > 0)
             {
                 velocity.x -= releaseDeAcc;
                 if (velocity.x < 0) velocity.x = 0;
             }
             else
             {
                 velocity.x += releaseDeAcc;
                 if (velocity.x > 0) velocity.x = 0;
             }
         }
 
         float maxSpeed = Sprint || AutoRun ? maxRunX : maxWalkX;
         if (velocity.x > maxSpeed)
         {
             velocity.x = maxSpeed;
         }
         else if (velocity.x < -maxSpeed)
         {
             velocity.x = -maxSpeed;
         }
         #endregion
     }
     #endregion
 
     #region Jump
     void Jump()
     {
         if(controller.isGrounded)
         {
             if (Input.GetButtonDown("Jump"))
             {
                 isJumping = true;
                 jumpPressed = true;
                 jumpTimeCounter = jumpTime;
                 velocity.y = jumpForce;
             }
         }       
 
         if (isJumping == true && Input.GetButton("Jump"))
         {
             jumpPressed = true;
 
             if (jumpTimeCounter > 0)
             {
                 velocity.y = jumpForce;
                 jumpTimeCounter -= Time.deltaTime;
             }
             else if (jumpTimeCounter < 0)
             {
                 isJumping = false;
             }
         }
 
         if (Input.GetButtonUp("Jump"))
         {
             jumpPressed = false;
             isJumping = false;
         }
     }
     #endregion
 
     #region Crouch
     #region Crouch Key Processing
     void CrouchKey()
     {
         if (Input.GetAxisRaw("Vertical") < 0f)
         {
             CrouchPressed = true;
         }
         else
         {
             CrouchPressed = false;
         }
     }
     #endregion
 
     #region Sliding
     void Sliding()
     {
         if (CrouchPressed == true && controller.isGrounded == true)
         {
             Crouch = true;
             if (velocity.x > 0 && velocity.x != 0)
             {
                 velocity.x -= skidPower;
                 if (velocity.x < 0.5f)
                 {
                     velocity.x = 0f;
                 }
             }
 
             if (velocity.x < 0 && velocity.x != 0)
             {
                 velocity.x += skidPower;
                 if (velocity.x > 0.5f)
                 {
                     velocity.x = 0f;
                 }
             }
         }
     }
     #endregion
 
     #region Button is pressed when crouching
     void BIPWC()
     {
         if (CrouchPressed == false && controller.isGrounded == true)
         {
             Crouch = false;
         }
 
         if (Crouch == true && controller.isGrounded == false && jumpPressed == false)
         {
             Crouch = true;
         }
 
         if (Crouch == true && controller.isGrounded == true)
         {
             CrouchGrounded = true;
         }
         else if (Crouch == false || Crouch == true && controller.isGrounded == false)
         {
             CrouchGrounded = false;
         }
     }
     #endregion
     #endregion
 
     void OnControllerColliderHit(ControllerColliderHit hit)
     {
         if (hit.gameObject.tag == "Ground")
         {
             if (!controller.isGrounded && controller.collisionFlags == CollisionFlags.Above)
             {
                 velocity.y -= 20f;
                 controller.stepOffset = 0f;
                 isJumping = false;
             }
         }
 
         if (hit.gameObject.tag == "Wall")
         {
             if (!controller.isGrounded && controller.collisionFlags == CollisionFlags.Above)
             {
                 velocity.y -= 20f;
                 controller.stepOffset = 0f;
                 isJumping = false;
             }
 
             if ((controller.collisionFlags & CollisionFlags.Sides) != 0)
             {
                 if (!PlayerState.instance.isFacingRight)
                 {
                     velocity.x = -0.1f;
                 }
                 if (PlayerState.instance.isFacingRight)
                 {
                     velocity.x = 0.1f;
                 }
             }
 
             if (controller.collisionFlags == CollisionFlags.Sides)
             {
                 if (PlayerState.instance.isFacingRight == true)
                 {
                     velocity.x = 0.1f;
                 }
 
                 if (PlayerState.instance.isFacingRight == false)
                 {
                     velocity.x = -0.1f;
                 }
             }
         }
 
         if (hit.gameObject.tag == "One Way Ground")
         {
             if (controller.isGrounded)
             {
                 float playerTop = controller.transform.position.y + controller.height;
                 float platformBottom = hit.transform.position.y - hit.transform.lossyScale.y * 0.5f;
 
                 if (playerTop <= platformBottom + 0.1f)
                 {
                     velocity.y = 0;
                 }
             }
         }
     }
 }

PlatformAttach.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
 public class PlatformAttach : MonoBehaviour
 {
     public GameObject player;
 
     void OnTriggerEnter(Collider other)
     {
         if(other.gameObject == player)
         {
             player.transform.parent = transform;
         }
     }
 
     void OnTriggerExit(Collider other)
     {
         if (other.gameObject == player)
         {
             player.transform.parent = null;
         }
     }
 }

自分で試したこと

あえてプレイヤーキャラクターを動く床の子オブジェクトにして動作確認しましたが、それでも同じ結果でした。

0

1Answer

プレイヤーと動く床の両方が Rigidbody で動いている場合は、親子関係を設定しても一緒に移動してくれないと思います。
動く床には Rigidbody をアタッチせず、Transform で動かし、床オブジェクトの子としてプレイヤーを設定すれば、床の動きに合わせてプレイヤーが動いてくれると思います。

0Like

Your answer might help someone💌