Unity 2D平台游戏:蹲伏问题

huangapple go评论52阅读模式
英文:

Unity 2D Platformer: Crouching issues

问题

我目前遇到了一个问题,关于我的C#脚本,用于制作在Unity中的2D平台游戏。我的问题是,当我长时间按住蹲下按钮(大约一秒钟或更短),我的角色会穿过地面掉出地图外。我不知道如何防止精灵做这个动作。

谢谢你的帮助!下面是我的代码!(我贴出了整个脚本以便更好地理解,但问题出现在与"Crouch"输入相关的if语句中。)

对于蹲伏,我尝试了一切,我查找了一些教程,有些我尝试重写了整个脚本,但都没有让我更接近解决问题。对于这个问题,我期望精灵在蹲伏时不会穿过地面。关于2D平台游戏中的蹲伏,没有太多的人提出问题。

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

public class PlayerMovement : MonoBehaviour
{
    private Rigidbody2D rb;
    private Animator anim;
    private SpriteRenderer sprite;
    private int jumpCount = 0;
    private int maxJumps = 2;
    private bool grounded = false;
    private float dirX;
    private new BoxCollider2D collider;
    private Sprite crouching;
    private Sprite standing;
    private Vector2 crouchingSize;
    private Vector2 standingSize;
    private Vector2 crouchingOffset;

    // Start is called before the first frame update
    private void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        sprite = GetComponent<SpriteRenderer>();
        collider = GetComponent<BoxCollider2D>();
    }

    // Update is called once per frame
    private void Update()
    {
        dirX = Input.GetAxisRaw("Horizontal");
        float dirY = Input.GetAxisRaw("Vertical");
        rb.velocity = new Vector3(dirX * 7f, rb.velocity.y, 0);

        // 跳跃按钮和二段跳
        if (Input.GetButtonDown("Jump") && jumpCount < maxJumps)
        {
            rb.velocity = new Vector3(rb.velocity.x, 14f, 0);
            grounded = false;
            jumpCount = jumpCount + 1;
        }

        if (grounded == true)
        {
            jumpCount = 0;
        }

        crouchingSize = new Vector2(1, 0.5f);
        crouchingOffset = new Vector2(0, -0.25f);
        standingSize = new Vector2(1, 1);
        crouchingOffset = Vector2.zero;

        // 开始蹲伏
        if (Input.GetButtonDown("Crouch"))
        {
            sprite.sprite = crouching;
            collider.size = crouchingSize;
        }

        // 停止蹲伏
        if (Input.GetButtonUp("Crouch"))
        {
            sprite.sprite = standing;
            collider.size = standingSize;
        }

        UpdateAnimationState();
    }

    private void UpdateAnimationState()
    {
        dirX = Input.GetAxisRaw("Horizontal");

        if (dirX > 0f)
        {
            anim.SetBool("running", true);
            sprite.flipX = false;
        }
        else if (dirX < 0f)
        {
            anim.SetBool("running", true);
            sprite.flipX = true;
        }
        else
        {
            anim.SetBool("running", false);
        }
    }

    private void OnCollisionEnter2D(Collision2D collider)
    {
        if (collider.gameObject.tag == "Ground")
        {
            jumpCount = maxJumps;
            grounded = true;
        }
    }
}

编辑:代码块已经编辑以反映解决我的问题的方法。

英文:

I am having an issue currently with my C# Script for my 2D PLatformer made in Unity.
My issue is that when I press the crouch button for long enough(a second or less), my character falls through the floor and out of the map. I am stumped on how to get the sprite to not do that.

Thank you for the help! Code is posted below! (I posted the entire script for more clarification, however the issue is within the if statements regarding the "Crouch" input.)

For crouching, I have tried everything, I searched some tutorials, some in which I tried rewriting my entire script, but it got me no closer than I am now. For this I am expecting the sprite to not phase through the ground while crouching. There is not too many results with people asking about crouching in a 2d platformer.

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private Rigidbody2D rb;
private Animator anim;
private SpriteRenderer sprite;
private int jumpCount = 0;
private int maxJumps = 2;
private bool grounded = false;
private float dirX;
private new BoxCollider2D collider;
private Sprite crouching;
private Sprite standing;
private Vector2 crouchingSize;
private Vector2 standingSize;
private Vector2 crouchingOffset;
// Start is called before the first frame update
private void Start()
{
rb = GetComponent&lt;Rigidbody2D&gt;();
anim = GetComponent&lt;Animator&gt;();
sprite = GetComponent&lt;SpriteRenderer&gt;();
collider = GetComponent&lt;BoxCollider2D&gt;();
}
// Update is called once per frame
private void Update()
{
dirX = Input.GetAxisRaw(&quot;Horizontal&quot;);
float dirY = Input.GetAxisRaw(&quot;Vertical&quot;);
rb.velocity = new Vector3(dirX * 7f, rb.velocity.y, 0);
//Jump Button and double jump
if (Input.GetButtonDown(&quot;Jump&quot;) &amp;&amp; jumpCount &lt; maxJumps)
{
rb.velocity = new Vector3(rb.velocity.x, 14f, 0);
grounded = false;
jumpCount = jumpCount + 1;
}
if (grounded == true)
{
jumpCount = 0;
}
crouchingSize = new Vector2(1, 0.5f);
crouchingOffset = new Vector2(0, -0.25f);
standingSize = new Vector2(1, 1);
crouchingOffset = Vector2.zero;
//Start crouch
if (Input.GetButtonDown(&quot;Crouch&quot;))
{
sprite.sprite = crouching;
collider.size = crouchingSize;
}
//Stop crouch
if (Input.GetButtonUp(&quot;Crouch&quot;))
{
sprite.sprite = standing;
collider.size = standingSize;
}
UpdateAnimationState();
}
private void UpdateAnimationState()
{
dirX = Input.GetAxisRaw(&quot;Horizontal&quot;);
if (dirX &gt; 0f)
{
anim.SetBool(&quot;running&quot;, true);
sprite.flipX = false;
}
else if (dirX &lt; 0f)
{
anim.SetBool(&quot;running&quot;, true);
sprite.flipX = true;
}
else
{
anim.SetBool(&quot;running&quot;, false);
}
}
private void OnCollisionEnter2D(Collision2D collider)
{
if (collider.gameObject.tag == &quot;Ground&quot;)
{
jumpCount = maxJumps;
grounded = true;
}
}
}

