using UnityEngine;
using System;
using CommonLang.Concurrent;
using CommonAI.Zone;
using CommonLang;
using CommonAIClient.Unity.Utils;
namespace CommonAIClient.Unity.Battle
{
public partial class BattleObject : IDisposable
{
#region RefCount
private static AtomicInteger s_alloc_count = new AtomicInteger(0);
private static AtomicInteger s_active_count = new AtomicInteger(0);
///
/// 分配实例数量
///
public static int AllocCount { get { return s_alloc_count.Value; } }
///
/// 未释放实例数量
///
public static int ActiveCount { get { return s_active_count.Value; } }
#endregion
private bool mDisposed;
private bool mActiveSelf;
private BattleScene mBattleScene;
private GameObject mObjectRoot;
private GameObject mDisplayRoot;
private GameObject mDummyRoot;
private GameObject mEffectRoot;
private DisplayCell mDisplayCell;
private HashMap mDummys = new HashMap();
//保存最后申请的动作
private string mLastAnimName;
private bool mLastCrossFade;
private WrapMode mLastWrapMode;
private float mLastSpeed;
public bool IsDisposed { get { return mDisposed; } }
protected BattleScene BattleScene { get { return mBattleScene; } }
protected GameObject ObjectRoot { get { return mObjectRoot; } }
public Vector3 Position { get { return this.mObjectRoot.Position(); } }
protected GameObject DisplayRoot { get { return mDisplayRoot; } }
protected GameObject DummyRoot { get { return mDummyRoot; } }
public GameObject EffectRoot { get { return mEffectRoot; } }
protected DisplayCell DisplayCell { get { return mDisplayCell; } }
protected HashMap Dummys { get { return mDummys; } }
public string LastAnimName { get { return mLastAnimName; } }
public bool LastCrossFade { get { return mLastCrossFade; } }
public WrapMode LastWrapMode { get { return mLastWrapMode; } }
public float LastSpeed { get { return mLastSpeed; } }
public bool ActiveSelf
{
get { return mActiveSelf; }
set
{
this.mActiveSelf = value;
this.ObjectRoot.SetActive(mActiveSelf);
this.PlayAnim(mLastAnimName, mLastCrossFade, mLastWrapMode, mLastSpeed);
}
}
public BattleObject(BattleScene battleScene, string name = "")
{
s_alloc_count++;
s_active_count++;
mBattleScene = battleScene;
mObjectRoot = new GameObject(name);
mDisplayRoot = new GameObject("DisplayRoot");
mDisplayRoot.ParentRoot(mObjectRoot);
mDummyRoot = new GameObject("DummyRoot");
mDummyRoot.ParentRoot(mObjectRoot);
mEffectRoot = new GameObject("EffectRoot");
mEffectRoot.ParentRoot(mObjectRoot);
mDisplayCell = BattleFactroy.Instance.CreateDisplayCell(mDisplayRoot);
}
~BattleObject()
{
s_alloc_count--;
}
protected virtual void CorrectDummyNode()
{
foreach (var elem in mDummys)
{
GameObject trace = mDisplayCell.GetDummyNode(elem.Key);
elem.Value.Init(elem.Key, trace);
}
}
///
/// 如果名字不为空 一定会返回一个DummyNode
///
///
///
public virtual DummyNode GetDummyNode(string name)
{
if (string.IsNullOrEmpty(name))
{
Debug.LogError("string.IsNullOrEmpty(name)");
return null;
}
DummyNode dummyNode = null;
if (!mDummys.TryGetValue(name, out dummyNode))
{
GameObject node = mDisplayCell.GetDummyNode(name);
if (node == null)
{
Debug.LogError("node not exist " + name);
}
GameObject tmp = new GameObject(name);
tmp.ParentRoot(mDummyRoot);
dummyNode = tmp.AddComponent();
dummyNode.Init(name, node);
mDummys.Add(name, dummyNode);
}
return dummyNode;
}
public virtual float GetAnimLength(string name)
{
if (this.DisplayCell != null)
{
return this.DisplayCell.GetAnimLength(name);
}
return 0f;
}
public virtual void PlayAnim(string name, bool crossFade
, WrapMode wrapMode = WrapMode.Once, float speed = 1f)
{
if (!string.IsNullOrEmpty(name))
{
mLastAnimName = name;
mLastCrossFade = crossFade;
mLastWrapMode = wrapMode;
mLastSpeed = speed;
mDisplayCell.PlayAnim(name, crossFade, wrapMode, speed);
}
}
///
///
///
///
/// unity pos
/// unity rot
public virtual void PlayEffect(LaunchEffect eff, Vector3 pos, Quaternion rot)
{
if (eff != null)
{
//声音
if (!string.IsNullOrEmpty(eff.SoundName))
{
if (eff.IsLoop)
{
BattleFactroy.Instance.SoundAdapter.PlaySound(eff.SoundName, eff.EffectTimeMS, pos);
}
else
{
BattleFactroy.Instance.SoundAdapter.PlaySound(eff.SoundName, pos);
}
}
//特效
if (!string.IsNullOrEmpty(eff.Name))
{
BattleFactroy.Instance.GameObjectAdapter.Load(eff.Name
, System.IO.Path.GetFileNameWithoutExtension(eff.Name)
, (succ, aoe) =>
{
if (succ)
{
if (IsDisposed && eff.BindBody)
{
BattleFactroy.Instance.GameObjectAdapter.Unload(aoe);
return;
}
OnLoadEffectSuccess(aoe, eff, pos, rot);
}
});
}
}
}
protected virtual void OnLoadEffectSuccess(AssetObjectExt aoe
, LaunchEffect eff, Vector3 pos, Quaternion rot)
{
aoe.gameObject.Parent(BattleScene.EffectRoot);
aoe.gameObject.Position(pos);
aoe.gameObject.Rotation(rot);
var script = aoe.gameObject.AddComponent();
script.aoeHandler = aoe;
script.duration = eff.IsLoop ? eff.EffectTimeMS / 1000f : 0f;
GameObject dummy = mEffectRoot;
if (!string.IsNullOrEmpty(eff.BindPartName))
{
dummy = mDisplayCell.GetDummyNode(eff.BindPartName);
if (dummy == null)
{
dummy = mEffectRoot;
}
aoe.gameObject.Position(dummy.Position());
}
if (eff.BindBody)
{
aoe.gameObject.ParentRoot(dummy);
}
}
public void Update(float deltaTime)
{
if (!mDisposed)
{
OnUpdate(deltaTime);
}
}
protected virtual void OnUpdate(float deltaTime)
{
}
public void Dispose()
{
if (!mDisposed)
{
OnDispose();
mDisposed = true;
s_active_count--;
}
}
protected virtual void OnDispose()
{
mDisplayCell.Dispose();
AssetObjectExt[] aoes = mDummyRoot.GetComponentsInChildren();
foreach (var elem in aoes)
{
EffectAutoDestroy[] scripts = elem.gameObject.GetComponents();
if (scripts.Length > 0)
{
foreach (var script in scripts)
{
script.DoDestroy();
}
}
else
{
BattleFactroy.Instance.GameObjectAdapter.Unload(elem);
}
}
GameObject.Destroy(mObjectRoot);
}
}
}