首页 > 其他分享 >3-8. 蜜蜂 - 基本的移动逻辑和动画

3-8. 蜜蜂 - 基本的移动逻辑和动画

时间:2024-02-26 12:55:19浏览次数:24  
标签:动画 逻辑 localScale transform 蜜蜂 currentEnemy override public

动画

切割图片,制作动画,注意:锚点在中心点

注意: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

标签:20240226_1214

标签:动画,逻辑,localScale,transform,蜜蜂,currentEnemy,override,public
From: https://www.cnblogs.com/hellozjf/p/18034091

相关文章

  • 3-6. 蜗牛-基本的移动逻辑和动画
    动画相关切割图片将蜗牛的图片切割成动画动画状态机这里将蜗牛的移动分为PreMove和Move两个状态,希望在PreMove也就是蜗牛头还没有伸出去的时候不移动,等蜗牛头伸出去之后才移动当walk为true的时候,从snailIdle立马进入snailPreMove状态snailPreMove完整播放......
  • 用QTimeLine实现滑动动画
    一般在Qt实现动画可以用QAbstractAnimation的子类实现。这里给出一个不一样的例子实现动画,即用QTimeLine实现。功能是有一个QStackedWidget,它有两个子页面。默认显示第一页。点击“动画”按钮播放一段动画使页面第一页滑动到第二页,然后切换到第二页。程序测试环境是VS2017和Qt5.9......
  • 3-3. 野猪-受伤及死亡的逻辑和动画
    制作受伤和死亡动画受伤动画死亡动画就是在受伤动画基础上,增加Color.a从1~0的变化动画状态机如下当hurt触发的时候,从AnyState立刻进入boarHurt,当boarHurt播放完一帧之后进入Exit当dead=true的时候,从AnyState立刻进入boarDead注意,从AnyState出......
  • powerpoint: 设置幻灯片的切换动画
    一,选择切换动画选中要切换的幻灯片    然后选择工具栏上的切换标签,   选择一个切换动画:说明:刘宏缔的架构森林—专注it技术的博客,网址:https://imgtouch.com本文: https://blog.imgtouch.com/index.php/2024/02/24/powerpoint-she-zhi-huan-deng-pian-de-qi......
  • 3-1. 野猪 - 基本的移动逻辑和动画
    野猪实现移动添加一个Enemy类usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassEnemy:MonoBehaviour{protectedRigidbody2Drb;protectedAnimatoranim;[Header("基本参数")]publicfloatnormalSpe......
  • 2-12. 三段攻击动画的实现
    创建动画片段修改动画状态机增加AttackLayer,把刚才制作好的动画片段加进去再增加两个变量,bool类型的isAttack和trigger类型的attackNewState->blueAttack1,isAttack=true并且attack触发blueAttack1->blueAttack2,isAttack=true并且attack触发,有exi......
  • 2-11. 受伤和死亡的逻辑和动画
    添加受伤和死亡动画片段通过新的层来实现受伤和死亡动画点击动画控制器右上角的+,然后新建一个Layer注意Weight要改成1,Blending要改成Additive受伤的话,我们通过hurt来触发,死亡我们通过isDead来控制在HurtLayer中,当hurt触发的时候,就会播放blueHurt动画,......
  • 2-9. 实现人物下蹲逻辑和动画
    动画片段做成动画片段,命名为blueCrouchStart和blueCrouchIdle动画状态机这里我们再接触一个新的东西,Sub-StateMachine,可以通过右键CreateSub-StateMachine来实现点开Crouch,把之前创建好的blueCrouchStart和blueCrouchIdle片段加进来另外添加一个变量,isCrouc......
  • 2-8. 创建人物跳跃动画
    人物跳跃的五个阶段根据这张图把图片切好,并做好动画状态使用BlendTree实现跳跃动画在动画状态机中新建一个BlendTree,然后给它添加三个Motion因为我设置的JumpForce是5,所以人物速度54时候是起跳阶段,41的时候是上升阶段,1~-1的时候是空中换腿阶段,-1以后是下降阶段。虽然......
  • 2-6. 创建人物基本动画
    给帧图片命名添加动画首先需要给Player添加Animator组件然后创建Animations/Player文件夹,并在该文件夹下面添加AnimatorController,起名叫Player然后把Player拖到Animator的Controller上面打开动画状态机Window->Animation->Animator创建Idle动......