实现玩家AI



using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;//使用AI命名空间
using UnityEngine.UI;//使用UI命名空间
/// <summary>
/// 玩家角色的AI实现思路:
/// 一.自动导航:
/// 1.需要using UnityEngine.AI
/// 2.需要获得玩角色身上的导航组件
/// 二、技能释放:
/// 1.技能对应的按键
/// 2.技能对应的图标(按钮)
/// 3.按键和图标的统一(按键和点击图标是一致的)
/// 4.技能的释放、销毁
/// 5.补兵
/// 三、动画控制
/// 1.需要获得角色动画控制者
/// 2.状态控制
/// 四实现上述要求的方法:
/// 1.角色状态控制
/// 2.操作者行为控制(按键、点图标)
/// </summary>
public class WarriorControl : MonoBehaviour
{
    NavMeshAgent nav;//角色导航
    Animator ani;//角色状态控制者
    GameObject Cav_Skll;//技能按钮的父物体画布
    Button Bu_Skill1;//Q技能按钮
    Button Bu_Skill2;//W技能按钮
    Image Im_Skill1;//Q技能的Image组件(图标)
    Image Im_Skill2;//W技能的Image组件(图标
    float life;//角色生命值
    GameObject skill1;//技能1资源
    GameObject Skill1;//生成的技能1
    GameObject skill2;//技能2资源
    GameObject Skill2;//生成的技能2
    Transform SkillPos;//技能生成的位置
    float sk1time;//技能1的冷却时间
    float sk2time;//技能2的冷却时间
    Vector3 TargetPos;//角色导航的下一个位置
    GameObject Cv_P;//角色头顶血条、姓名的父物体画布
    Image Im_Blood;//血条

    // Use this for initialization
    void Start()
    {
        //导航获取
        if (GetComponent<NavMeshAgent>() == null)//如果角色身上没有导航
        {
            gameObject.AddComponent<NavMeshAgent>();//为角色添加导航
        }
        nav = GetComponent<NavMeshAgent>(); //获取角色身上导航

        //动画控制者获取
        if (GetComponent<Animator>() == null)//如果角色身上没有导航
        {
            gameObject.AddComponent<Animator>();//为角色添加导航
        }
        ani = GetComponent<Animator>(); //获取角色身上导航

        //
        Cav_Skll = GameObject.Find("CaV_Skill");
        //技能按钮
        Bu_Skill1 = Cav_Skll.transform.FindChild("Bu_Skill1").GetComponent<Button>();//获取技能1按钮组件
        Bu_Skill1.onClick.AddListener(OnClickBu_Skill1);//响应按钮1点击事件
        Bu_Skill2 = Cav_Skll.transform.FindChild("But_Skill2").GetComponent<Button>();//获取技能2按钮组件
        Bu_Skill2.onClick.AddListener(OnClickBu_Skill2);//响应按钮2点击事件

        //技能图标(冷却)
        Im_Skill1 = Cav_Skll.transform.FindChild("Bu_Skill1").GetComponent<Image>();//Q技能图标
        Im_Skill2 = Cav_Skll.transform.FindChild("But_Skill2").GetComponent<Image>();//W技能图标

        //初始化角色生命值
        life = 100;

        //加载技能效果资源
        skill1 = (GameObject)Resources.Load("MagicEffectsPackFree/prefab/skillAttack");
        skill2 = (GameObject)Resources.Load("MagicEffectsPackFree/prefab/skillAttack2");

        //技能产生位置
        SkillPos = transform.FindChild("SkillPos");

        //初始时角色播放发呆的动画
        ani.Play("Idle");

        //血条、昵称的父物体画布
        Cv_P = transform.FindChild("Cv_P").gameObject;

        //血条
        Im_Blood = Cv_P.transform.FindChild("Im_blood").GetComponent<Image>();
    }

