480 lines
16 KiB
C#
480 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using DG.Tweening;
|
|
|
|
namespace BF
|
|
{
|
|
public class BattleManager : ManagerBase
|
|
{
|
|
public BattlePool PoolHelper { get; private set; }
|
|
private bool battleStart = false;
|
|
public bool UpdateEnabled { get; private set; }
|
|
public GameObject BattleRoot { get; private set; }
|
|
private Vector2 vector2A = Vector2.zero;
|
|
private Vector2 vector2B = Vector2.zero;
|
|
private BattleControlHero MainHero;
|
|
private Camera uiCamera;
|
|
private Camera battleCamera;
|
|
private GameObject numberRoot;
|
|
private RectTransform hpBarRootTransform;
|
|
private RectTransform skillToastRootTransform;
|
|
public List<BattleControlUnit> AtkUnitsList = new List<BattleControlUnit>();
|
|
public List<BattleControlUnit> DefUnitsList = new List<BattleControlUnit>();
|
|
public bool IsAutoUpdateNumberRootPosition = false;
|
|
private Action<int, int, float, float> luaOnPlayFxFunc;
|
|
private Action<int, int> luaOnWarningHeroNumChangedFunc;
|
|
private Action<int, int> luaOnWarningNumChangedFunc;
|
|
private HashSet<int> effectHeroWarningSet = new HashSet<int>(); // 包含了玩家的所有预警
|
|
private HashSet<int> effectWarningSet = new HashSet<int>(); // 场上显示的预警
|
|
private HashSet<BattleSkillToast> skillToastSet = new HashSet<BattleSkillToast>();
|
|
|
|
#region override
|
|
static BattleManager instance;
|
|
public static BattleManager Create()
|
|
{
|
|
BFLog.LogAssert(instance == null, "This method only allows BFMain to call once");
|
|
instance = new BattleManager();
|
|
return instance;
|
|
}
|
|
BattleManager() { }
|
|
|
|
public override void Init()
|
|
{
|
|
base.Init();
|
|
|
|
PoolHelper = new BattlePool();
|
|
}
|
|
|
|
public override void Destroy()
|
|
{
|
|
base.Destroy();
|
|
instance = null;
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
base.Update();
|
|
if(!UpdateEnabled)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
public override void SetMono(MonoBehaviour mono)
|
|
{
|
|
base.SetMono(mono);
|
|
}
|
|
#endregion
|
|
|
|
public void InitBattle(Transform sceneNode, Camera uiCamera, Camera battleCamera)
|
|
{
|
|
if (ReferenceEquals(BattleRoot, null))
|
|
{
|
|
BattleRoot = new GameObject(BattleConst.BATTLE_ROOT_NAME);
|
|
}
|
|
BattleRoot.transform.SetParent(sceneNode, false);
|
|
PoolHelper.SetSceneNode(BattleRoot.transform);
|
|
PoolHelper.Init();
|
|
this.uiCamera = uiCamera;
|
|
this.battleCamera = battleCamera;
|
|
BattleConfigure.BattleCenterPosX = 0.0f;
|
|
}
|
|
|
|
public void SetMainHero(BattleControlHero mainHero)
|
|
{
|
|
MainHero = mainHero;
|
|
}
|
|
|
|
public void StartFight()
|
|
{
|
|
battleStart = true;
|
|
UpdateEnabled = true;
|
|
}
|
|
|
|
public void EndFight()
|
|
{
|
|
battleStart = false;
|
|
UpdateEnabled = false;
|
|
}
|
|
|
|
public void PauseFight()
|
|
{
|
|
UpdateEnabled = false;
|
|
PoolHelper.Pause();
|
|
BattleHelper.Pause();
|
|
}
|
|
|
|
public void ResumeFight()
|
|
{
|
|
UpdateEnabled = true;
|
|
PoolHelper.Resume();
|
|
BattleHelper.Resume();
|
|
}
|
|
|
|
public void SetShadow(GameObject shadow)
|
|
{
|
|
PoolHelper.SetShadow(shadow);
|
|
}
|
|
|
|
public void SetHpBar(GameObject hpBarRoot, GameObject hpAtk, GameObject hpDef)
|
|
{
|
|
hpBarRootTransform = hpBarRoot.transform as RectTransform;
|
|
PoolHelper.SetHpBar(hpAtk, hpDef, hpBarRoot.transform);
|
|
}
|
|
|
|
public void SetSkillToast(GameObject skillToastRoot, GameObject skillToast)
|
|
{
|
|
skillToastRootTransform = skillToastRoot.transform as RectTransform;
|
|
PoolHelper.SetSkillToast(skillToast, skillToastRoot.transform);
|
|
}
|
|
|
|
public void ShowNormalSkillToast(string iconName, string str, float x, float y, float z, float addY)
|
|
{
|
|
var skillToast = PoolHelper.GetSkillToast();
|
|
skillToast.transform.SetAsLastSibling();
|
|
skillToast.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
|
|
skillToast.ShowNormalSkillToast(iconName, str);
|
|
var screenPosition = battleCamera.WorldToScreenPoint(new Vector3(x, y, z));
|
|
Vector2 lp;
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(this.skillToastRootTransform.transform as RectTransform, new Vector2(screenPosition.x, screenPosition.y), uiCamera, out lp);
|
|
var rectTransform = skillToast.transform as RectTransform;
|
|
rectTransform.anchoredPosition = new Vector2(lp.x, lp.y + addY);
|
|
|
|
skillToastSet.Add(skillToast);
|
|
}
|
|
|
|
public void ShowLegacySkillToast(string qltName, string iconName, string str, float x, float y, float z, float addY)
|
|
{
|
|
var skillToast = PoolHelper.GetSkillToast();
|
|
skillToast.transform.SetAsLastSibling();
|
|
skillToast.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
|
|
skillToast.ShowLegacySkillToast(qltName, iconName, str);
|
|
var screenPosition = battleCamera.WorldToScreenPoint(new Vector3(x, y, z));
|
|
Vector2 lp;
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(this.skillToastRootTransform.transform as RectTransform, new Vector2(screenPosition.x, screenPosition.y), uiCamera, out lp);
|
|
var rectTransform = skillToast.transform as RectTransform;
|
|
rectTransform.anchoredPosition = new Vector2(lp.x, lp.y + addY);
|
|
|
|
skillToastSet.Add(skillToast);
|
|
}
|
|
|
|
public void RemoveSkillToastSet(BattleSkillToast skillToast)
|
|
{
|
|
skillToastSet.Remove(skillToast);
|
|
}
|
|
|
|
public void SetEffectTextParent(GameObject numberRoot, GameObject effectText, GameObject effectTextRed, GameObject effectTextGreen, GameObject effectTextYellow)
|
|
{
|
|
this.numberRoot = numberRoot;
|
|
PoolHelper.SetEffectText(effectText, effectTextRed, effectTextGreen, effectTextYellow, numberRoot.transform);
|
|
IsAutoUpdateNumberRootPosition = true;
|
|
}
|
|
|
|
public void ShowEffectNumber(int colorType, int effectType, string effectNumber, float x, float y, float z, float addY)
|
|
{
|
|
var effectText = PoolHelper.GetEffectText(colorType);
|
|
effectText.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
|
|
effectText.ShowEffectNumber(effectType, effectNumber);
|
|
var screenPosition = battleCamera.WorldToScreenPoint(new Vector3(x, y, z));
|
|
Vector2 lp;
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(this.numberRoot.transform as RectTransform, new Vector2(screenPosition.x, screenPosition.y), uiCamera, out lp);
|
|
var rectTransform = effectText.transform as RectTransform;
|
|
rectTransform.anchoredPosition = new Vector2(lp.x, lp.y + addY);
|
|
}
|
|
|
|
public void UpdateEffectTextRootNode()
|
|
{
|
|
if (IsAutoUpdateNumberRootPosition)
|
|
{
|
|
numberRoot.transform.localPosition = new Vector3(-BattleConfigure.BattleCenterPosX * BattleConfigure.WorldToScreenWidth, 0.0f, 0.0f);
|
|
}
|
|
}
|
|
|
|
public void UpdateUIPosition(Vector3 worldPosition, float addY, RectTransform uiTransform)
|
|
{
|
|
var screenPosition = battleCamera.WorldToScreenPoint(worldPosition);
|
|
Vector2 lp;
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(hpBarRootTransform, new Vector2(screenPosition.x, screenPosition.y), uiCamera, out lp);
|
|
uiTransform.anchoredPosition = new Vector2(lp.x, lp.y + addY);
|
|
}
|
|
|
|
public void AddLuaOnPlayFxFunc(Action<int, int, float, float> luaFunc)
|
|
{
|
|
luaOnPlayFxFunc = luaFunc;
|
|
}
|
|
|
|
public void PlayFx(int fxId, int direction, float x, float z)
|
|
{
|
|
luaOnPlayFxFunc?.Invoke(fxId, direction, x, z);
|
|
}
|
|
|
|
public void AddLuaOnWarningHeroNumChangedFunc(Action<int, int> luaFunc)
|
|
{
|
|
luaOnWarningHeroNumChangedFunc = luaFunc;
|
|
}
|
|
|
|
public void WarningHeroNumChanged(int changedNum, int totalNum)
|
|
{
|
|
luaOnWarningHeroNumChangedFunc?.Invoke(changedNum, totalNum);
|
|
}
|
|
|
|
public void AddEffectHeroWarning(int uniqueId)
|
|
{
|
|
var success = effectHeroWarningSet.Add(uniqueId);
|
|
if (success)
|
|
{
|
|
WarningHeroNumChanged(1, GetEffectHeroWarningCount());
|
|
}
|
|
}
|
|
|
|
public void RemoveEffectHeroWarning(int uniqueId)
|
|
{
|
|
var success = effectHeroWarningSet.Remove(uniqueId);
|
|
if (success)
|
|
{
|
|
WarningHeroNumChanged(-1, GetEffectHeroWarningCount());
|
|
}
|
|
}
|
|
|
|
public int GetEffectHeroWarningCount()
|
|
{
|
|
return effectHeroWarningSet.Count;
|
|
}
|
|
|
|
public void AddLuaOnWarningNumChangedFunc(Action<int, int> luaFunc)
|
|
{
|
|
luaOnWarningNumChangedFunc = luaFunc;
|
|
}
|
|
|
|
public void WarningNumChanged(int changedNum, int totalNum)
|
|
{
|
|
luaOnWarningNumChangedFunc?.Invoke(changedNum, totalNum);
|
|
}
|
|
|
|
public void AddEffectWarning(int uniqueId)
|
|
{
|
|
var success = effectWarningSet.Add(uniqueId);
|
|
if (success)
|
|
{
|
|
WarningNumChanged(1, GetEffectWarningCount());
|
|
}
|
|
}
|
|
|
|
public void RemoveEffectWarning(int uniqueId)
|
|
{
|
|
var success = effectWarningSet.Remove(uniqueId);
|
|
if (success)
|
|
{
|
|
WarningNumChanged(-1, GetEffectWarningCount());
|
|
}
|
|
}
|
|
|
|
public int GetEffectWarningCount()
|
|
{
|
|
return effectWarningSet.Count;
|
|
}
|
|
|
|
public void AddToAtkUnitsList(BattleControlUnit unit)
|
|
{
|
|
AtkUnitsList.Add(unit);
|
|
}
|
|
|
|
public void RemoveFromAtkUnitsList(BattleControlUnit unit)
|
|
{
|
|
AtkUnitsList.Remove(unit);
|
|
}
|
|
|
|
|
|
public void AddToDefUnitsList(BattleControlUnit unit)
|
|
{
|
|
DefUnitsList.Add(unit);
|
|
}
|
|
|
|
public void RemoveFromDefUnitsList(BattleControlUnit unit)
|
|
{
|
|
DefUnitsList.Remove(unit);
|
|
}
|
|
|
|
public List<BattleControlUnit> GetUnitsList(int side)
|
|
{
|
|
if (side == BattleConst.SIDE_ATK)
|
|
{
|
|
return DefUnitsList;
|
|
}
|
|
else
|
|
{
|
|
return AtkUnitsList;
|
|
}
|
|
}
|
|
|
|
public int GetDefUnitsCount()
|
|
{
|
|
return DefUnitsList.Count;
|
|
}
|
|
|
|
public BattleControlUnit GetNearestUnit(int side)
|
|
{
|
|
BattleControlUnit unit = null;
|
|
if (side == BattleConst.SIDE_ATK)
|
|
{
|
|
var countDef = DefUnitsList.Count;
|
|
if(countDef <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
var position = MainHero.transform.position;
|
|
vector2A.Set(position.x, position.z);
|
|
float minDis = float.MaxValue;
|
|
for(int j = 0; j < countDef; j++)
|
|
{
|
|
var objB = DefUnitsList[j];
|
|
if (!objB.IsCollisionEnabled)
|
|
{
|
|
continue;
|
|
}
|
|
vector2B.Set(objB.transform.position.x, objB.transform.position.z);
|
|
var dis = (vector2B - vector2A).sqrMagnitude;
|
|
if (dis < minDis)
|
|
{
|
|
minDis = dis;
|
|
unit = objB;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return MainHero;
|
|
}
|
|
return unit;
|
|
}
|
|
|
|
public void GetNearestDefUnit(float x, float z, out BattleControlUnit leftUnit, out BattleControlUnit rightUnit)
|
|
{
|
|
leftUnit = null;
|
|
rightUnit = null;
|
|
var count = DefUnitsList.Count;
|
|
if (count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
float leftMinX = float.MaxValue;
|
|
float rightMinX = float.MaxValue;
|
|
float leftDisZ = 0.0f;
|
|
float rightDisZ = 0.0f;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var defUnit = DefUnitsList[i];
|
|
var defX = defUnit.transform.position.x;
|
|
if (defX >= x)
|
|
{
|
|
var diffX = defX - x;
|
|
if (Mathf.Abs(diffX - rightMinX) < 0.000001f)
|
|
{
|
|
var newDisZ = Mathf.Abs(defUnit.transform.position.z - z);
|
|
if (newDisZ < rightDisZ)
|
|
{
|
|
rightMinX = diffX;
|
|
rightDisZ = newDisZ;
|
|
rightUnit = defUnit;
|
|
}
|
|
}
|
|
else if (diffX < rightMinX)
|
|
{
|
|
rightMinX = diffX;
|
|
rightDisZ = Mathf.Abs(defUnit.transform.position.z - z);
|
|
rightUnit = defUnit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var diffX = x - defX;
|
|
if (Mathf.Abs(diffX - leftMinX) < 0.000001f)
|
|
{
|
|
var newDisZ = Mathf.Abs(defUnit.transform.position.z - z);
|
|
if (newDisZ < leftDisZ)
|
|
{
|
|
leftMinX = diffX;
|
|
leftDisZ = newDisZ;
|
|
leftUnit = defUnit;
|
|
}
|
|
}
|
|
else if (diffX < leftMinX)
|
|
{
|
|
leftMinX = diffX;
|
|
leftDisZ = Mathf.Abs(defUnit.transform.position.z - z);
|
|
leftUnit = defUnit;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public BattleControlUnit GetNearestDefUnitOnCurrDirection(float x, float z, int direction)
|
|
{
|
|
BattleControlUnit unit = null;
|
|
var countDef = DefUnitsList.Count;
|
|
if(countDef <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
vector2A.Set(x, z);
|
|
float minDis = float.MaxValue;
|
|
if (direction == 1) // 找右边的
|
|
{
|
|
for(int j = 0; j < countDef; j++)
|
|
{
|
|
var objB = DefUnitsList[j];
|
|
if (objB.transform.position.x >= x)
|
|
{
|
|
vector2B.Set(objB.transform.position.x, objB.transform.position.z);
|
|
var dis = (vector2B - vector2A).sqrMagnitude;
|
|
if (dis < minDis)
|
|
{
|
|
minDis = dis;
|
|
unit = objB;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else // 找左边的
|
|
{
|
|
for(int j = 0; j < countDef; j++)
|
|
{
|
|
var objB = DefUnitsList[j];
|
|
if (objB.transform.position.x <= x)
|
|
{
|
|
vector2B.Set(objB.transform.position.x, objB.transform.position.z);
|
|
var dis = (vector2B - vector2A).sqrMagnitude;
|
|
if (dis < minDis)
|
|
{
|
|
minDis = dis;
|
|
unit = objB;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return unit;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
battleStart = false;
|
|
UpdateEnabled = false;
|
|
AtkUnitsList.Clear();
|
|
DefUnitsList.Clear();
|
|
PoolHelper.Clear();
|
|
MainHero = null;
|
|
luaOnPlayFxFunc = null;
|
|
luaOnWarningHeroNumChangedFunc = null;
|
|
effectHeroWarningSet.Clear();
|
|
effectWarningSet.Clear();
|
|
skillToastSet.Clear();
|
|
if (!ReferenceEquals(BattleRoot, null))
|
|
{
|
|
GameObject.Destroy(BattleRoot);
|
|
BattleRoot = null;
|
|
}
|
|
}
|
|
}
|
|
}
|