Unity2D敌人/怪物AI控制 第一期

AI:原地巡逻自动攻击型

AI会在横版地图上向左向右移动,移动一段距离后会原地停止移动,等待一段时间后,会随机向左或向右移动,以此循环,其中AI移动速度,移动时间、停留时间均可以自行调控,当人物进入怪物攻击范围后 会自动面向人物进行攻击,攻击时不会移动,直至人物离开攻击范围,怪物受到攻击后会闪红,有血量:

脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChameleonController : MonoBehaviour
{
    public static ChameleonController chameleonController;
    private void Awake()
    {
        chameleonController = this;
    }

    Animator animator;
    Rigidbody2D rg;
    public float MoveSpeed = 0;
    float changeTime = 0;
    float time = 0;

    //随机时间
    public float minTime = 0;
    public float maxTime = 0;

    int direction = 1;
    float distance_ = 0;
    bool isChange = false;

    bool canHit = false;

    Transform PlayerTransform;
    public float Distance = 0;

    
    float Dwell_gap = 0; //停留时间
    float Dwell_Cumulative = 0; //停留时间累积
    public float DwellMinTime = 0;
    public float DwellMaxTime = 0;

    
    float moveTime = 0; //行走时间
    //行走的最大时间和最短时间设定
    public float moveMinTime = 0;
    public float moveMaxTime = 0;

    float moveTimeCumulative = 0;

    bool isDwell = false;
    bool isDwellRange = false;

    bool CanMove = false;
    bool CanCount = false;
    bool CanTimeCumulative = false;

    bool isAttacking = false;
    bool isAttacked = false;

    public bool TrackPlayer = false;
    public float TrackSpeed = 0;

    public float CurrentPlayer = 0;

    public float Life_value = 0;

    public float hitTime = 0;
    bool isHit = false;
    float time1 = 0;

    GameObject gm;

    bool isinvincible = false;

    void Start()
    {
        animator = GetComponent<Animator>();
        rg = GetComponent<Rigidbody2D>();
        CanMove = false;
        CanCount = true;
    }

    
    void Update()
    {
        PlayerTransform = GameObject.Find("Player").transform;
        //得到与玩家的距离
            distance_ = Mathf.Sqrt(Mathf.Abs(PlayerTransform.transform.position.x - transform.position.x) * Mathf.Abs(PlayerTransform.transform.position.x - transform.position.x) +
            Mathf.Abs(PlayerTransform.transform.position.y - transform.position.y) * Mathf.Abs(PlayerTransform.transform.position.y - transform.position.y));

        time = time + Time.deltaTime;

        if(isChange==false)
        {
            changeTime = Random.Range(minTime, maxTime);
            isChange = true;
        }

        transform.localScale = new Vector3(-direction, 1, 1);

        if (time > changeTime)
        {
            direction = -direction;
            transform.localScale = new Vector3(-direction, 1, 1);
            time = 0;
            isChange = false;
        }

        //判断是否在攻击距离之内
        if(distance_<Distance)
        {
            canHit = true;
        }
        else
        {
            canHit = false;
        }


        if(canHit)
        {
            //判断玩家在怪物的哪边
            if (PlayerTransform.transform.position.x < transform.position.x)
            {
                direction = 1;
                animator.SetBool("attack", true);
                GMF_PlayerController._PlayeController.inJured(CurrentPlayer);
                transform.localScale = new Vector3(direction, 1, 1);
            }
            else
            {
                direction = -1;
                animator.SetBool("attack", true);
                transform.localScale = new Vector3(direction, 1, 1);
                GMF_PlayerController._PlayeController.inJured(CurrentPlayer);
            }
        }else
        {
            animator.SetBool("attack", false);
        }
        
        //随机暂停时间 开始暂停 播放停留动画 人物停止移动 生成暂停时间
        if(CanCount)
        {
            isDwellRange = true;
            CanTimeCumulative = true;
            CanCount = false;
        }

        if(isDwellRange) //设置停留动画 设置暂停时间 
        {
            Dwell_gap = Random.Range(DwellMinTime, DwellMaxTime);
            animator.SetBool("idem", true);
            animator.SetBool("run", false);
            CanMove = false;
            isDwellRange = false;
        }

        if (CanTimeCumulative)
        {
            Dwell_Cumulative = Dwell_Cumulative + Time.deltaTime;
        }


        if (Dwell_Cumulative > Dwell_gap) //超过暂停时间 停留结束 结束停留动画 生成行走时间 开始行走动画
        {
            animator.SetBool("idem", false);
            animator.SetBool("run", true);
            moveTime = Random.Range(moveMinTime, moveMaxTime);
            CanMove = true;
            Dwell_Cumulative = 0;
            CanTimeCumulative = false;
        }

        //行走时间结束 
        if(CanMove)
        {
            
            moveTimeCumulative = moveTimeCumulative + Time.deltaTime;
            if(moveTimeCumulative>moveTime)
            {
                CanMove = false;
                moveTimeCumulative = 0;
                CanCount = true;
            }
        }

        if(Life_value<=0)
        {
            Destroy(this.gameObject);
        }

        if (isHit)
        {
           // animator.SetBool("current", true);
            time1 = time1 + Time.deltaTime;
            if (time1 > hitTime)
            {
                animator.SetBool("current", false);
                isinvincible = false;
                isHit = false;
                time1 = 0;
            }
        }
    }

    private void FixedUpdate()
    {
        //没有停留就可以移动
        if(CanMove)
        {
            MoveMent();
        }
        
    }

    void MoveMent()
    {

        if(TrackPlayer==false)
        {
            rg.velocity = new Vector2(1 * direction * MoveSpeed, 0);
        }
        else
        {
            if (distance_ < Distance)
            {
                if(PlayerTransform.transform.position.x < transform.position.x)
                {
                    rg.velocity = new Vector2(-1 * TrackSpeed, 0);
                }else
                {
                    rg.velocity = new Vector2( 1 * TrackSpeed, 0);
                }
            }

        }
        
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if(collision.tag=="Player")
        {
            CanMove = true;
        }
       
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Player")
        {
            CanMove = false;
        }

        if (collision.tag == "bullte")
        {
            if(isinvincible==false)
            {
                animator.SetBool("current", true);
                isinvincible = true;
                isHit = true;
            }
        }

    }

    public void Current(float value)
    {
        Life_value = Life_value - value;
    }

}