    // Update is called once per frame
    void Update()
    {
        AddLifeControl();//调用生命值控制函数
        AIControl();//调用角色控制函数
        ReleaseSkill();//释放技能函数
        Im_Blood.fillAmount = life / 100;//血条显示的血量等于生命值/100
        Cv_P.transform.LookAt(Camera.main.transform.position);//血条、昵称时刻朝向主相机
    }
    /// <summary>
    /// 技能1按钮点击事件
    /// </summary>
    void OnClickBu_Skill1()//点击Q技能图标(和按下Q键效果一致)
    {
        if (life > 0)//在角色生命值大于0的情况下
        {
            if (Im_Skill1.fillAmount >= 1)//如果技能1图标的fillAmount大于等于1
            {
                nav.Stop();//导航暂停
                Im_Skill1.fillAmount = 0;//技能图标的fillAmount归零
                ani.Play("Attack1");//播放攻击1动画(攻击1动画Event添加了回调函数,动画快结束时生成技能特效)
            }
        }
    }
    /// <summary>
    /// 技能2按钮点击事件
    /// </summary>
    void OnClickBu_Skill2()
    {
        if (life > 0)
        {
            if (Im_Skill2.fillAmount >= 1)
            {

                nav.Stop();
                Im_Skill2.fillAmount = 0;
                ani.Play("Attack2");
            }
        }
    }
    /// <summary>
    /// 生命值控制函数1:生命自增
    /// </summary>
    void AddLifeControl()
    {
        if (life < 100&&life>0)//如果生命值小于100大于0
        {
            life += Time.deltaTime * 0.01f;//生命自增
        }
    }
    /// <summary>
    /// 生命值控制函数2:生命减少
    /// </summary>
    public void SubLifeControl(float value)
    {
        life -= value;//生命值减少量
        if (life<=0)//如果生命值小于0
        {
            ani.Play("Death");//播放死亡动画
            Destroy(gameObject, 1);//1秒后销毁角色
        }
    }
    /// <summary>
    /// AI(导航)控制
    /// </summary>
    void AIControl()
    {
        if (life > 0)//在生命值大于的前提前下
        {
            if (Input.GetMouseButtonDown(1))//按下鼠标右键
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从相机发一条射线到鼠标的右键点击点
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit))//如果射线碰到了(检测到了)点击点
                {
                    if (hit.transform.tag.Equals("terian"))//如果点击点的标签是terian(地面)
                    {
                        nav.Resume();//导航恢复
                        ani.Play("Run");//播放跑的动画
                        TargetPos = hit.point;//记录射线碰撞点(鼠标点击点)的位置
                        nav.SetDestination(TargetPos);//导航到鼠标点击点
                    }
                }
            }
            if (nav.remainingDistance <= 0.1f)//如果角色和目标点的距离小于0.1,就认为导航到了目的地
            {
                nav.Stop();//导航暂停
                ani.Play("Idle");//播放发呆动画
            }
        }
    }
/// <summary>
/// 释放技能函数
/// </summary>
    void ReleaseSkill()
    {
        if (life<=100&&life>0)//在生命值小于100大于0的前提下
        {
            if (Input.GetKeyDown(KeyCode.Q))//如果按下Q键(点击Q技能图标效果一致)
            {
                print("按下Q键");
                if (Im_Skill1.fillAmount >= 1)
                {
                    nav.Stop();
                    Im_Skill1.fillAmount = 0;
                    ani.Play("Attack1");
                    print("释放Q技能");
                }
            }

            if (Input.GetKeyDown(KeyCode.W))
            {
                if (Im_Skill2.fillAmount >= 1)
                {

                    nav.Stop();
                    Im_Skill2.fillAmount = 0;
                    ani.Play("Attack2");
                }
            }

            //两个技能图标的冷却显示
            if (Im_Skill1.fillAmount <= 1)//如果技能1图标的fillAmount小于等于1
            {
                Im_Skill1.fillAmount += Time.deltaTime;//技能1图标的fillAmount自增(1秒就冷却完毕)
            }
            if (Im_Skill2.fillAmount <= 1)
            {
                Im_Skill2.fillAmount += Time.deltaTime / 3;//3秒冷却完毕
            }
        }
      
    }
    /// <summary>
    /// 两个技能动画的回调函数
    /// </summary>
    void OnAttack1End()//攻击1动画的Event回调函数
    {
        Skill1 = Instantiate(skill1, SkillPos.position, SkillPos.rotation);//在技能生成点生成技能1
        Destroy(Skill1, 1);//一秒后销毁技能1
        ani.Play("Idle");//播放发呆动画
    }
    void OnAttack2End()
    {
        Skill2 = Instantiate(skill2, SkillPos.position, SkillPos.rotation);
        Destroy(Skill2, 1);
        ani.Play("Idle");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值