从配置表角度浅谈游戏公司的资源管理

对于大部分商业游戏而言,一些需要热更新的资源往往是通过远端,传输到客户端。再加工使用的,这些资源有静态的,比如tilemap画的背景板,地面,云朵等等;有动态的,比如玩家的人物、技能特效、各种动画,这些可能是需要实时发生变更的,比如升级了你的技能就变化了。这些数据的种类、内容量以及类型大有不同。
一般的流程是,市场部根据调研整理用户需求,策划人员根据市场部的需求做出设计图纸,同时向美工和程序提需求,美术人员通过设计图,制作自己的原画集。程序员人员根据设计图和美术人员做出的资源,完成整个项目。
那么,美术需要在什么时间节点交付给程序哪些美术资源呢,怎么完成资源映射呢?
使用配置表。
配置表一般是可以通过office软件的表格模式编写的,简单易维护的excel文件。
多表之间通过一张总控表关联。读取方式一般从总控表通过唯一主键关联到分表ID,如果有嵌套,重复上述过程即可。
image.png
图 1-1 设计图中的配置表
image.png
图 1-2 配置表的一张总表
image.png
图 1-3 配置表的一张子表
比如设计图划红线部分的意思是通过总控表推荐书籍规则,找到20001到20005的五个ID为primary key和在百科场景推荐关卡图中拿到卡片的AB包路径,就完成了资源的定位。
比如,下面在做排位系统时,
拿到的配置表是这样的
image.png

所以本地数据结构需要定义这样的存储字段。

namespace GameData.Game
{
    [Serializable]
    public class AnswerQuestionsData : GameBaseData<AnswerQuestionsSubData>
    {
    }

    [Serializable]
    public class AnswerQuestionsSubData : GameSubBaseData
    {
        // 竞赛id	竞赛阶段名称	竞赛阶段类型	竞赛阶段勋章icon	勋章阶级icon	晋级需要星数	胜利升星数量	失败扣星数量	挑战题库	挑战题库权重	晋级题库	晋级题库权重	机器人库
        //     competitionId	competitionName	competitionType	competitionIcon1	competitionIcon2	competitionStart	victoryAdd	failReduce	competitionQuestion1	competitionWeights1	competitionQuestion2	competitionWeights2	robot
        // int32	string	int32	string	string	int32	int32	int32	[]int32	[]int32	[]int32	[]int32	[]int32
        //     cs	cs	cs	cs	cs	cs	cs	cs	cs	cs	cs	cs	cs
        public override int DataId => competitionId;
        public int competitionId; // 竞赛id
        public string competitionName; // 竞赛阶段名称
        public int competitionType; // 竞赛阶段类型
        public string competitionIcon1; // 竞赛阶段勋章icon
        public string competitionIcon2; // 勋章阶级icon
        public int competitionStart; // 晋级需要星数
        public int victoryAdd; // 胜利升星数量
        public int failReduce; // 失败扣星数量
        public int[] competitionQuestion1; // 挑战题库
        public int[] competitionWeights1; // 挑战题库权重
        public int[] competitionQuestion2; // 晋级题库
        public int[] competitionWeights2; // 晋级题库权重
        public int[] robot; // 机器人库
    }

    public class AnswerQuestions : ConfigBase
    {
        public override DataType GetDataType()
        {
            return DataType.AnswerQuestions;
        }

        protected override UniTask<GameBaseData> UnserializeData()
        {
            return Unserialize<AnswerQuestionsData, AnswerQuestionsSubData>(nameof(AnswerQuestions));
        }
    }
}

完成序列化和反序列化后(*本文只谈数据的读取,传输部分见本专栏的其他文章)。我们就可以直观地对AnswerQuestionsSubData类,根据需求封装相应的功能,为我们的GameLogic使用。
比如说,这里案子有一个需求,

需要做一个晋级赛答题的判定(参考王者荣耀排位系统,满星后开启晋级赛,当且仅当第一次参加晋级赛需要进行晋级答题)
1.本地读取 AnswerQuestionsSubData数据内容,封装功能。
_userBase封装了角色相应字段和方法的基类

public class UserBase{
        private UserBaseCache _userBaseCache;
        private AnswerQuestionsData _answerQuestionsData;
        //默认开始段位
        private const int DefaultRankSegment = 60001;

        public UserBase()
        {
            _userBaseCache = DataManager.Instance.GetGameDataByType(DataType.UserBaseCache) as UserBaseCache;
            _answerQuestionsData = DataManager.Instance.GetGameDataByType(DataType.AnswerQuestions) as AnswerQuestionsData;
        }
        //这里用到的方法
           
        //获取排位分段
        public int GetRankSegment()
        {
            return _userBaseCache.RankSegment == 0 ? DefaultRankSegment : _userBaseCache.RankSegment;
        }
        
          //获取MaxRankSegment
        public int GetMaxRankSegment()
        {
            return _userBaseCache.RankSegment == 0 ? DefaultRankSegment : _userBaseCache.RankSegment;;
        }
   		  //获取RankStar
        public int GetRankStar()
        {
            return _userBaseCache.RankStar;
        }
        //其他方法
}

2.编写相关逻辑IsPromotionMatch()
DataManager是数据管理的单例,GetGameDataByType(T) as T初始化了根据T的初始化了数据,并强制返回T类型的实例化对象

  public class RankTypeSettings{
		private UserBase _userBase { get; set; }
        private AnswerQuestionsData _answerQuestionsData { get; set; }

        public RankTypeSettings()
        {
            _userBase = UserDataSystem.Instance.UserBase;
            _answerQuestionsData = DataManager.Instance.GetGameDataByType(DataType.AnswerQuestions) as AnswerQuestionsData;
        }
        /// <summary>
        /// 是否开启晋级赛
        /// </summary>
        /// <param name="level"></param>
        /// <param name="currentType"></param>
        /// <returns></returns>
        public bool IsPromotionMatch()
        {
            AnswerQuestionsSubData[] dataList = _answerQuestionsData.data;
            int startID = dataList[0].competitionId - 1;
            int currentID = _userBase.GetRankSegment() - startID;
            int currentLevel = _userBase.GetRankStar();
            int competitionTypeMax = _answerQuestionsData.data.FirstOrDefault(data => data.competitionId == _userBase.GetMaxRankSegment())!.competitionType;
            int competitionTypeCurrent = _answerQuestionsData.data.FirstOrDefault(data => data.competitionId == _userBase.GetRankSegment())!.competitionType;
            //第一次到达目标段位并且目标段位是晋级段位可参加晋级答题
            return (dataList[currentID].competitionStart == currentLevel) && (competitionTypeMax <= competitionTypeCurrent);
        }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值