using UnityEngine; using Live2D.Cubism.Rendering; using System.IO; using FairyGUI; using UnityEngine.Rendering; using YooAsset; using System.Collections.Generic; namespace GFGGame { public class DressUpUtil { public const string HEAD_DEFAULT_RES_NAME = "head"; public const string BODY_DEFAULT_RES_NAME = "body"; public const string ROLE_OBJ_NAME = "Role"; public const string HEAD_SPRITE_NAME = "Head"; public const string BODY_SPRITE_NAME = "Body"; public const string BODY_ANIMATION_NAME = "Body_a"; public const string BODY_EFFECT_OBJ_NAME = "Body_eff"; public const string FORMAT_SPRITE_NAME = "T{0}_s{1}"; public const string FORMAT_ANIMATION_NAME = "T{0}_a{1}"; public const string FORMAT_EFFECT_OBJ_NAME = "T{0}_e{1}"; //public static void AddItem(int itemID, GameObject sceneObj, bool needSetMask = false, bool showAni = true, GameObject parentObj = null, int resLayer = 0) //{ // ItemCfg itemCfg = ItemCfgArray.Instance.GetCfg(itemID); // if (itemCfg == null) return; // if (parentObj == null) // { // if (itemCfg.subType == ConstDressUpItemType.BEI_JING || DressUpMenuItemCfg1Array.Instance.CheckIsSceneTypeBySubType(itemCfg.subType)) // { // parentObj = sceneObj; // } // else // { // //角色 // Transform role = sceneObj.transform.Find(ROLE_OBJ_NAME); // parentObj = role.gameObject; // } // } // showAni = showAni || itemCfg.subType == ConstDressUpItemType.ZHUANG_RONG; // if (resLayer > 0) // { // string layerName = ""; // switch (resLayer) // { // case 1: // layerName = itemCfg.resLayer1; // break; // case 2: // layerName = itemCfg.resLayer2; // break; // case 3: // layerName = itemCfg.resLayer3; // break; // } // if (!string.IsNullOrEmpty(layerName)) // { // UpdateLayerRes(itemCfg, parentObj, resLayer, needSetMask, showAni); // } // } // else // { // //普通层 // if (!string.IsNullOrEmpty(itemCfg.resLayer1)) // { // UpdateLayerRes(itemCfg, parentObj, 1, needSetMask, showAni); // } // //第二层 // if (!string.IsNullOrEmpty(itemCfg.resLayer2)) // { // UpdateLayerRes(itemCfg, parentObj, 2, needSetMask, showAni); // } // //第三层 // if (!string.IsNullOrEmpty(itemCfg.resLayer3)) // { // UpdateLayerRes(itemCfg, parentObj, 3, needSetMask, showAni); // } // } //} public static List AddItemAsync(int itemID, GameObject sceneObj, bool needSetMask = false, bool showAni = true, GameObject parentObj = null, int resLayer = 0) { ItemCfg itemCfg = ItemCfgArray.Instance.GetCfg(itemID); if (itemCfg == null) return null; if (parentObj == null) { if (itemCfg.subType == ConstDressUpItemType.BEI_JING || DressUpMenuItemCfg1Array.Instance.CheckIsSceneTypeBySubType(itemCfg.subType)) { parentObj = sceneObj; } else { //角色 Transform role = sceneObj.transform.Find(ROLE_OBJ_NAME); parentObj = role.gameObject; } } showAni = showAni || itemCfg.subType == ConstDressUpItemType.ZHUANG_RONG; List handlers = new List(); DressUpLayerOperation handler; if (resLayer > 0) { string layerName = ""; switch (resLayer) { case 1: layerName = itemCfg.resLayer1; break; case 2: layerName = itemCfg.resLayer2; break; case 3: layerName = itemCfg.resLayer3; break; } if (!string.IsNullOrEmpty(layerName)) { handler = UpdateLayerResAsync(itemCfg, parentObj, resLayer, needSetMask, showAni); if (handler != null) handlers.Add(handler); } } else { //普通层 if (!string.IsNullOrEmpty(itemCfg.resLayer1)) { handler = UpdateLayerResAsync(itemCfg, parentObj, 1, needSetMask, showAni); if (handler != null) handlers.Add(handler); } //第二层 if (!string.IsNullOrEmpty(itemCfg.resLayer2)) { handler = UpdateLayerResAsync(itemCfg, parentObj, 2, needSetMask, showAni); if (handler != null) handlers.Add(handler); } //第三层 if (!string.IsNullOrEmpty(itemCfg.resLayer3)) { handler = UpdateLayerResAsync(itemCfg, parentObj, 3, needSetMask, showAni); if (handler != null) handlers.Add(handler); } } if(handlers.Count > 0) { return handlers; } return null; } public static void RemoveItem(int itemID, GameObject sceneObj, GameObject parentObj = null) { ItemCfg itemCfg = ItemCfgArray.Instance.GetCfg(itemID); if (itemCfg != null) { if (parentObj == null) { if (itemCfg.subType == ConstDressUpItemType.BEI_JING || DressUpMenuItemCfg1Array.Instance.CheckIsSceneTypeBySubType(itemCfg.subType)) { parentObj = sceneObj; } else { //角色 Transform role = sceneObj.transform.Find(ROLE_OBJ_NAME); parentObj = role.gameObject; } } string spritObjName; string aniObjName; //默认层 if (!string.IsNullOrEmpty(itemCfg.resLayer1)) { spritObjName = string.Format(FORMAT_SPRITE_NAME, itemCfg.subType, 1); TryRemoveObj(parentObj, spritObjName); aniObjName = string.Format(FORMAT_ANIMATION_NAME, itemCfg.subType, 1); TryRemoveObj(parentObj, aniObjName); aniObjName = string.Format(FORMAT_EFFECT_OBJ_NAME, itemCfg.subType, 1); TryRemoveObj(parentObj, aniObjName); } //特殊层 if (!string.IsNullOrEmpty(itemCfg.resLayer2)) { spritObjName = string.Format(FORMAT_SPRITE_NAME, itemCfg.subType, 2); TryRemoveObj(parentObj, spritObjName); aniObjName = string.Format(FORMAT_ANIMATION_NAME, itemCfg.subType, 2); TryRemoveObj(parentObj, aniObjName); aniObjName = string.Format(FORMAT_EFFECT_OBJ_NAME, itemCfg.subType, 2); TryRemoveObj(parentObj, aniObjName); } //第三层 if (!string.IsNullOrEmpty(itemCfg.resLayer3)) { spritObjName = string.Format(FORMAT_SPRITE_NAME, itemCfg.subType, 3); TryRemoveObj(parentObj, spritObjName); aniObjName = string.Format(FORMAT_ANIMATION_NAME, itemCfg.subType, 3); TryRemoveObj(parentObj, aniObjName); aniObjName = string.Format(FORMAT_EFFECT_OBJ_NAME, itemCfg.subType, 3); TryRemoveObj(parentObj, aniObjName); } } } public static DressUpRemoveOperation RemoveItemAsync(int itemID, GameObject sceneObj, GameObject parentObj = null) { var operation = new DressUpRemoveOperation(itemID, sceneObj, parentObj); operation.Begin(); return operation; } //public static void UpdateHead(bool show, GameObject sceneObj, bool needSetMask = false, GameObject parentObj = null) //{ // var roleTf = sceneObj.transform.Find(ROLE_OBJ_NAME); // parentObj = parentObj == null ? roleTf.gameObject : parentObj; // string resPath = ResPathUtil.GetDressUpPath(HEAD_DEFAULT_RES_NAME); // Transform transform_t = parentObj.transform.Find(HEAD_SPRITE_NAME); // if (show) // { // if (transform_t != null) // { // transform_t.gameObject.SetActive(true); // return; // } // AddSpriteObj(resPath, HEAD_SPRITE_NAME, parentObj, 1, needSetMask); // } // else // { // if (transform_t == null) // { // return; // } // transform_t.gameObject.SetActive(false); // } //} public static DressUpLayerOperation UpdateHeadAsync(bool show, GameObject sceneObj, bool needSetMask = false, GameObject parentObj = null) { var roleTf = sceneObj.transform.Find(ROLE_OBJ_NAME); parentObj = parentObj == null ? roleTf.gameObject : parentObj; string res = null; string resPath = null; if(show) { res = HEAD_DEFAULT_RES_NAME; resPath = ResPathUtil.GetDressUpPath(res); } DressUpLayerOperation handler = new DressUpLayerOperation(parentObj, needSetMask, false, resPath, null); handler.InitHead(); handler.Begin(); return handler; } //public static void UpdateBody(string actionRes, GameObject sceneObj, bool needSetMask = false, GameObject parentObj = null) //{ // //角色 // var roleTf = sceneObj.transform.Find(ROLE_OBJ_NAME); // parentObj = parentObj == null ? roleTf.gameObject : parentObj; // var extPng = "png"; // if (!string.IsNullOrEmpty(actionRes)) // { // string resPath = ResPathUtil.GetDressUpAnimationPath(actionRes); // if (GetGameObjExisted(parentObj, BODY_ANIMATION_NAME, resPath) != null) // { // return; // } // } // else // { // string resPath = ResPathUtil.GetDressUpPath(BODY_DEFAULT_RES_NAME, extPng); // if (GetGameObjExisted(parentObj, BODY_SPRITE_NAME, resPath) != null) // { // return; // } // } // var removeBodyAni = TryRemoveObj(parentObj, BODY_ANIMATION_NAME); // TryRemoveObj(parentObj, BODY_EFFECT_OBJ_NAME); // TryRemoveObj(parentObj, BODY_SPRITE_NAME); // if (!string.IsNullOrEmpty(actionRes)) // { // string aniResPath = ResPathUtil.GetDressUpAnimationPath(actionRes); // var addAniObj = AddAnimationObj(aniResPath, BODY_ANIMATION_NAME, parentObj, 0); // //特效 // var resPath = ResPathUtil.GetDressUpEffectPath(actionRes, addAniObj != null); // TryAddEffectObj(resPath, BODY_EFFECT_OBJ_NAME, parentObj, 0); // } // else // { // AddSpriteObj(ResPathUtil.GetDressUpPath(BODY_DEFAULT_RES_NAME), BODY_SPRITE_NAME, parentObj, 0, needSetMask); // if (removeBodyAni) // { // parentObj.transform.SetPositionAndRotation(new Vector3(), new Quaternion()); // } // } //} public static DressUpLayerOperation UpdateBodyAsync(string actionRes, GameObject sceneObj, bool needSetMask = false, GameObject parentObj = null) { //角色 var roleTf = sceneObj.transform.Find(ROLE_OBJ_NAME); parentObj = parentObj == null ? roleTf.gameObject : parentObj; var extPng = "png"; string resPath = null; string effectResPath = null; string objName; bool showAni = !string.IsNullOrEmpty(actionRes); string aniResPath = null; if (showAni) { aniResPath = ResPathUtil.GetDressUpAnimationPath(actionRes); if(!YooAssets.CheckResExist(aniResPath)) { showAni = false; } } if(showAni) { resPath = aniResPath; objName = BODY_ANIMATION_NAME; //特效 effectResPath = ResPathUtil.GetDressUpEffectPath(actionRes, true); if (!YooAssets.CheckResExist(effectResPath)) { effectResPath = null; } } else { resPath = ResPathUtil.GetDressUpPath(BODY_DEFAULT_RES_NAME, extPng); objName = BODY_SPRITE_NAME; } if (GetGameObjExisted(parentObj, objName, resPath) != null || !YooAssets.CheckResExist(resPath)) { return null; } DressUpLayerOperation handler = new DressUpLayerOperation(parentObj, needSetMask, showAni, resPath, effectResPath); handler.InitBody(); handler.Begin(); return handler; } //private static void UpdateLayerRes(ItemCfg itemCfg, GameObject parentObj, int layerId, bool needSetMask, bool showAni = true) //{ // string res = ResPathUtil.GetDressUpItemLayerRes(itemCfg, layerId); // string resPath = ResPathUtil.GetDressUpPath(itemCfg, layerId); // int sortingOrder = ItemTypeCfgArray.Instance.GetSortingOrder(itemCfg.subType, layerId); // //清理旧的 // var spritObjName = string.Format(FORMAT_SPRITE_NAME, itemCfg.subType, layerId); // TryRemoveObj(parentObj, spritObjName); // var objName = string.Format(FORMAT_ANIMATION_NAME, itemCfg.subType, layerId); // TryRemoveObj(parentObj, objName); // string ext = ItemUtil.GetItemResExt(itemCfg.itemType, itemCfg.subType); // GameObject spriteObj = null; // if (DressUpMenuItemCfg1Array.Instance.CheckIsDefaultType(itemCfg.subType)) // { // //默认类型的部件需要先添加静态图,防止加载动画有延迟,出现光头 // spriteObj = AddSpriteObj(resPath, spritObjName, parentObj, sortingOrder, needSetMask); // } // GameObject addAniObj = null; // if (showAni) // { // string aniResPath = ResPathUtil.GetDressUpAnimationPath(res); // addAniObj = AddAnimationObj(aniResPath, objName, parentObj, sortingOrder); // if (addAniObj != null && spriteObj != null) // { // var dressUpPart = addAniObj.GetComponent(); // if (dressUpPart == null) // { // dressUpPart = addAniObj.AddComponent(); // } // dressUpPart.OnTimer = (obj) => // { // if (parentObj != null && parentObj.transform != null) // { // string resPath = ResPathUtil.GetDressUpPath(itemCfg, layerId); // spriteObj = GetGameObjExisted(parentObj, spritObjName, resPath); // if (spriteObj != null) // { // PrefabManager.Instance.Restore(spriteObj); // } // //Transform tf = parentObj.transform.Find(spritObjName); // //if (tf != null && tf.gameObject != null && tf.gameObject.activeInHierarchy) // //{ // // var assetDisposer = tf.gameObject.GetComponent(); // // if (assetDisposer != null) // // { // // if (!string.IsNullOrEmpty(assetDisposer.resPath)) // // { // // string resPath = ResPathUtil.GetDressUpPath(itemCfg, layerId); // // if (assetDisposer.resPath == resPath) // // { // // TryRemoveObj(parentObj, spritObjName); // // } // // } // // } // //} // } // }; // Timers.inst.Add(0.03f, 1, dressUpPart.OnTimer); // } // } // if (spriteObj == null && addAniObj == null) // { // //如果两个都没有,就添加静态图 // spriteObj = AddSpriteObj(resPath, spritObjName, parentObj, sortingOrder, needSetMask); // } // objName = string.Format(FORMAT_EFFECT_OBJ_NAME, itemCfg.subType, layerId); // TryRemoveObj(parentObj, objName); // resPath = ResPathUtil.GetDressUpEffectPath(res, addAniObj != null); // TryAddEffectObj(resPath, objName, parentObj, sortingOrder); //} private static DressUpLayerOperation UpdateLayerResAsync(ItemCfg itemCfg, GameObject parentObj, int layerId, bool needSetMask, bool showAni = true) { string res = ResPathUtil.GetDressUpItemLayerRes(itemCfg, layerId); string resPath; string aniResPath = null; //根据资源存在与否再次检查是否播放动画 if (showAni) { aniResPath = ResPathUtil.GetDressUpAnimationPath(res); if(!YooAssets.CheckResExist(aniResPath)) { showAni = false; } } string objName; if (showAni) { resPath = aniResPath; objName = string.Format(DressUpUtil.FORMAT_ANIMATION_NAME, itemCfg.subType, layerId); } else { resPath = ResPathUtil.GetDressUpPath(itemCfg, layerId); objName = string.Format(DressUpUtil.FORMAT_SPRITE_NAME, itemCfg.subType, layerId); } var gameObj = DressUpUtil.GetGameObjExisted(parentObj, objName, resPath); if (gameObj != null || !YooAssets.CheckResExist(resPath)) { return null; } //特效 string effectResPath = ResPathUtil.GetDressUpEffectPath(res, showAni); if (!YooAssets.CheckResExist(effectResPath)) { effectResPath = null; } DressUpLayerOperation handler = new DressUpLayerOperation(parentObj, needSetMask, showAni, resPath, effectResPath); handler.InitLayer(itemCfg, layerId); handler.Begin(); return handler; } public static GameObject AddSpriteObj(string resPath, string objName, GameObject parentObj, int sortingOrder, bool needSetMask) { if (!YooAssets.CheckResExist(resPath)) { return null; } var gameObj = GetGameObjExisted(parentObj, objName, resPath); if (gameObj != null) { return gameObj; } SpriteRenderer spr = null; gameObj = parentObj.transform.Find(objName)?.gameObject; if (gameObj == null) { gameObj = new GameObject(objName); gameObj.transform.SetParent(parentObj.transform, false); } spr = gameObj.GetComponent(); if (spr == null) { spr = gameObj.AddComponent(); } float tx, ty; LoadSpritePos(resPath, out tx, out ty); gameObj.transform.localPosition = new Vector3(tx, ty, gameObj.transform.localPosition.z); SpriteHelper.AddSpriteTo(spr, resPath); spr.sortingOrder = sortingOrder; if (needSetMask) { spr.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; if (parentObj.transform.parent != null && parentObj.transform.parent.name == "targetRole") { spr.maskInteraction = SpriteMaskInteraction.VisibleOutsideMask; } else { spr.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; } } else { spr.maskInteraction = SpriteMaskInteraction.None; } return gameObj; } public static GameObject AddAnimationObj(string resPath, string objName, GameObject parentObj, int sortingOrder) { var gameObj = GetGameObjExisted(parentObj, objName, resPath); if (gameObj != null) { return gameObj; } gameObj = CreateObj(resPath); if(gameObj == null) { return null; } if (objName == BODY_ANIMATION_NAME) { //如果是动作动画,就根据动画位置及角度信息设置给Role对象 parentObj.transform.SetPositionAndRotation(gameObj.transform.localPosition, gameObj.transform.localRotation); gameObj.transform.SetPositionAndRotation(new Vector3(), new Quaternion()); } gameObj.name = objName; gameObj.transform.SetParent(parentObj.transform, false); var render = gameObj.GetComponent(); if (render == null && gameObj.transform.childCount > 0) { var childObj = gameObj.transform.GetChild(0); if (childObj != null) { render = childObj.GetComponent(); } } if (render != null && render.gameObject.activeSelf == true) { render.SortingOrder = sortingOrder; } SetRenderersOrder(gameObj, sortingOrder); return gameObj; } public static GameObject TryAddEffectObj(string resPath, string objName, GameObject parentObj, int sortingOrder) { var gameObj = GetGameObjExisted(parentObj, objName, resPath); if (gameObj != null) { return gameObj; } gameObj = CreateObj(resPath); if (gameObj == null) { return null; } gameObj.transform.SetParent(parentObj.transform, false); gameObj.name = objName; var sortingGroup = gameObj.transform.GetComponent(); if (sortingGroup != null) { GameObject.Destroy(sortingGroup); } SetRenderersOrder(gameObj, sortingOrder + 1);//特效层默认高一个层级 return gameObj; } public static bool TryRemoveObj(GameObject parentObj, string objName) { if (parentObj == null) { return false; } Transform transform = parentObj.transform.Find(objName); if (transform != null) { GameObject gameObj = transform.gameObject; if (gameObj != null) { PrefabManager.Instance.Restore(gameObj); return true; } } return false; } public static GameObject GetGameObjExisted(GameObject parentObj, string objName, string resPath) { if (parentObj == null) { return null; } Transform transform = parentObj.transform.Find(objName); if (transform != null) { GameObject gameObj = transform.gameObject; if (gameObj != null) { var assetReleaser = gameObj.GetComponent(); if (assetReleaser != null) { if (assetReleaser.ResPath == resPath) { return gameObj; } } } } return null; } public static GameObject CreateObj(string resPath) { if (!YooAssets.CheckResExist(resPath)) { return null; } //var handle = YooAssets.LoadAssetSync(resPath); //Sprite sp = handle.AssetObject as Sprite; var gameObj = PrefabManager.Instance.SpawnSync(resPath); //AddAssetReleaser(gameObj, resPath); return gameObj; } public static void LoadSpritePos(string resPath, out float tx, out float ty) { int index = resPath.LastIndexOf('.'); resPath = resPath.Substring(0, index) + ".bytes"; //resPath = resPath.Replace(".png", ".bytes"); //resPath = resPath.Replace(".jpg", ".bytes"); if (YooAssets.CheckResExist(resPath)) { //var asset = GFGAsset.Load(resPath); var handle = YooAssets.LoadAssetSync(resPath); TextAsset asset = handle.AssetObject as TextAsset; var st = new MemoryStream(asset.bytes); var br = new BinaryReader(st); tx = br.ReadInt32() / 100f; ty = -br.ReadInt32() / 100f; //GFGAsset.Release(resPath); handle.Release(); } else { tx = 0; ty = 0; } } private static void SetRenderersOrder(GameObject gameObj, int sortingOrder, bool isAdd = false) { var meshRenderers = gameObj.transform.GetComponentsInChildren(); for (int i = 0; i < meshRenderers.Length; i++) { var renderer = meshRenderers[i].GetComponent(); if (renderer != null) { if (isAdd) { renderer.sortingOrder = renderer.sortingOrder + sortingOrder; } else { renderer.sortingOrder = sortingOrder; } } } ParticleSystem[] particles = gameObj.transform.GetComponentsInChildren(); for (int i = 0; i < particles.Length; i++) { var renderer = particles[i].GetComponent(); if (renderer != null) { if (isAdd) { renderer.sortingOrder = renderer.sortingOrder + sortingOrder; } else { renderer.sortingOrder = sortingOrder; } } } } //public static void SetSpriteRenderSortingOrder(GameObject gameObj, int sortingOrder, bool isAdd = false) //{ // SpriteRenderer[] spriteRenders = gameObj.transform.GetComponentsInChildren(); // for (int i = 0; i < spriteRenders.Length; i++) // { // if (isAdd) // { // spriteRenders[i].sortingOrder = spriteRenders[i].sortingOrder + sortingOrder; // } // else // { // spriteRenders[i].sortingOrder = sortingOrder; // } // } //} } }