Top-down-Rpg-Start-kit插件的使用与二次开发
2015-04-19 16:27
501 查看
这几天都在说仙剑Demo,为啥突然讲Top-down-Rpg-Start-kit,因为Top-down-Rpg-Start-kit是个非常完整的动作游戏插件,根据其完整文档可以快速开发单机的rpg游戏,我们做的Demo是回合制的,但这个插件的交易系统,状态机,背包系统,小地图系统做的非常好,我们的demo后面的几个系统都使用了Top-down-Rpg-Start-kit的插件源码,利用别人的成熟代码,来完善自己的游戏快速开发,这是我多年的一个开发习惯,废话不说,我们开始,不过开篇可能有些奇怪,因为这个文档我是去年12月份写的,当时是在学习Top-down-Rpg-Start-kit的插件并且整合游戏的任务系统,但后来发现Top-down-Rpg-Start-kit1.2自己加入了任务系统,并且我的实验项目也基本完成所以停了下来,后来开发仙剑的Demo,所以这个文档上面的源码与Top-down-Rpg-Start-kit1.0的源码有很多地方不太一样,不过具体修改的源码我会帖出来,并且写详细的中文注释。我们开始
这一篇的篇幅都是在讲我整喝一个任务系统到这个插件的全过程,因为直接看估计很难看得懂,所以后面我会提供完整的整合任务系统的工程文件,所以到时候再看把,建议大家跳过这一篇,直接看下一篇,等到我提供的工程文件放出来,大家在回来看,否则估计会有很多小伙伴骂我。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/tongue.gif)
这个任务系统需要的源码包下载地址密码wjd3,这个包复制进下载的Top-down-Rpg-Start-kit1.0,然后按照最后Hierarchy设置,完整的工程文件因为太大,所以以后有时间放上来。
![](http://img.blog.csdn.net/20150419170003461?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
先上一张插件的logo,新建
![](http://img.blog.csdn.net/20150419170112554?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
建立新文件夹,存放修改后的模型元件,代码,资源
![](http://img.blog.csdn.net/20150419170217200?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
2.添加角色控制脚本到模型上
![](http://img.blog.csdn.net/20150419170445579?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
3.把人物模型层layer和标签tag改为player
任务系统开发
playerBase.cs修改
![](http://img.blog.csdn.net/20150419170531436?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
中的预制件
![](http://img.blog.csdn.net/20150419170613650?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419171103692?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419170813153?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
注意上面的PlayerNew.cs是我们后加的,源码
运行后的效果
![](http://img.blog.csdn.net/20150419172114074?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419172147505?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419172217317?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419172530579?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419172609548?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419172814136?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419172803179?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419173011917?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419172949852?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
EnemyController.cs中添加
![](http://img.blog.csdn.net/20150419173207528?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
monsterDeadAI中的nameOfMobToSend暂时测试直接写入,后面会改为通用。
杀怪任务修改完毕。。。。。。。。。。。。。。。。。。。。
在EnemyController中添加 privateMonsterAI Monsterai;
在void Start () {}中添加 Monsterai=this.GetComponent<MonsterAI>();
void MonsterDeadAI(){}中修改代码为
string nameOfMobToSend=Monsterai.NameOfMob;
Messenger<string>.Broadcast("MonsterKilled",nameOfMobToSend);
![](http://img.blog.csdn.net/20150419173150268?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419173308144?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
注释掉void Update (){}中的
// floatcurHealth = GetComponent<Health>().CurrentHealth;
//
// if(curHealth<= 0 ){
// MonsterHealth= 0;
// isDead= true;
// }
//
修改PlayerBase中LevelUpAnimation方法,确保只有一种升级
![](http://img.blog.csdn.net/20150419173433538?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419173637924?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419173703860?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419173810207?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419173915072?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419173950421?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
看看player.QuestsInProgress[i].nameOfMobThatDropsItem这个东东的值是什么,
![](http://img.blog.csdn.net/20150419174257597?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174214722?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174253659?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174449356?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174419849?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174626185?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174652839?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174845712?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174924150?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419175004679?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419174959914?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419175154846?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419175247169?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
一口气贴了这么多东西,其实这是我一周时间写的代码和调试信息,而且用到的类也是一个成熟的任务系统,我只是做了整合,
注意要看上面提供了需要的代码包和任务Npc预制件。
![](http://img.blog.csdn.net/20150419181837281?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419181735499?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150419181913857?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dvcmRmaXNoeDgy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
这一篇的篇幅都是在讲我整喝一个任务系统到这个插件的全过程,因为直接看估计很难看得懂,所以后面我会提供完整的整合任务系统的工程文件,所以到时候再看把,建议大家跳过这一篇,直接看下一篇,等到我提供的工程文件放出来,大家在回来看,否则估计会有很多小伙伴骂我。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/tongue.gif)
这个任务系统需要的源码包下载地址密码wjd3,这个包复制进下载的Top-down-Rpg-Start-kit1.0,然后按照最后Hierarchy设置,完整的工程文件因为太大,所以以后有时间放上来。
先上一张插件的logo,新建
建立新文件夹,存放修改后的模型元件,代码,资源
建立人物模型组件
1.添加模型(模型要包括动作)到Hierarchy窗口2.添加角色控制脚本到模型上
3.把人物模型层layer和标签tag改为player
任务系统开发
playerBase.cs修改
if(globalPrefabs== null){ //globalPrefabs=GameObject.FindGameObjectWithTag("GameMaster").GetComponent<GlobalPrefabs>(); } OptionsMenuGUI.cs //gameSettings=GameObject.FindGameObjectWithTag("GameMaster").GetComponent<GameSettings>(); MyGUI.cs //DisplayPlayerVitalsAndExp();制作一个用于测试的敌人修改
中的预制件
注意上面的PlayerNew.cs是我们后加的,源码
using System.Collections.Generic; using System.Linq; using UnityEngine; using System.Collections; //You must include these namespaces //to use BinaryFormatter using System; using System.Runtime.Serialization.Formatters.Binary; using System.IO; public class PlayerNew : PlayerBase { #region "Inventorys, Banks, Stashes" public int MaxInventorySpace = 25; private List<Item> _inventory = new List<Item>(); public List<Item> Inventory { get{return _inventory;} set{_inventory = value;} } private int MaxStashSpace = 125; private List<Item> _stash = new List<Item>(); public List<Item> Stash { get{return _stash;} set{_stash = value;} } #endregion #region "Tracking" private List<NPCQuest> _QuestsComplete = new List<NPCQuest>(); public List<NPCQuest> questsComplete { get{return _QuestsComplete;} set{_QuestsComplete = value;} } private List<NPCQuest> _questsInProgress = new List<NPCQuest>(); public List<NPCQuest> QuestsInProgress { get{return _questsInProgress;} set{_questsInProgress = value;} } #endregion #region "Achievement Variables" private int monstersKilled = 0; public int MonstersKilled { get{return monstersKilled;} set{monstersKilled = value;} } private List<string> _bossesKilled = new List<string>(); public List<string> BossesKilled { get{return _bossesKilled;} set{_bossesKilled = value;} } #endregion #region "Variables" private bool canConsume = true; #endregion // Use this for initialization void Start () { //For testing ///////////////////////////////////// ModifyAttribute(AttributeName.Strength,10); ModifyAttribute(AttributeName.Dexterity,10); ModifyAttribute(AttributeName.Vitality,10); ModifyAttribute(AttributeName.Intelligence,10); Name = "Player"; RefreshVitals(); /////////////////////////////////////////////////// Item item = ItemGenerator.CreateItem ("consum","random",100); item.CurStacks = 10; Item itemcopy = DeepCopy.CopyItem (item); Inventory.Add (item); Inventory.Add (itemcopy); } public void OnEnable(){ Messenger<string>.AddListener("MonsterKilled",AddMobsKilled); } public void OnDisable(){ Messenger<string>.RemoveListener("MonsterKilled",AddMobsKilled); } // Update is called once per frame void Update () { if(Input.GetKeyDown(KeyCode.P)){ for (int i = 0; i < Vitals.Length; i++) { _vitals[i].CurValue = (int)(0.5f * _vitals[i].CurValue); } } if(Input.GetKeyDown(KeyCode.O)){ GiveStuff(); } } //Methods public void ModifyAttribute(AttributeName att, int amount) { GetAttribute((int)att).BaseValue += amount; UpdateStats(); } public bool ModifyGold(int amount){ Gold += amount; return true; } //Mobs killed private void AddMobsKilled(string mobName){ MonstersKilled += 1; if(mobName.StartsWith("BOSS")){ BossesKilled.Add (mobName.Substring(4)); } } //Bank Adding public bool AddToBank(int arrayNum){ if(_inventory[arrayNum].MaxStacks > 1){ //maybe check this first Debug.Log ("Bank is not full!,AddToBank"+_inventory[arrayNum].MaxStacks); bool addedToStack = CheckBankStack(_inventory[arrayNum]); if(addedToStack){ _inventory.RemoveAt (arrayNum); Debug.Log ("Bank is not full!,AddToBank,arrayNum"+arrayNum); Debug.Log ("Bank is not full!,AddToBank,"+_inventory); return true; } } if(Stash.Count < MaxStashSpace){ Stash.Add (_inventory[arrayNum]); _inventory.RemoveAt (arrayNum); return true; } Debug.Log ("Bank is full!"); return false; } private bool CheckBankStack(Item item){ bool itemsAdded = false; foreach(Item i in Stash){ //Is the item already there if(i.Name == item.Name){ Debug.Log("CheckBankStack==="+i.ItemType); if(i.ItemType == ItemEquipType.QuestItem){ Debug.Log ("Cannot bank quest items"); return false; } //Is there space in that stack to add the current item if(i.CurStacks + item.CurStacks <= i.MaxStacks){ i.CurStacks += item.CurStacks; itemsAdded = true; return true; } } } if(!itemsAdded){ //Manually Check Inventory if(Stash.Count < MaxStashSpace){ Stash.Add (item); return true; } else { Debug.Log("Bank too full to add more of this stack"); } } return false; } //Inventory Adding public bool AddItem(Item item){ if(item.Name.Contains("Gold")){ bool isNotGold = true; //Just in case we want to put goldin item name, we check if name has numbers in it foreach (char c in item.Name) if (char.IsNumber(c)) isNotGold = false; if(!isNotGold) ModifyGold(item.Value); return true; } if(item.MaxStacks > 1){ //maybe check this first bool addedToStack = CheckStack(item); if(addedToStack) return true; } if(Inventory.Count < MaxInventorySpace){ Inventory.Add (item); return true; } return false; } private bool CheckStack(Item item){ bool itemsAdded = false; foreach(Item i in Inventory){ //Is the item already there if(i.Name == item.Name){ if(i.ItemType == ItemEquipType.QuestItem){ i.CurStacks += item.CurStacks; if(i.CurStacks > i.MaxStacks) i.CurStacks = i.MaxStacks; return true; } //Is there space in that stack to add the current item if(i.CurStacks + item.CurStacks <= i.MaxStacks){ i.CurStacks += item.CurStacks; itemsAdded = true; return true; } } } if(!itemsAdded){ //Manually Check Inventory if(Inventory.Count < MaxInventorySpace){ Inventory.Add (item); return true; } else { Debug.Log("Inventory too full to add more of this stack"); } } return false; } //Stat Handling public void ResetStats() { HealthFromAttr = ManaFromAttr = EnergyFromAttr = 0; PlayerArmor = PlayerDamageBlocked = StrEquipValue = DexEquipValue = IntEquipValue = VitEquipValue = 0; PlayerChanceToBlock = PlayerMoveSpeedBuff = 0.0f; CritChance = BaseCritChance; AttackSpeed = MaxDamage = 1; DmgVariance = 0.1f; CritDamage = 2; } public List<Item> AllEquippedItems(){ return new List<Item>(){ EquipedArmorBack, EquipedArmorChest, EquipedArmorFeet, EquipedArmorGloves, EquipedArmorHead, EquipedArmorLegs, EquipedWeapon }; } public void UpdateStats() { ResetStats(); List<Item> EquippedItems = AllEquippedItems(); foreach(Item item in EquippedItems){ if(item != null){ BuffItem equippedItem = item as BuffItem; if(equippedItem.EquippedSockets.Count > 0){ foreach(AttributeBuff ab in equippedItem.EquippedSockets[0].AttribBuffs){ if (ab.attribute == AttributeName.Vitality){ VitEquipValue += ab.amount; } else if(ab.attribute == AttributeName.Strength){ StrEquipValue += ab.amount; } else if(ab.attribute == AttributeName.Dexterity){ DexEquipValue += ab.amount; } else if(ab.attribute == AttributeName.Intelligence){ IntEquipValue += ab.amount; } } foreach(VitalBuff vb in equippedItem.EquippedSockets[0].VitalBuffs){ if (vb.vital == VitalName.Health){ HealthFromAttr += vb.amount; } else if(vb.vital == VitalName.Mana){ ManaFromAttr += vb.amount; } else if(vb.vital == VitalName.Energy){ EnergyFromAttr += vb.amount; } } } if (item.ItemType == ItemEquipType.Clothing){ Armor equippedArmor = item as Armor; PlayerArmor += equippedArmor.ArmorAmt; PlayerChanceToBlock += equippedArmor.ChanceToBlock; PlayerDamageBlocked += equippedArmor.DamageBlocked; PlayerMoveSpeedBuff += equippedArmor.MoveSpeedBuff; } if(equippedItem.ItemType == ItemEquipType.Weapon){ Weapon equippedWep= equippedItem as Weapon; MaxDamage += equippedWep.MaxDamage; DmgVariance = equippedWep.DmgVariance; //replace AttackSpeed = equippedWep.AttackSpeed; //replace CritDamage += equippedWep.CritDamage; //additive, always 2.0 } foreach(AttributeBuff ab in equippedItem.AttribBuffs){ if (ab.attribute == AttributeName.Vitality){ VitEquipValue += ab.amount; } else if(ab.attribute == AttributeName.Strength){ StrEquipValue += ab.amount; } else if(ab.attribute == AttributeName.Dexterity){ DexEquipValue += ab.amount; } else if(ab.attribute == AttributeName.Intelligence){ IntEquipValue += ab.amount; } } foreach(VitalBuff vb in equippedItem.VitalBuffs){ if (vb.vital == VitalName.Health){ HealthFromAttr += vb.amount; } else if(vb.vital == VitalName.Mana){ ManaFromAttr += vb.amount; } else if(vb.vital == VitalName.Energy){ EnergyFromAttr += vb.amount; } } } } foreach(Attribute att in _attributes){ if(att.Name == "Strength") { att.EquipValue = StrEquipValue; } else if(att.Name == "Vitality") { att.EquipValue = VitEquipValue; } else if(att.Name == "Dexterity") { att.EquipValue = DexEquipValue; } else if(att.Name == "Intelligence") { att.EquipValue = IntEquipValue; } att.RecalculateValue(); } ScaleStats(); } private void ScaleStats(){ //Scale Vitals based on Attributes foreach(Vital vit in _vitals){ if(vit.Name == "Health") { HealthFromAttr += GetAttribute((int)AttributeName.Strength).AttributeValue * 10 + GetAttribute((int)AttributeName.Vitality).AttributeValue * 50; vit.MaxValue = HealthFromAttr ; } else if(vit.Name == "Mana") { ManaFromAttr += GetAttribute((int)AttributeName.Intelligence).AttributeValue * 10; vit.MaxValue = ManaFromAttr ; } else if(vit.Name == "Energy") { EnergyFromAttr += GetAttribute((int)AttributeName.Dexterity).AttributeValue * 10; vit.MaxValue = EnergyFromAttr ; } } //Scale damage based off stat MaxDamage += GetAttribute((int)AttributeName.Strength).AttributeValue * 2; //Scale armour based off stat PlayerArmor += GetAttribute((int)AttributeName.Vitality).AttributeValue * 2; //Scale Crit chance based on level BaseCritChance = Level * 0.002f; //Recalc Movement Speed MoveSpeed = 1.0f + PlayerMoveSpeedBuff; //Recalc Crit Chance float wepCritChance = EquipedWeapon != null ? (EquipedWeapon as Weapon).CritChance : 0; CritChance = BaseCritChance + wepCritChance; } private void RefreshVitals(){ foreach(Vital v in Vitals){ v.CurValue = v.MaxValue; } } public void Respawn(){ //Load level if needed GameObject RespawnLocation = GameObject.FindGameObjectWithTag("Respawn"); if(RespawnLocation != null) { gameObject.transform.position = RespawnLocation.transform.position; } else { Debug.Log ("No respawn gameObject found to use as respawn location."); } CharacterControl.useNewPosition = true; CharacterControl.newPosition = transform.position; GetVital((int)VitalName.Health).CurValue = (int)((GetVital((int)VitalName.Health).MaxValue)*.75); //respawn with 10% health GetVital((int)VitalName.Mana).CurValue = (int)((GetVital((int)VitalName.Mana).MaxValue)*.75f); GetVital((int)VitalName.Energy).CurValue = (int)((GetVital((int)VitalName.Energy).MaxValue)*.75f); Alive = true; } public bool UseConsumable(int getVitalInt, int amount){ if(canConsume){ StartCoroutine(UsePot(getVitalInt, amount)); return true; } return false; } IEnumerator UsePot(int getVitalInt, int amount){ canConsume = false; GetVital(getVitalInt).CurValue += amount; yield return new WaitForSeconds(1.0f); canConsume = true; } //Exit Combat Vars public int secondsBeforeExitingCombat = 5; public int secondsWaited = 0; public void CheckForExitCombat(){ if(!_waitingToExitCombat) InvokeRepeating("TryToExitCombat",1.0f,1.0f); else{ CancelInvoke("TryToExitCombat"); secondsWaited = 0; InvokeRepeating("TryToExitCombat",1.0f,1.0f); } } public void TryToExitCombat(){ WaitingToExitCombat = true; secondsWaited += 1; if(secondsWaited > secondsBeforeExitingCombat){ secondsWaited = 0; CancelInvoke("TryToExitCombat"); playerState = PlayerState.Normal; WaitingToExitCombat = false; } } void GiveStuff(){ AddItem(ItemGenerator.CreateItem("weapon","legendary",2)); Item fireItem = ItemGenerator.CreateItem("weapon","legendary",2); Weapon fireWeapon = fireItem as Weapon; fireWeapon.DmgType = DamageType.Fire; fireWeapon.DmgValue = 100; fireWeapon.CritChance = 0.7f; fireWeapon.CritDamage = 4.0f; AddItem(fireWeapon); Item waterItem = ItemGenerator.CreateItem("weapon","legendary",2); Weapon waterWeapon = waterItem as Weapon; waterWeapon.DmgType = DamageType.Water; waterWeapon.DmgValue = 100; AddItem(waterWeapon); Item knockBackItem = ItemGenerator.CreateItem("weapon","legendary",2); Weapon knockBackWep = knockBackItem as Weapon; knockBackWep.Proc = ProcType.Knockback; knockBackWep.ProcModifier = 0.8f; AddItem(knockBackWep); Item stunItem = ItemGenerator.CreateItem("weapon","legendary",2); Weapon stunWep = stunItem as Weapon; stunWep.Proc = ProcType.Stun; stunWep.ProcModifier = 0.8f; AddItem(stunWep); Item slowItem = ItemGenerator.CreateItem("weapon","legendary",2); Weapon slowWep = slowItem as Weapon; slowWep.Proc = ProcType.Slow; slowWep.ProcModifier = 0.8f; AddItem(slowWep); Item poisonItem = ItemGenerator.CreateItem("weapon","legendary",2); Weapon poisonWep = poisonItem as Weapon; poisonWep.Proc = ProcType.Poison; poisonWep.ProcModifier = 0.8f; AddItem(poisonWep); AddItem(ItemGenerator.CreateItem("armor","legendary",2)); AddItem(ItemGenerator.CreateItem("armor","legendary",2)); AddItem(ItemGenerator.CreateItem("armor","legendary",2)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("consum","legendary",25)); AddItem(ItemGenerator.CreateItem("socket","legendary",10)); AddItem(ItemGenerator.CreateItem("socket","legendary",10)); AddItem(ItemGenerator.CreateItem("socket","legendary",10)); AddItem(ItemGenerator.CreateItem("socket","legendary",10)); ModifyGold(1000); } }代码量比较大,palyernew中用到的几个类
//Add _description for displaying info about an item: //e.g. "This will heal your health" //e.g. A might sword forged in gallifrey etc //e.g. "Quest Item: Hand to Alabar" using UnityEngine; //[System.Serializable] [System.Serializable] public class Item { private string _name; private int _value; //Gold Value private RarityTypes _rarity; private bool _canBeSold; [System.NonSerialized] private Texture2D _icon; private string _iconPath; private int _curStacks; private int _maxStacks; private int _requiredLevel; private ItemEquipType _itemType; private bool _canBeDropped; //Number you can have in one slot, e.g. 1 for equips, 20 for pots private string _description; public Item(){ _name = "Unnamed Item"; _value = 100; _rarity = RarityTypes.Common; _itemType = ItemEquipType.Clothing; _requiredLevel = 0; _canBeSold = true; _icon = Resources.Load ("Item Icons/defaultItem") as Texture2D; _iconPath = "Item Icons/defaultItem"; _maxStacks = 1; _curStacks = 1; _description = ""; _canBeDropped = true; } public Item(string name, int val, RarityTypes rare, ItemEquipType itemType, int reqLvl, int enchants, bool sellable, int maxStacks, int curStacks, string description, bool canBeDropped) { _name = name; _value = val; _rarity = rare; _requiredLevel = reqLvl; _canBeSold = sellable; _itemType = itemType; _maxStacks = maxStacks; _curStacks = curStacks; _description = description; _canBeDropped = canBeDropped; } //For Gold only public Item(string name, int val) { _name = name; _value = val; _icon = Resources.Load("Item Icons/goldItem") as Texture2D; _iconPath = "Item Icons/goldItem"; } public string Name{ get{return _name;} set{_name = value;} } public int Value{ get{return _value;} set{_value = value;} } public bool CanBeSold { get{return _canBeSold;} set{_canBeSold = value;} } public bool CanBeDropped { get{return _canBeDropped;} set{_canBeDropped = value;} } public RarityTypes Rarity { get{return _rarity;} set{_rarity = value;} } public ItemEquipType ItemType { get{return _itemType;} set{_itemType = value;} } public int RequiredLevel { get{return _requiredLevel;} set{_requiredLevel = value;} } public Texture2D Icon { get{return _icon;} set{_icon = value;} } public string IconPath { get{return _iconPath;} set{_iconPath = value;} } public int MaxStacks { get{return _maxStacks;} set{_maxStacks = value;} } public int CurStacks { get{return _curStacks;} set{_curStacks = value;} } public string Description { get{return _description;} set{_description = value;} } public virtual string UniqueIdentifier(){ return (Name+Value.ToString()+RequiredLevel+Description); } public virtual string ToolTip() { if(!Name.Contains("Gold")){ return "Name" + "\n" + "Value: " + Value; } return Value + " Gold!"; } } public enum RarityTypes { Common, Uncommon, Rare, Epic, Legendary, Unique, CraftedItem, //not rarity, just used for identifying unique items QuestItem, CraftItem, SocketItem } public enum ItemEquipType { Clothing, Weapon, Consumable, QuestItem, CraftItem, Socket }
using UnityEngine; using System.Collections; using System.Collections.Generic; public class NPCQuest : MonoBehaviour { private PlayerNew player; public int QuestID; public string QuestName; public string QuestText; public string QuestNPCName; public int QuestExpReward; public int QuestGoldReward; public List<Item> QuestReward = new List<Item>(); public bool isComplete; public bool isAccepted; public bool isFinished; public int RewardNum; public string rewardType; public RequirementsStatus requirementStatus; //Quest Requirements public int[] QuestIDReq; public int QuestLevelReq; //Quest Completion Steps public bool trackSteps; public string nameOfMob; public int numberToKill; public int numberKilled; public bool killDone; public string nameOfItem; public string nameOfMobThatDropsItem; public int numberToObtain; public int numberObtained; public bool itemDone; public EnableGameObject qego; public bool EnableQuestGOPerm; public bool talkingCompletesQuest; public string nameOfNPCtoTalkTo; public string[] npcResponse; public bool talkDone; //TEMP public string questTracker; // Use this for initialization void Start () { if(player == null){ player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerNew>(); } trackSteps = true; for (int i = 0; i < RewardNum; i++) { Item x = ItemGenerator.CreateItem(rewardType,"legendary",player.Level); QuestReward.Add(x); } QuestNPCName = GetComponent<NPCDialog>().NpcName; CheckRequirements(); } public void OnEnable(){ Messenger<string>.AddListener("MonsterKilled",AddMobsKilled); } public void OnDisable(){ Messenger<string>.RemoveListener("MonsterKilled",AddMobsKilled); } void Update() { if(isAccepted && !isFinished){ questTracker = ""; if(numberToKill > 0){ CheckForMobs(); questTracker += ToolTipStyle.Break; } if(numberToObtain > 0){ CheckForItems(); questTracker += ToolTipStyle.Break; } if(talkingCompletesQuest){ CheckForTalk(); } CheckForCompletion(); } else if(isFinished){ string addS = numberToKill > 1 ? "s" : ""; string txtDone = talkDone ? "Done" : "Not Done"; questTracker = ""; if(numberToKill > 0){ questTracker = string.Format("{0}{1} Killed: {2} of {3}",nameOfMob,addS,numberKilled,numberToKill); } if(numberToObtain > 0){ if(questTracker != "") questTracker += ToolTipStyle.Break; questTracker += string.Format("{0} Gained: {1} of {2}",nameOfItem,numberObtained,numberToObtain); } if(talkingCompletesQuest){ if(questTracker != "") questTracker += ToolTipStyle.Break; questTracker += string.Format("Talked to {0} : {1}",nameOfNPCtoTalkTo,txtDone); } } } private void AddMobsKilled(string mobName){ if(isAccepted && !isFinished){ if(mobName.Contains (nameOfMob)){ numberKilled += 1; if(numberKilled > numberToKill){ numberKilled = numberToKill; } } } } private void CheckForMobs(){ if(numberKilled >= numberToKill) killDone = true; string addS = numberToKill > 1 ? "s" : ""; questTracker = string.Format("{0}{1} Killed: {2} of {3}",nameOfMob,addS,numberKilled,numberToKill); } private void CheckForItems(){ numberObtained = 0; for (int i = 0; i < player.Inventory.Count; i++) { if(player.Inventory[i].Name == nameOfItem){ numberObtained = player.Inventory[i].CurStacks; if(player.Inventory[i].CurStacks > numberToObtain){ player.Inventory[i].CurStacks = numberToObtain; } } } if(numberObtained >= numberToObtain){ itemDone = true; } questTracker += string.Format("{0} Gained: {1} of {2}",nameOfItem,numberObtained,numberToObtain); } private void CheckForTalk(){ string txtDone = talkDone ? "Done" : "Not Done"; questTracker += string.Format("Talked to {0} : {1}",nameOfNPCtoTalkTo,txtDone); } private void CheckForCompletion(){ bool completed = true; if(numberToKill > 0 && !killDone) completed = false; if(numberToObtain > 0 && !itemDone) completed = false; if(talkingCompletesQuest && !talkDone) completed = false; if(completed){ isComplete = true; } } private int numberOfQuestsNeeded = 0; private int numberOfQuestsFound = 0; public void CheckRequirements() { numberOfQuestsNeeded = QuestIDReq.Length; //Check Level if(player.Level >= QuestLevelReq){ requirementStatus = RequirementsStatus.Level; } foreach(int nqID in QuestIDReq){ foreach(NPCQuest nq in player.questsComplete){ if(nq.QuestID == nqID){ numberOfQuestsFound = numberOfQuestsFound + 1; } } } if(numberOfQuestsFound >= numberOfQuestsNeeded){ if(requirementStatus == RequirementsStatus.Level) requirementStatus = RequirementsStatus.All; else requirementStatus = RequirementsStatus.Quests; } numberOfQuestsFound = 0; } //FOR GUI public string QuestInfo(){ string questInfo = ToolTipStyle.Blue + QuestName + ToolTipStyle.EndColor + ToolTipStyle.Break + QuestNPCName; return questInfo; } public string QuestRewardString(){ string questRewardString = "Exp: " + QuestExpReward.ToString() + " Gold: " + QuestGoldReward.ToString(); return questRewardString; } public void CancelQuest(){ talkDone = killDone = itemDone = isComplete = isAccepted = false; numberKilled = numberObtained = 0; Debug.Log("Quest Canceled"); player.QuestsInProgress.Remove(this); } public void LoadFinishedQuest(){ if(player == null){ player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerNew>(); } foreach(NPCQuest nq in player.questsComplete){ if (nq.QuestID == this.QuestID) return; } player.questsComplete.Add(this); } public void LoadInProgressQuest(){ if(player == null){ player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerNew>(); } if(player.QuestsInProgress.Count > 0){ foreach(NPCQuest nq in player.QuestsInProgress){ if (nq.QuestID == this.QuestID) return; } } player.QuestsInProgress.Add(this); } } public enum RequirementsStatus { None, Quests, Level, All }
using UnityEngine; using System.Collections; using System.Collections.Generic; public class MonsterAI : MonoBehaviour { private PlayerNew player; public string NameOfMob = "Cube"; public int LevelOfMob = 1; public MonsterType monsterType = MonsterType.Normal; public int Damage = 10; public int expValue = 30; public float RunSpeed = 2; public float AttacksPerSecond; private float OriginalAttacksPerSecond; public float timeSinceLastAttack; public int MonsterHealth; public string NumberOfItemsToDrop = "random"; public string ItemTypesToDrop = "random"; public string ItemsDroppedRarity = "random"; //AI public bool inCombat; public bool isDead; public bool EnableCombat; //sgo public GlobalPrefabs globalPrefabs; //From Player Procs public bool isUseless; //Won't do anything public bool isStunned; //can't move public bool isSlowed; //Attack Speed is slowed public float amountSlowedBy; //Attack speed reduction public bool isKnockedBack; //If knocked back( so can't chain knockback) public List<string> currentDots = new List<string>(); void Start(){ QuestItemsClasses.AddAllItems(); if(player == null){ player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerNew>(); } if(globalPrefabs == null){ // globalPrefabs = GameObject.FindGameObjectWithTag("GameMaster").GetComponent<GlobalPrefabs>(); } OriginalAttacksPerSecond = AttacksPerSecond; } void Update () { timeSinceLastAttack += Time.deltaTime; // float curHealth = GetComponent<Health>().CurrentHealth; // // if(curHealth <= 0 ){ // MonsterHealth = 0; // isDead = true; // } // if(isDead){ player.AddExp(expValue); string nameOfMobToSend = monsterType == MonsterType.Normal ? NameOfMob : "BOSS" + NameOfMob; Messenger<string>.Broadcast("MonsterKilled",nameOfMobToSend); //Destroy all floating text attached to this FloatingTextGUI[] floatingTexts = GetComponentsInChildren<FloatingTextGUI>(); for (int i = 0; i < floatingTexts.Length; i++) { Destroy(floatingTexts[i].gameObject,0.5f); } //死亡掉落物品 DropLoot(); Destroy(gameObject); } else{ if(inCombat){ EnableCombat =true; } else { EnableCombat = false; } if(isStunned){ EnableCombat = false; } if(isUseless){ return; } if(EnableCombat){ float angleToTarget = Mathf.Atan2((player.transform.position.x - transform.position.x), (player.transform.position.z - transform.position.z)) * Mathf.Rad2Deg; transform.eulerAngles = new Vector3(0,angleToTarget, 0); if(Vector3.Distance (transform.position,player.transform.position) > 2){ transform.position = Vector3.MoveTowards(transform.position, player.transform.position, RunSpeed * Time.deltaTime); } bool canDealDamage = timeSinceLastAttack > 1 / AttacksPerSecond ? true : false; if(canDealDamage){ timeSinceLastAttack = 0; PlayerHealth php = player.GetComponent<PlayerHealth>(); if(php == null) Debug.Log ("No player health"); DealDamage(php); canDealDamage = false; } } } } public void DropLoot(){ Debug.Log("9999DropLoot,notsee9999"); GameObject loot = GameObject.FindGameObjectWithTag("ItemSpawner"); // Debug.Log("loot"+loot); loot.GetComponent<ItemSpawner>().positionToSpawn = transform.position; // // if(ItemsDroppedRarity != null) // loot.GetComponent<ItemSpawner>().chestRarity = ItemsDroppedRarity; // // if(ItemTypesToDrop != null) // loot.GetComponent<ItemSpawner>().chestSpawnType = ItemTypesToDrop; // // if(NumberOfItemsToDrop != null) // loot.GetComponent<ItemSpawner>().itemsInChest = NumberOfItemsToDrop; // // loot.GetComponent<ItemSpawner>().chestItemLevel = LevelOfMob; // // //Clear loot and populate with random items // loot.GetComponent<ItemSpawner>().PopulateChest(); // // //40% Chance to drop gold // int amountOfGold = Random.Range(100*LevelOfMob,1000*LevelOfMob+1); // int randomlyAddGold = Random.Range (0,101); // if(randomlyAddGold > 60) { // loot.GetComponent<ItemSpawner>().loot.Add (StaticItems.GoldItem(amountOfGold)); // } ItemSpawner lootOfMob = loot.GetComponent<ItemSpawner>(); HandleQuestLoot(lootOfMob); //Finally, spawn all the items loot.GetComponent<ItemSpawner>().SpawnItems(); } void HandleQuestLoot(ItemSpawner lootOfMob){ Debug.Log("HandleQuestLoot"); bool dropLoot = false; int questIndex = 1000; Debug.Log("player.QuestsInProgress.Count"+player.QuestsInProgress.Count); for (int i = 0; i < player.QuestsInProgress.Count; i++) { Debug.Log("player.QuestsInProgress[i].numberToKill"+player.QuestsInProgress[i].numberToKill); if(player.QuestsInProgress[i].numberToKill > 0){ Debug.Log("player.QuestsInProgress[i].nameOfMobThatDropsItem="+player.QuestsInProgress[i].nameOfMobThatDropsItem); Debug.Log("player.QuestsInProgress[i].nameOfMobThatDropsItem.Contains(NameOfMob)="+player.QuestsInProgress[i].nameOfMobThatDropsItem.Contains(NameOfMob)); if(player.QuestsInProgress[i].nameOfMobThatDropsItem.Contains(NameOfMob)){ Debug.Log("player.QuestsInProgress[i].itemDone="+player.QuestsInProgress[i].itemDone); if(!player.QuestsInProgress[i].itemDone){ Debug.Log("check dropLoot="+dropLoot); dropLoot = true; questIndex = i; Debug.Log("questIndex int for"+questIndex); } } } } if(dropLoot){ Debug.Log("questIndex=="+questIndex); Item QuestItemToAdd = MobQuestItem(questIndex); Debug.Log("QuestItemToAdd.Name"+QuestItemToAdd.Name); //create a new instance QuestItemToAdd = new QuestItem(QuestItemToAdd.Name,QuestItemToAdd.Description,QuestItemToAdd.CurStacks,QuestItemToAdd.MaxStacks,QuestItemToAdd.Icon); if(QuestItemToAdd != null) lootOfMob.loot.Add (QuestItemToAdd); } } Item MobQuestItem(int questIndex) { Debug.Log (QuestItemsClasses.AllQuestItems.Count); for (int i = 0; i < QuestItemsClasses.AllQuestItems.Count; i++) { Debug.Log("player.QuestsInProgress[questIndex].nameOfItem"+player.QuestsInProgress[questIndex].nameOfItem); Debug.Log("QuestItemsClasses.AllQuestItems[i].Name=="+QuestItemsClasses.AllQuestItems[i].Name); //If the name of the quest item is the name of the quest item if(player.QuestsInProgress[questIndex].nameOfItem == QuestItemsClasses.AllQuestItems[i].Name){ return QuestItemsClasses.AllQuestItems[i]; } } return null; } //Deal Damage void DealDamage(PlayerHealth hp){ if(hp){ hp.DealDamage((int)Damage); player.playerState = PlayerState.Combat; player.CheckForExitCombat(); } } //Procs //KnockBack public void KnockBackSelf(){ StartCoroutine("KnockBack"); } private IEnumerator KnockBack(){ StopCoroutine("KnockBack"); isUseless = true; isKnockedBack = true; GameObject dmgTxt = (GameObject)Instantiate(globalPrefabs.floatingDamageText); dmgTxt.transform.parent = this.transform; FloatingTextGUI dmgText = dmgTxt.GetComponent<FloatingTextGUI>(); dmgText.SetDmgInfo(ToolTipStyle.Purple + "Knockback!" + ToolTipStyle.EndColor,transform.position); yield return new WaitForSeconds(0.5f); isKnockedBack = false; isUseless = false; } //Stun public void StunSelf(float timeToStunSelf){ StartCoroutine("Stun",timeToStunSelf); } private IEnumerator Stun(float timeToStun){ StopCoroutine("Stun"); GameObject dmgTxt = (GameObject)Instantiate(globalPrefabs.floatingDamageText); dmgTxt.transform.parent = this.transform; FloatingTextGUI dmgText = dmgTxt.GetComponent<FloatingTextGUI>(); dmgText.SetDmgInfo(ToolTipStyle.Purple + "Stunned!" + ToolTipStyle.EndColor,transform.position); isStunned = true; yield return new WaitForSeconds(timeToStun); isStunned = false; } //Slow public void SlowAttackSpeed(float amountToSlow){ AttacksPerSecond = OriginalAttacksPerSecond; StartCoroutine("Slow",amountToSlow); } private IEnumerator Slow(float amountToReduceBy){//e.g. 0.3f = 30% attack speed lost StopCoroutine("Slow"); GameObject dmgTxt = (GameObject)Instantiate(globalPrefabs.floatingDamageText); dmgTxt.transform.parent = this.transform; FloatingTextGUI dmgText = dmgTxt.GetComponent<FloatingTextGUI>(); dmgText.SetDmgInfo(ToolTipStyle.Purple + "Attack slowed!" + ToolTipStyle.EndColor,transform.position); AttacksPerSecond += amountToReduceBy * AttacksPerSecond; yield return new WaitForSeconds(3.0f); AttacksPerSecond = OriginalAttacksPerSecond; } //DOT public void UseDot(string dotName, int damage,int ticks, float timeBetweenTicks){ for (int i = 0; i < currentDots.Count; i++) { if(currentDots[i].Contains(dotName)){ Debug.Log ("Same DOT, will not cast"); return; } } StartCoroutine(DoDot(dotName,ticks,damage, timeBetweenTicks)); } private IEnumerator DoDot(string dotName,int damage, int ticks, float timeBetweenTicks){ currentDots.Add(dotName); for (int i = 0; i < ticks; i++) { this.GetComponent<Health>().CurrentHealth -= damage; GameObject dmgTxt = Instantiate(globalPrefabs.floatingDamageText) as GameObject; dmgTxt.transform.parent = this.transform; FloatingTextGUI dmgText = dmgTxt.GetComponent<FloatingTextGUI>(); dmgText.SetDmgInfo(ToolTipStyle.Purple + damage.ToString() + ToolTipStyle.EndColor,transform.position); yield return new WaitForSeconds(timeBetweenTicks); } currentDots.Remove(dotName); } } public enum MonsterType { Normal, MiniBoss, Boss }
运行后的效果
EnemyController.cs中添加
monsterDeadAI中的nameOfMobToSend暂时测试直接写入,后面会改为通用。
杀怪任务修改完毕。。。。。。。。。。。。。。。。。。。。
在EnemyController中添加 privateMonsterAI Monsterai;
在void Start () {}中添加 Monsterai=this.GetComponent<MonsterAI>();
void MonsterDeadAI(){}中修改代码为
string nameOfMobToSend=Monsterai.NameOfMob;
Messenger<string>.Broadcast("MonsterKilled",nameOfMobToSend);
注释掉void Update (){}中的
// floatcurHealth = GetComponent<Health>().CurrentHealth;
//
// if(curHealth<= 0 ){
// MonsterHealth= 0;
// isDead= true;
// }
//
修改PlayerBase中LevelUpAnimation方法,确保只有一种升级
看看player.QuestsInProgress[i].nameOfMobThatDropsItem这个东东的值是什么,
一口气贴了这么多东西,其实这是我一周时间写的代码和调试信息,而且用到的类也是一个成熟的任务系统,我只是做了整合,
using UnityEngine; using System.Collections; using System.Collections.Generic; public class NPCDialog : MonoBehaviour { public string Title; public string NpcName; public TextMesh npcNameLevel; public GameObject npcBorder; public bool isVendor; public bool isBlacksmith; public Light HighlightLight; public NPCVendor vendor; public NPCBlacksmith blacksmith; public GUISkin mySkin; private PlayerNew player; public bool _isNear; public string[] npcText; public string[] npcTextOrig; public int textNum; public string[] buttonText = new string[2]; public int buttonTextNum; public List<NPCQuest> quests = new List<NPCQuest>(); //Quests public int OptionNumber = 0; public TextMesh hasQuestText; private float distToBeActive = 30; // Use this for initialization void Start () { if(player == null){ player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerNew>(); Debug.Log("player.transform.position.x"+player.transform.position.x); Debug.Log("player.transform.position.y"+player.transform.position.y); Debug.Log("player.transform.position.z"+player.transform.position.z); } npcTextOrig = npcText; textNum = 0; if(HighlightLight != null) HighlightLight.enabled = false; if(npcNameLevel != null) npcNameLevel.text = NpcName; vendor = GetComponent<NPCVendor>(); if(vendor != null) isVendor = true; else isVendor = false; blacksmith = GetComponent<NPCBlacksmith>(); if(blacksmith != null) isBlacksmith = true; else isBlacksmith = false; if(string.IsNullOrEmpty(buttonText[0])) buttonText[0] = "Next"; if(string.IsNullOrEmpty(buttonText[1])) buttonText[0] = "Close"; } void Update(){ float viewDist = Vector3.Distance(player.transform.position, transform.position); if(NPCDialogGUI.openedNPCDialog != null && NPCDialogGUI.openedNPCDialog == this) if(viewDist > 7 || player.playerState != PlayerState.NPCDialog) CloseDialog(); var allQuests = GetComponents<NPCQuest>(); if(allQuests.Length > 0) //if we have quests { CheckQuests(); if(quests.Count > 0){ //If has quests and one or more in progress, show grey ! for (int i = 0; i < quests.Count; i++) { if(quests[i].isAccepted) hasQuestText.text = ToolTipStyle.Grey + ToolTipStyle.Bold + "!" + ToolTipStyle.EndBold + ToolTipStyle.EndColor; } //If has quests but none accepted or completed, show yellow ! for (int i = 0; i < quests.Count; i++) { if(!quests[i].isAccepted) hasQuestText.text = ToolTipStyle.Yellow + ToolTipStyle.Bold + "!" + ToolTipStyle.EndBold + ToolTipStyle.EndColor; } //If has quests and one or more complete, show yellow ? for (int i = 0; i < quests.Count; i++) { if(quests[i].isComplete) hasQuestText.text = ToolTipStyle.Yellow + ToolTipStyle.Bold + "?" + ToolTipStyle.EndBold + ToolTipStyle.EndColor; } } else if(isVendor){ hasQuestText.text = "$"; } else { hasQuestText.text = ""; } } if(viewDist < distToBeActive){ npcNameLevel.text = NpcName; npcBorder.SetActive(true); }else{ npcNameLevel.text = ""; npcBorder.SetActive(false); if(quests.Count > 0) hasQuestText.text = ""; } } public void CompleteQuest(NPCQuest quest){ if(player.Inventory.Count + quest.QuestReward.Count <= player.MaxInventorySpace){ for (int i = 0; i < quest.QuestReward.Count; i+=0) { bool addedItem = player.AddItem(quest.QuestReward[i]); if(addedItem){ quest.QuestReward.RemoveAt(i); } else { Debug.Log ("Stack is full"); } } if(quest.QuestReward.Count == 0){ player.AddExp(quest.QuestExpReward); player.ModifyGold(quest.QuestGoldReward); quest.isFinished = true; player.questsComplete.Add(quest); if(quest.qego != null && !quest.EnableQuestGOPerm) quest.qego.DisableGameObjects(); if(quest.numberToObtain > 0){ for (int i = 0; i < player.Inventory.Count; i++) { if(player.Inventory[i].Name == quest.nameOfItem){ player.Inventory[i].CurStacks -= quest.numberToObtain; if(player.Inventory[i].CurStacks <= 0) player.Inventory.RemoveAt(i); } } } player.QuestsInProgress.Remove(quest); EnterDialog(); } } else { Debug.Log("Inventory is Full!"); } } void CheckQuests(){ npcText = npcTextOrig; var _quests = GetComponents<NPCQuest>(); quests = new List<NPCQuest>(); //Check this NPCs quests foreach(NPCQuest nq in _quests){ nq.CheckRequirements(); if(nq.talkingCompletesQuest && nq.isAccepted && NpcName.Contains(nq.nameOfNPCtoTalkTo)){ nq.talkDone = true; } if(!nq.isFinished && nq.requirementStatus != RequirementsStatus.None && nq.requirementStatus != RequirementsStatus.Level) quests.Add(nq); } //Check player quests foreach(NPCQuest nq in player.QuestsInProgress ){ nq.CheckRequirements(); if(nq.talkingCompletesQuest && !nq.talkDone && NpcName.Contains(nq.nameOfNPCtoTalkTo)){ npcText = nq.npcResponse; OptionNumber = 1; //Force Conversation } } } public void EnterDialog(){ if(player.playerState != PlayerState.Normal) return; player.playerState = PlayerState.NPCDialog; OptionNumber = 0; textNum = 0; CheckQuests(); NPCDialogGUI.openedNPCDialog = this; Messenger.Broadcast ("DisplayNPCWindow"); } public void CloseDialog(){ player.playerState = PlayerState.Normal; Messenger.Broadcast ("CloseNPCWindow"); } void OnTriggerEnter(Collider other){ // if(other.CompareTag("Player") && other.GetType() != typeof(SphereCollider) && !_isNear){ // EnterDialog(); // } CheckQuests(); } void OnTriggerExit(Collider other){ // if(other.CompareTag("Player") && other.GetType() != typeof(SphereCollider)){ // CloseDialog(); // } } void OnMouseDown () { float viewDist = Vector3.Distance(player.transform.position, transform.position); if(viewDist < 7) EnterDialog(); } void OnMouseEnter () { if(HighlightLight != null) HighlightLight.enabled = true; } void OnMouseExit () { if(HighlightLight != null) HighlightLight.enabled = false; } } public enum NpcType { NPC, Vendor, Bank }虽然贴出了代码,但说实话,就这么看,估计没人看得懂,而且任务系统还包括一段存储的部分,所以我建议这一篇大家先跳过吧,过段时间我整理一下代码,把整个工程文件发出来,否则这篇真的没法看了。建议大家跳过直接看下一篇。
注意要看上面提供了需要的代码包和任务Npc预制件。
相关文章推荐
- Topdown Kit1.2新增的任务系统(我们仙剑demo中暂时使用这种简单的任务系统,tk插件完结)
- Topdown Kit插件继续第3篇
- android开发(41) Fragment中使用POP_BACK_STACK_INCLUSIVE达到一次跳转到栈底。类似Activity的 采用FLAG_ACTIVITY_CLEAR_TOP
- 有关谷歌插件的开发使用
- 开发过程使用Tomcat Maven插件持续快捷部署Web项目
- Topdown Kit文档中文版-原创翻译(继续仙剑demo的周边部件)第2篇
- 在ubuntu上搭建开发环境6---安装和使用vim及其插件(Pathogen和NERDTree)
- 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取"产品付费数量等于0的问题"】
- 【无线互联】ios开发之MKNetworkKit的介绍和使用
- JEECMS二次开发 -------标签使用说明
- jQuery相当于对 javascript二次开发,所以基于 jQuery实现的各种插件直接调用即可
- 浏览器插件开发框架FireBreath的使用--linux版本
- 使用Python开发chrome插件
- Ionic 开发之旅 一(搭建基本工程)(使用ngCordova插件)(开发自己的ngCordova插件)
- 使用Python开发chrome插件
- 使用Notepad++进行php开发所必需的插件
- Web开发接口测试工具——Postman插件的使用(chrome浏览器)
- iOS开发笔记2-使用Alcatraz管理Xcode的插件
- NSIS学习笔记(二)-使用C++开发NSIS插件
- 作品-网站-【使用CMS系统二次开发】融锦易贷网