unity3d 大型项目 -- UFPS --- 背包系统(三)--- 角色模型下实现武器实体与背包功能扩展

在角色身上实现武器实体:

1. 在摄像机下添加一把武器(游戏物体),挂载上Weapon脚本。

2. 武器处理器自动查找 所有摄像机下的Weapon,生成List<vp_Weapon> Weapons,代表当前武器集合

3. 将游戏物体挂载上Identifier脚本,并将bank对象(asset文件)拖拽赋值,还有子弹的赋值

4. bank对象拖拽给Inventory面板(或在游戏中调用TryGiveItem),然后我们的背包中就有了一个bankInstance,并且在武器处理器中有一把Weapon与它对应

5. 现在的连接关系:

bank对象(asset文件)------ bankInstance(背包中) ----- Weapon(武器处理器中)

6. 如何切换武器

    1.直接通过读取键盘输入:

       if (vp_Input.GetButtonDown("SetWeapon1")) FPPlayer.SetWeapon.TryStart(1);

       if (vp_Input.GetButtonDown("SetWeapon2")) FPPlayer.SetWeapon.TryStart(2);

       if (vp_Input.GetButtonDown("SetWeapon3")) FPPlayer.SetWeapon.TryStart(3);

       if (vp_Input.GetButtonDown("SetWeapon4")) FPPlayer.SetWeapon.TryStart(4);

 

    2.通过背包中的item实例:

          TryWield ( vp_ItemInstance  item ) :

            1. 遍历武器处理器中的所有武器Weapons的identifier

                 2. 通过item.Type == identifier.Type,找到对应的Weapon

            3. Player.SetWeapon.TryStart(index);

7. 武器切换(背包)的条件

CanStart_SetWeapon():

       1. int index = (int)Player.SetWeapon.Argument;

           ....检查索引

       2. 检查武器的Identifier

              不为null,其中的item引用也不为null

       3. 背包中是否存在这把武器的实例

               bool haveItem = HaveItem(Identifier.Type, Identifier.ID);

8. 进入武器处理器

OnStart_SetWeapon():

1.停止当前武器的所有活动,卸下当前武器m_CurrentWeapon.Wield(false);,设置切换武器这个动作的持续时间(0.1s,就是说0.1秒后SetWeapon这个活动直接结束)

OnStop_SetWeapon()

     1.index = (int)m_Player.SetWeapon.Argument;

     2.SetWeapon(index)

            1.DeactivateAll(Weapons) //禁用所有武器

            2.ActivateWeapon(index); //激活新的武器

                      a. m_CurrentWeaponIndex = index; //更新当前武器索引

                     b. m_CurrentWeapon = Weapons[m_CurrentWeaponIndex -                    

                           1]; //更新当前武器引用

                     c. m_CurrentWeapon.ActivateGameObject(true);

                         //激活当前武器游戏物体

                        d. m_CurrentShooter = CurrentWeapon.GetComponent

                        <vp_Shooter>();//更新当前武器shooter

    3. m_CurrentWeapon.Wield();

                       1. m_Wielded = isWielding;

           2. Refresh();

           3.StateManager.CombineStates();

9. 总结

       1.我们先实现了一把武器的所有功能(开火,后坐力,摇摆,火光,声音等等),生成一个武器游戏物体,放到我们的摄像机下,然后这把武器默认是禁用的,同理,所有武器在开始时都是禁用的,然后通过武器处理器设置不同的武器可用,通过这种方式来进行不同武器的切换(切换当前手持的武器,激活这个武器)

       2. 这些武器全部会在武器处理器中的Weapons集合存在,代表我们所有可用的武器库,可以想象成一个物品库,里面是我们所有可以得到的物品,但是不代表我们当前可以使用这些武器,我们还要在背包中存在这把武器,对吧,我们必须将这把武器添加到背包中

                                     1.游戏开始前:拖拽到inventory的面板中

                                     2.游戏中:调用TryGiveItem(weapon.identifier.type))

       3. 现在这把武器就在我们的背包中存在了,我们就可以切换到这把武器了,有2种方式

                            1.键盘输入切换对应的武器,背包遍历背包中的所有bank实例,发现背包中                              确实存在这么一个bank实例,开始切换

                            2.调用背包的TryWield( getItem(weapon.identifier.type)),背包遍历武器处         理器中的所有武器,发现武器处理器中确实有这么一把Weapon,开始切换

 

 

vp_PlayerInventory功能重载

 

1.添加武器实例(重写父类)

DoAddUnitBank( vp_UnitBankType  unitBankType):(重写父类)

        1. 获取我们背包中是否有这个bank对象的bank实例

        2. 用这个bank对象添加一个bank实例到我们的背包中

        3. 尝试穿戴新的bank对象(不是实例),调用TryWieldNewItem (vp_ItemType type,

     bool alreadyHaveIt) ,然后他会调用TryWield( GetItem(type) )尝试穿戴这个武器,   

     因为已经添加到背包了,所以一定是能穿戴成功的

父类功能二次实现:

    1.TryGiveItem (vp_ItemType itemType)

    2.TryGiveItems

 

2.尝试穿戴武器

TryWield ( vp_ItemInstance  item ) :

            1. 遍历武器处理器中的所有武器Weapons的identifier

                 2. 通过item.Type == identifier.Type,找到对应的Weapon

            3. Player.SetWeapon.TryStart(index);

 

 

 

