unity c# ai 随机漫游 攻击 避让

定义

        //敌人类型枚举 有策划人员选择
        public EnemyType enemyType = EnemyType.PlayerTest;
        public string enemyName;
        //平均每次随机方向持续的时间,use it's 50%-150%
        public float m_randomDirectionAvergeTime=5;


        //主角游戏对象
        private GameObject[] players;

        //敌人状态 普通状态 旋转状态 奔跑状态 追击主角状态 攻击主角状态
        private const int EMEMY_NORMAL = 0;
        private const int EMEMY_ROTATION = 1;
        private const int EMEMY_RUN = 2;
        private const int EMEMY_CHASE = 3;
        private const int EMEMY_ATTACK = 4;

        //记录当前敌人状态 根据不同类型 敌人播放不同动画
        private int state;
        //旋转状态,敌人自身旋转
        private int rotation_state;
        //记录敌人上一次思考时间
        private float aiThinkLastTime;
        //记录敌人上一次RandomDirection
        private float aiThinkRandomDirectionLastTime;
        //每次随机方向持续的时间
        public float randomDirectionTime=5;
        //the Direction setted from last think,which will be kept during randomDirectionTime
        public int randomLastDirection=0;

        public TankControl tankControl;

        //15
        public float MinShootRange=15;
        //<=30
        public float MaxShootRange=20;
        //5
        public float MaxAvoidDistance=5;
        //
        public float MaxChaseRange=25;

        public Ray shootRay;
        // A ray from the gun end forwards.
        public RaycastHit shootHit;
        // A raycast hit to get information about what was hit.
        //public int shootableMask;
        // A layer mask so the raycast only hits things on the shootable layer.

获取随机方向,并持续一个随机间隔

        float getRandomDirection ()
        {
            //start a new think
            if (Time.time - aiThinkRandomDirectionLastTime >= randomDirectionTime) {
                randomLastDirection = Random.Range (-1, 2);//it will be -1,0,1
                randomDirectionTime = m_randomDirectionAvergeTime * Random.Range(0.5f,1.5f);//start rand a new time detal for keep a direction
                aiThinkRandomDirectionLastTime = Time.time;//recorad last thinktime
                #if debug_ai_think
                Debug.Log ("randomLastDirection"+randomLastDirection+"randomDirectionTime"+randomDirectionTime);
                #endif
                return randomLastDirection * Random.Range(0.7f,1f);
            } 
            //keep last think result
            else {
                return randomLastDirection * Random.Range(0.7f,1f);
            }
        }

周期更新,提升效率

        bool isAIthank ()
        {
            //这里表示敌人每3秒进行一次思考
            if (Time.time - aiThinkLastTime >= randomDirectionTime) {
                aiThinkLastTime = Time.time;
                return true;
            }
            return false;
        }

        //更新第一种敌人的AI
        void updateEnemyTypeEasyRand ()
        {
            //判断敌人是否开始思考
            if (isAIthank ()) {
            } else {
                EmenyEasyRandAction ();
            }
        }

        //更新第二种敌人的AI
        void updateEnemyTypeNormalDiscover ()
        {
            //判断敌人是否开始思考
            if ( isAIthank () ) {
            } else {
                EmenyNormalDiscoverChase ();
                EmenyNormalDiscoverAction ();
            }
        }

执行

        #region EmenyNormalDiscover

        void EmenyNormalDiscoverChase()
        {
            foreach (GameObject player in players)
            {
                #if debug_ai
                Debug.Log ("player"+player+"Distance:"+Vector3.Distance (player.transform.position, this.transform.position));
                #endif

                if (Vector3.Distance (player.transform.position, this.transform.position) <= MaxChaseRange) {
                    //在追击范围内
                    //转向敌人
                    this.transform.LookAt (player.transform);
                    if (Vector3.Distance (player.transform.position, this.transform.position) >= MaxShootRange) {
                        //射程之外 前进追击
                        //tankControl.MoveControl (1, 0);
                        state = EMEMY_CHASE;
                    } else if (Vector3.Distance (player.transform.position, this.transform.position) <= MinShootRange) {
                        //太近了,需要后退
                        tankControl.MoveControl (-1, 0);
                        state = EMEMY_NORMAL;
                    } 
                    else 
                    {   //可以射击
                        state=EMEMY_ATTACK;
                    }

                } else 
                {
                    state = getRandom (5);//Random.Range (0, 5);
                }
            }
        }

        //随机行驶,发现目标攻击
        void EmenyNormalDiscoverAction ()
        {
            // Set the shootRay so that it starts at the end of the gun and points forward from the barrel.
            shootRay.origin = transform.position;
            shootRay.direction = transform.forward;

            // Perform the raycast against gameobjects on the shootable layer and if it hits something...
            //, shootableMask
            if (Physics.Raycast (shootRay, out shootHit, MaxShootRange)) {
                //人类 控制的坦克 有tankshooting
                //Debug.Log ("Raycast"+shootHit.collider.gameObject.name);
                if (shootHit.collider.GetComponent<TankShooting> ()) {
                    //float rangetoamney = Mathf.InverseLerp (MinShootRange, MaxShootRange, shootHit.distance);
                    #if debug_ai
                    //Debug.Log ("shootHit.distance"+shootHit.distance+"rangetoamney:"+rangetoamney);
                    #endif
                    tankControl.Fire ();//rangetoamney
                    return;
                    //setEmemyState(EMEMY_ATTACK);

                } else if (shootHit.distance < MaxAvoidDistance) {
                    //Debug.Log ("obstacle or barrier");
                    tankControl.MoveControl (0, Random.Range (-1, 2));//tankControl.MoveControl (0, -1);
                    return;
                } else {
                }

            }
            //state = Random.Range (0, 5);
            //Debug.Log (state);
            #if debug_ai
            //state=0;
            #endif
            switch (state) {
            case EMEMY_NORMAL:
                break;
            case EMEMY_ROTATION:
                //旋转状态时 敌人开始旋转, 旋转时间为1秒 这样更加具有惯性
                //transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, rotation_state * 90, 0), Time.deltaTime * 1);
                //tankControl.MoveControl (0, Random.Range (-1, 2));
                tankControl.MoveControl (0, getRandomDirection() );
                //Debug.Log ("rotation");
                break;
            case EMEMY_RUN:
                //奔跑状态,敌人向前奔跑
                // transform.Translate(Vector3.forward * 0.02f);
                tankControl.MoveControl (0.5f, 0);
                //Debug.Log ("run");
                break;
            case EMEMY_CHASE:
                //追击状态 敌人向前开始追击
                // transform.Translate(Vector3.forward * 0.02f);
                //Debug.Log ("chase");
                tankControl.MoveControl (1, 0);
                break;
            default:
                //Debug.Log ("defalut");
                //tankControl.MoveControl ( Random.Range(0,1), 0);
                break;
            }

        }
        #endregion
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页