NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/UI/SkinChangeController.cs

652 lines
21 KiB
C#
Raw Normal View History

2024-07-17 17:07:27 +08:00
using cfg.ActorCfg;
using cfg.CharacterCfg;
using Cysharp.Threading.Tasks;
using Framework;
using Gameplay;
using Gameplay.Common;
2024-07-17 17:07:27 +08:00
using Gameplay.Emoji;
using Gameplay.Net;
using Gameplay.Utils;
using PhxhSDK;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
2024-07-17 17:07:27 +08:00
using UnityEngine.EventSystems;
using UnityEngine.Playables;
using UnityEngine.UI;
using Button = UnityEngine.UI.Button;
using Image = UnityEngine.UI.Image;
public class SkinChangeController : UIWindow
{
#region UI_Obj
//UI GameObj
///Auto Gen Start///
public Image Image_BG;
//public Button Button_Back;
public Button Button_back;
public TMP_Text Text_Back;
public Button Button_Home;
public Image Image_Dark;
public Image Image_LeftBG;
public Image Image_ModelPosition;
public Image Image_Poster;
public Image Image_PosterPreview;
public Image Image_MidBG;
public Button Button_ShowAllPic;
public TMP_Text Text_Name;
public TMP_Text Text_SkinName;
public TMP_Text Text_Info;
public TMP_Text Text_GetWay;
public Button Button_Buy;
public TMP_Text Text_Buy;
public Button Button_Wear;
public TMP_Text Text_Wear;
///Auto Gen End///
RawImage rt;
public GameObject UpperUI;
2024-06-20 15:20:23 +08:00
private RawImage rawImageGaussianBlurMask;
#endregion
ShowModelPreviewNode node;
2024-06-20 15:20:23 +08:00
private PinchZoomModule PinchZoom;
private DragForUI Drag;
private PhxhSDK.PhxhScrollView ScrollView;
SkinScrollView skinScrollView = new SkinScrollView();
GameObject _sampleModel;
GameObject _instModel;
2024-06-24 15:13:42 +08:00
private UnitEmojiManager _emojiManager;
private bool isShowPosterPic = false;
private CharacterDataInfo curCharacterInfo;
private int curSelectSkinId;
private int curUsingSkinId;
List<DataCharacterSkin> characterSkinList;
2024-07-17 17:07:27 +08:00
Dictionary<int, GameObject> characterModels = new();
2024-06-21 17:14:19 +08:00
PosterFader fader = new PosterFader();
public static async UniTask<UIWindow> Open(CharacterDataInfo characterData)
{
2024-09-18 16:03:02 +08:00
CommonUtils.CaptureScreenshot();
return await UIManager.Instance.CreateAndOpenWindow(UINameConst.UI_SkinChange, characterData);
}
// deal with input data
public override void PreLoad(object data = null)
{
curCharacterInfo = data as CharacterDataInfo;
2024-06-24 13:53:23 +08:00
curSelectSkinId = (int)curCharacterInfo.SkinID;// + 1;
if(curSelectSkinId == 0)
{
2024-07-17 17:07:27 +08:00
DebugUtil.LogError("当前角色数据内皮肤ID为0已设置为默认皮肤ID");
2024-06-24 13:53:23 +08:00
curSelectSkinId = 1;
}
curUsingSkinId = curSelectSkinId;
characterSkinList = CommonUtils.GetCharacterSkinCfgList((int)curCharacterInfo.ID);
2024-06-24 13:53:23 +08:00
PreLoadSpritesAsync();
}
2024-06-24 13:53:23 +08:00
void refreshCharacterInfo()
{
curCharacterInfo = CharacterDataInfoManager.Instance.GetCharacterInfo(curCharacterInfo.ID);
curSelectSkinId = (int)curCharacterInfo.SkinID;
if (curSelectSkinId == 0)
{
2024-07-17 17:07:27 +08:00
DebugUtil.LogError("当前角色数据内皮肤ID为0已设置为默认皮肤ID");
2024-06-24 13:53:23 +08:00
curSelectSkinId = 1;
}
curUsingSkinId = curSelectSkinId;
}
void PreLoadSpritesAsync()
{
foreach (var dataCharacter in characterSkinList)
{
string path = CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Poster, dataCharacter.SkinID);
AssetManager.Instance.PostPreload<Sprite>(path).Forget();
2024-07-17 17:07:27 +08:00
//TODO 目前半身图使用好感度图片路径
var halfpath = CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Favorable, dataCharacter.SkinID);
AssetManager.Instance.PostPreload<Sprite>(halfpath).Forget();
2024-10-16 14:46:41 +08:00
//DebugUtil.Log("目前半身图暂用使用路径为:" + halfpath + ",请待补充相关资源与更新配置表后在此处更新相关代码");
}
}
2024-07-17 17:07:27 +08:00
async void LoadModel(int skinID)
{
2024-07-17 17:07:27 +08:00
if (characterModels.ContainsKey(skinID))
{
_sampleModel = characterModels[skinID];
}
else
{
rt.gameObject.SetActive(false);
2024-07-17 17:07:27 +08:00
var data = TableManager.Instance.Tables.SkinCfg.Get(skinID, (int)curCharacterInfo.ID);
var prefabPath = PathEx.GetCharacterDisplayModelPath(data.NameID);
_sampleModel = await AssetManager.Instance.LoadAssetAsync<GameObject>(prefabPath);
if(_sampleModel == null)
{
DebugUtil.LogError($"加载模型失败角色ID{(int)curCharacterInfo.ID},角色皮肤ID{skinID},模型路径{prefabPath}");
return;
}
characterModels.Add(skinID, _sampleModel);
rt.gameObject.SetActive(true);
2024-07-17 17:07:27 +08:00
}
GameObject model = Object.Instantiate(_sampleModel, node.modelParent.transform, true);
2024-07-17 17:07:27 +08:00
if (_instModel != null)
Object.Destroy(_instModel);
_instModel = model;
model.transform.ResetLocals();
model.transform.localPosition = new(2, 0, 2);
model.transform.localRotation = Quaternion.Euler(new(0, 50, 0));
//model.transform.localScale = 300 * Vector3.one;
model.gameObject.SetLayerEx(LayerDefine.TeamEdit);
var pd = model.GetComponentInChildren<PlayableDirector>();
if (pd != null)
{
pd.enabled = false;
}
var animator = model.GetComponentInChildren<Animator>();
if (animator != null)
{
animator.Play("standready001");
}
2024-07-17 17:07:27 +08:00
else
{
DebugUtil.LogError("模型中未找到Animator组件请检查模型配置");
}
2024-06-24 15:13:42 +08:00
_InitEmoji();
}
2024-06-24 15:13:42 +08:00
private void _InitEmoji()
{
if (_emojiManager != null)
{
_emojiManager.Dispose();
_emojiManager = null;
}
var charSingleData = curCharacterInfo.Cfg;
_emojiManager = new UnitEmojiManager(_instModel, charSingleData.EmojiEyesColor,
charSingleData.EmojiEyeBowsType, charSingleData.EmojiEyeBowsColor, true);
_emojiManager.SwitchEmoji(charSingleData.DefaultDisplayEmojiId);
}
void ModelNodeInit()
{
//展示界面时,创建模型节点
CreateModelNode().Forget();
}
private async UniTask CreateModelNode()
{
if (node == null && rt != null)
{
node = new ShowModelPreviewNode();
var size = rt.rectTransform.sizeDelta;
await node.Show((int)size.x, (int)size.y);
//modelParent = node.modelParent;
RefreshPreviewNodeRawImage();
}
}
private void RefreshPreviewNodeRawImage()
{
if (node != null)
{
rt.texture = node.RTexture;
}
}
2024-06-24 15:13:42 +08:00
// Use this for initialization
public override void OnInit()
{
//bind UI GameObj
SkinChangeBinder.GetComponents(this);
UpperUI = FindObj("Image_BG/UpperUI");
2024-06-20 15:20:23 +08:00
rawImageGaussianBlurMask = GetComponent<RawImage>("GaussianBlurMask");
rawImageGaussianBlurMask.texture = CommonUtils.GetScreenTexture2D();
2024-06-20 15:20:23 +08:00
2024-06-24 13:53:23 +08:00
Image_Poster.GetComponent<RectTransform>().sizeDelta = Vector2.zero;
2024-06-20 15:20:23 +08:00
PinchZoom = GetComponent<PinchZoomModule>("Image_BG/Image_Poster");
2024-07-17 18:42:19 +08:00
//Drag = GetComponent<DragForUI>("Image_BG/Image_Poster");
ScrollView = GetComponent<PhxhSDK.PhxhScrollView>("Image_BG/UpperUI/ChangeSkin/ScrollView");
rt = GetComponent<RawImage>("Image_BG/UpperUI/Image_LeftBG/rt");
skinScrollView.SetScrollRect(ScrollView);
2024-07-17 17:07:27 +08:00
skinScrollView.SetItemCountFunc(() => characterSkinList.Count + 2);//列表上下各加一个空白item作为padding
skinScrollView.SetItemSizeFunc((index) => skinScrollView.GetItemSizeFromList(index));
skinScrollView.SetUpdateFunc(_RefreshSkinItem);
skinScrollView.InitItemCellList(characterSkinList.Count);
BindButton(Button_ShowAllPic, OnShowPicButton);
BindButton(Button_back, OnReturnButton);
2024-08-14 19:13:50 +08:00
BindButton(Button_Home, OnHomeButton);
2024-06-24 13:53:23 +08:00
BindButton(Button_Wear, OnChangeSkinClick);
2024-07-17 17:07:27 +08:00
//LoadModel(curSelectSkinId);
2024-07-17 18:42:19 +08:00
//Drag.OnDragStarted += OnDragBegin;
//Drag.OnDraging += OnDrag;
//Drag.OnDragCompleted += OnDragEnd;
PinchZoom.OnDragStarted += OnDragBegin;
PinchZoom.OnDraging += OnDrag;
PinchZoom.OnDragCompleted += OnDragEnd;
2024-06-24 13:53:23 +08:00
EventManager.Instance.Register(EventManager.EventName.CharacterInfoRefresh, CharacterInfoRefreshListener);
_SetSkinPosYListData();
skinScrollView.UpdateData();
skinScrollView.ScrollTo(curSelectSkinId);
ModelNodeInit();
2024-06-24 13:53:23 +08:00
}
void CharacterInfoRefreshListener()
{
refreshCharacterInfo();
SetSkinInfoAndButton();
}
//invoke when open window
protected override void OnShowWindow(object data = null)
{
2024-06-24 13:53:23 +08:00
base.OnShowWindow(data);
if (PinchZoom != null)
PinchZoom.enabled = false;
isShowPosterPic = false;
2024-06-24 13:53:23 +08:00
SetSkinInfoAndButton();
SetPosterSkinPic();
}
//invoke when reload window
protected override void OnReloadWindow(object data = null)
{
}
//invoke when close window
protected override void OnHideWindow()
{
2024-06-24 13:53:23 +08:00
base.OnHideWindow();
EventManager.Instance.Send(EventManager.EventName.EN_UIControllCultivateMainInput, true);
}
//invoke when destroy
public override void OnRelease()
{
base.OnRelease();
2024-06-24 13:53:23 +08:00
EventManager.Instance.Unregister(EventManager.EventName.CharacterInfoRefresh, CharacterInfoRefreshListener);
rt.texture = null;
node.ReleasePreviewNode();
node = null;
#region 预加载释放
foreach (var dataCharacter in characterSkinList)
{
string path = CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Poster, dataCharacter.SkinID);
AssetManager.Instance.Unload(path);
var halfpath = CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Favorable, dataCharacter.SkinID);
AssetManager.Instance.Unload(halfpath);
}
#endregion
2024-08-20 14:14:08 +08:00
}
#region Button Event
void OnShowPicButton()
{
2024-10-18 18:39:38 +08:00
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
ShowAllPic(true);
}
void OnReturnButton()
{
if(isShowPosterPic)
{
ShowAllPic(false);
SetSkinInfoAndButton();
}
else
{
CloseWindow();
}
}
2024-08-14 19:13:50 +08:00
void OnHomeButton()
{
UIManager.Instance.CloseAllNormalExcept(UINameConst.UI_MainPanel);
}
void _OnClickSkinItem(int to)
{
if (curSelectSkinId == to)
{
return;
}
2024-10-18 18:39:38 +08:00
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
int from = curSelectSkinId;
curSelectSkinId = to;
//_RefreshPosterButton();
skinScrollView.DoTwoItemScale(to - 1, from - 1, skinScrollView.ItemFullRectTrans.rect.size, skinScrollView.ItemRectTrans.rect.size, 0.1f,
() =>
{
_SetSkinPosYListData(false);
}, () =>
{
skinScrollView.AnimScrollTo(to);
SetSkinInfoAndButton();
});
2024-06-21 17:14:19 +08:00
fader.DoFade(Image_Poster, 0f, 0.12f, () =>
{
SetPosterSkinPic();
fader.DoFade(Image_Poster, 1f, 0.12f);
});
}
#endregion
#region drag event
float scaleFactor;
void OnDragBegin(PointerEventData data)
{
if(!isShowPosterPic)
{
return;
}
scaleFactor = UIRoot.Instance.RootCanvas.GetComponent<RectTransform>().sizeDelta.x / Screen.width;
}
void OnDrag(PointerEventData data)
{
if(!isShowPosterPic)
{
return;
}
2024-07-17 18:42:19 +08:00
PinchZoom.GetComponent<RectTransform>().anchoredPosition += data.delta * scaleFactor;//Drag
//drag.transform.position = GoRoot.transform.position;
}
void OnDragEnd(PointerEventData data)
{
if (!isShowPosterPic)
{
return;
}
}
#endregion
private void _SetSkinPosYListData(bool setSize = true)
{
if (setSize)
{
for (int i = 0; i < characterSkinList.Count; i++)
{
Vector2 size = skinScrollView.SkinItemSize(i + 1, curSelectSkinId);
skinScrollView._itemCells[i].size = size;
}
}
var posY = -skinScrollView.SkinItemSize(0, curSelectSkinId).y;
for (int i = 0; i < characterSkinList.Count; i++)
{
Vector2 size = skinScrollView._itemCells[i].size;
posY -= size.y / 2;
skinScrollView._itemCells[i].localPosY = posY;
posY -= size.y / 2;
}
}
private void _RefreshSkinItem(int index, RectTransform item)
{
if (index <= 0 || index >= characterSkinList.Count + 1)
{
if (item.GetComponent<CanvasGroup>() == null)
{
item.gameObject.AddComponent<CanvasGroup>();
}
item.GetComponent<CanvasGroup>().alpha = 0;
return;
}
if(item.GetComponent<CanvasGroup>() != null)
{
item.GetComponent<CanvasGroup>().alpha = 1;
}
var go = item.gameObject;
go.SetActive(true);
var posterPic =
CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Favorable, index);
var imgSkin = CommonUtils.GetComponent<Image>(go, "ButtonChange/ImageSkin");
var imgSelect = CommonUtils.GetGameObject(go, "ButtonChange/ImageChooseRect");
var imgDoSelect = CommonUtils.GetGameObject(go, "ButtonChange/ImageCover");
var btnChange = CommonUtils.GetComponent<Button>(go, "ButtonChange");
var btnNotSelect = CommonUtils.GetComponent<Button>(go, "ButtonNotSelect");
imgSkin.sprite = AssetManager.Instance.GetPreLoadResult<Sprite>(posterPic);
btnChange.gameObject.SetActive(true);
btnNotSelect.gameObject.SetActive(false);
imgSelect.SetActive(curSelectSkinId == index);
imgDoSelect.SetActive(curSelectSkinId != index);
ClearBind(btnChange);
ClearBind(btnNotSelect);
BindButton(btnChange, _OnClickSkinItem, index);
btnChange.GetComponent<RectTransform>().sizeDelta = skinScrollView.GetItemSizeFromList(index);
}
void ShowAllPic(bool showPic)
{
var UI_HIDE_POSITION = new Vector3(0, -1800, 0);
isShowPosterPic = showPic;
PinchZoom.enabled = showPic;
UpperUI.transform.localPosition = showPic ? UI_HIDE_POSITION : Vector3.zero;
Image_LeftBG.gameObject.SetActive(!showPic);
if (!showPic)
{
if (curSelectSkinId == 1)
Image_Poster.transform.position = Image_PosterPreview.transform.position;
else
Image_Poster.transform.localPosition = Vector3.zero;
Image_Poster.transform.localScale = Image_PosterPreview.transform.localScale;
var animator = _instModel.GetComponentInChildren<Animator>();
if (animator != null)
{
animator.Play("standready001");
}
}
}
void SetPosterSkinPic()
{
var posterPic =
CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Poster, curSelectSkinId);
Image_Poster.sprite = AssetManager.Instance.GetPreLoadResult<Sprite>(posterPic);//await LoadAssetAsync<Sprite>(posterPic);
2024-06-24 13:53:23 +08:00
2024-07-17 17:07:27 +08:00
RefreshModel();
//TODO 尺寸调整
2024-06-24 13:53:23 +08:00
if (curSelectSkinId != 1)
{
Image_Poster.transform.localPosition = Vector3.zero;
Image_Poster.SetNativeSize();
2024-06-26 15:39:50 +08:00
if (Image_Poster.sprite.rect.width >= Image_Poster.sprite.rect.height)
{
2024-06-24 13:53:23 +08:00
Image_Poster.GetComponent<RectTransform>().sizeDelta = new Vector2(1800, 1800 * Image_Poster.sprite.rect.height / Image_Poster.sprite.rect.width);
}
else
{
Image_Poster.GetComponent<RectTransform>().sizeDelta = new Vector2(1080 * Image_Poster.sprite.rect.width / Image_Poster.sprite.rect.height, 1080);
}
}
2024-06-24 13:53:23 +08:00
else
{
Image_Poster.transform.position = Image_PosterPreview.transform.position;
Image_Poster.GetComponent<RectTransform>().sizeDelta = Image_PosterPreview.GetComponent<RectTransform>().sizeDelta;
}
return;
}
2024-06-24 13:53:23 +08:00
/// <summary>
2024-07-17 17:07:27 +08:00
/// 刷新对应皮肤的模型
/// </summary>
void RefreshModel()
{
LoadModel(curSelectSkinId);
}
/// <summary>
/// 设置皮肤文本内容与按钮状态
2024-06-24 13:53:23 +08:00
/// </summary>
void SetSkinInfoAndButton()
{
if (curSelectSkinId == 0)
{
return;
}
var skinCfg = characterSkinList[curSelectSkinId - 1];
2024-07-17 17:07:27 +08:00
if (CategoryManager.Instance.TryGetSkinItemInfo((int)curCharacterInfo.ID, curSelectSkinId, out DataItem info))//物品皮肤
{
2024-07-17 17:07:27 +08:00
if (CategoryManager.Instance.GetItemCount(info.ID) > 0 || curSelectSkinId == 1)//拥有皮肤
{
Button_Buy.gameObject.SetActive(false);
Button_Wear.gameObject.SetActive(true);
Text_GetWay.text = string.Empty;
}
else
{
Button_Buy.gameObject.SetActive(true);
2024-06-21 17:14:19 +08:00
Button_Buy.transition = Selectable.Transition.None;
Button_Buy.interactable = false;
Button_Wear.gameObject.SetActive(false);
2024-08-27 20:26:13 +08:00
Text_GetWay.text = CommonUtils.GetSkinAcquireCondition(skinCfg);//GetLocalizeText(skinCfg.AcquireCondition);
2024-06-24 13:53:23 +08:00
Text_Buy.text = CommonUtils.GetLocalizeText("SkinInfo_PanelLocalText_Locked");
}
}
2024-06-24 13:53:23 +08:00
else
{
Button_Buy.gameObject.SetActive(false);
Button_Wear.gameObject.SetActive(true);
Text_GetWay.text = string.Empty;
//if (curSelectSkinId != 1)
//{
2024-07-17 17:07:27 +08:00
DebugUtil.LogError("这个皮肤在Item配置表内并未配置为皮肤物品请检查\n角色ID" + curCharacterInfo.ID + " 皮肤ID" + curSelectSkinId);
//}
}
if (curUsingSkinId == curSelectSkinId)
{
Button_Wear.interactable = false;
Text_Wear.text = CommonUtils.GetLocalizeText("SkinInfo_PanelLocalText_Wearing");
}
else
{
Button_Wear.interactable = true;
Text_Wear.text = CommonUtils.GetLocalizeText("SkinInfo_PanelLocalText_DoWear");
}
Text_Name.text = CommonUtils.GetLocalizeText(curCharacterInfo.Name);
2024-08-27 20:26:13 +08:00
Text_SkinName.text = CommonUtils.GetSkinName(skinCfg);
Text_Info.text = CommonUtils.GetSkinDesc(skinCfg);
}
2024-06-24 13:53:23 +08:00
void OnChangeSkinClick()
{
2024-10-18 18:39:38 +08:00
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
2024-06-24 13:53:23 +08:00
if (CategoryManager.Instance.TryGetSkinItemInfo((int)curCharacterInfo.ID, curSelectSkinId, out DataItem info))
{
NetHelper.UseItem((uint)info.ID, 1);
}
else
{
2024-07-17 17:07:27 +08:00
DebugUtil.LogError("这个皮肤在Item配置表内并未配置为皮肤物品请检查\n角色ID" + curCharacterInfo.ID + " 皮肤ID" + curSelectSkinId);
2024-06-24 13:53:23 +08:00
}
}
class SkinScrollView : IPanelScrollView
{
public override void SetScrollRect(PhxhScrollView scrollRect)
{
centerAnchor = true;
canDrag = false;
Self_aligning = false;
base.SetScrollRect(scrollRect);
SetItemRectTrans(CommonUtils.GetComponent<RectTransform>(_scrollRect.itemTemplate.gameObject, "ButtonNotSelect"),
CommonUtils.GetComponent<RectTransform>(_scrollRect.itemTemplate.gameObject, "ButtonChange"));
SetPaddingSize(_itemRectTrans.rect.size);
}
public Vector2 SkinItemSize(int index, int curIndex)
{
if (index == 0 || index == _itemCells.Count + 1)
{
return ScrollPaddingSize;
}
if (index == curIndex)
{
return _itemFullRectTrans.rect.size;
}
else
{
return _itemRectTrans.rect.size;
}
}
/// <summary>
2024-07-17 17:07:27 +08:00
/// 注意操作完请调用_SetSkinPosYListData
/// </summary>
/// <param name="count"></param>
public void InitItemCellList(int count)
{
_itemCells.Clear();
for (int i = 1; i <= count; i++)
{
UIScrollViewItemCell cell = new UIScrollViewItemCell();
cell.index = i;
_itemCells.Add(cell);
}
}
/// <summary>
2024-07-17 17:07:27 +08:00
/// 这个函数用于缓动动画动态的设置需要缩放的item的大小
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public Vector2 GetItemSizeFromList(int index)
{
if (index > _itemCells.Count + 1)
{
DebugUtil.Log("index out of range!index: " + index);
return ScrollPaddingSize;
}
if (index == 0 || index == _itemCells.Count + 1)
{
return ScrollPaddingSize;
}
else
{
return _itemCells[index - 1].size;
}
}
}
}