array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 unity游戏框架学习-用户设置 - 爱码网

概述:https://www.cnblogs.com/wang-jin-fu/p/10975660.html

游戏设置用于保存玩家的游戏设置,例如玩家希望关掉音乐、音效啥的。当玩家设置完后,第二次登录可以保持之前的设置。例如以下选项

unity游戏框架学习-用户设置

 

保存玩家设置有两种方式

1.保存在本地,可以是json、xml、txt等所有可以读取的文件格式,也可以使用unity的PlayerPrefs进行保存。不需要占用网络资源,缺点是用户更换手机、卸载重装、清理游戏缓存都会导致设置丢失。

2.上传到服务器。优点是不会丢失,缺点是需要占用网络资源,需要在服务器保存数据。

具体使用哪种方式由策划大大决定。

 

具体实现:其实原理就是用一个容器存储设置(键值对),在游戏开始时载入设置,在游戏结束时保存设置。

一、c#端:这边示例使用unity的PlayerPrefs进行本地存储

1.消息定义:

/// <summary>
/// 所有设置名字都在这里定义 为了知道游戏中所有的本地缓存数据 避免重复定义
/// </summary>
public enum UserSettingDefeine
{
    MUSIC_SWITCH ,                // 音乐开关
    SOUND_SWITCH ,                // 音效开关

    USER_LEVEL,                    // 玩家等级
}

2.消息保存、获取。在游戏登录时调用Load加载设置,在游戏退出时调用Save保存设置。

using System;
using System.Collections.Generic;
using UnityEngine;
using SRF;

/// <summary>
/// 用户设置,key在UserSettingDefeine定义
/// </summary>
public static class UserSetting
{
    static string SettingKey = "SETTING";
    private static Dictionary<int, string> settings = null;

    public static void Load()
    {
        // 加载配置
        settings = new Dictionary<int, string>();
        
        if (PlayerPrefs.HasKey(SettingKey))
        {
            string jsonString = PlayerPrefs.GetString(SettingKey);
            settings = Json.Deserialize(jsonString) as Dictionary<int, string>;
        }

        //test
        //bool music = GetBool(UserSettingDefeine.MUSIC_SWITCH, true);
        //SetBool(UserSettingDefeine.MUSIC_SWITCH, music);

        //int level = GetValue(UserSettingDefeine.USER_LEVEL, 1);
        //SetValue(UserSettingDefeine.USER_LEVEL, level);
    }

    public static void Save()
    {
        // 保存配置
        string json = Json.Serialize(settings);
        PlayerPrefs.SetString(SettingKey, json);
        PlayerPrefs.Save();
    }

    #region 获取玩家设置
    public static int GetInt(UserSettingDefeine key, int defaultVal = 0)
    {
        string val = null;
        int intKey = (int)key;

        if (settings.TryGetValue(intKey, out val))
            return System.Convert.ToInt32(val);
        settings[intKey] = defaultVal.ToString();
        return defaultVal;
    }

    public static float GetFloat(UserSettingDefeine key, float defaultVal = 0f)
    {
        string val = null;
        int intKey = (int)key;

        if (settings.TryGetValue(intKey, out val))
            return System.Convert.ToSingle(val);
        settings[intKey] = defaultVal.ToString();
        return defaultVal;
    }

    public static bool GetBool(UserSettingDefeine key, bool defaultVal = false)
    {
        string val = null;
        int intKey = (int)key;

        if (settings.TryGetValue(intKey, out val))
            return System.Convert.ToBoolean(val);
        settings[intKey] = defaultVal.ToString();
        return defaultVal;
    }

    public static string GetString(UserSettingDefeine key, string defaultVal = "")
    {
        string val = null;
        int intKey = (int)key;

        if (settings.TryGetValue(intKey, out val))
            return val.ToString();
        settings[intKey] = defaultVal.ToString();
        return defaultVal;
    }
    #endregion

    #region 设置玩家设置
    public static void SetInt(UserSettingDefeine key, int val)
    {
        settings[(int)key] = val.ToString();
    }

    public static void SetFloat(UserSettingDefeine key, float val)
    {
        settings[(int)key] = val.ToString();
    }

    public static void SetBool(UserSettingDefeine key, bool val)
    {
        settings[(int)key] = val.ToString();
    }

    public static void SetString(UserSettingDefeine key, string val)
    {
        settings[(int)key] = val;
    }
    #endregion

    /// <summary>
    /// 设置玩家设置
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key"></param>设置id
    /// <param name="val"></param>
    public static void SetValue<T>(UserSettingDefeine key, T val)
    {
        settings[(int)key] = val.ToString();
    }

    /// <summary>
    /// 获取玩家设置信息
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key"></param>设置id
    /// <param name="defaultVal"></param>默认值,必传
    /// <returns></returns>
    public static T GetValue<T>(UserSettingDefeine key, T defaultVal)
    {
        string val = null;
        int intKey = (int)key;

        if (settings.TryGetValue(intKey, out val))
        {
            if (defaultVal is int)
            {
                return (T)Convert.ChangeType(Convert.ToInt32(defaultVal), typeof(T));         
            }
            else if (defaultVal is float)
            {
                return (T)Convert.ChangeType(Convert.ToSingle(defaultVal), typeof(T));
            }
            else if (defaultVal is bool)
            {
                return (T)Convert.ChangeType(Convert.ToBoolean(defaultVal), typeof(T));
            }
            else
            {
                return (T)Convert.ChangeType(Convert.ToString(defaultVal), typeof(T));
            }
        }
            
        settings[intKey] = defaultVal.ToString();
        return defaultVal;
    }
}

 

二、lua端(这边示例保存服务端)

在游戏开始时,服务器会同步玩家设置信息。玩家更改设置后,会调用服务器接口进行保存。

local PlayerSettingCtrl = class("PlayerSettingCtrl", LogicCtrlBase)
local json = require("cjson")
local SettingUtil = SettingUtil

function PlayerSettingCtrl:ctor()
    PlayerSettingCtrl.super.ctor(self)
    self._isInitGameSetting = false
    self._settingData = {}
    self._gameSettingData = {}
end

function PlayerSettingCtrl:Init()
    PlayerSettingCtrl.super.Init(self)

    local NetMsg = NetMsg
    NetMsg.Register("playersetting_init_syn", self, self.OnSyncPlaySetting)
end

-- 同步玩家设置 -- 保存PlayerSettingDefine.SettingType的数据
function PlayerSettingCtrl:OnSyncPlaySetting(data, session)
for _, v in pairs(data.playersettinginfolist) do
self._settingData[v.key] = json.decode(v.value)
end
end
function PlayerSettingCtrl:ClearData() 
  self._settingData
= {}
end

--获取玩家设置,如果有传默认值,则会自动创建记录 ---- 如果value是table类型,不要修改这个值(自己拷贝一份)
function PlayerSettingCtrl:GetSettingValue(key, defaultValue)
  local value
= self._settingData[key]
  if value == nil and defaultValue ~= nil then
    value
= defaultValue self:ReqChangePlaySetting(key, value)
  self._settingData[key]
= defaultValue
  end
  return value
end

---endregion ---region 请求 -- 请求更改玩家设置
function PlayerSettingCtrl:ReqChangePlaySetting(settingType, value)
  self._settingData[settingType]
= value
  local valueStr
= json.encode(value)
  local data
= {key = settingType, value = valueStr}
  NetMsg.SendMsg(
"playersetting_change_req", data, true)
end

---endregion

return PlayerSettingCtrl

 

相关文章: