查看: 35846|回复: 122

爆甲英雄传】3.道具管理器

[复制链接]

1

主题

342

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
75866
发表于 2014-11-5 19:18:57 | 显示全部楼层 |阅读模式
  1. 道具系统设计
  2. 3. 道具管理器

  3. 上篇连接 :2. 道具的设计
  4. 【爆甲英雄传】道具系统设计 2.道具的设计 ...
  5. http://www.unitymanual.com/thread-25147-1-1.html
  6. (出处: 游戏开发者社区【游戏蛮牛】unity3d官网)

  7. 本篇开始,少说废话,多干事实。

  8. 上次讲完了道具的设计,想必大家目前也有成千上万的道具等着上线,如果有效管理起这么大量的道具呢?答案是数据库。呃,难道不成重新建立一堆数据库表,然后每次都要加载记录然后赋值到道具中吗?答案是否定的,我们并不需要设计或者使用数据库,我们今天要做的就是,设计一个道具管理类,假装是个数据库就好了。

  9. 新建一个C#脚本,重命名为 Item_Database_Manager

  10. 首先,要将这个管理器设计成单例模式,这样保证全局的唯一性和信息的统一,首先添加如下代码,
  11. [C#] 纯文本查看 复制代码

  12. 01
  13. 02
  14. 03
  15. 04
  16. 05
  17. 06
  18. 07
  19. 08
  20. 09
  21. 10
  22. static Item_Database_Manager idm;

  23. public static Item_Database_Manager Get_Manager()
  24.         {
  25.                 if (idm == null)
  26.                 {
  27.                         Global_Manager.InitAll();
  28.                 }
  29.                 return idm;
  30.         }


  31. 简单到无法用言语来形容了,至于 Global_Manager.InitAll() 这个方法,以后再说明,简单来说,就是通过查询tag来寻找所有被设计成单例模式的实例,Global_Manager 是一个全局的管理器,管理管理器的管理器,后面我会给出代码,这里只要理解这么多就够了,以后遇到会再说的。

  32. 所以,外部只要通过这个静态方法就能ref他的实例了,是不是很方便呢。

  33. 管理器的作用就是管理,所以我们需要一些容器来保存道具们。
  34. 我们这里简单使用数组就可以了,因为道具们属于静态数据,

  35. [C#] 纯文本查看 复制代码

  36. 01
  37. 02
  38. 03
  39. 04
  40. 05
  41. 06
  42. 07
  43. 08
  44. 09
  45. 10
  46. 11
  47. 12
  48. 13
  49. 14
  50. 15
  51. 16
  52. 17
  53. 18
  54. 19
  55. 20
  56. public Item_Profile[] items;

  57. void Awake ()
  58.         {
  59.           // 场景切换时不删除
  60.                 DontDestroyOnLoad(gameObject);
  61.                 idm = gameObject.GetComponent<Item_Database_Manager>();

  62.                 // 分配道具ID
  63.                 ReSort();
  64.         }

  65.         public void ReSort()
  66.         {
  67.                 // auto assign the id to item
  68.                 for(int i=0;i<items.Length;i++)
  69.                 {
  70.                         items[i].item_id = i;
  71.                 }
  72.         }


  73. 就如注释,就是这么回事。DontDestroyOnLoad 保证在切换场景是不需要删除这个对象,因为这个管理器几乎每个场景必备,所以频繁的加载卸载并无意义。配合茶水给出的 Global_Manager,智能加载 (即场景中若存在相同的管理系,则不会再次加载),从而保证全局有且只有一个这样的对象。ReSort 则是自动为道具分配一个ID,ID其实就是数组下标而已。

  74. 然后,我们要提供一个获取道具信息的方法,

  75. [C#] 纯文本查看 复制代码

  76. 1
  77. 2
  78. 3
  79. 4
  80. 5
  81. 6
  82. // also referr to item id
  83.         public Item_Profile Get_Item(int index)
  84.         {
  85.                 index = Mathf.Clamp(index, 0,items.Length);
  86.                 return items[index];
  87.         }


  88. 根据ID获取道具,index = Mathf.Clamp(index, 0,items.Length) 这里做法可能并不准确,这里只是简单的裁剪了index的值,放置越位,但是一般来说,获取那些道具应该由caller来保证他的合法性,而不是管理器,当然,也可以修改成越位返回null,取决于你的程序架构。

  89. 基本上,管理器就这么回事了,看茶水的文章当然不会是这么肤浅的啦,作为报答大家对茶水的关注,这里提供一个设计道具时候的小技巧,先跟着做,后面再解释,
  90. 添加一下代码,

  91. [C#] 纯文本查看 复制代码

  92. 01
  93. 02
  94. 03
  95. 04
  96. 05
  97. 06
  98. 07
  99. 08
  100. 09
  101. 10
  102. public Item_Profile empty_item;

  103. public void Create_Empty_Item()
  104.         {
  105.                 if (empty_item)
  106.                 {
  107.                         GameObject go = Instantiate(empty_item.gameObject) as GameObject;
  108.                         go.name = "item";
  109.                 }
  110.         }


  111. 然后在Scene中添加一个空的GameObject,然后挂载 Item_Profile 脚本,重命名为 Empty Item,然后保存在prefabs。Create_Empty_Item 方法提供一个捷径去创建一个新的道具GameObject,已包含挂载好的脚本,并且命名为item,方便在Hierarchy中查找。

  112. Done!!管理器设计完成,后面就是万众期待的Editor编程了,这里就不浪费篇幅来详细说明了,大家直接使用茶水给出的代码即可,代码也很简单,一看就会懂的了。

  113. 好了,返回到Scene中,创建空GameObject,重命名 Item Database,tag也改为Item Database,然后挂载Item_Database_Manager,你会看到如下,
复制代码
爆甲英雄传】3.道具管理器
  1. 将我们之前的Empty Item 的prefabs拖到红色框框的栏目里,嘿嘿,勇敢地点击 <Create a empty item>按钮,看看有什么神奇的事情发生?没错,就是这么神奇,Hierarchy出现了一个新的Item对象,编辑好这个Item,然后将他保存为prefabs,然后拖到Items的element X里面,放好你的所有道具,点击<Sort>,就会为他们自动分配ID了,是不是很过瘾呢。

  2. 记得事后将Item Database保存为prefabs。

  3. 未完,还有我们之前说过的那个 Global_Manager,指定动作,创建空GameObject,命名为Global_Manager,tag改为Global_Manager,挂在Global_Manager脚本,看到如下景象,
复制代码
将Item Database的prefabs拖到正确的位置,good,收工!

这个时候测试运行,无论场景是否已存在Item Database的实例,我们伟大的Global_Manager都能正确的判断是否需要加载新的Item Database,怎么样,是不是很炫酷?

好了,你可能还会注意到这里有个Inventory_Manager,没错,我们下篇就要讨论,设计一个背包系统了,这样,我们道具才有了本质的意义。

为了配合背包系统的设计,大家请多设计出几个道具,以供背包系统使用。设计出来的效果图应该是这样子的。



希望大家喜欢我这个设计思路。

好了,期待下篇再见咯。
tem_Database_Manager_Editor
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;

  4. public class Item_Database_Manager : MonoBehaviour
  5. {

  6.         public Item_Profile empty_item;

  7.         public Item_Profile[] items;

  8.         static Item_Database_Manager idm;

  9.         // Use this for initialization
  10.         void Awake ()
  11.         {
  12.                 DontDestroyOnLoad(gameObject);
  13.                 idm = gameObject.GetComponent<Item_Database_Manager>();

  14.                 // auto assign the id to item
  15.                 ReSort();
  16.         }

  17.         public void ReSort()
  18.         {
  19.                 // auto assign the id to item
  20.                 for(int i=0;i<items.Length;i++)
  21.                 {
  22.                         items[i].item_id = i;
  23.                 }
  24.         }

  25.         public static Item_Database_Manager Get_Manager()
  26.         {
  27.                 if (idm == null)
  28.                 {
  29.                         Global_Manager.InitAll();
  30.                 }
  31.                 return idm;
  32.         }

  33.         // also referr to item id
  34.         public Item_Profile Get_Item(int index)
  35.         {
  36.                 index = Mathf.Clamp(index, 0,items.Length);
  37.                 return items[index];
  38.         }

  39.         public void Create_Empty_Item()
  40.         {
  41.                 if (empty_item)
  42.                 {
  43.                         GameObject go = Instantiate(empty_item.gameObject) as GameObject;
  44.                         go.name = "item";
  45.                 }
  46.         }

  47. }
复制代码
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. [CustomEditor(typeof(Item_Database_Manager))]
  5. public class Item_Database_Manager_Editor : Editor
  6. {

  7.         void OnEnable ()
  8.         {
  9.         }
  10.          
  11.         public override void OnInspectorGUI ()
  12.         {
  13.                 Item_Database_Manager manager = target as Item_Database_Manager;
  14.                 serializedObject.Update();

  15.                 EditorGUILayout.PropertyField( serializedObject.FindProperty("empty_item"));


  16.                 if(GUILayout.Button("Create a empty item"))
  17.                 {
  18.                         manager.Create_Empty_Item();
  19.                 }

  20.                 if(GUILayout.Button("Sort"))
  21.                 {
  22.                         manager.ReSort();
  23.                 }


  24.                 EditorGUILayout.PropertyField( serializedObject.FindProperty("items"),true);

  25.                 serializedObject.ApplyModifiedProperties();

  26.                 EditorGUILayout.HelpBox("The Item Database required non-null emelent in the array and each item only appare once.", MessageType.Info);
  27.         }

  28. }
复制代码
Global_Manager
[color=white !important]
  1. using UnityEngine;
  2. using System.Collections;

  3. public class Global_Manager : MonoBehaviour {

  4.         public GameObject item_database_manager_prefab;
  5.         public GameObject inventory_manager_prefab;

  6.         static Global_Manager gm;

  7.         // Use this for initialization
  8.         void Awake ()
  9.         {
  10.                 Init(item_database_manager_prefab);
  11.                 Init(inventory_manager_prefab);
  12.                 gm = gameObject.GetComponent<Global_Manager>();

  13.                 // set up the FPS
  14.                 if (Application.platform == RuntimePlatform.IPhonePlayer)
  15.                 {
  16.                         Application.targetFrameRate = 60;
  17.                 }
  18.         }

  19.         public static void InitAll()
  20.         {
  21.                 gm.Awake();
  22.         }
  23.          

  24.         void Init( GameObject prefab )
  25.         {
  26.                 if (prefab == null)
  27.                         return;

  28.                 GameObject obj = GameObject.FindWithTag(prefab.tag);
  29.                 if (obj == null)
  30.                 {
  31.                         Instantiate(prefab);
  32.                 }
  33.         }


  34. }
复制代码


回复

使用道具 举报

ngk02lds78 该用户已被删除
发表于 2014-12-28 02:51:06 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

xbit 该用户已被删除
发表于 2014-12-28 02:51:40 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

woaiwojia6188 该用户已被删除
发表于 2014-12-28 02:52:14 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

简单 该用户已被删除
发表于 2015-4-5 21:32:57 来自手机 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

1247

帖子

3881

积分

vip会员

Rank: 1

积分
3881
发表于 2015-4-9 21:48:02 来自手机 | 显示全部楼层
前排支持下了哦~
回复 支持 反对

使用道具 举报

0

主题

1263

帖子

3968

积分

vip会员

Rank: 1

积分
3968
发表于 2015-4-10 00:41:58 来自手机 | 显示全部楼层
是爷们的娘们的都帮顶!大力支持
回复 支持 反对

使用道具 举报

0

主题

1249

帖子

4017

积分

vip会员

Rank: 1

积分
4017
发表于 2015-4-10 04:58:59 来自手机 | 显示全部楼层
秀起来~
回复 支持 反对

使用道具 举报

拉倒 该用户已被删除
发表于 2015-4-11 08:03:07 来自手机 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

1277

帖子

3949

积分

vip会员

Rank: 1

积分
3949
发表于 2015-4-11 14:47:26 来自手机 | 显示全部楼层
LZ帖子不给力,勉强给回复下吧
回复 支持 反对

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | enginedx注册

本版积分规则

 
 



邮件留言:


 
返回顶部