Files
Main/Assets/GameAssets/Resources/GameUI/Form/UIComponents/Scripts/UIRoleSkinCompoent.cs
2025-01-25 04:38:09 +08:00

631 lines
19 KiB
C#

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<int, int> _equips = new Dictionary<int, int>();
protected Dictionary<int, Dictionary<string, bool>> _anims = new Dictionary<int, System.Collections.Generic.Dictionary<string, bool>>();
//装备接口
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<FSkinBase, int> _partChangedCallBack;
private int _showFrameCount = 0;
private List<Renderer> _skinAllRenders = new List<Renderer>();
#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<UIWidget>();
_widget.pivot = UIWidget.Pivot.Bottom;
if (_widget.depth <= 0) _widget.depth = 1;
_collider = TransformInst.Find("Box").GetComponent<BoxCollider>();
_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<UIEventListener>();
_listener.onDrag = OnDrag;
CalculatePos();
//默认的动作
_defaultClipNames = new string[] { defaultAnim };
renderQvalue = TransformInst.GetComponent<UIPanel>();
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<string, bool> 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<string, bool>(clipCount);
var tmpStr = string.Empty;
for(int i = 0; i < clipCount; ++i)
{
if(animTable.TryGet<int, string>(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<TweenPosition>();
var bodytween = body.RootTransform.RequireComponent<TweenPosition>();
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<UIVfxSkinCompoent>();
_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<FSkinBase, int> handler)
{
_partChangedCallBack = handler;
}
//获取所有渲染列表
public List<Renderer> 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
}
}