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

695 lines
23 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.Common;
using Gameplay.Emoji;
using Gameplay.Net;
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
{
#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;
private RawImage rawImageGaussianBlurMask;
#endregion
ShowModelPreviewNode node;
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;
/// <summary>
/// 用于保存尚未加载节点前创建的模型
/// </summary>
private GameObject ModelTemp = null;
Dictionary<int, GameObject> characterModels = new();
PosterFader fader = new PosterFader();
public static async UniTask<UIWindow> Open(CharacterDataInfo characterData)
{
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;
}
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();
//TODO 目前半身图使用好感度图片路径
var halfpath = CommonUtils.GetCharacterPicPath((int)curCharacterInfo.ID, CommonUtils.ECharacterPicPathType.Favorable, dataCharacter.SkinID);
AssetManager.Instance.PostPreload<Sprite>(halfpath).Forget();
//DebugUtil.Log("目前半身图暂用使用路径为:" + halfpath + ",请待补充相关资源与更新配置表后在此处更新相关代码");
}
}
async void LoadModel(int skinID)
{
if (characterModels.ContainsKey(skinID))
{
_sampleModel = characterModels[skinID];
}
else
{
rt.gameObject.SetActive(false);
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);
}
GameObject model = null;
if (node.modelParent == null)//模型节点异步加载尚未完成
{
DebugUtil.Log("模型节点异步加载尚未完成");
model = Object.Instantiate(_sampleModel);
ModelTemp = model;
}
else
{
model = Object.Instantiate(_sampleModel, node.modelParent.transform, true);
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.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");
}
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);
}
async void ModelNodeInit()
{
rt.gameObject.SetActive(false);
//展示界面时,创建模型节点
await CreateModelNode();
if (ModelTemp != null)
{
ModelTemp.transform.SetParent(node.modelParent.transform);
_instModel = ModelTemp;
ModelTemp = null;
_instModel.transform.ResetLocals();
_instModel.transform.localPosition = new(2, 0, 2);
_instModel.transform.localRotation = Quaternion.Euler(new(0, 50, 0));
}
}
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);
RefreshPreviewNodeRawImage();
rt.gameObject.SetActive(true);
}
}
private void RefreshPreviewNodeRawImage()
{
if (node != null)
{
rt.texture = node.RTexture;
}
}
// 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");
rt = GetComponent<RawImage>("Image_BG/UpperUI/Image_LeftBG/rt");
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);
ModelNodeInit();
}
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);
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
}
#region Button Event
void OnShowPicButton()
{
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
ShowAllPic(true);
}
void OnReturnButton()
{
if(isShowPosterPic)
{
ShowAllPic(false);
SetSkinInfoAndButton();
}
else
{
CloseWindow();
}
}
void OnHomeButton()
{
CommonUtils.HomeToMain();
}
void _OnClickSkinItem(int to)
{
if (curSelectSkinId == to)
{
return;
}
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();
});
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;
}
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);
RefreshModel();
//TODO 尺寸调整
if (curSelectSkinId != 1)
{
Image_Poster.transform.localPosition = Vector3.zero;
Image_Poster.SetNativeSize();
var heightVal = Image_Poster.sprite.rect.height / Screen.height;
var widthVal = Image_Poster.sprite.rect.width / Screen.width;
var height = UIRoot.Instance.RootCanvas.GetComponent<RectTransform>().sizeDelta.y;
var width = UIRoot.Instance.RootCanvas.GetComponent<RectTransform>().sizeDelta.x;
if (heightVal > widthVal)//高限
{
Image_Poster.GetComponent<RectTransform>().sizeDelta = new Vector2(height * Image_Poster.sprite.rect.width / Image_Poster.sprite.rect.height, height);
}
else//宽限
{
Image_Poster.GetComponent<RectTransform>().sizeDelta = new Vector2(width, width * Image_Poster.sprite.rect.height / Image_Poster.sprite.rect.width);
}
//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(false);//Button_Buy.gameObject.SetActive(true);
//Button_Buy.transition = Selectable.Transition.None;
//Button_Buy.interactable = false;
Button_Wear.gameObject.SetActive(false);
Text_GetWay.text = CommonUtils.GetSkinAcquireCondition(skinCfg);//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.GetSkinName(skinCfg);
Text_Info.text = CommonUtils.GetSkinDesc(skinCfg);
}
void OnChangeSkinClick()
{
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
if (CategoryManager.Instance.TryGetSkinItemInfo((int)curCharacterInfo.ID, curSelectSkinId, out DataItem info))
{
NetHelper.UseItem((uint)info.ID, 1);
ShowManager.Instance.RefreshShow(cfg.ShowCfg.E_ShowSceneType.Main);
}
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 ScrollPaddingSize;
}
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 ScrollPaddingSize;
}
if (index == 0 || index == _itemCells.Count + 1)
{
return ScrollPaddingSize;
}
else
{
return _itemCells[index - 1].size;
}
}
}
}