【发布时间】:2020-06-14 17:26:59
【问题描述】:
我在这么短的时间内问了这么多 Unity 问题,我非常感谢所有回答的人。我不知道为什么我总是面临这样的问题,而我在网上看到的任何答案都无法帮助我。好的,这是我的问题:
if (Input.GetKey(KeyCode.Q) && (rightHit.collider != null || leftHit.collider != null) && groundHit.collider == null)
如果我按住任何墙上的 Q 按钮,Update 函数中的这行代码会检查每一帧。如果条件满足,那么
void Grapple()
{
if (wallGrapple)
{
x = 0f;
rb.gravityScale = 0;
rb.velocity = new Vector2(speed * x, speed * y);
if (Input.GetKeyDown(KeyCode.Space)) { jumpRequest = true; }
}
}
这个函数被调用,它允许玩家根据垂直轴输入(输入 y 变量)在墙上粘贴和滑动。现在的问题是,如果我只在墙上按 Q 一次,它就会留在墙上,即使它应该被按住以便调用 Graapple() [我使用 Input.GetKey 而不是 Input.GetKeyDown] 和即使在 if 行中,我也能够在墙壁上方滑动(就像有一些看不见的墙壁一样),正在检查检测墙壁的条件。
我已经玩了大约 30-45 分钟,但我无法破解它。我想到的另一个解决方法是使用协程,但我不知道如何使用,因为我没有找到任何关于它如何工作以及应该如何使用的基本解释。这是完整的代码,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SocialPlatforms;
public class Move : MonoBehaviour
{
[SerializeField] private LayerMask groundMask;
[SerializeField] private LayerMask Wall;
[Header("Horizontal")]
public float x;
float dirX;
public float speed;
float initialSpeed;
[SerializeField] [Range(0, 1)] float LerpConstant;
public float dashForce = 100f;
public bool canDash;
public bool dashRequest;
[Header("Vertical")]
public float y;
public bool canJump;
public bool jumpRequest;
public float initialJumpForce;
public float jumpForce;
public bool canWallJump;
public float modifiedJumpForce;
public float sideJumpForce;
public bool wallGrapple;
[Header("Other")]
public Rigidbody2D rb;
public float gScale = 10f;
BoxCollider2D boxcollider;
RaycastHit2D groundHit;
RaycastHit2D leftHit;
RaycastHit2D rightHit;
// Start is called before the first frame update
void Start()
{
rb = gameObject.GetComponent<Rigidbody2D>();
boxcollider = gameObject.GetComponent<BoxCollider2D>();
jumpForce = initialJumpForce;
initialSpeed = speed;
rb.gravityScale = gScale;
}
// Update is called once per frame
void Update()
{
//Instant 1, 0, -1 inputs
x = Input.GetAxisRaw("Horizontal");
y = Input.GetAxisRaw("Vertical");
if(x < 0)
{ dirX = -1; }
else if(x > 0)
{ dirX = 1; }
if (Input.GetKeyDown(KeyCode.Space) && (canJump || canWallJump)) //for jumps
{ jumpRequest = true; }
if (Input.GetKey(KeyCode.Q) && (rightHit.collider != null || leftHit.collider != null) && groundHit.collider == null) //for wall grappling
{ wallGrapple = true; }
if (Input.GetKeyDown(KeyCode.LeftShift) && (canDash)) //for dashing
{ dashRequest = true; }
Detection();
JumpDash();
Grapple();
}
void FixedUpdate()
{
Movement();
}
void Detection()
{
groundHit = Physics2D.BoxCast(boxcollider.bounds.center, boxcollider.bounds.size, 0f, Vector2.down, 0.1f, groundMask);
if (groundHit.collider != null) //If player is on ground
{
canJump = true;
canWallJump = false;
canDash = false;
jumpForce = initialJumpForce;
sideJumpForce = 0;
LerpConstant = 0.25f;
}
else if (groundHit.collider == null)//not on ground
{
LerpConstant = 0.12f;
canJump = false;
}
//Wall detection
//Left wall
leftHit = Physics2D.BoxCast(boxcollider.bounds.center, boxcollider.bounds.size, 0f, Vector2.left, 0.1f, Wall);
if (leftHit.collider != null && groundHit.collider == null) //if player on left wall and not on ground
{
canWallJump = true;
jumpForce = modifiedJumpForce;
sideJumpForce = jumpForce;
}
//Right wall
rightHit = Physics2D.BoxCast(boxcollider.bounds.center, boxcollider.bounds.size, 0f, Vector2.right, 0.1f, Wall);
if (rightHit.collider != null && groundHit.collider == null) //if player on right wall and not on ground
{
canWallJump = true;
jumpForce = modifiedJumpForce;
sideJumpForce = -jumpForce; // negative of jump force to jump in left direction
}
if (rightHit.collider == null && leftHit.collider == null) //if both walls are not detected
{
canWallJump = false;
}
}
void Movement()
{
Vector2 move = new Vector2(x * speed, rb.velocity.y);
rb.velocity = Vector2.Lerp(rb.velocity, move, LerpConstant);
}
void JumpDash()
{
//Jump
if (jumpRequest)
{
wallGrapple = false;
rb.gravityScale = gScale;
rb.AddForce(new Vector2(sideJumpForce * 2.1f, jumpForce), ForceMode2D.Impulse);
speed = initialSpeed;
jumpRequest = false; //setting jumpRequest to false after jumping to prevent unlimited jumps
canDash = true;
}
/*if (dashRequest)
{
rb.velocity = Vector2.zero;
rb.AddForce((dashForce, 0f), ForceMode2D.Impulse);
}*/ //remember to put this code in later
}
void Grapple()
{
if (wallGrapple)
{
x = 0f;
rb.gravityScale = 0;
rb.velocity = new Vector2(speed * x, speed * y);
if (Input.GetKeyDown(KeyCode.Space)) { jumpRequest = true; }
}
}
}
附:我最初想使用 Space 本身而不是 Q 来进行摇杆和滑动,但是会弹出更多错误,例如不一致的墙壁跳跃,所以这就是我使用 Q 的原因。
【问题讨论】:
-
尽管有你的解释,我还是不明白你的问题……你的问题在哪里
-
好的,我已经上传了一个显示问题的视频。我还希望当我按住 Q 而不是只按一次时,播放器会粘在墙上(并滑到墙上)。您还可以在视频中看到,即使 if 条件不允许,玩家也可以越过墙壁