using System; using System.Collections.Generic; using Thousandto.Cfg.Data; using Thousandto.Code.Center; using Thousandto.Code.Logic; using Thousandto.Core.Asset; using Thousandto.Plugins.Common; using Thousandto.Plugins.LuaType; using UnityEngine; using XLua; namespace Thousandto.GameUI.Form { //UI上的模型管理组件 public class UIRoleSkinCompoent : LuaBehaviour { #region//私有变量 //父UI protected UINormalForm _parent = null; //transform实例 protected Transform _transformInst = null; //模型位置边框 private UIWidget _widget = null; //模型位置的Transform protected Transform _widgetTrans = null; //模型boxcollider protected BoxCollider _collider = null; // protected UIEventListener _listener = null; //模型根节点 protected Transform _modelRoot = null; protected GameObject _modelGo = null; //默认旋转Y值 protected float _normalRot = 180f; //默认旋转值 protected Vector3 _nomalEuleAngles = Vector3.zero; //默认位置 protected Vector3 _nomalPos = Vector3.zero; //已经装备的数据 protected Dictionary _equips = new Dictionary(); protected Dictionary> _anims = new Dictionary>(); //装备接口 protected FSkinModel _skin = null; //是否可以拖动旋转 protected bool _enableDrag = true; //使用的层 protected int _layer = LayerUtils.AresUI; protected string[] _defaultClipNames = null; protected UIPanel renderQvalue; //场景模型旋转 private Transform _uiModelDragTrs = null; //神兵头部开始动画位置 private Vector3 _godWeaponHeadPos = new Vector3(0, 0, 0.4f); //神兵身体开始动画位置 private Vector3 _godWeaponBodyPos = new Vector3(0, 0, -0.4f); //神兵动画曲线 private AnimationCurve _godWeaponCurve = new AnimationCurve(new Keyframe(0f, 0f, 0f, 1), new Keyframe(0.8f, 0.25f, 1, 1), new Keyframe(1f, 1f, 1f, 0f)); private Action _partChangedCallBack; private int _showFrameCount = 0; private List _skinAllRenders = new List(); #endregion #region//属性 public Transform TransformInst { get { if (_transformInst == null) { _transformInst = transform; } return _transformInst; } } public bool EnableDrag { get { return _enableDrag; } set { _enableDrag = value; _collider.enabled = _enableDrag; } } public UIWidget Widget { get { return _widget; } set { _widget = value; } } //使用的摄像机大小 public void SetCameraSize(float size) { if (_modelRoot == null) { return; } //设置的摄像机大小不可以小于0 if (size <= 0) { _modelRoot.localScale = new Vector3(320, 320, 320); } else { _modelRoot.localScale = new Vector3(320 / size, 320 / size, 320 / size); } } //设置缩放值 public void SetLocalScale(float scale) { if (_modelRoot == null) { return; } //设置的摄像机大小不可以小于0 if (scale <= 0) { _modelRoot.localScale = new Vector3(320, 320, 320); } else { _modelRoot.localScale = new Vector3(scale, scale, scale); } } //设置UI上的位置 public void SetPos(float posX,float posY, float posZ = 0) { _nomalPos = new Vector3(posX, posY, posZ == 0 ? _modelRoot.localPosition.z : posZ); if (_modelRoot == null) { return; } _modelRoot.localPosition = _nomalPos; } public Vector3 GetEulerAngles() { return _modelRoot.localEulerAngles; } //设置EulerAngles public void SetEulerAngles(float angleX, float angleY, float angleZ) { _nomalEuleAngles = new Vector3(angleX, angleY, angleZ); _normalRot = angleY; if (_modelRoot != null) { _modelRoot.localEulerAngles = _nomalEuleAngles; } } //默认旋转值 public float NormalRot { get { return _normalRot; } set { _normalRot = value; _nomalEuleAngles.y = _normalRot; } } //当前旋转值 public float CurRot { get { if (_modelRoot != null) { return _modelRoot.localEulerAngles.y; } return 0; } set { if (_modelRoot != null) { var angles = _modelRoot.localEulerAngles; angles.y = value; _modelRoot.localEulerAngles = angles; if (_uiModelDragTrs != null) { _uiModelDragTrs.localEulerAngles = angles; } } } } //使用的层 public int Layer { get { return _layer; } set { if (_layer != value) { _layer = value; _skin.SetLayer(_layer, true); } } } //装备接口 public FSkinModel Skin { get { return _skin; } } public FSkinTypeCode SkinTypeCode { get { return _skin.SkinTypeCode; } set { _skin.SkinTypeCode = value; } } public AnimatorCullingMode SkinAnimationCullingType { get { return _skin.CullingType; } set { _skin.CullingType = value; } } public int AnimUpdateRate { get { return _skin.AnimUpdateRate; } set { _skin.AnimUpdateRate = value; } } #endregion #region//公有函数 public virtual void OnFirstShow(UINormalForm parent, FSkinTypeCode skinType = FSkinTypeCode.Monster, string defaultAnim = AnimClipNameDefine.NormalIdle, float animSpeed = 1,bool isUseUIValue = false,bool isUIModel = true) { if (_parent != null) { //UnityEngine.Debug.LogErrorFormat("UIRoleSkinCompoent 重复调用 OnFirstShow 请检查错误"); return; } _parent = parent; _widgetTrans = TransformInst.Find("Box"); _widget = _widgetTrans.GetComponent(); _widget.pivot = UIWidget.Pivot.Bottom; if (_widget.depth <= 0) _widget.depth = 1; _collider = TransformInst.Find("Box").GetComponent(); _collider.enabled = _enableDrag; _collider.center = new Vector3(0f, _collider.size.y / 2f, 0f); _modelRoot = TransformInst.Find("Box/ModelRoot"); _modelGo = _modelRoot.gameObject; if (isUseUIValue) { _nomalPos = _modelRoot.localPosition; _nomalEuleAngles = _modelRoot.localRotation.eulerAngles; _normalRot = _modelRoot.localRotation.eulerAngles.y; } else { _nomalEuleAngles.x = 0; _nomalEuleAngles.y = _normalRot; _nomalEuleAngles.z = 0; } _listener = _widgetTrans.RequireComponent(); _listener.onDrag = OnDrag; CalculatePos(); //默认的动作 _defaultClipNames = new string[] { defaultAnim }; renderQvalue = TransformInst.GetComponent(); renderQvalue.onRenderQueueChanged = RenderQueueChanged; //初始化 _skin = GameCenter.LuaSystem.Adaptor.CreateFSkinModel(skinType); _skin.SetParent(_modelRoot, true); _skin.SetLayer(_layer, true); _skin.PlayAnim(defaultAnim, AnimationPartType.AllBody, WrapMode.Loop, true, 0.2f, animSpeed); _skin.SetDefaultAnim(defaultAnim, AnimationPartType.AllBody); _skin.SetBreastJiggly(true); _skin.IsPriorityLoad = true; _skin.SetRenderQueue(renderQvalue.startingRenderQueue + 1); _skin.SetOnSkinPartChangedHandler(OnSkinChange); _skin.IsUIModel = isUIModel; _skin.CullingType = AnimatorCullingMode.AlwaysAnimate; //FGameObjectBody body = _skin.GetSkinPart(FSkinPartCode.Body) as FGameObjectBody; //body.UserCloth = true; } //RenderQueue的改变事件 private void RenderQueueChanged(int sq) { if (_skin != null) { if (_skin.RenderQueue != sq + 1) { _skin.SetRenderQueue(sq + 1); } } } public void SetDefaultAnim(string name, AnimationPartType type) { if (_skin != null) { _skin.SetDefaultAnim(name, type); } } public void SetSkinPos(Vector3 pos) { _skin.SetLocalPosition(pos); } public void SetSkinRot(Vector3 angle) { _skin.SetLocalEulerAngles(angle); } public void CalculatePos() { _modelRoot.localPosition = _nomalPos; } public int GetEquipID(int type) { int result = 0; _equips.TryGetValue((int)type, out result); return result; } public void SetEquip(int type, int id, Dictionary animList = null, string slot = null) { //_skin.SetBoneClothEnable(true); if ( !GameExtentScript._showPlayerModel ) return; _equips[(int)type] = id; if (animList != null) { _anims[(int)type] = animList; } if (gameObject.activeInHierarchy) { _skin.SetSkinPartFromCfgID(type, id, _anims.ContainsKey((int)type) ? _anims[(int)type] : null, false, slot); } } public void SetEquip(int type, int id, LuaTable animTable) { _equips[(int)type] = id; if(animTable != null) { var clipCount = animTable.Length; var animList = new Dictionary(clipCount); var tmpStr = string.Empty; for(int i = 0; i < clipCount; ++i) { if(animTable.TryGet(i + 1, out tmpStr)) { animList[tmpStr] = false; } } _anims[(int)type] = animList; } if (gameObject.activeInHierarchy) { _skin.SetSkinPartFromCfgID(type, id, _anims.ContainsKey((int)type) ? _anims[(int)type] : null, false); } } //设置神兵动画,给神兵UI界面用的 public void SetGodWeaponAnim(int godweaponVfxid, Transform trs) { var head = _skin.GetSkinPart(FSkinPartCode.GodWeaponHead); var body = _skin.GetSkinPart(FSkinPartCode.GodWeaponBody); if (body != null && head != null) { SetEquip(FSkinPartCode.GodWeaponVfx, 0); var headtween = head.RootTransform.RequireComponent(); var bodytween = body.RootTransform.RequireComponent(); head.RootTransform.localPosition = _godWeaponHeadPos; body.RootTransform.localPosition = _godWeaponBodyPos; headtween.from = _godWeaponHeadPos; headtween.to = Vector3.zero; headtween.duration = 0.4f; headtween.animationCurve = _godWeaponCurve; headtween.style = UITweener.Style.Once; headtween.ResetToBeginning(); headtween.PlayForward(); bodytween.from = _godWeaponBodyPos; bodytween.to = Vector3.zero; bodytween.duration = 0.4f; bodytween.style = UITweener.Style.Once; bodytween.animationCurve = _godWeaponCurve; bodytween.ResetToBeginning(); bodytween.PlayForward(); bodytween.SetOnFinished(() => { SetEquip(FSkinPartCode.GodWeaponVfx, godweaponVfxid); if (trs != null) { var _vfx = trs.RequireComponent(); _vfx.OnCreateAndPlay(ModelTypeCode.UIVFX, 39, LayerUtils.AresUI); } }); } } //设置头发颜色 public void SetHairColor(float r, float g, float b) { _skin.SetHairColor(new Color(r, g, b)); } //重置模型数据 public void ResetSkin() { _equips.Clear(); _anims.Clear(); if (_skin != null) { _skin.RemoveAllSkinPart(); } } //重置旋转角度 public void ResetRot() { _modelRoot.localEulerAngles = _nomalEuleAngles; } //设置点击回调 public void SetClickCallBack(UIEventListener.VoidDelegate callBack) { _listener.onClick = callBack; } //播放动作 public void Play(string animName, AnimationPartType partType, WrapMode wrapMode, float animSpeed) { _skin.PlayAnim(animName, partType, wrapMode, true, 0.2f, animSpeed); } public bool IsPlaying() { return _skin.IsPlaying(); } //设置皮肤部位改变的处理 public void SetOnSkinPartChangedHandler(Action handler) { _partChangedCallBack = handler; } //获取所有渲染列表 public List GetAllRenders() { _skinAllRenders.Clear(); if (_skin != null) { _skin.GetRenderers(_skinAllRenders); } return _skinAllRenders; } #endregion #region//子类继承 protected virtual void OnSkinChange(FSkinBase skin, int part) { if (_partChangedCallBack != null) _partChangedCallBack(skin, part); } protected virtual void OnUpdate(float dt) { } #endregion #region//私有函数 private void OnDrag(GameObject go, Vector2 value) { if (!EnableDrag) { return; } var angles = _modelRoot.localEulerAngles; angles.y -= value.x; _modelRoot.localEulerAngles = angles; if (_uiModelDragTrs != null) { _uiModelDragTrs.localEulerAngles = angles; } } public void SetUIModelDrag(Transform trs) { _uiModelDragTrs = trs; } #endregion #region //Behaviour的方法 protected override void OnBehaviourAwake() { _showFrameCount = 2; if(_modelGo == null) { _modelRoot = TransformInst.Find("Box/ModelRoot"); _modelGo = _modelRoot.gameObject; } _modelGo.SetActive(false); } protected override void OnBehaviourOnEnable() { _showFrameCount = 2; if (_modelGo == null) { _modelRoot = TransformInst.Find("Box/ModelRoot"); _modelGo = _modelRoot.gameObject; } _modelGo.SetActive(false); if (_skin != null && !_skin.IsFreeze) { _skin.SetActive(true); if (_equips.Count > 0) { var iter = _equips.GetEnumerator(); try { while (iter.MoveNext()) { _skin.SetSkinPartFromCfgID(iter.Current.Key, iter.Current.Value, _anims.ContainsKey(iter.Current.Key) ? _anims[iter.Current.Key] : null); } } finally { iter.Dispose(); } } _skin.PlayLastAnimInfo(); CalculatePos(); _modelRoot.localEulerAngles = _nomalEuleAngles; } base.OnBehaviourOnEnable(); } protected override void OnBehaviourOnDisable() { if (_skin != null) { _skin.RemoveAllSkinPart(); _skin.SetActive(false); } base.OnBehaviourOnDisable(); } protected override void OnBehaviourOnDestroy() { if (_skin != null) { _skin.Destroy(); } _listener.onClick = null; _listener.onDrag = null; base.OnBehaviourOnDestroy(); } private void Update() { if(renderQvalue != null) { var active = renderQvalue.finalAlpha > 0.002f; if(active != _modelGo.activeSelf) { _modelGo.SetActive(active); } } if (_skin != null) { _skin.Update(Time.deltaTime); } OnUpdate(Time.deltaTime); base.OnBehaviourOnUpdate(); } #endregion #region//静态函数 #endregion } }