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

608 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using cfg.ActorCfg;
using cfg.CharacterCfg;
using Cysharp.Threading.Tasks;
using Framework;
using Gameplay;
using Gameplay.Emoji;
using Gameplay.Net;
using Gameplay.Performance;
using Gameplay.Utils;
using PhxhSDK;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Playables;
using UnityEngine.UI;
using Button = UnityEngine.UI.Button;
using Image = UnityEngine.UI.Image;
public class SkinChangeController : UIWindow
{
//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;
public GameObject UpperUI;
private RawImage rawImageGaussianBlurMask;
///Auto Gen End///
private PinchZoomModule PinchZoom;
private DragForUI Drag;
private PhxhSDK.PhxhScrollView ScrollView;
SkinScrollView skinScrollView = new SkinScrollView();
GameObject _sampleModel;
GameObject _instModel;
private UnitEmojiManager _emojiManager;
private bool isShowPosterPic = false;
private CharacterDataInfo curCharacterInfo;
private int curSelectSkinId;
private int curUsingSkinId;
List<DataCharacterSkin> characterSkinList;
Dictionary<int, Sprite> posterLargePics = new();
Dictionary<int, Sprite> posterHalfPics = new();
Dictionary<int, GameObject> characterModels = new();
PosterFader fader = new PosterFader();
public static async UniTask<UIWindow> Open(CharacterDataInfo characterData)
{
await 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;
curSelectSkinId = (int)curCharacterInfo.SkinID;// + 1;
if(curSelectSkinId == 0)
{
DebugUtil.LogError("当前角色数据内皮肤ID为0已设置为默认皮肤ID");
curSelectSkinId = 1;
}
curUsingSkinId = curSelectSkinId;
characterSkinList = CommonUtils.GetCharacterSkinCfgList((int)curCharacterInfo.ID);
PreLoadSpritesAsync();
}
void refreshCharacterInfo()
{
curCharacterInfo = CharacterDataInfoManager.Instance.GetCharacterInfo(curCharacterInfo.ID);
curSelectSkinId = (int)curCharacterInfo.SkinID;
if (curSelectSkinId == 0)
{
DebugUtil.LogError("当前角色数据内皮肤ID为0已设置为默认皮肤ID");
curSelectSkinId = 1;
}
curUsingSkinId = curSelectSkinId;
}
async void PreLoadSpritesAsync()
{
foreach (var dataCharacter in characterSkinList)
{
string path = CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Poster, dataCharacter.SkinID);
var sprite = await LoadAssetAsync<Sprite>(path);
if (!posterLargePics.ContainsKey(dataCharacter.SkinID))
posterLargePics.Add(dataCharacter.SkinID, sprite);
else
posterLargePics[dataCharacter.SkinID] = sprite;
//TODO 目前半身图使用好感度图片路径
path = CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Favorable, dataCharacter.SkinID);
DebugUtil.Log("目前半身图暂用使用路径为:" + path + ",请待补充相关资源与更新配置表后在此处更新相关代码");
var halfSprite = await LoadAssetAsync<Sprite>(path);
if (!posterHalfPics.ContainsKey(dataCharacter.SkinID))
posterHalfPics.Add(dataCharacter.SkinID, halfSprite);
else
posterHalfPics[dataCharacter.SkinID] = halfSprite;
}
}
async void LoadModel(int skinID)
{
if (characterModels.ContainsKey(skinID))
{
_sampleModel = characterModels[skinID];
}
else
{
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);
}
//var prefabPath = PathEx.GetCharacterDisplayModelPath(curCharacterInfo.Cfg.NameID);
//_sampleModel = await LoadAssetAsync<GameObject>(prefabPath);
GameObject model = Object.Instantiate(_sampleModel, Image_ModelPosition.transform, true);
if (_instModel != null)
Object.Destroy(_instModel);
_instModel = model;
model.transform.localPosition = new Vector3(0, -200, -300);
model.transform.localRotation = new(0, 180, 0, 1);
model.transform.localScale = 300 * Vector3.one;
model.gameObject.SetLayerEx(5);
var pd = model.GetComponentInChildren<PlayableDirector>();
if (pd != null)
{
pd.enabled = false;
}
var animator = model.GetComponentInChildren<Animator>();
if (animator != null)
{
animator.Play("standready001");
}
else
{
DebugUtil.LogError("模型中未找到Animator组件请检查模型配置");
}
_InitEmoji();
}
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);
}
// Use this for initialization
public override void OnInit()
{
//bind UI GameObj
SkinChangeBinder.GetComponents(this);
UpperUI = FindObj("Image_BG/UpperUI");
rawImageGaussianBlurMask = GetComponent<RawImage>("GaussianBlurMask");
rawImageGaussianBlurMask.texture = CommonUtils.GetScreenTexture2D();
Image_Poster.GetComponent<RectTransform>().sizeDelta = Vector2.zero;
PinchZoom = GetComponent<PinchZoomModule>("Image_BG/Image_Poster");
//Drag = GetComponent<DragForUI>("Image_BG/Image_Poster");
ScrollView = GetComponent<PhxhSDK.PhxhScrollView>("Image_BG/UpperUI/ChangeSkin/ScrollView");
skinScrollView.SetScrollRect(ScrollView);
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);
BindButton(Button_Home, OnHomeButton);
BindButton(Button_Wear, OnChangeSkinClick);
//LoadModel(curSelectSkinId);
//Drag.OnDragStarted += OnDragBegin;
//Drag.OnDraging += OnDrag;
//Drag.OnDragCompleted += OnDragEnd;
PinchZoom.OnDragStarted += OnDragBegin;
PinchZoom.OnDraging += OnDrag;
PinchZoom.OnDragCompleted += OnDragEnd;
EventManager.Instance.Register(EventManager.EventName.CharacterInfoRefresh, CharacterInfoRefreshListener);
_SetSkinPosYListData();
skinScrollView.UpdateData();
skinScrollView.ScrollTo(curSelectSkinId);
}
void CharacterInfoRefreshListener()
{
refreshCharacterInfo();
SetSkinInfoAndButton();
}
//invoke when open window
protected override void OnShowWindow(object data = null)
{
base.OnShowWindow(data);
if (PinchZoom != null)
PinchZoom.enabled = false;
isShowPosterPic = false;
SetSkinInfoAndButton();
SetPosterSkinPic();
}
//invoke when reload window
protected override void OnReloadWindow(object data = null)
{
}
//invoke when close window
protected override void OnHideWindow()
{
base.OnHideWindow();
EventManager.Instance.Send(EventManager.EventName.EN_UIControllCultivateMainInput, true);
}
//invoke when destroy
public override void OnRelease()
{
base.OnRelease();
EventManager.Instance.Unregister(EventManager.EventName.CharacterInfoRefresh, CharacterInfoRefreshListener);
}
#region Button Event
void OnShowPicButton()
{
ShowAllPic(true);
}
void OnReturnButton()
{
if(isShowPosterPic)
{
ShowAllPic(false);
SetSkinInfoAndButton();
}
else
{
if (_instModel != null)
Object.Destroy(_instModel);
CloseWindow();
}
}
void OnHomeButton()
{
if (_instModel != null)
Object.Destroy(_instModel);
UIManager.Instance.CloseAllNormalExcept(UINameConst.UI_MainPanel);
}
void _OnClickSkinItem(int to)
{
if (curSelectSkinId == to)
{
return;
}
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();
});
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 / PerformanceManager.instance.fullScreenWidth;
}
void OnDrag(PointerEventData data)
{
if(!isShowPosterPic)
{
return;
}
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(-1, 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 async void _RefreshSkinItem(int index, RectTransform item)
{
if (index <= 0 || index >= characterSkinList.Count + 1)
{
item.gameObject.SetActive(false);
return;
}
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");
if (posterHalfPics.ContainsKey(index))
imgSkin.sprite = posterHalfPics[index];
else
imgSkin.sprite = await LoadAssetAsync<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");
}
}
}
async void SetPosterSkinPic()
{
if (posterLargePics.ContainsKey(curSelectSkinId))
{
Image_Poster.sprite = posterLargePics[curSelectSkinId];
}
else
{
var posterPic =
CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Poster, curSelectSkinId);
Image_Poster.sprite = await LoadAssetAsync<Sprite>(posterPic);
}
RefreshModel();
//TODO 尺寸调整
if (curSelectSkinId != 1)
{
Image_Poster.transform.localPosition = Vector3.zero;
Image_Poster.SetNativeSize();
if (Image_Poster.sprite.rect.width >= Image_Poster.sprite.rect.height)
{
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);
}
}
else
{
Image_Poster.transform.position = Image_PosterPreview.transform.position;
Image_Poster.GetComponent<RectTransform>().sizeDelta = Image_PosterPreview.GetComponent<RectTransform>().sizeDelta;
}
return;
}
/// <summary>
/// 刷新对应皮肤的模型
/// </summary>
void RefreshModel()
{
LoadModel(curSelectSkinId);
}
/// <summary>
/// 设置皮肤文本内容与按钮状态
/// </summary>
void SetSkinInfoAndButton()
{
if (curSelectSkinId == 0)
{
return;
}
var skinCfg = characterSkinList[curSelectSkinId - 1];
if (CategoryManager.Instance.TryGetSkinItemInfo((int)curCharacterInfo.ID, curSelectSkinId, out DataItem info))//物品皮肤
{
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);
Button_Buy.transition = Selectable.Transition.None;
Button_Buy.interactable = false;
Button_Wear.gameObject.SetActive(false);
Text_GetWay.text = CommonUtils.GetLocalizeText(skinCfg.AcquireCondition);
Text_Buy.text = CommonUtils.GetLocalizeText("SkinInfo_PanelLocalText_Locked");
}
}
else
{
Button_Buy.gameObject.SetActive(false);
Button_Wear.gameObject.SetActive(true);
Text_GetWay.text = string.Empty;
//if (curSelectSkinId != 1)
//{
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);
Text_SkinName.text = CommonUtils.GetLocalizeText(skinCfg.SkinName);
Text_Info.text = CommonUtils.GetLocalizeText(skinCfg.SkinDesc);
}
void OnChangeSkinClick()
{
if (CategoryManager.Instance.TryGetSkinItemInfo((int)curCharacterInfo.ID, curSelectSkinId, out DataItem info))
{
NetHelper.UseItem((uint)info.ID, 1);
}
else
{
DebugUtil.LogError("这个皮肤在Item配置表内并未配置为皮肤物品请检查\n角色ID" + curCharacterInfo.ID + " 皮肤ID" + curSelectSkinId);
}
}
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 _itemRectTrans.rect.size;
}
if (index == curIndex)
{
return _itemFullRectTrans.rect.size;
}
else
{
return _itemRectTrans.rect.size;
}
}
/// <summary>
/// 注意操作完请调用_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>
/// 这个函数用于缓动动画动态的设置需要缩放的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 _itemFullRectTrans.rect.size;
}
if (index == 0 || index == _itemCells.Count + 1)
{
return _itemFullRectTrans.rect.size;
}
else
{
return _itemCells[index - 1].size;
}
}
}
}