Unity2D 敌人追踪/攻击/移动AI 第二期

Posted Z_hongli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity2D 敌人追踪/攻击/移动AI 第二期相关的知识,希望对你有一定的参考价值。

AI功能简介:这个AI是在第一期的基础上进行修改后的AI,第一期的AI不能够自动追踪Palyer,只能够停留在原地不动,现在能够去自动追踪主角,只要进入了追踪范围内,就会一直追踪玩家,直至玩家离开追踪范围或被消灭,相关代码如下,操作与第一期相同,第一期链接如下:AI 第一期
展示:

脚本:

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

public class Bunny : MonoBehaviour

    public static Bunny bunny;
    private void Awake()
    
        bunny = 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;

    public float TrackDistance = 0;

    GameObject gm;

    bool isinvincible = false;

    public float destory_door_value = 0;

    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&&TrackPlayer)
        
            //判断玩家在怪物的哪边
            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)
        
            if (distance_ < TrackDistance)
            
                CanMove = true;
                Vector2 temp = Vector2.MoveTowards(transform.position, PlayerTransform.position, MoveSpeed * 2 * Time.deltaTime);
                //考虑到可能有碰撞检测,所以使用刚体的移动方式
                GetComponent<Rigidbody2D>().MovePosition(temp);

                //判断玩家在怪物的哪边
                if (PlayerTransform.transform.position.x < transform.position.x)
                
                    direction = -1;
                    transform.localScale = new Vector3(direction, 1, 1);
                
                else
                
                    direction = 1;
                    transform.localScale = new Vector3(direction, 1, 1);
                
            
            else
            
                rg.velocity = new Vector2(1 * direction * MoveSpeed, 0);
            
        
        else
        

            rg.velocity = new Vector2(1 * direction * MoveSpeed, 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" || collision.tag=="hammer")
        
            if (isinvincible == false)
            
                animator.SetBool("current", true);
                isinvincible = true;
                isHit = true;
            
        

    

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



以上是关于Unity2D 敌人追踪/攻击/移动AI 第二期的主要内容,如果未能解决你的问题,请参考以下文章

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

[Unity2D/3D]实用的血条制作(第二期)

unity_实用小技巧(敌人追踪主角)

Unity入门计划Unity2D动画-脚本与混合树实现玩家角色动画过渡

Unity2D实现敌人自动追击主角并判断路障

王者光耀第三次