我向我的玩家添加了击退,这一切都成功了,但是当我添加了 wallSliding 和 wallJumping 部分时,玩家开始在他跑步的同一方向上被击退。所以问题出在 wallSliding 和 wallJumping 部分的任何地方,但我找不到它。 下面是我的播放器脚本,所以任何帮助将不胜感激。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum MovementState { idle, running, jumping, falling, stagger, walljumping, wallsliding }
public class PlayerMovement : MonoBehaviour
{
public MovementState currentState;
private Rigidbody2D rb;
private BoxCollider2D coll;
private SpriteRenderer sprite;
private Animator anim;
public FloatValue currentHealth;
public SignalSender playerHealthSignal;
[SerializeField] private LayerMask jumpableGround;
[SerializeField] private LayerMask wallLayer;
private float dirX = 0f;
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float jumpForce = 10f;
public Transform wallCheck;
bool IsWalled;
bool isSliding;
public float wallSlidingSpeed;
public float wallJumpDuration;
public Vector2 wallJumpForce;
bool wallJumping;
public float attackDamage = 20;
public float attackRate = 2f;
float nextAttackTime = 0f;
[SerializeField] private Transform _center;
[SerializeField] private float _knockbackVel = 8f;
[SerializeField] private float _knockbackTime = 1f;
[SerializeField] private bool _knockbacked;
// Start is called before the first frame update
private void Start()
{
Debug.Log("Hello World!");
rb = GetComponent<Rigidbody2D>();
coll = GetComponent<BoxCollider2D>();
sprite = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
}
// Update is called once per frame
private void Update()
{
if(!_knockbacked) //knockback und Damage
{
dirX = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
currentState = MovementState.idle;
}
else
{
var lerpedXVelocity = Mathf.Lerp(rb.velocity.x, 0f, Time.deltaTime * 3);
rb.velocity = new Vector2(lerpedXVelocity, rb.velocity.y);
currentState = MovementState.stagger;
}
IsWalled= Physics2D.OverlapBox(wallCheck.position, new Vector2(0.7f, 0.9f), 0, wallLayer);
if (Input.GetButtonDown("Jump") && IsGrounded() && !isSliding)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
currentState = MovementState.jumping;
}
else if(Input.GetButtonDown("Jump") && isSliding)
{
wallJumping = true;
Invoke("StopWallJump", wallJumpDuration);
currentState = MovementState.walljumping;
}
if(Time.time >= nextAttackTime)
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
attack();
nextAttackTime = Time.time + 1f/attackRate;
}
}
if(IsWalled && !IsGrounded() && dirX != 0)
{
anim.SetTrigger("WallSlide");
isSliding = true;
}
else
{
anim.SetTrigger("WallSlideOf");
isSliding = false;
}
UpdateAnimationUpdate();
}
void StopWallJump()
{
wallJumping = false;
}
private void FixedUpdate()
{
if(isSliding)
{
rb.velocity = new Vector2(rb.velocity.x, Mathf.Clamp(rb.velocity.y, -wallSlidingSpeed, float.MaxValue));
}
if (wallJumping)
{
rb.velocity = new Vector2(-dirX * wallJumpForce.x,wallJumpForce.y);
}
else
{
rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
}
}
void attack()
{
if (sprite.flipX == false)
{
anim.SetTrigger("Attack");
}
else if (sprite.flipX == true)
{
anim.SetTrigger("AttackLeft");
}
}
private void UpdateAnimationUpdate()
{
MovementState state;
if (dirX > 0f)
{
state = MovementState.running;
sprite.flipX = false;
}
else if (dirX < 0f)
{
state = MovementState.running;
sprite.flipX = true;
}
else
{
state = MovementState.idle;
}
if (rb.velocity.y > .1f)
{
state = MovementState.jumping;
}
else if (rb.velocity.y < -.1f)
{
state = MovementState.falling;
}
anim.SetInteger("state", (int)state);
}
private bool IsGrounded()
{
return Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector2.down, .1f, jumpableGround);
}
public void Knockback(Transform t, float damage)
{
currentHealth.RuntimeValue -= damage;
playerHealthSignal.Raise();
if (currentHealth.RuntimeValue > 0)
{
anim.SetTrigger("Hit");
var dir = _center.position - t.position;
Debug.Log(dir);
_knockbacked = true;
rb.velocity = (Vector2)(dir.normalized * _knockbackVel);
StartCoroutine(routine:Unknockback());
}
else
{
this.gameObject.SetActive(false);
}
}
private IEnumerator Unknockback()
{
yield return new WaitForSeconds(_knockbackTime);
_knockbacked = false;
}
}