UnityRPG系列笔记----3

敌人的AI----1

上次两次博客把主角的移动写完了,这次根据作者的顺序会开始做敌人,需要资源的可以到作者本人的百度贴吧里面下载,由于版权问题,我这里就不提供下载了。AI一直是一个游戏的灵魂,先把简单的做好以后,之后我会好好研究一下ai的一些算法。

创建一个一个Enemy脚本

using UnityEngine;
using System.Collections;
///Author:CWH
///email:cwhisme@qq.com
///date:2014.1.17
public class Enemy : MonoBehaviour
{
    #region 属性
    public string m_name;//名字
    public int m_level;//等级,以判断角色应当获取的经验
    public int m_maxLife;//生命
    public int m_currentLife;//当前生命
    public int m_defense;//防御力
    public int m_attack;//攻击力
    public float m_speed;//速度
    public int m_rotateSpeed;//旋转速度
    public float m_attackRadius;//攻击半径
    #endregion
    #region 对象
    public Transform m_transform;//自己
    protected Animation m_animation;//动画组件
    public Transform m_attackTarget;//攻击对象
    public BattleChange m_damageTarget;//伤害对象

    private BattleChange m_changeState;//战斗时改变生命等属性脚本对象
    protected Rigidbody m_rigidbody;


    #endregion

    #region 判断
    public bool m_isBoss=false;
    protected bool m_isIdle=true;
    protected bool m_isDead=false;

    #endregion

    #region 变量
    protected int m_idleStat;//定义空闲状态动画的随机值
    protected float m_idleTime=0;//每一个空闲状态持续时间
    ///声音
    public AudioClip m_sound;
    public AudioClip m_attackSound;
    public AudioClip m_skillSound;


    protected Vector3 m_forward;//敌人的前方向
    protected RaycastHit m_hit;//射线碰撞
    protected float m_attackDistance=8;//会攻击的视线距离
    protected LayerMask m_layerMask;
    protected float m_distanceToOther;//与攻击对象的距离
    public Transform m_attackParticle;//普通攻击粒子效果
    public Transform m_skillParticle;//技能攻击粒子效果

    protected float m_attackDelay=2;//攻击延时
    protected float m_skillRandom;//随机出现技能

    #endregion

    #region 动画状态
    protected string m_animationIdle="idle1";
    protected string m_animationIdle2="idle2";
    protected string m_animationIdle3="idle3";
    protected string m_animationWalk="walk";
    protected string m_animationAttack="attack";
    protected string m_animationSkill="skill";
    protected string m_animationDeath="death";
    #endregion





    void Start () {


        ///加刚体设置
        //m_rigidbody = (Rigidbody)m_transform.gameObject.AddComponent("Rigidbody");
        ///m_rigidbody.freezeRotation = true;

        Init();


        m_transform=this.transform;//获取自己对象
        m_animation=GetComponent<Animation>();
        m_layerMask=1<<LayerMask.NameToLayer("Human");

        //m_layerMask=LayerMask.NameToLayer("Human");
        m_changeState=GetComponent<BattleChange>();
        m_changeState.m_defense=m_defense;
        m_changeState.m_life=m_currentLife;







    }

    protected void SetAttribute(string name,int level,int Life,int defense,int attack,int speed,int rotatteSpeed,float attackRadius)
    {
        m_name=name;
        m_level=level;
        m_maxLife=Life;
        m_currentLife=Life;
        m_defense=defense;
        m_attack=attack;
        m_speed=speed;
        m_rotateSpeed=rotatteSpeed;
        m_attackRadius=attackRadius;


    }

    protected virtual void Init()
    {
    }

    void Update () {



        if(m_isIdle)
        {
            m_idleTime-=Time.deltaTime;
            if(m_idleTime<0)///空闲随机时间到了就随机做出新动作
            {
                m_idleStat=Random.Range(0,11);
                audio.clip=m_sound;
                audio.Play();
                m_idleTime=3;
            }
        }else if(m_isDead){
            //Debug.Log("is Dead");
        }else{
            RotateTo();
            Attack();

        }

        switch(m_idleStat)
        {
        case 1:m_animation.CrossFade(m_animationIdle);
            audio.clip=m_sound;
            audio.Play();
            break;
        case 2:m_animation.CrossFade(m_animationIdle);
            m_transform.Rotate(0,m_rotateSpeed*Time.deltaTime,0);
            break;
        case 3:m_animation.CrossFade(m_animationIdle2);
            break;
        case 4:m_animation.CrossFade(m_animationIdle2);
            break;
        case 5:m_animation.CrossFade(m_animationWalk);
            m_transform.Rotate(0,m_rotateSpeed*Time.deltaTime,0);
            break;
        case 6:m_animation.CrossFade(m_animationWalk);
            m_transform.Rotate(0,m_rotateSpeed*Time.deltaTime,0);
            break;
        case 7:m_animation.CrossFade(m_animationWalk);
            m_transform.Rotate(0,m_rotateSpeed*Time.deltaTime,0);
            break;
        case 8:m_animation.CrossFade(m_animationWalk);
            m_transform.Translate(Vector3.forward*m_speed*Time.deltaTime);
            break;
        default:m_animation.CrossFade(m_animationIdle3);
            m_transform.Translate(Vector3.forward*m_speed*Time.deltaTime);
            break;
        }



        m_forward = m_transform.TransformDirection(Vector3.forward);

        if (Physics.Raycast(m_transform.position + Vector3.up, m_forward, out m_hit, m_attackDistance, m_layerMask))
        {


            m_attackTarget=m_hit.collider.gameObject.transform;//如果看见任何人类对象,就获取其位置,并将Idle状态置为false
            if(m_attackTarget.GetComponent<BattleChange>().m_life!=0)
            {
                m_isIdle=false;
            }
        }

        GetState();




    }

