using UnityEngine; using System; using CommonLang.Concurrent; using CommonAI.Zone; using System.IO; using CommonAIClient.Unity.Utils; using CommonLang; namespace CommonAIClient.Unity.Battle { public class DisplayCell : IDisposable { #region RefCount private static AtomicInteger s_alloc_count = new AtomicInteger(0); private static AtomicInteger s_active_count = new AtomicInteger(0); /// <summary> /// 分配实例数量 /// </summary> public static int AllocCount { get { return s_alloc_count.Value; } } /// <summary> /// 未释放实例数量 /// </summary> public static int ActiveCount { get { return s_active_count.Value; } } #endregion /// <summary> /// 主体上的挂载列表 /// </summary> private HashMap<string, DisplayCell> mAttachParts = new HashMap<string, DisplayCell>(); private bool mDisposed = false; private bool mActiveSelf; private GameObject mRootNode; private AssetObjectExt mModel; private Animation mAnimation; //保存最后申请的动作 private string mLastAnimName; private bool mLastCrossFade; private WrapMode mLastWrapMode; private float mLastSpeed; public bool IsDisposed { get { return mDisposed; } } 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 AssetObjectExt Model { set { mModel = value; mModel.gameObject.ParentRoot(mRootNode); mAnimation = mModel.GetComponent<Animation>(); PlayAnim(LastAnimName, LastCrossFade, LastWrapMode, LastSpeed); } } public bool ActiveSelf { get { return mActiveSelf; } set { this.mActiveSelf = value; this.mRootNode.SetActive(mActiveSelf); } } public DisplayCell(GameObject root, string name = "DisplayCell") { mRootNode = new GameObject(name); if (root != null) { mRootNode.ParentRoot(root); } s_alloc_count++; s_active_count++; } ~DisplayCell() { s_alloc_count--; } public DisplayCell AttachPart(string name, string dummy) { GameObject dummyNode = GetDummyNode(dummy); if (dummyNode == null) { dummyNode = mRootNode; } DisplayCell displayCell = BattleFactroy.Instance.CreateDisplayCell(dummyNode, name); mAttachParts.Add(name.ToLower(), displayCell); return displayCell; } public void DetachPart(string name) { DisplayCell displayCell = mAttachParts.RemoveByKey(name.ToLower()); if (displayCell != null) { displayCell.Dispose(); } } public virtual GameObject GetDummyNode(string name) { if (mModel == null || string.IsNullOrEmpty(name)) { return null; } GameObject dummyNode = mModel.GetDummyNode(name); if (dummyNode == null) { foreach (var elem in mAttachParts) { dummyNode = elem.Value.GetDummyNode(name); if (dummyNode != null) break; } } return dummyNode; } public float GetAnimCurrentTime() { if (!string.IsNullOrEmpty(mLastAnimName) && mAnimation != null) { AnimationState state = mAnimation[mLastAnimName]; if (state != null) { return state.time; } } return 0f; } public float GetAnimLength(string name) { if (!string.IsNullOrEmpty(name) && mAnimation != null && mAnimation[name] != null) { return mAnimation[name].length; } return 0f; } public virtual void PlayAnim(string name, bool crossFade , WrapMode wrapMode = WrapMode.Once, float speed = 1f, float currentTime = 0f) { if (!string.IsNullOrEmpty(name)) { foreach (var elem in mAttachParts) { elem.Value.PlayAnim(name, crossFade, wrapMode, speed, currentTime); } mLastAnimName = name; mLastCrossFade = crossFade; mLastWrapMode = wrapMode; mLastSpeed = speed; if (mAnimation != null) { AnimationState state = mAnimation[name]; if (state != null) { state.time = 0; state.wrapMode = wrapMode; state.speed = speed; state.layer = 1; state.time = currentTime; if (crossFade) { mAnimation.CrossFade(name, 0.1f); } else { mAnimation.Play(name, PlayMode.StopAll); } } } } } 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() { foreach (var elem in mAttachParts) { elem.Value.Dispose(); } mAttachParts.Clear(); BattleFactroy.Instance.GameObjectAdapter.Unload(mModel); GameObject.DestroyObject(mRootNode); } } }