我有一个2D角色控制器和控制器的一部分是双跳的能力,但如果我的球员击中敌人时,在空中后,双跳或下斜线攻击的球员开始走在一条直线在空中,我假设我错过了地面检查,但不知道我是否可以有任何帮助,请:
CS代码为:
public class PlayerController : MonoBehaviour
{
[Header("Input")]
public float jumpHoldTime = 0.3f;
float horizontalInput;
float lastHorizontalInput;
bool dead = false;
[Header("Movement")]
public Animator anim;
public float moveSpeed = 5.0f;
float currentMove = 0f;
public bool facingRight = true;
private Rigidbody2D rb;
Vector2 finalMovement;
bool runMovement = false;
bool isMoving = false;
[Header("Vertical Movement")]
public int jumpCounter = 2;
public float jumpSpeed = 5f;
public bool inAir = true;
public bool canDoubleJump = false;
bool jumpHeld = false;
[Header("Gravity")]
public float upGravity = -16f;
public float downGravity = -20f;
public float jumpHoldGravity = -5f;
public float maxFallSpeed = -10f;
float currentGravity = 0f;
[Header("Col Handler")]
public bool wallRight = false;
public bool wallLeft = false;
Collider2D currentGround;
Collider2D leftWall;
Collider2D rightWall;
[Header("Attack")]
public Transform attackPointRight;
public Transform attackPointDown;
public float attackRange = 0.5f;
public int attackDamage = 1;
public float attackRate = 2f;
private float nextAttackCount = 0f;
private bool attackingForward = true;
public LayerMask enemyLayer;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if(dead)
{
return;
}
GetInput();
}
void GetInput()
{
horizontalInput = Input.GetAxis("Horizontal");
if(horizontalInput != 0 && lastHorizontalInput == 0) // move if input on current frame
{
isMoving = true;
anim.SetBool("Moving", true);
}
if(horizontalInput == 0 && lastHorizontalInput != 0) // stop when movement ends on frame
{
isMoving = false;
anim.SetBool("Moving", false);
}
if(horizontalInput > 0f && !facingRight || horizontalInput < 0f && facingRight)
{
dirFlip();
}
if(Input.GetButtonDown("Jump"))
{
Jump();
}
lastHorizontalInput = horizontalInput;
}
void dirFlip()
{
facingRight = !facingRight;
transform.Rotate(transform.up, 180f);
}
void Jump()
{
if(canDoubleJump)
{
jumpCounter -= 1;
}
if(jumpCounter < 0 || (inAir && !canDoubleJump))
{
return;
}
inAir = true;
anim.SetTrigger("Jump");
anim.SetBool("InAir", true);
currentGravity = jumpSpeed;
StartCoroutine(JumpHoldRoutine());
}
IEnumerator JumpHoldRoutine()
{
jumpHeld = true;
float timer = 0f;
while(timer < jumpHoldTime && Input.GetButton("Jump"))
{
timer += Time.deltaTime;
yield return null;
}
jumpHeld = false;
}
private void FixedUpdate()
{
if(inAir)
{
setMovement();
if(jumpHeld)
{
currentGravity += jumpHoldGravity * Time.deltaTime;
}
else
{
if(currentGravity > 0f)
{
currentGravity += upGravity * Time.deltaTime;
}
else if(currentGravity <= 0f)
{
currentGravity += downGravity * Time.deltaTime;
}
}
currentGravity = Mathf.Clamp(currentGravity, maxFallSpeed, jumpSpeed);
finalMovement.y = currentGravity;
}
if(isMoving)
{
setMovement();
currentMove = horizontalInput * moveSpeed;
if(currentMove > 0f && wallRight || currentMove < 0f && wallLeft || wallRight)
{
currentMove = 0f;
}
finalMovement.x = currentMove;
}
if(runMovement)
{
rb.MovePosition((Vector2)transform.position + finalMovement * Time.deltaTime);
runMovement = false;
}
}
void setMovement()
{
if(!runMovement)
{
runMovement = true;
finalMovement = Vector2.zero;
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
ColliderDistance2D collDist = collision.collider.Distance(GetComponent<Collider2D>());
Debug.DrawRay(collDist.pointA, collDist.normal, Color.black, 1f);
if(collision.collider.tag == "Enviro")
{
if(collDist.normal.y > 0.1f) // On ground to reset double jump
{
jumpCounter = 2;
}
if(collDist.normal.y > 0.1f) // Ground check
{
Ground(collision.collider);
}
if(collDist.normal.y < -0.1f) // ceiling
{
currentGravity = 0f;
jumpHeld = false;
}
if(collDist.normal.x < -0.9f) // right wall
{
wallRight = true;
rightWall = collision.collider;
}
if(collDist.normal.x > 0.9f)
{
wallLeft = true;
leftWall = collision.collider;
}
}
else if(collision.collider.tag == "Rat")
{
inAir = false;
Jump();
GetComponent<Health>().TakeDamage(1);
}
else if(collision.collider.tag == "Ghost")
{
inAir = false;
Jump();
GetComponent<Health>().TakeDamage(1);
}
else if(collision.collider.tag == "LavaB")
{
inAir = false;
Jump();
GetComponent<Health>().TakeDamage(1);
}
else if(collision.collider.tag == "BouncySpikeBall")
{
inAir = false;
Jump();
}
else if(collision.collider.tag == "Skeleton")
{
inAir = false;
Jump();
GetComponent<Health>().TakeDamage(1);
}
}
void Ground(Collider2D newGround)
{
inAir = false;
currentGravity = 0f;
currentGround = newGround;
anim.SetBool("InAir", false);
}
private void OnCollisionExit2D(Collision2D collision) // no longer collidiing with object
{
if(collision.collider.tag == "Enviro")
{
if(collision.collider == currentGround)
{
if(!inAir)
{
inAir = true;
currentGround = null;
anim.SetTrigger("Jump");
anim.SetBool("InAir", true);
}
}
if(collision.collider == rightWall)
{
rightWall = null;
wallRight = false;
}
if(collision.collider == leftWall)
{
leftWall = null;
wallLeft = false;
}
}
}
}
我很抱歉,这是有点长,我削减了部分是关于攻击或一些无关的东西,试图限制有多少在这里。
基本上,如果我双跳,然后击中/向下击中或接触敌人,而我仍然在空中我的球员冻结在该轴,只能左右移动,但动画仍然工作正常。
有点困惑,这需要一些帮助,请,也让我知道,如果我没有给足够的信息的问题:)
我试过在击中后切换inAir布尔,但它似乎对这个问题没有帮助。我希望球员只是再次下降,而不是停留在空中移动
1条答案
按热度按时间owfi6suc1#
你可以让你的玩家在击中敌人的时候,用很小的力量把他往上推
rb.addforce
,然后跳格(jumpheld或jumpcounter)会被复位。