C# “如何拥有刚体对象”;骑乘;一个下落的平台,同时仍然能够水平移动

C# “如何拥有刚体对象”;骑乘;一个下落的平台,同时仍然能够水平移动,c#,unity3d,2d,game-physics,C#,Unity3d,2d,Game Physics,我正在Unity中制作一个2D游戏,游戏中有可以“骑”下来的坠落平台。我希望玩家站在坠落的平台上时仍然能够向左或向右移动(即水平移动)。如果没有额外的代码,仅使用刚体物理,玩家确实会随着平台一起坠落,但坠落是起伏的,游戏并不总是看到玩家站在平台上(这很重要,因为玩家只能站在某物上跳跃) 我已经尝试设置播放器对象的transform.translate,它可以防止播放器在触摸平台时向左或向右移动。我还尝试将播放器对象的transform.parent设置为平台的transform,但这会将播放器“

我正在Unity中制作一个2D游戏,游戏中有可以“骑”下来的坠落平台。我希望玩家站在坠落的平台上时仍然能够向左或向右移动(即水平移动)。如果没有额外的代码,仅使用刚体物理,玩家确实会随着平台一起坠落,但坠落是起伏的,游戏并不总是看到玩家站在平台上(这很重要,因为玩家只能站在某物上跳跃)

我已经尝试设置播放器对象的
transform.translate
,它可以防止播放器在触摸平台时向左或向右移动。我还尝试将播放器对象的
transform.parent
设置为平台的
transform
,但这会将播放器“粘”到平台上,甚至防止跳跃。我也尝试过寻找一个解决方案/例子,有很多关于乘坐左右移动平台的例子,但我还没能让这些例子适用于坠落平台

这是控制玩家左右移动和跳跃的脚本。这将附加到播放器对象:

public class Player : MonoBehaviour
{
  public float jumpForce = 5;
  public float horizontalSpeed = 0.1F;
  public LayerMask whatIsGround;

  private Rigidbody2D rb2d;
  private Collider2D myCollider;
  private bool grounded;
  private float lastHorizontalInput;

  void Start()
  {
    rb2d = GetComponent<Rigidbody2D>();
    myCollider = GetComponent<Collider2D>();
  }

  void Update()
  {
    // If the player is trying to jump, only do so if the player is on a platform
    grounded = Physics2D.IsTouchingLayers(myCollider, whatIsGround);
    if (Input.GetKeyDown(KeyCode.Space) && grounded)
    {
      rb2d.velocity = new Vector2(rb2d.velocity.x, jumpForce);
    }

    MoveHorizonltally();
  }

  private void MoveHorizonltally()
  {
    float horizontalVelocity;
    float horizontalInput = Input.GetAxis("Horizontal");

    horizontalVelocity = GetHorizontalVelocity(horizontalInput);
    if (horizontalVelocity != 0)
    {
      rb2d.position = new Vector2(rb2d.position.x + horizontalVelocity, rb2d.position.y);
    }
  }

  private float GetHorizontalVelocity(float horizontalInput)
  {
    // Default to no horizontal motion
    float result = 0;
    bool leftPressed = Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow);
    bool rightPressed = Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow);

    // Only a left key is being pressed; the player is going left
    if (leftPressed && !rightPressed)
    {
      result = -1 * horizontalSpeed;
    }
    // Only a right key is being pressed; the player is going right
    else if (rightPressed && !leftPressed)
    {
      result = horizontalSpeed;
    }
    // Both keys are being pressed
    else if (leftPressed && rightPressed)
    {
      // The most recent key press gets priority; ignore the oldest key press
      if (lastHorizontalInput < 0)
      {
        // Oldest key pressed is a left direction, so go right
        result = horizontalSpeed;
      }
      else
      {
        // Oldest key pressed is a right direction, so go left
        result = -1 * horizontalSpeed;
      }
    }

    lastHorizontalInput = horizontalInput;
    return result;
  }
}
公共类玩家:单行为
{
公众浮力=5;
公共浮动水平速度=0.1F;
公共层码头;
私有刚体2d rb2d;
私人碰撞R2D准直器;
私人学校;
私人水平投入;
void Start()
{
rb2d=GetComponent();
myCollider=GetComponent();
}
无效更新()
{
//如果玩家试图跳跃,只有当玩家在平台上时才这样做
接地=Physics2D.IsTouchingLayers(myCollider,whatIsGround);
if(Input.GetKeyDown(KeyCode.Space)和接地)
{
rb2d.velocity=新矢量2(rb2d.velocity.x,跳跃力);
}
水平移动();
}
私有无效横向移动()
{
浮动水平速度;
float horizontalInput=Input.GetAxis(“水平”);
水平速度=获取水平速度(水平输入);
如果(水平速度!=0)
{
rb2d.position=新矢量2(rb2d.position.x+水平速度,rb2d.position.y);
}
}
专用浮点GetHorizontalVelocity(浮点水平输入)
{
//默认为无水平运动
浮动结果=0;
bool leftPressed=Input.GetKey(KeyCode.A)| Input.GetKey(KeyCode.LeftArrow);
bool rightPressed=Input.GetKey(KeyCode.D)| Input.GetKey(KeyCode.RightArrow);
//只按了一个左键;播放器向左移动
如果(左按&!右按)
{
结果=-1*水平速度;
}
//只按了一个右键;播放器向右转
else if(右按&!左按)
{
结果=水平速度;
}
//两个键都被按下了
else if(左按和右按)
{
//最新的按键优先;忽略最早的按键
如果(最后水平输入<0)
{
//最早按下的键是向左,所以向右走
结果=水平速度;
}
其他的
{
//按的最早的键是右方向,所以向左走
结果=-1*水平速度;
}
}
lastHorizontalInput=水平输入;
返回结果;
}
}
下面是负责使平台坠落的脚本。这将附着到平台对象:

public class PlatformFalling : MonoBehaviour
{
  public float fallSpeed;
  private GameObject player;

  public void Start()
  {
    player = GameObject.FindGameObjectWithTag("Player");
  }

  // Update is called once per frame
  void Update()
  {
    bool playerIsOnPlatform = player.GetComponent<Collider2D>().IsTouching(GetComponent<Collider2D>()); ;
    Vector2 fallDistance = Vector2.down * fallSpeed;

    transform.Translate(fallDistance);
    if (playerIsOnPlatform)
    {
      player.transform.Translate(fallDistance);
    }
  }
}
公共类平台:单一行为
{
公共交通速度;
私人游戏对象玩家;
公开作废开始()
{
player=GameObject.FindGameObjectWithTag(“player”);
}
//每帧调用一次更新
无效更新()
{
bool playerIsOnPlatform=player.GetComponent().IsTouching(GetComponent());
向量2下降距离=向量2.down*下降速度;
transform.Translate(下降距离);
if(playerIsOnPlatform)
{
player.transform.Translate(下降距离);
}
}
}

首先,无论何时使用物理,都不要通过
变换
组件应用任何移动,因为这会破坏物理和碰撞检测。然后简单地确保重力对玩家的影响大于对环境的影响platform@derHugo这成功了!你能把你的评论作为一个答案,这样我就可以接受它,并给你信用吗?