动画
切割图片,制作动画,注意:锚点在中心点
注意:beeFly 和 beeChase 使用相同的动画,但是速度不一样
代码
Enemy
因为 蜜蜂 的行动方式与 野猪、蜗牛 都不一样,它是在空中飞的,所以它检测玩家和移动的方式都是不一样的,所以我们需要对 Enemy 中 FoundPlayer、OnDrawGizmosSelected、Move 这三个方法都进行重写,将它们标记成 virtual
另外,蜜蜂移动的时候需要一个目标点,所以还需要在 Enemy 中再增加一个 GetNewPoint 方法
Bee
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bee : Enemy
{
[Header("移动范围")]
public float patrolRadius;
protected override void Awake()
{
base.Awake();
patrolState = new BeePatrolState();
}
public override bool FoundPlayer()
{
var obj = Physics2D.OverlapCircle(transform.position, checkDistance, attackLayer);
if (obj)
{
attacker = obj.transform;
}
return obj;
}
public override void OnDrawGizmosSelected()
{
// 画出警戒区大小
Gizmos.DrawWireSphere(transform.position, checkDistance);
// 画出巡逻范围大小
Gizmos.color = Color.green;
if (spwanPoint == Vector3.zero)
{
Gizmos.DrawWireSphere(transform.position, patrolRadius);
}
else
{
Gizmos.DrawWireSphere(spwanPoint, patrolRadius);
}
}
public override Vector3 GetNewPoint()
{
// 算出随机角度
float randomAngle = Random.Range(0f, 2f * Mathf.PI);
// 算出随机向量
Vector2 randomVector2 = new Vector2(Mathf.Cos(randomAngle), Mathf.Sin(randomAngle));
// 算出随机半径
float radius = Random.Range(0.0f, patrolRadius);
return spwanPoint + (Vector3) (randomVector2 * radius);
}
public override void Move()
{
}
}
蜜蜂检测玩家的方式,是通过一个圆圈的范围进行检测
所以绘制检测范围的时候也需要使用圆圈来进行检测,蜜蜂的巡逻范围也是一个圆圈,用不同的颜色标识出来
蜜蜂需要一个目标点,目标点应该是在绿色的巡逻范围内,所以使用随机角度乘以随机距离,再加上出身点位置,获取目标点
蜜蜂的 Move 不需要实现,直接在 BeePatrolState.PhysicsUpdate 里面实现
BeePatrolState
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BeePatrolState : BaseState
{
private Vector3 target;
private Vector3 moveDir;
public override void OnEnter(Enemy enemy)
{
currentEnemy = enemy;
currentEnemy.currentSpeed = currentEnemy.normalSpeed;
currentEnemy.anim.SetBool("walk", true);
// 进入巡逻状态的时候,先设置一个目标点
target = currentEnemy.GetNewPoint();
}
public override void LogicUpdate()
{
// 发现 player 切换到 chase
if (currentEnemy.FoundPlayer())
{
currentEnemy.SwitchState(NPCState.Chase);
}
if ((currentEnemy.transform.position - target).sqrMagnitude < 0.1f)
{
// 说明到达目标点了
currentEnemy.wait = true;
target = currentEnemy.GetNewPoint();
}
// 移动方向 = 目标位置 - 当前位置
moveDir = (target - currentEnemy.transform.position).normalized;
if (moveDir.x > 0)
{
currentEnemy.transform.localScale = new Vector3(
-1 * Mathf.Abs(currentEnemy.transform.localScale.x),
currentEnemy.transform.localScale.y,
currentEnemy.transform.localScale.z
);
}
else if (moveDir.x < 0)
{
currentEnemy.transform.localScale = new Vector3(
Mathf.Abs(currentEnemy.transform.localScale.x),
currentEnemy.transform.localScale.y,
currentEnemy.transform.localScale.z
);
}
}
public override void PhysicsUpdate()
{
if (!currentEnemy.isHurt && !currentEnemy.isDead && !currentEnemy.wait)
{
currentEnemy.rb.velocity = moveDir * currentEnemy.currentSpeed;
}
else
{
// 否则需要停下来
currentEnemy.rb.velocity = Vector2.zero;
}
}
public override void OnExit()
{
currentEnemy.anim.SetBool("walk", false);
}
}
在 OnEnter 的时候,需要设置当前对象、速度、动画,此外还要获取一个目标点
在 LogicUpdate 的时候,发现玩家进入追逐状态,到达目的的时候进入等待状态,算出移动的方向并调整朝向
在 PhysicsUpdate 的时候,修改蜜蜂刚体的速度,如果受伤、死亡、等待的话速度变0
在 OnExit 的时候,取消动画
设置变量
Layer
Sprite Renderer
Rigidbody2D
蜜蜂不要受到重力影响,否则会掉下去
Animator
PhysicsCheck
蜜蜂是在空中飞的,可以穿墙,所以不需要设置物理监测参数
Bee
Capsule Collider 2D
蜜蜂只需要触发器,不需要碰撞体,因为它可以穿墙
项目相关代码
代码仓库:https://gitee.com/nbda1121440/2DAdventure.git
标签:动画,逻辑,localScale,transform,蜜蜂,currentEnemy,override,public From: https://www.cnblogs.com/hellozjf/p/18034091