    protected void RotateTo()
    {
        Vector3 m_oldAngle=m_transform.eulerAngles;//当前旋转角度
        m_transform.LookAt(m_attackTarget.position);//盯着攻击对象
        float m_target=m_transform.eulerAngles.y;//目标角度吧
        float m_targetAngle=Mathf.MoveTowardsAngle(m_oldAngle.y,m_target,m_rotateSpeed*Time.deltaTime);//计算应转动的角度
        m_transform.eulerAngles=new Vector3(0,m_targetAngle,0);//转动角度
    }

    protected void Attack()
    {
        m_distanceToOther=Vector3.Distance(m_transform.position,m_attackTarget.position);

        m_attackDelay-=Time.deltaTime;
        if(m_distanceToOther<m_attackRadius)///目标进入攻击半径,攻击
        {
            if(m_attackDelay<0)
            {
                m_forward=m_transform.TransformDirection(Vector3.forward);
///             if(Physics.Raycast(m_transform.position+Vector3.up,m_forward,out m_hit,m_attackRadius,m_layerMask))
///             {
///                 m_animation.CrossFade(m_animationAttack);
///                 Instantiate(m_attackParticle,m_hit.collider.gameObject.transform.position+Vector3.up,Quaternion.identity);//攻击,实例化一个粒子
///                 m_attackDelay=2;//攻击成功,重置延时
///             }



                if(Physics.Raycast(m_transform.position+Vector3.up,m_forward,out m_hit,m_attackRadius,m_layerMask))
                {
                    m_skillRandom=Random.value;
                    if(m_skillRandom<0.96f)///大概有4%的几率发出技能
                    {
                        m_animation.CrossFade(m_animationAttack);

                        m_damageTarget=m_hit.collider.gameObject.GetComponent<BattleChange>();
                        StartCoroutine(WaitForAttack(0.6f,m_attackParticle,m_attackSound,m_attack));


                        if(m_damageTarget.m_isDead)///如果攻击目标死掉了的话,就回到Idle状态吧
                        {
                            m_isIdle=true;
                        }
                        if(m_currentLife==0){
                            m_isDead=true;
                        }
                    }else
                    {
                        m_animation.CrossFade(m_animationSkill);

                        m_damageTarget=m_hit.collider.gameObject.GetComponent<BattleChange>();
                        StartCoroutine(WaitForAttack(0.6f,m_attackParticle,m_attackSound,m_attack*3));
                        if(m_damageTarget.m_isDead)///如果攻击目标死掉了的话,就回到Idle状态吧
                        {
                            m_isIdle=true;
                        }
                        if(m_currentLife==0){
                            m_isDead=true;
                        }
                    }
                    m_attackDelay=2;
                }

            }
        }else if(m_distanceToOther<20)///如果距离小于20,对目标进行追击
        {
            m_animation.CrossFade(m_animationWalk);
            m_transform.Translate(Vector3.forward*m_speed*Time.deltaTime);
        }else if(m_distanceToOther<90)/// 如果距离大于20,就回到Idle状态,不追目标了
        {
            m_isIdle=true;
        }else///超过九十米的话,为了省点资源,就把这个敌人销毁罢
        {
            Destroy(this.gameObject);
        }

    }


    void GetState()
    {

            m_currentLife=m_changeState.m_life;



    }

    IEnumerator WaitForAttack(float timer,Transform particle,AudioClip m_audio,int attack)
    {

        yield return new WaitForSeconds(timer); 
        Instantiate(particle ,m_damageTarget.transform.position+Vector3.up,Quaternion.identity);
        audio.PlayOneShot(m_audio);//播放声音
        m_damageTarget.Damage(attack);//调用对象的伤害函数
        if(m_damageTarget.m_isDead)///如果攻击目标死掉了的话,就回到Idle状态吧
        {
            m_isIdle=true;
        }
    }




}

一开始代码可能比较多,所以尽量贴出代码,但是要照着做就比较麻烦了,敌人的内容会在下一节继续说下去,有看过的朋友或者做这有疑问的朋友可以留言大家一起交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值