【问题标题】:How can I get a character to walk on a moving platform in Unity如何让角色在 Unity 中的移动平台上行走
【发布时间】:2020-08-13 22:29:35
【问题描述】:

我在 Unity 2020.1 中内置的 2D Sidescroller 中有一个移动平台

移动平台使用 MoveTo 方法在两点之间平移。它没有 RigidBody2D 组件。

我通过使用 OnCollisionEnter2D 和 OnCollisionExit2D 将 Player 设置为平台的子级来将 Player 附加到平台,并将 Player 设置为父级并分别重置为 null。效果很好。

我正在使用 Standard Assets 中的 CharacterController。

问题:

当我试图在平台上来回移动玩家时,玩家只是在原地行走。

到目前为止我已经尝试过:

  1. 通过在其移动向量的 x 维度上添加一个常数来更改玩家的当前速度。 有点工作,但这个常数需要很大才能让它移动一点点。这是一个违反所有编码正当性的大杂烩。

  2. 在平台上放置一个 RigidBody2D。让它运动起来,这样当我降落时它就不会掉到地上。通过“rb.velocity = new Vector2(speed, rb.velocity.y)”移动平台;

2a) 尝试使 Player 成为运动学平台的子项。 玩家被制作成一个孩子,但它并没有像预期的那样随着平台移动。我相信这是因为这两个对象都有 RigidBody2D 组件,根据我所阅读的内容,我认为它们不能很好地配合使用。

2b) 尝试将平台的移动向量添加到玩家的移动向量中,以使他停留在一个地方。玩家保持静止以确保他固定在平台上。 没有骰子。

我完全没有想法。细读有关让玩家坚持移动平台的视频都是使用平台将玩家从一个地方移动到另一个地方,而不是期望游戏可能希望玩家在平台移动时在平台上来回移动。

我不敢相信这不是一个已解决的问题,但我的 Google foo 没有给我任何答案。

谢谢。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    我是 Unity 和 C# 的新手,但我想提供帮助,因此我尝试模拟您的游戏以获得解决方案,并且使用此脚本作为 Player 运动我没有遇到任何问题(您可以修改变量为例如,为跳跃速度添加一个单独的变量以使其更平滑等)

    public class Player : MonoBehaviour {
    
    Rigidbody2D rb;
    
    float speed = 7f;
    
    Vector3 movement;
    
    public bool isOnGround;
    public bool isOnPlatform;
    
    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }
    
    // Update is called once per frame
    void Update()
    {
        movement = new Vector3(Input.GetAxis("Horizontal"), 0f, 0f);
        transform.position += movement * speed * Time.deltaTime;
    
        Jump();
    }
    
    void Jump()
    {
        if (Input.GetButtonDown("Jump") && isOnGround || Input.GetButtonDown("Jump") && isOnPlatform)
        {
            rb.AddForce(transform.up * speed, ForceMode2D.Impulse);
        }
    }
    

    }

    同时添加一个空的子对象到你的 Player 游戏对象并在他的脚下添加一个 BoxCollider2D,在 Y 轴上缩小它like this

    还要将此脚本附加到该子游戏对象以检查玩家是否在地面上(使用新标签“地面”标记地面碰撞对象),这样你就不会在空中无限跳跃或玩家是否在平台上(用“平台”标记平台对撞机对象)所以你仍然可以跳下它

    public class GroundCheck : MonoBehaviour {
    
    Player player;
    MovingPlatform mp;
    
    // Start is called before the first frame update
    void Start()
    {
        player = FindObjectOfType<Player>();
        mp = FindObjectOfType<MovingPlatform>();
    }
    
    
    private void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.tag == "Ground")
        {
            player.isOnGround = true;
        }
    
        if (other.gameObject.tag == "Platform")
        {
            player.isOnPlatform = true;
            transform.parent.SetParent(other.transform);
            mp.MoveThePlatform();
        }
    }
    
    private void OnCollisionExit2D(Collision2D other)
    {
        if (other.gameObject.tag == "Ground")
        {
            player.isOnGround = false;
        }
    
        if (other.gameObject.tag == "Platform")
        {
            transform.parent.SetParent(null);
        }
    }
    

    }

    最后是平台移动(没有 RigidBody2D,只是一个对撞机)

    public class MovingPlatform : MonoBehaviour {
    
    bool moving;
    
    public Transform moveHere;
    
    // Update is called once per frame
    void Update()
    {
        if (moving)
        {
            gameObject.transform.position = Vector2.MoveTowards(transform.position, moveHere.position, 2f * Time.deltaTime);
        }
    }
    
    
    public void MoveThePlatform()
    {
        moving = true;
    }
    

    }

    其他图片 Player, Platform

    附:忘记添加 - 在 Player 的 RigidBody2D 上,在 Constraints 下,选中“Freeze Rotation Z”框。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多