unity多人副本中 某敌人攻击某角色
程序员文章站
2022-04-09 10:52:51
EnemyCtrl.cs 此脚本是挂在敌人(怪物)身上下面重点分析一下,这个脚本中的Update函数 void Update() { Collider[] colliders =Physics.OverlapSphere(transform.position, _chaseDistance, LayerMask.GetMask("Player......
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
本文地址:https://blog.csdn.net/qq_15267341/article/details/85937132
上一篇: 离职 需要注意三个问题