unity多人副本中 某敌人攻击某角色

 EnemyCtrl.cs   此脚本是挂在敌人(怪物)身上 


 下面重点分析一下,这个脚本中的Update函数

    void Update()
    {
        Collider[] colliders =Physics.OverlapSphere(transform.position, _chaseDistance, LayerMask.GetMask("Player"));  //搜寻角色
        print(colliders.Length);
        float minDistance = _chaseDistance;
        if (colliders.Length > 0)
        {
            for (int i = 0; i < colliders.Length; i++)  //通过此次遍历,找到离自己最近的角色
            {
                print(gameObject.name +"     :     "+ colliders[i].gameObject.name);
                float distance = Vector3.Distance(transform.position, colliders[i].transform.position);
                if (distance < minDistance)
                {
                    minDistance = distance;
                    if (colliders[i].GetComponent<OtherPlayer>() != null)
                    {
                        _userDto = colliders[i].GetComponent<OtherPlayer>().OtherUserDto;
                    }
                    else
                    {
                        _userDto = Global.Instance.UserDto;
                    }
                    if (_userDto.Hp >= 0)
                    {
                        _target = colliders[i].gameObject;
                    }
                    else
                    {
                        _target = null;
                    }
                }
            }
        }
        else
        {
            minDistance = _chaseDistance;
        }

        if (_target != null)
        {
            if (minDistance < _chaseDistance)
            {
                if (minDistance < _attackDistance) //适合攻击
                {
                    _timer += Time.deltaTime;
                    if (_timer > _attackRate)  //每隔几秒进行一次攻击
                    {
                        if (_userDto.Hp <= 0)
                        {
                            Anim.CrossFade("Idle");
                            return;
                        }
                        Attack(_target); 
                    }
                }
                else //发现敌人,但是有没有在攻击范围内,就朝向敌人方向移动 
                {
                    Move(_target);
                }
            }
            else
            {
                Anim.CrossFade("Idle");
                _target = null;
            }
        }
        else
        {
            Anim.CrossFade("Idle");
            _target = null;
        }
    }

//   public const int RAID_ENEMY_FIGHT_CREQ = 30;
 public void Attack(GameObject target)
    {
        _timer = 0;
        transform.LookAt(target.transform);  //面向玩家
        Anim.CrossFade("Attack1");  //播放攻击动画
        RaidEnemyAttackDTO attackDto =new RaidEnemyAttackDTO(RaidHandler.Instance.RaidDto.Code, EnemyDto.Code,EnemyDto.Attack,"Attack1",_userDto, false); //保存攻击信息
        this.Write(Protocol.TYPE_RAID,-1,RaidProtocol.RAID_ENEMY_FIGHT_CREQ, attackDto); //发送给服务器
    }

 RaidEnemyAttackDTO   构造函数:

 public RaidEnemyAttackDTO(int id,int code,int harm,string name,UserDTO dto,bool isDeath)
 {
            this.RaidId = id;
            this.EnemyCode = code;
            this.Harm = harm;
            this.AnimName = name;
            this.Player = dto;
            this.IsDeath = isDeath;
 }

下面看一下服务器:





        private void RaidEnemyFight(UserToken userToken, RaidEnemyAttackDTO enemyAttackDto)
        {
            if (!_raidDtos.ContainsKey(enemyAttackDto.RaidId)) return;
            RaidDTO raidDto = _raidDtos[enemyAttackDto.RaidId];
            if(enemyAttackDto.Player==null) return;
            UserDTO[] userDtos = raidDto.Players;
            for (int i = 0; i < userDtos.Length; i++)
            {
                if (userDtos[i].Id == enemyAttackDto.Player.Id) //此次攻击的玩家
                {
                    if(userDtos[i].Hp<=0)return;
                    bool isDeath = false;
                    bool allDeath = false;
                    int value = enemyAttackDto.Harm - (userDtos[i].Def/100);//扣掉敌方的防御,算出本次对敌的伤害
                    userDtos[i].Hp -= value;  //敌人减血

                    List<int> teamMemberIdlist = new List<int>();
                    foreach (UserDTO userDto in userDtos)
                    {
                        teamMemberIdlist.Add(userDto.Id);  //找出副本中所有的玩家
                    }

                    if (userDtos[i].Hp <= 0) //判断敌人是否死亡
                    {
                        isDeath = true;
                        for (int j = 0; j < raidDto.Players.Length; j++)  //判断敌方所有成员是否死亡
                        {
                            if (raidDto.Players[j].Hp > 0)
                            {
                                allDeath = false;
                                break;
                            }
                            else
                            {
                                allDeath = true;
                            }
                        }
                    }

                    RaidEnemyAttackDTO attackDto = new RaidEnemyAttackDTO(raidDto.Id, enemyAttackDto.EnemyCode,value,enemyAttackDto.AnimName, userDtos[i], isDeath);

                    if (userDtos.Length > 1) //多人副本
                    {
                        this.Write(teamMemberIdlist.ToArray(), Protocol.TYPE_RAID, -1, RaidProtocol.RAID_ENEMY_FIGHT_BRO,
                            attackDto); //发送数字:32
                    }
                    else  //单人副本
                    {
                        this.Write(userToken, Protocol.TYPE_RAID, -1, RaidProtocol.RAID_ENEMY_FIGHT_SRES, attackDto); //发送数字:31
                    }


                    if (allDeath) //副本中所有玩家都死了
                    {
                        this.Write(teamMemberIdlist.ToArray(), Protocol.TYPE_RAID, 0, RaidProtocol.RAID_DEATH_SRES, null); //发送数字:42
                    }

                    break;
                }
            }
        }

客户端:





或:




 下面是本次副本中的所有玩家都死了:

客户端:


服务器





    public event OnPlayerInfoChanged OnPlayerInfoChange;  这个是个事件,玩家信息改变的时候,及时的通知UI更新数字




FR:海涛高软(hunk Xu)
QQ技术交流群:386476712

猜你喜欢

转载自blog.csdn.net/qq_15267341/article/details/85937132
今日推荐