简体   繁体   English

在我统一制作的 2D 平台游戏中,我的玩家被困在墙内

[英]My player is getting stuck inside the wall in the 2D platforming game I am making in unity

I am making a 2D platforming game in unity.我正在统一制作 2D 平台游戏。 For some reason, the player is getting stuck in the wall.由于某种原因,玩家被困在墙上。 I have used a Tilemap for the wall, then used tilemap Collider 2D with composite collider .我在墙上使用了Tilemap ,然后将tilemap Collider 2Dcomposite collider一起使用。 The same thing works fine with the ground.同样的事情也适用于地面。

When I go left facing the wall, it behaves as expected:当我 go 面对墙壁离开时,它的行为符合预期: 在此处输入图像描述

When I release the left arrow button, it also shows the expected result:当我松开左箭头按钮时,它还会显示预期结果: 在此处输入图像描述

But when I click right arrow next, the player gets stuck inside the wall:但是当我下一步点击向右箭头时,玩家会卡在墙内: 在此处输入图像描述

and cannot get out:并且不能出去: 在此处输入图像描述

Here is my player movement code:这是我的播放器移动代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playerScript : MonoBehaviour
{
    // Start is called before the first frame update
    
    [SerializeField] private float movement_speed = 2;
    [SerializeField] private float jump_power = 5;
    [SerializeField] private LayerMask groundLayer;
    [SerializeField] private LayerMask wallLayer;

    private Rigidbody2D rb_player;
    private BoxCollider2D boxCollider;
    private Animator anim;

    private void Start()
    {
        
    }

    private void Awake()
    {
        rb_player = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        boxCollider = GetComponent<BoxCollider2D>();
        groundLayer = LayerMask.GetMask("ground");
        wallLayer = LayerMask.GetMask("wall");
    }

    // Update is called once per frame
    private void Update()
    {
        float x = Input.GetAxis("Horizontal");

        
        rb_player.velocity = new Vector2(x * movement_speed, rb_player.velocity.y);
        

        //flip the player
        if(x > 0.01f)
        {
            transform.localScale = new Vector3(1, 1, 1);
        }

        else if(x < -0.01f)
        {
            transform.localScale = new Vector3(-1, 1, 1);
        }


        if(Input.GetKeyDown(KeyCode.Space) && isGrounded())
        {
            jump();
        }


        anim.SetBool("run", x != 0);

        anim.SetBool("jump", !isGrounded());


        print("wall: "+isTouchingWall());
        print("ground: "+isGrounded());
        
    }


    private void jump()
    {
        rb_player.velocity = new Vector2(rb_player.velocity.x, jump_power);
        anim.SetTrigger("jump_trigger");
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        // if(collision.gameObject.tag == "ground")
        // {
        //     grounded = true;
        // }
    }

    private bool isGrounded()
    {
        RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.bounds.size, 0, Vector2.down, .2f, groundLayer);
        return raycastHit.collider != null;
    }


    private bool isTouchingWall()
    {
        RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.bounds.size, 0, new Vector2(transform.localScale.x,0), .1f, wallLayer);
        return raycastHit.collider != null;
    }
}

It would be nice if anyone can help me as I am a complete beginner in game development with unity.如果有人可以帮助我,那就太好了,因为我是统一游戏开发的完全初学者。

The problem问题

Your pivot point of your player (where your player script is attached) isn't centered like your collider.播放器的pivot 点(播放器脚本所在的位置)不像对撞机那样居中。 Because of this, your box collider is being flipped like a page from a book and it lands inside the wall.正因为如此,你的盒子对撞机就像书页一样被翻动并落在墙内。

To fix it要解决这个问题

Make sure that your player pivot point is the same as the center of your BoxCollider2D.确保您的播放器 pivot 点与 BoxCollider2D 的中心相同。 This way, your collider won't "teleport" from right to left and bypass walls.这样,您的对撞机就不会从右到左“传送”并绕过墙壁。

Other tips其他提示

I see some beginner's mistakes in your code, so even if you manage to fix your issue, I highly recommend to follow the next tips:我在您的代码中看到了一些初学者的错误,所以即使您设法解决了问题,我也强烈建议您遵循以下提示:

  • All physic based code (jump, movement, etc.) should go inside FixedUpdate() method and use Time.deltaTime or Time.fixedDeltaTime to keep the same speed (for movement and jump) among computers.所有基于物理的代码(跳跃、移动等)都应在FixedUpdate()方法中使用 go 并使用Time.deltaTimeTime.fixedDeltaTime在计算机之间保持相同的速度(移动和跳跃)。
  • Use the proper naming conventions , your variables should be camel case, no underscores.使用正确的命名约定,你的变量应该是驼峰式的,没有下划线。 Methods (and Classes) should always start with a capital letter in C# (PascalCase).方法(和类)应始终以 C# (PascalCase) 中的大写字母开头。

Hopefully this will help you.希望这会对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM