unity3d - Unity 2D - 跳转功能无法正常工作
问题描述
我是编码和 Unity2D 的新手,所以请多多包涵。
我创建了一个角色控制器,它通过针对 UI 按钮对象设置的 EventTriggers 调用。控制器工作正常(虽然可能是矫枉过正),但以下是我遇到的跳跃功能的挑战。对此的任何帮助都非常感谢。
非常感谢!
挑战
- 即使从静止状态,玩家也会朝着正确的方向跳跃。
- 即使在空中,玩家也可以继续跳跃。
这是脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
Rigidbody2D rb2d;
SpriteRenderer spriteRenderer;
Animator animator;
public Transform groundCheck;
private LayerMask groundLayer = 1 << LayerMask.NameToLayer ("groundLayer");
private bool moveLeft;
private bool moveRight;
private bool moveJump;
private bool isGrounded;
private float horizontalMove;
private float verticalMove;
public float playerSpeed = 0f;
public float jumpForce = 0f;
public float groundCheckRadius;
public void Start()
{
rb2d = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
animator = GetComponent<Animator>();
moveLeft = false;
moveRight = false;
moveJump = false;
}
//Function - Left button pressed
public void MoveLeft()
{
moveLeft = true;
Debug.Log("Function - Move Left");
}
//Function - Right button pressed
public void MoveRight()
{
moveRight = true;
Debug.Log("Function - Move Right");
}
//Function - Jump button pressed
public void MoveJump()
{
moveJump = true;
Debug.Log("Function - Move Jump");
}
//Function - Stop player movement
public void MoveStop()
{
rb2d.velocity = Vector3.zero;
animator.Play("PlayerIdle");
moveLeft = false;
moveRight = false;
moveJump = false;
}
//Function - Check if player 'GroundCheck' is touching the ground layer
private void PlayerGrounded()
{
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
if (isGrounded == true)
{
Debug.Log("Player is touching the ground!");
}
if (isGrounded == false)
{
Debug.Log("Player is not touching the ground!");
}
}
//Function - Plays once every frame
private void Update()
{
PlayerMovement();
PlayerGrounded();
}
//Function - Move the player GameObject
public void PlayerMovement()
{
//Set the player horizontal right axis
if (moveRight)
{
horizontalMove = playerSpeed;
Debug.Log("Function - PlayerMovement - Move Right!");
}
//Set the player horizontal left axis
if (moveLeft)
{
horizontalMove = -playerSpeed;
Debug.Log("Function - PlayerMovement - Move Left!");
}
//Set the player vertical axis
if (moveJump)
{
verticalMove = jumpForce;
Debug.Log("Function - PlayerMovement - Move Jump!");
}
}
//Function - Plays once every loaded frame
private void FixedUpdate()
{
//Move the player right, don't flip, play animation
if (moveRight)
{
rb2d.velocity = new Vector2(horizontalMove, rb2d.velocity.y * playerSpeed * Time.deltaTime);
spriteRenderer.flipX = false;
animator.Play("PlayerRun");
Debug.Log("Function - Player Moving Right!");
}
//Move the player left, don't flip, play animation
if (moveLeft)
{
rb2d.velocity = new Vector2(horizontalMove, rb2d.velocity.y * playerSpeed * Time.deltaTime);
spriteRenderer.flipX = true;
animator.Play("PlayerRun");
Debug.Log("Function - Player Moving Left!");
}
//Move the player into the air via a jump
if (moveJump && (rb2d.velocity.y == 0))
{
rb2d.velocity = new Vector2(verticalMove, rb2d.velocity.x * jumpForce);
animator.Play("PlayerJump");
Debug.Log("Function - Player Moving Up!");
}
}
}
解决方案
问题出在固定更新的末尾。这就是你所拥有的:
if (moveJump && (rb2d.velocity.y == 0))
{
rb2d.velocity = new Vector2(verticalMove, rb2d.velocity.x * jumpForce);
animator.Play("PlayerJump");
Debug.Log("Function - Player Moving Up!");
}
让我们看看开头。它说if (moveJump && (rb2d.velocity.y == 0)
。所以,(我假设你在他们按下跳跃按钮时设置 moveJump)如果你按下跳跃按钮并且y速度为0。但是,这与玩家是否在地面上无关。我们应该将其更改为if (moveJump && isGrounded)
. 这样,它会在跳转之前检查 isGrounded 是否为真。
当您将速度更改为跳跃时,我注意到几个问题。这就是它所说的:
rb2d.velocity = new Vector2(verticalMove, rb2d.velocity.x * jumpForce);
创建新的 Vector2 时,第一个参数是x,第二个参数是y。您正在以相反的顺序进行操作。你做了y,然后x。你应该像这样交换它们:
rb2d.velocity = new Vector2(rb2d.velocity.x, verticalMove * jumpForce);
由于此交换,您将跳转应用到 x 轴,并移动到 y 轴,但现在它已修复。
这是所有的变化:
if (moveJump && (rb2d.velocity.y == 0))
{
rb2d.velocity = new Vector2(verticalMove, rb2d.velocity.x * jumpForce);
animator.Play("PlayerJump");
Debug.Log("Function - Player Moving Up!");
}
推荐阅读
- generics - 如何为 kotlin 存储 KFunction1 列表?
- mysql - 在 MariaDB10 中恢复 MySQL 5.7 表
- html - HTML CSS 水平滚动根本不起作用
- ruby-on-rails - RoR:类方法未生效
- reactjs - laravel react 命令运行开发不起作用
- javascript - 如何在表单提交时获取 v-select 字段的值?
- c++ - 为每个 MPI 进程等级创建一个组的并行 HDF5 C++ 程序
- r - 带有浮点数的字符列不会转换为数字
- webrtc - webrtc - 在 Firefox 测试版中给出 InvalidSessionDescriptionError: Local descriptions must have a=mid attributes 错误
- pandas - 合并数据框(python pandas)