php - 有没有办法将 UMA 头像配方**包括其转义字符**保存到我的数据库?

标签 php mysql unity-game-engine

<分区>

在 unity 中,我有一个 UMA 角色创建器。

最后它给了我一个头像配方,可以让我加载保存的角色。

我想把这个头像食谱保存到我的mysql数据库中。

所以我将配方传递给服务器上的存储过程并尝试保存它,但它不会加载,因为转义字符已被删除。

这是一个例子:

这是一个有效的 UMA 食谱:

{"packedRecipeType":"DynamicCharacterAvatar","name":"Player","race":"HumanMaleDCS","dna":[{"dnaType":"DynamicUMADna","dnaTypeHash":815443803,"packedDna":"{\"bDnaAsset\":{\"instanceID\":26992},\"bDnaAssetName\":\"HumanMaleDynamicDnaAsset\",\"bDnaSettings\":[{\"name\":\"skinGreenness\",\"value\":128}, etc... it goes on like that for a long time

但在我的数据库中它看起来像这样:

{"packedRecipeType":"DynamicCharacterAvatar","name":"Player","race":"HumanMaleDCS","dna":[{"dnaType":"DynamicUMADna","dnaTypeHash":815443803,"packedDna":"{"bDnaAsset":{"instanceID":26992},"bDnaAssetName":"HumanMaleDynamicDnaAsset","bDnaSettings":[{"name":"skinGreenness","value":128}, etc..

这是关键的区别 \"bDnaAssetName\" 变为 "bDnaAssetName"\"HumanMaleDynamicDnaAsset\" 变为 "HumanMaleDynamicDnaAsset" 等等……

\(s)消失了!!!

所以:

  1. 我可以保存这个带有所有反斜杠的字符串,以便在我重新加载它时它能正常工作吗?

  2. 这是个好主意吗?我是在自找麻烦吗?有没有更好的方法将 UMA 食谱保存到我的数据库?

最佳答案

我在将食谱保存为 postgresql 中的 json 字段时遇到了类似的问题。问题来自 UMA 开发人员将 json 包装在 json 中。它本质上是一个嵌套的 json 字符串,只会导致问题。我几个月前就告诉过他们,并发布了一些代码来提供帮助,但我认为他们从未更新过它。

在任何情况下,我的代码都会通过将配方的外部 json 转换为泛型来评估问题的根源,并保留内部的。它仍然有点 hack,因为我必须再次嵌套 json 才能加载食谱。这是代码,您可以将其放在 Assets 文件夹中的任何位置:

// Brought to you by Tarball 5/28/2019
// Drop in Asset folder to save your UMA data to generic types
// Call public methods from any script

using UMA.CharacterSystem;
using System.Collections.Generic;
using System.Linq;

namespace UMA
{
    namespace EasyMode
    {
        public static class EasyUMA
        {
            public static List<UMAPackedRecipeBase.UMAPackedDna> dnaPackedRecipe = new List<UMAPackedRecipeBase.UMAPackedDna>();
            public static UMAPackedRecipeBase.UMAPackedDna packedDna = new UMAPackedRecipeBase.UMAPackedDna();
            public static Dictionary<int, Dictionary<string, string>> DNAInfo = new Dictionary<int, Dictionary<string, string>>();
            public static Dictionary<string, short[]> colorRecipe = new Dictionary<string, short[]>();
            public static Dictionary<string, string> wardrobeRecipe = new Dictionary<string, string>();
            public static UMATextRecipe.DCSPackRecipe totalRecipe = new UMATextRecipe.DCSPackRecipe();
            public static bool saveAsMale;
            public static string[] colorNames;
            public static short[][] colorData;

            private static DynamicCharacterAvatar.SaveOptions saveOptions = DynamicCharacterAvatar.SaveOptions.saveDNA
                    | DynamicCharacterAvatar.SaveOptions.saveColors | DynamicCharacterAvatar.SaveOptions.saveWardrobe;

            private static Dictionary<string, string> wardrobe_slots = new Dictionary<string, string>();
            private static Dictionary<string, short[]> UMA_colors = new Dictionary<string, short[]>();
            private static List<UMAPackedRecipeBase.UMAPackedDna> dnaList = new List<UMAPackedRecipeBase.UMAPackedDna>();

            // Returns the current DCSPackRecipe from a DynamicCharacterAvatar
            private static UMATextRecipe.DCSPackRecipe packedRecipe(DynamicCharacterAvatar currentAvatar)
            {
                if (currentAvatar != null)
                {
                    return new UMATextRecipe.DCSPackRecipe(currentAvatar, currentAvatar.name, "DynamicCharacterAvatar", saveOptions);
                }
                else return null;
            }

            /// <summary>
            /// Returns a Dictionary with raw DNA information for saving in c# generic types
            /// </summary>
            public static Dictionary<int, Dictionary<string, string>> PrintDNADictionary(DynamicCharacterAvatar dynamicCharacterAvatar)
            {
                if (dynamicCharacterAvatar != null)
                {
                    dnaList = packedRecipe(dynamicCharacterAvatar).dna;
                    if (dnaList != null && dnaList.Count != 0)
                    {
                        Dictionary<string, string> tempStrings = new Dictionary<string, string>();
                        Dictionary<int, Dictionary<string, string>> tempDict = new Dictionary<int, Dictionary<string, string>>();
                        tempStrings.Add(dnaList.First().dnaType, dnaList.First().packedDna);
                        tempDict.Add(dnaList.First().dnaTypeHash, tempStrings);
                        return tempDict;
                    }
                    else return null;
                }
                else return null;
            }

            /// <summary>
            /// Returns a Dictionary with wardrobe information in the format: (string wardrobe_slot_name, string wardrobe_item_name), for example ("Chest", "BreastPlate001")
            /// </summary>
            public static Dictionary<string, string> PrintWardrobe(DynamicCharacterAvatar dynamicCharacterAvatar)
            {
                if (dynamicCharacterAvatar != null)
                {
                    var recipe = packedRecipe(dynamicCharacterAvatar);
                    wardrobe_slots.Clear();
                    foreach (WardrobeSettings wardrobe_item in recipe.wardrobeSet)
                    {
                        wardrobe_slots.Add(wardrobe_item.slot, wardrobe_item.recipe);
                    }
                    return wardrobe_slots;
                }
                else return null;
            }

            /// <summary>
            /// Returns a Dictionary with shared color information (string color_name, short[] RGBA_numbers)
            /// </summary>
            public static Dictionary<string, short[]> PrintColors(DynamicCharacterAvatar dynamicCharacterAvatar)
            {
                if (dynamicCharacterAvatar != null)
                {
                    var recipe = packedRecipe(dynamicCharacterAvatar);
                    colorNames = new string[recipe.characterColors.Count];
                    colorData = new short[recipe.characterColors.Count][];
                    int i = 0;
                    UMA_colors.Clear();
                    foreach (UMAPackedRecipeBase.PackedOverlayColorDataV3 charColors in recipe.characterColors)
                    {
                        UMA_colors.Add(charColors.name, charColors.colors);
                        colorNames[i] = charColors.name;
                        colorData[i] = charColors.colors;
                        i++;
                    }
                    return UMA_colors;
                }
                else return null;
            }

            /// <summary>
            /// Returns the full recipe as a DCSPackRecipe 
            /// </summary>
            public static UMATextRecipe.DCSPackRecipe gatherFullRecipe(DynamicCharacterAvatar currentAvatar, bool isMale,
                Dictionary<int, Dictionary<string, string>> DNAInfo, Dictionary<string, short[]> colorsData, Dictionary<string, string> wardrobeData)
            {
                UMATextRecipe.DCSPackRecipe recipe = new UMATextRecipe.DCSPackRecipe();
                UMAPackedRecipeBase.UMAPackedDna item = new UMAPackedRecipeBase.UMAPackedDna();
                if (DNAInfo != null && DNAInfo.Count != 0)
                {
                    item.dnaTypeHash = DNAInfo.First().Key;
                    item.dnaType = DNAInfo.First().Value.First().Key;
                    item.packedDna = DNAInfo.First().Value.First().Value;
                    List<UMAPackedRecipeBase.UMAPackedDna> senselessList = new List<UMAPackedRecipeBase.UMAPackedDna>();
                    senselessList.Add(item);
                    recipe.dna = senselessList;
                }

                if (isMale)
                    recipe.race = "HumanMale";
                else recipe.race = "HumanFemale";

                if (colorsData != null && colorsData.Count != 0)
                {
                    UMAPackedRecipeBase.PackedOverlayColorDataV3[] overlays = new UMAPackedRecipeBase.PackedOverlayColorDataV3[colorsData.Count];
                    recipe.characterColors = new List<UMAPackedRecipeBase.PackedOverlayColorDataV3>();
                    int i = 0;
                    foreach (var uniqueColor in colorsData)
                    {
                        overlays[i] = new UMAPackedRecipeBase.PackedOverlayColorDataV3();
                        overlays[i].name = uniqueColor.Key;
                        overlays[i].colors = uniqueColor.Value;
                        recipe.characterColors.Add(overlays[i]);
                        i++;
                    }
                }

                if (wardrobeData != null && wardrobeData.Count != 0)
                {
                    WardrobeSettings[] wardrobeInfo = new WardrobeSettings[wardrobeData.Count];
                    recipe.wardrobeSet = new List<WardrobeSettings>();
                    int i = 0;
                    foreach (var wardrobePiece in wardrobeData)
                    {
                        wardrobeInfo[i] = new WardrobeSettings();
                        wardrobeInfo[i].slot = wardrobePiece.Key;
                        wardrobeInfo[i].recipe = wardrobePiece.Value;
                        recipe.wardrobeSet.Add(wardrobeInfo[i]);
                        i++;
                    }
                }
                return recipe;
            }
        }
    }
}

现在,您应该可以在任何数据库中进行保存,而不会有太多麻烦。然而,现在这个食谱被分成了几部分。要保存/加载,只需将此代码片段放入处理保存和加载的脚本中:

private DynamicCharacterAvatar avatar;

public void SaveRecipe()
    {
        EasyUMA.DNAInfo = EasyUMA.PrintDNADictionary(avatar);
        EasyUMA.colorRecipe = EasyUMA.PrintColors(avatar);

        EasyUMA.wardrobeRecipe = EasyUMA.PrintWardrobe(avatar);

        if (avatar.umaData.umaRecipe.raceData.raceName == "HumanMale")
            EasyUMA.saveAsMale = true;
        else EasyUMA.saveAsMale = false;
    }

    public void LoadRecipe()
    {
        avatar.ClearSlots();
        EasyUMA.dnaPackedRecipe.Clear();
        EasyUMA.dnaPackedRecipe.Add(EasyUMA.packedDna);
        EasyUMA.totalRecipe = EasyUMA.gatherFullRecipe(avatar, EasyUMA.saveAsMale, EasyUMA.DNAInfo, EasyUMA.colorRecipe, EasyUMA.wardrobeRecipe);
        var dummyRecipe = JsonUtility.ToJson(EasyUMA.totalRecipe);
        avatar.LoadFromRecipeString(dummyRecipe);
    }

关于php - 有没有办法将 UMA 头像配方**包括其转义字符**保存到我的数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57068509/

相关文章:

mysql - 无法获取正确的值以使用 JDBC for MySQL 从 latin1 字段查询中文值

android - Google Play 服务 Unity 插件显示排行榜

php - 如何在 Google Drive REST API 中检查团队驱动器是否已被删除?

php - 使用插件向 WordPress 添加新页面

mysql - Ruby:按列名访问mysql数据?

android - 在android上使用smsManager.sendTextManager发送短信的问题

c# - 协程停止工作

php - 从 MySQL 条目中提取某些信息

javascript - 对于具有多个类的按钮,Jquery 单击事件失败

Php Mysql 选择查询不起作用