3.移除武器实例(重写父类)

DoRemoveUnitBank(vp_UnitBankInstance bank)

       1.尝试卸下这把武器(如果当前正好穿戴着这把武器)

         Unwield(bank);

       2.移除武器:base.DoRemoveUnitBank(bank);

DoRemoveItem(vp_ItemInstance item)

       1.尝试卸下这把武器(如果当前正好穿戴着这把武器)

         Unwield(item);

       2.移除武器:base.DoRemoveUnitBank(item);

父类功能二次实现:

    1. TryRemoveItem (vp_ItemType type, int id)

 

 

4.尝试卸下武器:

Unwield(vp_ItemInstance item):

如果需要卸下的是当前正在穿戴着的武器,就卸下它

           1. if (item.Type != CurrentWeaponIdentifier.Type) return; //只卸当前武器

        2. Player.SetWeapon.Start(0); //设置空手(注意:设置0时背包会跳过检查武器是否存在于背包中)

             3. Player.SetNextWeapon.Try(); //角色不应该为空手(注意:因为不是SetWeapon事件,所以这里会让武器处理器自动切换到下一把武器库的武器,而不会检查identifier,或是否存在于背包,这样就可能装上一把不存在背包中的武器,所以就有了下一行)

             4. vp_Timer.In(1.0f, UnwieldMissingWeapon); //1秒后检查当前武器的身份

 

 

 

5.检查当前武器身份

UnwieldMissingWeapon():

确认当前穿戴的武器的身份信息:

                            1. 当前武器是否有Identifier组件

                            2. 当前武器的Identifier 的item对象是否为 null

                            3. 当前武器的Identifier 的item对象是否存在于背包中(item实例集合,bank  

              实例集合)

如果上述条件有一个不满足,那么我们会

                            1.切换为空手(没有武器,null)

                            2.打印错误(提示这个武器身上的Identifier 组件错误)

 

 

 

 

6.设置武器的子弹(重写父类)

1.移除武器的子弹

DoRemoveUnits(vp_UnitBankInstance bank, int amount)

        1.移除子弹

         base.DoRemoveUnits(bank, amount);

       2.如果没子弹了,尝试自动换弹

       if (bank.Count == 0)

              vp_Timer.In(0.3f, delegate() { Player.AutoReload.Try(); });

 

2.增加武器子弹

DoAddUnits(vp_UnitBankInstance bank, int amount)

实现了一点新逻辑,如果是给内部银行添加库存,会尝试切换枪,和自动换弹的一些逻辑,不用深究

父类功能二次实现:

    1. TryDeduct (vp_UnitBankType unitBankType, int unitBankId, int amount)      消耗一把枪的多少子弹

    2. TryGiveUnits (vp_UnitBankInstance bank, int amount)

    3. TryReload (vp_UnitBankInstance bank, int amount)

 

 

 

7.武器的子弹数:

//获取武器的子弹数

GetAmmoInWeapon(vp_Weapon weapon)

实现方法:

       1.找到identifier,获取bank对象,通过getItem,获取itemInstance,强

          转为bankInstance,获取数量

//获取武器子弹的库存数

GetExtraAmmoForWeapon(vp_Weapon weapon)

实现方法:

       1. 找到identifier,获取bank对象,获取unit对象,作为参数获取内部银行          的库存量

 

 

 

8.穿戴使用这种子弹的武器

TryWieldByUnit (vp_UnitType unitType):

实现方式:

    1.用一个字典保存每个武器对应的identifier(保存武器库里所有的武器和它的identifier,不涉及背包)

    2.用一个字典保存每种子弹对应的武器集合(遍历每个武器,找到identifier,获取子弹类型,也是保存武器库里所有的武器和它的子弹类型,不涉及背包)

    3.获取这个子弹对应武器库中的所有武器,每一把都尝试穿戴m_Player.SetWeapon

.TryStart(),不在背包中的会穿戴失败,直到有一把背包中的武器穿戴上,返回true,否则返回false

 

9.当前武器信息

1.当前武器子弹

OnValue_CurrentWeaponAmmoCount

实现方式:

       1.CurrentWeaponIdentifier属性:调用时通过访问武器处理器获取当前使用武   

          器的identifier

       2.CurrentWeaponInstance属性:当前使用武器的在背包中的itemInstance

                 通过GetItem(CurrentWeaponIdentifier.Type);

      3.返回:((vp_bankInstance)CurrentWeaponInstance).Count

2.当前武器子弹的库存量(内部银行)

OnValue_CurrentWeaponClipCount:

实现方式:

通过当前武器的item实例,转成bank实例,读取unit,作为参数获取内部银行库存量

 

10. 武器对象 <---> 背包实例  互相转换

武器对象  转  背包实例

vp_UnitBankInstance GetUnitBankInstanceOfWeapon(vp_Weapon weapon)

实现方法:

获取identifier,获取bank,作为参数传入getItem,返回itemInstance,强转为bankInstance返回

背包实例  转  武器对象

vp_Weapon GetWeaponOfItemInstance(vp_ItemInstance itemInstance)

实现方法:

遍历武器库所有武器,找到一把武器满足identifier.Type == itemInstance.Type,返回武器

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值