Top-down-Rpg-Start-kit插件的使用与二次开发

来源:互联网 发布:越狱软件源 编辑:程序博客网 时间:2024/06/05 04:05

这几天都在说仙剑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的源码有很多地方不太一样,不过具体修改的源码我会帖出来,并且写详细的中文注释。我们开始

这一篇的篇幅都是在讲我整喝一个任务系统到这个插件的全过程,因为直接看估计很难看得懂,所以后面我会提供完整的整合任务系统的工程文件,所以到时候再看把,建议大家跳过这一篇,直接看下一篇,等到我提供的工程文件放出来,大家在回来看,否则估计会有很多小伙伴骂我。吐舌头这个任务系统需要的源码包下载地址密码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 BinaryFormatterusing 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 initializationvoid 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 framevoid 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();}}//Methodspublic void ModifyAttribute(AttributeName att, int amount){GetAttribute((int)att).BaseValue += amount;UpdateStats();}public bool ModifyGold(int amount){Gold += amount;return true;}//Mobs killedprivate void AddMobsKilled(string mobName){MonstersKilled += 1;if(mobName.StartsWith("BOSS")){BossesKilled.Add (mobName.Substring(4));}}//Bank Addingpublic bool AddToBank(int arrayNum){if(_inventory[arrayNum].MaxStacks > 1){//maybe check this firstDebug.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 thereif(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 itemif(i.CurStacks + item.CurStacks <= i.MaxStacks){i.CurStacks += item.CurStacks;itemsAdded = true;return true;}}}if(!itemsAdded){//Manually Check Inventoryif(Stash.Count < MaxStashSpace){Stash.Add (item);return true;}else {Debug.Log("Bank too full to add more of this stack");}}return false;}//Inventory Addingpublic 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 itforeach (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 firstbool 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 thereif(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 itemif(i.CurStacks + item.CurStacks <= i.MaxStacks){i.CurStacks += item.CurStacks;itemsAdded = true;return true;}}}if(!itemsAdded){//Manually Check Inventoryif(Inventory.Count < MaxInventorySpace){Inventory.Add (item);return true;}else {Debug.Log("Inventory too full to add more of this stack");}}return false;}//Stat Handlingpublic 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; //replaceAttackSpeed = equippedWep.AttackSpeed; //replaceCritDamage += 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 Attributesforeach(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 statMaxDamage += GetAttribute((int)AttributeName.Strength).AttributeValue * 2;//Scale armour based off statPlayerArmor += GetAttribute((int)AttributeName.Vitality).AttributeValue * 2;//Scale Crit chance based on levelBaseCritChance = Level * 0.002f;//Recalc Movement SpeedMoveSpeed = 1.0f + PlayerMoveSpeedBuff;//Recalc Crit Chancefloat 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 neededGameObject 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% healthGetVital((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 Varspublic 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 Valueprivate 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 potsprivate 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 onlypublic 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 itemsQuestItem,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 Requirementspublic int[] QuestIDReq;public int QuestLevelReq;//Quest Completion Stepspublic 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;//TEMPpublic string questTracker;// Use this for initializationvoid 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 Levelif(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;elserequirementStatus = RequirementsStatus.Quests;}numberOfQuestsFound = 0;}//FOR GUIpublic 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";//AIpublic bool inCombat;public bool isDead;public bool EnableCombat;//sgopublic GlobalPrefabs globalPrefabs;//From Player Procspublic bool isUseless; //Won't do anythingpublic bool isStunned;//can't movepublic bool isSlowed;//Attack Speed is slowedpublic float amountSlowedBy;//Attack speed reductionpublic 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 thisFloatingTextGUI[] 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 itemsloot.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 instanceQuestItemToAdd = 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 itemif(player.QuestsInProgress[questIndex].nameOfItem == QuestItemsClasses.AllQuestItems[i].Name){return QuestItemsClasses.AllQuestItems[i];}}return null;}//Deal Damagevoid DealDamage(PlayerHealth hp){if(hp){hp.DealDamage((int)Damage);player.playerState = PlayerState.Combat;player.CheckForExitCombat();}}//Procs//KnockBackpublic 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;}//Stunpublic 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;}//Slowpublic void SlowAttackSpeed(float amountToSlow){AttacksPerSecond = OriginalAttacksPerSecond;StartCoroutine("Slow",amountToSlow);}private IEnumerator Slow(float amountToReduceBy){//e.g. 0.3f = 30% attack speed lostStopCoroutine("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;}//DOTpublic 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>();//Questspublic int OptionNumber = 0;public TextMesh hasQuestText;private float distToBeActive = 30;// Use this for initializationvoid 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 questsforeach(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 questsforeach(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预制件。 








0 0