AI属性面板:
Unity2D敌人/怪物AI控制 第一期_第1张图片

AI动画设置,注意动画的命名要一样,不然需要修改代码:
Unity2D敌人/怪物AI控制 第一期_第2张图片
Unity2D敌人/怪物AI控制 第一期_第3张图片
Unity2D敌人/怪物AI控制 第一期_第4张图片
Unity2D敌人/怪物AI控制 第一期_第5张图片
Unity2D敌人/怪物AI控制 第一期_第6张图片
Unity2D敌人/怪物AI控制 第一期_第7张图片
Unity2D敌人/怪物AI控制 第一期_第8张图片
Unity2D敌人/怪物AI控制 第一期_第9张图片
Unity2D敌人/怪物AI控制 第一期_第10张图片
Unity2D敌人/怪物AI控制 第一期_第11张图片
Unity2D敌人/怪物AI控制 第一期_第12张图片
Unity2D敌人/怪物AI控制 第一期_第13张图片
Unity2D敌人/怪物AI控制 第一期_第14张图片
需要注意的是,每个动画没有过度,直接切换,不然会有一些卡顿
Unity2D敌人/怪物AI控制 第一期_第15张图片
人物标签需要设置为Player
在这里插入图片描述
怪物标签需要设置为Chameleon
在这里插入图片描述
如果想让怪物之间不能够相互碰撞,让怪物和玩家间可以相互碰撞,可以给怪物AI和玩家分别设置一个碰撞层级,方法如下:
首先我们需要为人物和怪物设置分别设置一个层级,一个是人物层级,一个是怪物层级,点击Layer下拉菜单:
在这里插入图片描述
添加一个层级:
Unity2D敌人/怪物AI控制 第一期_第16张图片
接下来:
在这里插入图片描述
在编辑下拉菜单下找到Project Setting,将不想发生碰撞的两个层级较差的对勾取消掉
Unity2D敌人/怪物AI控制 第一期_第17张图片
子弹攻击,AI掉血摧毁设置:
Unity2D敌人/怪物AI控制 第一期_第18张图片
bullte为子弹,需要有boxCollider2D,勾选Is TriggerUnity2D敌人/怪物AI控制 第一期_第19张图片

你可能感兴趣的:(Unity2D,Unity,AI)