我在这么短的时间内问了很多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,那么即使它应该被按住以使Grapple()被调用[我已经使用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; }
}
}
}
P.S。我本来想使用Space本身而不是Q来操纵杆和滑梯,但是会弹出更多错误,例如不一致的跳墙,因此这就是我使用Q的原因。
似乎您没有设置
wallGrapple =否
除了跳转请求中,代码中的任何位置。因此,由于它永远不会被设置为false,因此您的播放器将不断努力。也许您可以先在Update函数中将其设置为false并进行密钥检测。
我向您展示一个协程示例代码片段。您可以从注释行中了解它,并将其应用于您自己的代码。
void Start()
{
StartCoroutine("coroutineFunc"); // calling for example
}
和这样的协程函数:
IEnumerator coroutineFunc()
{
// before waiting... if u wanna try something
yield return new WaitForSeconds(1); // waiting..
// after waiting something what do you want
}