EDIT: Code block has been edited to reflect the solution to my question.

答案1

得分: 0

你似乎正在转换你的玩家,然后给它的刚体添加力,如果力的因子太大可能会导致碰撞。你尝试实现什么类型的2D游戏?在2D游戏中,通常只需缩小碰撞体对象并将精灵更改为蹲下的形象。

public Sprite crouching;
public Sprite standing;
public Vector2 crouchingSize;
public Vector2 standingSize;
......... 
...... 
.... 
private void Update() 
{
    if (Input.GetButtonDown("Crouch"))
    {
        SpriteRenderer.sprite = crouching;
        Collider.size = crouchingSize;
    }
    //停止蹲下
    if (Input.GetButtonUp("Crouch"))
    {
        SpriteRenderer.sprite = standing;
        Collider.size = standingSize;
    }
}
英文:

You seem to be transforming your player and then adding force to it's rigid body, which might cause clipping if the force factor is too big. What kind of 2D game are you trying to implement? In 2D you'd usually just want to scale down the collider object and change the sprite to a crouching one.

public sprite crouching;
public sprite standing;
public vector2 crouchingSize;
public vector2 standingSize;
.........
......
....
private void Update() 
{
if (Input.GetButtonDown(&quot;Crouch&quot;))
{
SpriteRenderer.sprite = crouching;
Collider.size = crouchingSize;
}
//Stop crouch
if (Input.GetButtonUp(&quot;Crouch&quot;))
{
SpriteRenderer.sprite = standing
Collider.size = standingSize;
}
}

答案2

得分: 0

我认为更好的方法是改变碰撞器的大小和偏移量。将偏移量更改为正确的值可以确保您将碰撞器缩小到所需的枢轴点周围,这是Unity默认不支持的。

假设您的角色使用2D框碰撞器,当蹲下时,您的碰撞器在y轴上缩小了50%。为了确保碰撞器不浮动,我们需要将碰撞器的偏移量更改为初始碰撞器大小的负25%。(这将使碰撞器缩放到角色脚部/碰撞器底部的枢轴点周围)
例如:大小:(1, 1),偏移量(0, 0) -> 大小:(1, 0.5f);偏移量(0, -0.25f)。
代码将类似于这样:

crouchingSize = new Vector2(1, 0.5f);
crouchingOffset = new Vector2(0, -0.25f);
standingSize = new Vector2(1, 1);
standingOffset = Vector2.zero;
if (Input.GetButtonDown("Crouch"))
{
    SpriteRenderer.sprite = crouching;
    Collider.size = crouchingSize;
    Collider.offset = crouchingOffset;
}
if (Input.GetButtonUp("Crouch"))
{
    SpriteRenderer.sprite = standing;
    Collider.size = standingSize;
    Collider.offset = standingOffset;
}
英文:

I think a better approach would be to change the size of the collider and its offset. Changing the offset to the right amount makes sure you shrink the collider around the desired pivot point, something that Unity does not allow out of the box.

Let's assume that your character uses a box collider 2d, and when crouching your collider's size on the y-axis shrinks by 50%. In order to make sure that the collider doesn't float, we need to change the collider offset by negative 25% of your initial collider's size. (this will scale the collider around the pivot point at the feet of the character/ the bottom of the collider)
Ex. Size: (1, 1), Offset (0, 0) -> Size: (1, 0.5f); Offset (0, -0.25f).
The code would look something like this:

crouchingSize = new Vector2(1, 0.5f);
crouchingOffset = new Vector2(0, -0.25f);
standingSize = new Vector2(1, 1);
crouchingOffset = Vector2.zero;
if (Input.GetButtonDown(&quot;Crouch&quot;))
{
SpriteRenderer.sprite = crouching;
Collider.size = crouchingSize;
Collider.offset = crouchingOffset;
}
if (Input.GetButtonUp(&quot;Crouch&quot;))
{
SpriteRenderer.sprite = standing
Collider.size = standingSize;
Collider.offset = standindOffset;
}

huangapple
  • 本文由 发表于 2023年7月18日 06:23:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76708445.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定