类银河恶魔城学习记录-Crash Course
本文记录一下学习过程中照着教程敲的代码~
Enemy_Skeleton.cs
using UnityEngine;
//骷髅敌人
public class Enemy_Skeleton : Entity
{
[Header("Move Info")]
[SerializeField] private float moveSpeed;
[Header("Player Detection")]
[SerializeField] private float playerCheckDistance;
[SerializeField] private LayerMask whatIsPlayer;
private RaycastHit2D isPlayerDetected;
bool isAttacking;
protected override void Start()
{
base.Start();
}
protected override void Update()
{
base.Update();
//只要检测到玩家
if (isPlayerDetected)
{
if (isPlayerDetected.distance > 3)
{
rb.velocity = new Vector2(facingDir * moveSpeed * 1.5f, rb.velocity.y);
Debug.Log("I see the Player!");
isAttacking = false;
}
else
{
Debug.Log("Attaking " + isPlayerDetected.collider.gameObject.name);
isAttacking = true;
}
}
if (!isGrounded || isWallDetected)
Flip();
Movement();
}
private void Movement()
{
if(!isAttacking)
rb.velocity = new Vector2(facingDir * moveSpeed, rb.velocity.y);
}
protected override void CheckCollision()
{
base.CheckCollision();
isPlayerDetected = Physics2D.Raycast(transform.position, Vector2.right, playerCheckDistance * facingDir, whatIsPlayer);
}
protected override void OnDrawGizmos()
{
base.OnDrawGizmos();
Gizmos.color = Color.blue;
Gizmos.DrawLine(transform.position, new Vector3(transform.position.x + playerCheckDistance * facingDir, transform.position.y));
}
}
Entity.cs
using UnityEngine;
//实体类
public class Entity : MonoBehaviour
{
protected Rigidbody2D rb;
protected Animator anim;
protected bool isGrounded;
protected bool isWallDetected;
[Header("Collision Info")]
[SerializeField] protected LayerMask whatIsGround;
[SerializeField] protected float groundCheckDistance;
[SerializeField] protected Transform groundCheck;
[Space]
[SerializeField] protected Transform wallCheck;
[SerializeField] protected float wallCheckDistance;
protected int facingDir = 1;
protected bool facingRight = true;
protected virtual void Start()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponentInChildren<Animator>();
}
protected virtual void Update()
{
CheckCollision();
}
//检测是否撞墙或者离开地面
protected virtual void CheckCollision()
{
isGrounded = Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsGround);
isWallDetected = Physics2D.Raycast(wallCheck.position, Vector2.right, wallCheckDistance * facingDir, whatIsGround);
}
//转向
protected virtual void Flip()
{
facingDir *= -1;
facingRight = !facingRight;
transform.Rotate(0, 180, 0);
}
//画线 检测撞墙的线和检测离地的线
protected virtual void OnDrawGizmos()
{
Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));
Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance * facingDir, wallCheck.position.y));
}
}
Player.cs
using UnityEngine;
//玩家类
public class Player : Entity
{
[Header("Move Info")]
[SerializeField] private float xInput;
[SerializeField] private float moveSpeed = 4;
[SerializeField] private float junpForce = 7;
[Header("Dash Info")]
[SerializeField] private float dashDuration;
[SerializeField] private float dashTime;
[SerializeField] private float dashSpeed;
[SerializeField] private float dashCalmDuration;
[SerializeField] private float dashCalmTime;
[Header("Attack Info")]
[SerializeField] private bool isAttacking;
[SerializeField] private int comboCounter;
[SerializeField] private float comboDuration;
[SerializeField] private float comboTimeWindow;
protected override void Start()
{
base.Start();
}
protected override void Update()
{
base.Update();
FlipController();
Movement();
CheckInput();
AnimatorController();
Dash();
Attack();
comboTimeWindow -= Time.deltaTime;
}
//鼠标左键攻击
private void Attack()
{
if (!isGrounded)
return;
if (Input.GetKeyDown(KeyCode.Mouse0))
{
StartAttackEvent();
}
}
//攻击事件
private void StartAttackEvent()
{
if (comboTimeWindow < 0)
comboCounter = 0;
isAttacking = true;
comboTimeWindow = comboDuration;
}
//攻击结束
public void AttackOver()
{
isAttacking = false;
comboCounter++;
if (comboCounter > 2)
comboCounter = 0;
}
//冲刺控制
private void Dash()
{
dashTime -= Time.deltaTime;
dashCalmTime -= Time.deltaTime;
if (Input.GetKeyDown(KeyCode.LeftShift))
{
DashAbillity();
}
}
//冲刺判定
private void DashAbillity()
{
if (dashCalmTime < 0 && !isAttacking)
{
dashTime = dashDuration;
dashCalmTime = dashCalmDuration;
}
}
//检查输入
private void CheckInput()
{
xInput = Input.GetAxisRaw("Horizontal");
if (Input.GetKeyDown(KeyCode.Space))
{
Jump();
}
}
//移动控制
private void Movement()
{
if (isAttacking)
{
rb.velocity = new Vector2(0, 0);
}
else if(dashTime > 0)
{
rb.velocity = new Vector2(facingDir * dashSpeed,0);
}
else
{
rb.velocity = new Vector2(xInput * moveSpeed, rb.velocity.y);
}
}
//跳跃控制
private void Jump()
{
if(isGrounded)
rb.velocity = new Vector2(rb.velocity.x, junpForce);
}
//动画播放控制
private void AnimatorController()
{
bool isMoving = rb.velocity.x != 0;
anim.SetBool("isMoving", isMoving);
anim.SetBool("isGrounded", isGrounded);
anim.SetFloat("yVelocity", rb.velocity.y);
anim.SetBool("isDashing", dashTime > 0);
anim.SetBool("isAttacking", isAttacking);
anim.SetInteger("comboCounter", comboCounter);
}
//转向控制
private void FlipController()
{
if(rb.velocity.x > 0 && !facingRight)
Flip();
else if(rb.velocity.x < 0 && facingRight)
Flip();
}
}
PlayerAnimEvents.cs
using UnityEngine;
public class PlayerAnimEvents : MonoBehaviour
{
private Player player;
private void Start()
{
player = GetComponentInParent<Player>();
}
private void AnimationTrigger()
{
player.AttackOver();
}
}