using UnityEngine; using System; using Live2D.Cubism.Rendering; using System.IO; namespace GFGGame { public class DressUpUtil { private const string BODY_DEFAULT_RES_NAME = "renmo"; private const string ROLE_OBJ_NAME = "Role"; private const string BODY_OBJ_NAME = "Body"; private const string BODY_EFFECT_OBJ_NAME = "Body_eff"; private const string FORMAT_OBJ_NAME = "T{0}_{1}"; private const string FORMAT_EFFECT_OBJ_NAME = "T{0}_eff"; private const string FORMAT_LAYER_RES_NAME_WITH_T = "{0}_t"; public static void AddItem(int itemID, GameObject sceneObj, bool needSetMask = false, bool showAni = true, GameObject parentObj = null, int resLayer = int.MinValue) { ItemCfg itemCfg = ItemCfgArray.Instance.GetCfg(itemID); if (itemCfg != null) { // GameObject parentObj = null; if (parentObj == null) { if (itemCfg.subType == ConstDressUpItemType.BEI_JING) { parentObj = sceneObj; } else { //角色 Transform role = sceneObj.transform.Find(ROLE_OBJ_NAME); parentObj = role.gameObject; } } if (resLayer > int.MinValue) { updateLayerRes(itemCfg, parentObj, resLayer, resLayer == 2, needSetMask, showAni); } else { //普通层 if (itemCfg.resLayer1 > 0) { updateLayerRes(itemCfg, parentObj, 1, itemCfg.resLayer1 == 2, needSetMask, showAni); } //特殊层 if (itemCfg.resLayer2 > 0) { updateLayerRes(itemCfg, parentObj, 2, itemCfg.resLayer2 == 2, needSetMask, showAni); } } //特效 if (itemCfg.effLayer > 0) { var objName = string.Format(FORMAT_EFFECT_OBJ_NAME, itemCfg.subType); ItemTypeCfg typeCfg = ItemTypeCfgArray.Instance.GetCfg(itemCfg.subType); int sortingOrder = typeCfg.defaultLayer; if (itemCfg.effLayer == 2) { sortingOrder = typeCfg.specialLayer; } AddEffectObj(itemCfg.res, objName, parentObj, sortingOrder); } } } public static void RemoveItem(int itemID, GameObject sceneObj) { ItemCfg itemCfg = ItemCfgArray.Instance.GetCfg(itemID); if (itemCfg != null) { GameObject parentObj = null; if (itemCfg.subType == (int)ConstDressUpItemType.BEI_JING) { parentObj = sceneObj; } else { //角色 Transform role = sceneObj.transform.Find(ROLE_OBJ_NAME); parentObj = role.gameObject; } string objName; //默认层 if (itemCfg.resLayer1 > 0) { objName = string.Format(FORMAT_OBJ_NAME, itemCfg.subType, 1); Transform transform = parentObj.transform.Find(objName); if (transform != null) { GameObject gameObj = transform.gameObject; if (gameObj != null) { GameObject.DestroyImmediate(gameObj); } } } //特殊层 if (itemCfg.resLayer2 > 0) { objName = string.Format(FORMAT_OBJ_NAME, itemCfg.subType, 2); Transform transform_t = parentObj.transform.Find(objName); if (transform_t != null) { GameObject gameObj_t = transform_t.gameObject; if (gameObj_t != null) { GameObject.DestroyImmediate(gameObj_t); } } } //特效 if (itemCfg.effLayer > 0) { string effObjName = string.Format(FORMAT_EFFECT_OBJ_NAME, itemCfg.subType); var effTf = parentObj.transform.Find(effObjName); if (effTf != null) { GameObject.DestroyImmediate(effTf.gameObject); } } } } public static void UpdateBody(string res, GameObject sceneObj, bool isAni = false, string effRes = null, bool needSetMask = false, GameObject parentObj = null) { //角色 Transform roleTf = sceneObj.transform.Find(ROLE_OBJ_NAME); GameObject roleObj = parentObj == null ? roleTf.gameObject : parentObj; if (res == null) { res = BODY_DEFAULT_RES_NAME; } var objName = BODY_OBJ_NAME; Transform tf = roleObj.transform.Find(objName); if (tf != null) { GameObject.DestroyImmediate(tf.gameObject); tf = null; } if (isAni) { AddAnimationObj(res, objName, roleObj, 0); } else { AddSpriteObj(res, "png", objName, roleObj, 0, needSetMask); } //特效 objName = BODY_EFFECT_OBJ_NAME; tf = roleObj.transform.Find(objName); if (tf != null) { GameObject.DestroyImmediate(tf.gameObject); } if (!string.IsNullOrEmpty(effRes)) { AddEffectObj(effRes, objName, roleObj, 0); } } public static void AddAssetReleaser(GameObject gameObj, string resPath) { var assetDisposer = gameObj.AddComponent(); assetDisposer.resPath = resPath; } public static void ChangeAssetReleaser(GameObject gameObj, string resPath) { var assetDisposer = gameObj.GetComponent(); if (assetDisposer == null) { assetDisposer = gameObj.AddComponent(); } assetDisposer.resPath = resPath; } private static void updateLayerRes(ItemCfg itemCfg, GameObject parentObj, int layerId, bool isT, bool needSetMask, bool showAni = true) { ItemTypeCfg typeCfg = ItemTypeCfgArray.Instance.GetCfg(itemCfg.subType); string objName = string.Format(FORMAT_OBJ_NAME, typeCfg.type, layerId); string res = itemCfg.res; int sortingOrder = typeCfg.defaultLayer; if (layerId == 2) { sortingOrder = typeCfg.specialLayer; } if (isT) { res = string.Format(FORMAT_LAYER_RES_NAME_WITH_T, res); } Transform tf = parentObj.transform.Find(objName); if (tf != null) { GameObject.DestroyImmediate(tf.gameObject); tf = null; } if (itemCfg.isAni > 0 && showAni) { AddAnimationObj(res, objName, parentObj, sortingOrder); } else { string ext = ItemUtil.GetItemResExt(itemCfg.itemType, itemCfg.subType); AddSpriteObj(res, ext, objName, parentObj, sortingOrder, needSetMask); } } private static GameObject AddSpriteObj(string res, string ext, string objName, GameObject parentObj, int sortingOrder, bool needSetMask) { string resPath = ResPathUtil.GetDressUpPath(res, ext); SpriteRenderer spr = null; var gameObj = new GameObject(objName); spr = gameObj.AddComponent(); AddAssetReleaser(gameObj, resPath); gameObj.transform.SetParent(parentObj.transform, false); float tx, ty; LoadSpritePos(res, out tx, out ty); gameObj.transform.localPosition = new Vector3(tx, ty, gameObj.transform.localPosition.z); Sprite sp = GFGAsset.Load(resPath); spr.sprite = sp; spr.sortingOrder = sortingOrder; if (needSetMask) { spr.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; } else { spr.maskInteraction = SpriteMaskInteraction.None; } return gameObj; } private static GameObject AddAnimationObj(string res, string objName, GameObject parentObj, int sortingOrder) { string resPath = ResPathUtil.GetDressUpAnimationPath(res); var prefab = GFGAsset.Load(resPath); var gameObj = GameObject.Instantiate(prefab); AddAssetReleaser(gameObj, resPath); 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.SortingOrder = sortingOrder; } SetParticleSortingOrder(gameObj, sortingOrder); return gameObj; } public static GameObject AddAnimationObj(string resPath) { // string resPath = ResPathUtil.GetCardAnimationPath(res); var prefab = GFGAsset.Load(resPath); if (prefab == null) { return null; } var gameObj = GameObject.Instantiate(prefab); AddAssetReleaser(gameObj, resPath); return gameObj; } private static GameObject AddEffectObj(string res, string objName, GameObject parentObj, int sortingOrder) { var resPath = ResPathUtil.GetDressUpEffectPath(res); GameObject effPre = GFGAsset.Load(resPath); var gameObj = GameObject.Instantiate(effPre); AddAssetReleaser(gameObj, resPath); gameObj.transform.SetParent(parentObj.transform); gameObj.name = objName; SetParticleSortingOrder(gameObj, sortingOrder); return gameObj; } public static void LoadSpritePos(string res, out float tx, out float ty) { string resPath = ResPathUtil.GetDressUpPath(res, "bytes"); if (VEngine.Versions.Contains(resPath)) { var asset = GFGAsset.Load(resPath); if (asset != null) { var st = new MemoryStream(asset.bytes); var br = new BinaryReader(st); tx = br.ReadInt32() / 100f; ty = -br.ReadInt32() / 100f; GFGAsset.Release(resPath); return; } } tx = 0; ty = 0; } public static void SetParticleSortingOrder(GameObject gameObj, int sortingOrder, bool isAdd = false) { var count = gameObj.transform.childCount; for (int i = 0; i < count; i++) { var tf = gameObj.transform.GetChild(i); var ps = tf.GetComponent(); if (ps != null) { var renderer = ps.GetComponent(); if (renderer != null) { if (isAdd) { renderer.sortingOrder = renderer.sortingOrder + sortingOrder; } else { renderer.sortingOrder = sortingOrder; } } } } } } }