第一个游戏动作开发日志——敌人初步AI设定

这篇博客记录了游戏中敌人AI的行为设定,包括待机、搜寻、追击和攻击四种状态的切换。在 Animator 中设置了状态切换参数,并采用两层 Ykn 模型控制移动和动画。代码部分使用 C# 编写 AI Enemy,强调了 FixedUpdate 的使用、旋转冻结以及状态切换的实现方式。
摘要由CSDN通过智能技术生成

敌人状态:

1、待机状态,idle原地

2、搜寻玩家状态,walk前进

3、追击玩家,run前进

4、攻击玩家,atk!

5、收到伤害,onhit

6、死亡状态,延迟销毁。

——————————————————————————

目前实现:待机、搜寻、追击、攻击四个状态切换。

Animator中参数 如下:状态切换注意Exit time 取消勾选,切换变为立即切换.


人物模型设置:两层Ykn ,Yknsprite.

第一层控制移动受力,碰撞检测。

第二层控制动画切换,和朝向切换。



代码部分:AI Enemy(C#):因为数据以后为代码传入,在此设为共有方便调试。

代码注意点:

1、FixedUpdate()是 固定的时间间隔执行,不受游戏帧率(fps)的影响, 防止动画发生抽搐。

2、锁定RigidbodyConstraints2D.FreezeRotation。防止人物扑街倒地。

3、状态转换通过检测和玩家距离实现切换。

using UnityEngine;
using System.Collections;

public class AIEnemy : MonoBehaviour
{
    private bool IsWalk;
    private bool IsRun;
    private bool IsDead;
    private bool IsOnhit;
    private bool IsAtk;

    public Animator enemy_ani;
    public Transform player;
    public GameObject enemyOBG;
    public float finddistance = 10;
    public float chargedistance = 5;
    public float atkdistance = 2f;
    public float walkspeed = 2500;
    public float runspeed = 3500;


    private bool IsLookRight;
    private Vector3 SpriteOriginalScale;
    private Vector3 direction;

    void Start()
    {
        IsWalk = false;
        IsRun = false;
        IsDead = false;
        IsAtk = false;
        IsOnhit = false;

        SpriteOriginalScale = enemyOBG.transform.localScale;

        this.GetComponent<Rigidbody2D>().constraints = RigidbodyConstraints2D.FreezeRotation;
    }

    void FixedUpdate()
    {
        direction = player.position - this.transform.position;
        Lookplayer(direction);
        CanWalk(direction);
        CanRun(direction);
        CanAtk(direction);

        //动画设置
        enemy_ani.SetBool("IsRun", IsRun);
        enemy_ani.SetBool("IsWalk", IsWalk);
        enemy_ani.SetBool("IsDead", IsDead);
        enemy_ani.SetBool("IsAtk", IsAtk);
        enemy_ani.SetBool("IsOnhit", IsOnhit);
    }

    void Lookplayer(Vector3 direction)
    {
        if (direction.x > 0)
        {
            IsLookRight = true;
            enemyOBG.transform.localScale = SpriteOriginalScale;
            //collider错位补正
            this.GetComponent<Collider2D>().offset = new Vector2(-0.5f, -0.12f);
        }
        else if (direction.x < 0)
        {
            IsLookRight = false;
            enemyOBG.transform.localScale = new Vector3(-SpriteOriginalScale.x, SpriteOriginalScale.y, SpriteOriginalScale.z);
            //collider错位补正
            this.GetComponent<Collider2D>().offset = new Vector2(0.5f, -0.12f);
        }
    }

    void CanWalk(Vector3 direction)
    {
        if (Mathf.Abs(direction.x) <= finddistance && Mathf.Abs(direction.x) >= chargedistance)
        {
            IsWalk = true;
            //向玩家移动
            Vector3 forcedirect = Vector3.Normalize(direction);
            this.transform.GetComponent<Rigidbody2D>().AddForce(forcedirect * walkspeed * Time.deltaTime);
        }
        else
        {
            IsWalk = false;
        }
    }

    void CanRun(Vector3 direction)
    {
        if(Mathf.Abs(direction.x) <= chargedistance && Mathf.Abs(direction.x) >= atkdistance)
        {
            IsRun = true;
            //向玩家追击
            Vector3 forcedirect = Vector3.Normalize(direction);
            this.transform.GetComponent<Rigidbody2D>().AddForce(forcedirect * runspeed * Time.deltaTime);
        }
        else
        {
            IsRun = false;
        }
    }

    void CanAtk(Vector3 direction)
    {
        if (Mathf.Abs(direction.x) <= atkdistance && Mathf.Abs(direction.x) >= 0)
        {
            IsAtk = true;
            //向玩家攻击
            
          
        }
        else
        {
            IsAtk = false;
        }
    }

}
最终效果图:





  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值