public void addSoldier(XLSpriteBase soldier) { if (soldier == null) { return; } if (soldier._data.Country == Defaults.Country.Enemy) { if (!_enemySoldiers.Contains(soldier)) { _enemySoldiers.Add(soldier); } } bool isSelf = (soldier.Country == Defaults.Country.Me || soldier.Country == Defaults.Country.Friend); if (isSelf) { if (!_selfSoldiers.Contains(soldier)) { _selfSoldiers.Add(soldier); } } }
/// <summary> /// 逻辑更新 /// </summary> public override void update() { if(_target == null) // 是否没有目标 { _host.walkStop(); _target = SpriteMgr.getInstance().getCloselyMatchSprite(_host, null); if(_target != null) { _targetPostion = new Vector3(_target.transform.position.x, _target.transform.position.y, _target.transform.position.z); _oldPositionCount = 0; _dodgeStartPosition = new Vector3(_host.transform.position.x, _host.transform.position.y, _host.transform.position.z); //设置寻路的目标点 _navmeshAgent.SetDestination(_targetPostion); // 如果带转向就过于愣了,所以注视掉 // _host.transform.LookAt(new Vector3(_targetPostion.x, _host.transform.position.y, _targetPostion.z)); } return; } // 没在避让 if (_dodgeFrameCount == 0) { _oldPositionCount++; if (_oldPositionCount > CHECK_MOVE_FRAME_COUNT) // 数帧检测移动量 { float moveDistance = Vector3.Distance(_host.transform.position, _dodgeStartPosition); if(moveDistance<3.0f) // 移动量太小 { // 一半概率向左 if (Random.value<0.5f) { _dodgeTargetPosition = _host.DodgeLeftPostion; } else // 一半概率向右 { _dodgeTargetPosition = _host.DodgeRightPostion; } _navmeshAgent.SetDestination(_dodgeTargetPosition); //转向 _host.transform.LookAt(new Vector3(_dodgeTargetPosition.x, _host.transform.position.y, _dodgeTargetPosition.z)); _dodgeFrameCount = DODGE_FRAME_COUNT_MAX; } _oldPositionCount = 0; _dodgeStartPosition = new Vector3(_host.transform.position.x, _host.transform.position.y, _host.transform.position.z); } } else // 避让中 { _dodgeFrameCount--; if (_dodgeFrameCount == 0) { _target = null; return; } float dis = Vector3.Distance(_host.transform.position, _dodgeTargetPosition); if (dis<0.2) { _target = null; return; } return; } // 判断目标距离<攻击距离的时候,就可以结束了 float hostToTargetDistance = Vector3.Distance(_host.transform.position, _targetPostion); _host._data.AttckDistance = 4f; if (hostToTargetDistance <= _host._data.AttckDistance) { _host.walkStop(); notifyEvent(EVENT_CHANGE_TO_ATTACK, _target); return; } }
/// <summary> /// 初始化 /// </summary> public override void init() { _target = null; //播放移动动作 _host.GetComponent<Animator>().Play("run01"); _host.walkStop(); _host.walkEnable(); }
/// <summary> /// 获取距离我最近的对手 /// </summary> /// <param name="sprite"></param> /// <returns></returns> public XLSpriteBase getCloselyMatchSprite1(XLSpriteBase sprite, XLSpriteBase ignoreSprite) { if (sprite == null) { return null; } List<XLSpriteBase> matchSprites = null; if (sprite.Country == Defaults.Country.Enemy) { matchSprites = _selfSoldiers; } else if(sprite.Country == Defaults.Country.Me || sprite.Country == Defaults.Country.Friend){ matchSprites = _enemySoldiers; } if(matchSprites == null){ return null; } XLSpriteBase ret = null; float retDistance = -1; List<float> distArray = new List<float>(matchSprites.Count); //float[] distArray = new float[matchSprites.Count]; float maxDist = 100000f; float totalHP = 0; for (int i = 0; i < matchSprites.Count; i++) { XLSpriteBase matchSprite = matchSprites[i]; if (!matchSprite.isCanBeTarget()) { distArray.Add(maxDist); continue; } // 如果对手就只有一个那就不用换目标了 && 更换目标 if (matchSprites.Count>1 && matchSprite == ignoreSprite) { distArray.Add(maxDist); continue; } float matchDistance = Vector3.Distance(sprite.transform.position, matchSprite.transform.position); distArray.Add(matchDistance); totalHP += matchSprite._data.HP; } // 对距离进行排序,然后在距离最短的几个里面找一个血量最小的攻击 var sorted = distArray.Select((x, i) => new KeyValuePair<float, int>(x, i)).OrderBy(x => x.Key).ToList(); List<float> sortedDistArray = sorted.Select(x => x.Key).ToList(); List<int> idx = sorted.Select(x => x.Value).ToList(); float minRatio = 1; //if (sprite._data.Country == Defaults.Country.Me) // 只有我方士兵才适用这种寻敌方式 if(true) // 双方士兵都用这种寻敌方式 { //Debug.Log("xueliang--------"); for (int i = 0; i < Math.Min(8, distArray.Count); i++) // 以8人为小组单位,在里面选一个血量最小的士兵进行攻击。 { float ratio = (float)matchSprites[idx[i]]._data.HP / (float)sprite._data.HP; // *UnityEngine.Random.Range(0.1f, 1); if (ret == null || ratio < minRatio) { ret = matchSprites[idx[i]]; minRatio = ratio; continue; } } } else { ret = matchSprites[idx[0]]; } // 调试用的,用来显示最后有多少士兵存活,总共还剩多少血量 //string strTotal = String.Format("#.{0},HP={1}", matchSprites.Count, totalHP); //if(matchSprites[0]._data.Country != Defaults.Country.Me) // Debug.Log(strTotal); return ret; }
/// <summary> /// 获取距离我最近的对手 /// </summary> /// <param name="sprite"></param> /// <returns></returns> public XLSpriteBase getCloselyMatchSprite(XLSpriteBase sprite, XLSpriteBase ignoreSprite) { if (sprite == null) { return null; } List<XLSpriteBase> matchSprites = null; if (sprite.Country == Defaults.Country.Enemy) { matchSprites = _selfSoldiers; } else if (sprite.Country == Defaults.Country.Me || sprite.Country == Defaults.Country.Friend) { matchSprites = _enemySoldiers; } if (matchSprites == null) { return null; } XLSpriteBase ret = null; float retDistance = -1; for (int i = 0; i < matchSprites.Count; i++) { XLSpriteBase matchSprite = matchSprites[i]; if (!matchSprite.isCanBeTarget()) { continue; } // 如果对手就只有一个那就不用换目标了 && 更换目标 if (matchSprites.Count > 1 && matchSprite == ignoreSprite) { continue; } float matchDistance = Vector3.Distance(sprite.transform.position, matchSprite.transform.position); if (ret == null || matchDistance < retDistance) { ret = matchSprite; retDistance = matchDistance; continue; } } return ret; }