饥荒联机版攻略 loot stash怎么开

随笔(63)
这几天都在说仙剑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的源码有很多地方不太一样,不过具体修改的源码我会帖出来,并且写详细的中文注释。我们开始
这一篇的篇幅都是在讲我整喝一个任务系统到这个插件的全过程,因为直接看估计很难看得懂,所以后面我会提供完整的整合任务系统的工程文件,所以到时候再看把,建议大家跳过这一篇,直接看下一篇,等到我提供的工程文件放出来,大家在回来看,否则估计会有很多小伙伴骂我。这个任务系统需要的源码包,这个包复制进下载的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&();
//DisplayPlayerVitalsAndExp();
制作一个用于测试的敌人修改中的预制件
注意上面的PlayerNew.cs是我们后加的,源码
using System.Collections.G
using System.L
using UnityE
using System.C
//You must include these namespaces
//to use BinaryFormatter
using System.Runtime.Serialization.Formatters.B
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 _}
set{_inventory =}
private int MaxStashSpace = 125;
private List&Item& _stash = new List&Item&();
public List&Item& Stash {
get{return _}
set{_stash =}
#endregion
#region &Tracking&
private List&NPCQuest& _QuestsComplete = new List&NPCQuest&();
public List&NPCQuest& questsComplete {
get{return _QuestsC}
set{_QuestsComplete =}
private List&NPCQuest& _questsInProgress = new List&NPCQuest&();
public List&NPCQuest& QuestsInProgress {
get{return _questsInP}
set{_questsInProgress =}
#endregion
#region &Achievement Variables&
private int monstersKilled = 0;
public int MonstersKilled {
get{return monstersK}
set{monstersKilled =}
private List&string& _bossesKilled = new List&string&();
public List&string& BossesKilled {
get{return _bossesK}
set{_bossesKilled =}
#endregion
#region &Variables&
private bool canConsume =
#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.L i++) {
_vitals[i].CurValue = (int)(0.5f * _vitals[i].CurValue);
if(Input.GetKeyDown(KeyCode.O)){
GiveStuff();
public void ModifyAttribute(AttributeName att, int amount)
GetAttribute((int)att).BaseValue +=
UpdateStats();
public bool ModifyGold(int amount){
//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);
if(Stash.Count & MaxStashSpace){
Stash.Add (_inventory[arrayNum]);
_inventory.RemoveAt (arrayNum);
Debug.Log (&Bank is full!&);
private bool CheckBankStack(Item item){
bool itemsAdded =
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&);
//Is there space in that stack to add the current item
if(i.CurStacks + item.CurStacks &= i.MaxStacks){
i.CurStacks += item.CurS
itemsAdded =
if(!itemsAdded){
//Manually Check Inventory
if(Stash.Count & MaxStashSpace){
Stash.Add (item);
Debug.Log(&Bank too full to add more of this stack&);
//Inventory Adding
public bool AddItem(Item item){
if(item.Name.Contains(&Gold&)){
bool isNotGold =
//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 =
if(!isNotGold)
ModifyGold(item.Value);
if(item.MaxStacks & 1){ //maybe check this first
bool addedToStack = CheckStack(item);
if(addedToStack)
if(Inventory.Count & MaxInventorySpace){
Inventory.Add (item);
private bool CheckStack(Item item){
bool itemsAdded =
foreach(Item i in Inventory){
//Is the item already there
if(i.Name == item.Name){
if(i.ItemType == ItemEquipType.QuestItem){
i.CurStacks += item.CurS
if(i.CurStacks & i.MaxStacks)
i.CurStacks = i.MaxS
//Is there space in that stack to add the current item
if(i.CurStacks + item.CurStacks &= i.MaxStacks){
i.CurStacks += item.CurS
itemsAdded =
if(!itemsAdded){
//Manually Check Inventory
if(Inventory.Count & MaxInventorySpace){
Inventory.Add (item);
Debug.Log(&Inventory too full to add more of this stack&);
//Stat Handling
public void ResetStats()
HealthFromAttr = ManaFromAttr = EnergyFromAttr = 0;
PlayerArmor = PlayerDamageBlocked = StrEquipValue = DexEquipValue = IntEquipValue = VitEquipValue = 0;
PlayerChanceToBlock = PlayerMoveSpeedBuff = 0.0f;
CritChance = BaseCritC
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 BuffI
if(equippedItem.EquippedSockets.Count & 0){
foreach(AttributeBuff ab in equippedItem.EquippedSockets[0].AttribBuffs){
if (ab.attribute == AttributeName.Vitality){
VitEquipValue += ab.
else if(ab.attribute == AttributeName.Strength){
StrEquipValue += ab.
else if(ab.attribute == AttributeName.Dexterity){
DexEquipValue += ab.
else if(ab.attribute == AttributeName.Intelligence){
IntEquipValue += ab.
foreach(VitalBuff vb in equippedItem.EquippedSockets[0].VitalBuffs){
if (vb.vital == VitalName.Health){
HealthFromAttr += vb.
else if(vb.vital == VitalName.Mana){
ManaFromAttr += vb.
else if(vb.vital == VitalName.Energy){
EnergyFromAttr += vb.
if (item.ItemType == ItemEquipType.Clothing){
Armor equippedArmor = item as A
PlayerArmor += equippedArmor.ArmorA
PlayerChanceToBlock += equippedArmor.ChanceToB
PlayerDamageBlocked += equippedArmor.DamageB
PlayerMoveSpeedBuff += equippedArmor.MoveSpeedB
if(equippedItem.ItemType == ItemEquipType.Weapon){
Weapon equippedWep= equippedItem as W
MaxDamage += equippedWep.MaxD
DmgVariance = equippedWep.DmgV //replace
AttackSpeed = equippedWep.AttackS //replace
CritDamage += equippedWep.CritD //additive, always 2.0
foreach(AttributeBuff ab in equippedItem.AttribBuffs){
if (ab.attribute == AttributeName.Vitality){
VitEquipValue += ab.
else if(ab.attribute == AttributeName.Strength){
StrEquipValue += ab.
else if(ab.attribute == AttributeName.Dexterity){
DexEquipValue += ab.
else if(ab.attribute == AttributeName.Intelligence){
IntEquipValue += ab.
foreach(VitalBuff vb in equippedItem.VitalBuffs){
if (vb.vital == VitalName.Health){
HealthFromAttr += vb.
else if(vb.vital == VitalName.Mana){
ManaFromAttr += vb.
else if(vb.vital == VitalName.Energy){
EnergyFromAttr += vb.
foreach(Attribute att in _attributes){
if(att.Name == &Strength&)
att.EquipValue = StrEquipV
else if(att.Name == &Vitality&)
att.EquipValue = VitEquipV
else if(att.Name == &Dexterity&)
att.EquipValue = DexEquipV
else if(att.Name == &Intelligence&)
att.EquipValue = IntEquipV
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 = HealthFromA
else if(vit.Name == &Mana&)
ManaFromAttr += GetAttribute((int)AttributeName.Intelligence).AttributeValue * 10;
vit.MaxValue = ManaFromA
else if(vit.Name == &Energy&)
EnergyFromAttr += GetAttribute((int)AttributeName.Dexterity).AttributeValue * 10;
vit.MaxValue = EnergyFromA
//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 + PlayerMoveSpeedB
//Recalc Crit Chance
float wepCritChance = EquipedWeapon != null ? (EquipedWeapon as Weapon).CritChance : 0;
CritChance = BaseCritChance + wepCritC
private void RefreshVitals(){
foreach(Vital v in Vitals){
v.CurValue = v.MaxV
public void Respawn(){
//Load level if needed
GameObject RespawnLocation = GameObject.FindGameObjectWithTag(&Respawn&);
if(RespawnLocation != null) {
gameObject.transform.position = RespawnLocation.transform.
Debug.Log (&No respawn gameObject found to use as respawn location.&);
CharacterControl.useNewPosition =
CharacterControl.newPosition = transform.
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);
public bool UseConsumable(int getVitalInt, int amount){
if(canConsume){
StartCoroutine(UsePot(getVitalInt, amount));
IEnumerator UsePot(int getVitalInt, int amount){
canConsume =
GetVital(getVitalInt).CurValue +=
yield return new WaitForSeconds(1.0f);
canConsume =
//Exit Combat Vars
public int secondsBeforeExitingCombat = 5;
public int secondsWaited = 0;
public void CheckForExitCombat(){
if(!_waitingToExitCombat)
InvokeRepeating(&TryToExitCombat&,1.0f,1.0f);
CancelInvoke(&TryToExitCombat&);
secondsWaited = 0;
InvokeRepeating(&TryToExitCombat&,1.0f,1.0f);
public void TryToExitCombat(){
WaitingToExitCombat =
secondsWaited += 1;
if(secondsWaited & secondsBeforeExitingCombat){
secondsWaited = 0;
CancelInvoke(&TryToExitCombat&);
playerState = PlayerState.N
WaitingToExitCombat =
void GiveStuff(){
AddItem(ItemGenerator.CreateItem(&weapon&,&legendary&,2));
Item fireItem = ItemGenerator.CreateItem(&weapon&,&legendary&,2);
Weapon fireWeapon = fireItem as W
fireWeapon.DmgType = DamageType.F
fireWeapon.DmgValue = 100;
fireWeapon.CritChance = 0.7f;
fireWeapon.CritDamage = 4.0f;
AddItem(fireWeapon);
Item waterItem = ItemGenerator.CreateItem(&weapon&,&legendary&,2);
Weapon waterWeapon = waterItem as W
waterWeapon.DmgType = DamageType.W
waterWeapon.DmgValue = 100;
AddItem(waterWeapon);
Item knockBackItem = ItemGenerator.CreateItem(&weapon&,&legendary&,2);
Weapon knockBackWep = knockBackItem as W
knockBackWep.Proc = ProcType.K
knockBackWep.ProcModifier = 0.8f;
AddItem(knockBackWep);
Item stunItem = ItemGenerator.CreateItem(&weapon&,&legendary&,2);
Weapon stunWep = stunItem as W
stunWep.Proc = ProcType.S
stunWep.ProcModifier = 0.8f;
AddItem(stunWep);
Item slowItem = ItemGenerator.CreateItem(&weapon&,&legendary&,2);
Weapon slowWep = slowItem as W
slowWep.Proc = ProcType.S
slowWep.ProcModifier = 0.8f;
AddItem(slowWep);
Item poisonItem = ItemGenerator.CreateItem(&weapon&,&legendary&,2);
Weapon poisonWep = poisonItem as W
poisonWep.Proc = ProcType.P
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 UnityE
//[System.Serializable]
[System.Serializable]
public class Item {
private string _
private int _
//Gold Value
private RarityTypes _
private bool _canBeS
[System.NonSerialized]
private Texture2D _
private string _iconP
private int _curS
private int _maxS
private int _requiredL
private ItemEquipType _itemT
private bool _canBeD
//Number you can have in one slot, e.g. 1 for equips, 20 for pots
private string _
public Item(){
_name = &Unnamed Item&;
_value = 100;
_itemType = ItemEquipType.C
_requiredLevel = 0;
_canBeSold =
_icon = Resources.Load (&Item Icons/defaultItem&) as Texture2D;
_iconPath = &Item Icons/defaultItem&;
_maxStacks = 1;
_curStacks = 1;
_description = &&;
_canBeDropped =
public Item(string name, int val, RarityTypes rare, ItemEquipType itemType,
int reqLvl, int enchants, bool sellable, int maxStacks,
int curStacks, string description, bool canBeDropped) {
_requiredLevel = reqL
_canBeSold =
_itemType = itemT
_maxStacks = maxS
_curStacks = curS
_description =
_canBeDropped = canBeD
//For Gold only
public Item(string name, int val) {
_icon = Resources.Load(&Item Icons/goldItem&) as Texture2D;
_iconPath = &Item Icons/goldItem&;
public string Name{
get{return _}
set{_name =}
public int Value{
get{return _}
set{_value =}
public bool CanBeSold {
get{return _canBeS}
set{_canBeSold =}
public bool CanBeDropped {
get{return _canBeD}
set{_canBeDropped =}
public RarityTypes Rarity {
get{return _}
set{_rarity =}
public ItemEquipType ItemType {
get{return _itemT}
set{_itemType =}
public int RequiredLevel {
get{return _requiredL}
set{_requiredLevel =}
public Texture2D Icon {
get{return _}
set{_icon =}
public string IconPath {
get{return _iconP}
set{_iconPath =}
public int MaxStacks {
get{return _maxS}
set{_maxStacks =}
public int CurStacks {
get{return _curS}
set{_curStacks =}
public string Description {
get{return _}
set{_description =}
public virtual string UniqueIdentifier(){
return (Name+Value.ToString()+RequiredLevel+Description);
public virtual string ToolTip() {
if(!Name.Contains(&Gold&)){
return &Name& + &\n& +
&Value: & + V
return Value + & Gold!&;
public enum RarityTypes {
Legendary,
CraftedItem,
//not rarity, just used for identifying unique items
QuestItem,
CraftItem,
SocketItem
public enum ItemEquipType {
Consumable,
QuestItem,
CraftItem,
using UnityE
using System.C
using System.Collections.G
public class NPCQuest : MonoBehaviour {
private PlayerN
public int QuestID;
public string QuestN
public string QuestT
public string QuestNPCN
public int QuestExpR
public int QuestGoldR
public List&Item& QuestReward = new List&Item&();
public bool isC
public bool isA
public bool isF
public int RewardN
public string rewardT
public RequirementsStatus requirementS
//Quest Requirements
public int[] QuestIDR
public int QuestLevelR
//Quest Completion Steps
public bool trackS
public string nameOfM
public int numberToK
public int numberK
public bool killD
public string nameOfI
public string nameOfMobThatDropsI
public int numberToO
public int numberO
public bool itemD
public EnableGameO
public bool EnableQuestGOP
public bool talkingCompletesQ
public string nameOfNPCtoTalkTo;
public string[] npcR
public bool talkD
public string questT
// Use this for initialization
void Start () {
if(player == null){
player = GameObject.FindGameObjectWithTag(&Player&).GetComponent&PlayerNew&();
trackSteps =
for (int i = 0; i & RewardN i++) {
Item x = ItemGenerator.CreateItem(rewardType,&legendary&,player.Level);
QuestReward.Add(x);
QuestNPCName = GetComponent&NPCDialog&().NpcN
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.B
if(numberToObtain & 0){
CheckForItems();
questTracker += ToolTipStyle.B
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.B
questTracker += string.Format(&{0} Gained: {1} of {2}&,nameOfItem,numberObtained,numberToObtain);
if(talkingCompletesQuest){
if(questTracker != &&)
questTracker += ToolTipStyle.B
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 = numberToK
private void CheckForMobs(){
if(numberKilled &= numberToKill)
killDone =
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.C i++) {
if(player.Inventory[i].Name == nameOfItem){
numberObtained = player.Inventory[i].CurS
if(player.Inventory[i].CurStacks & numberToObtain){
player.Inventory[i].CurStacks = numberToO
if(numberObtained &= numberToObtain){
itemDone =
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 =
if(numberToKill & 0 && !killDone)
completed =
if(numberToObtain & 0 && !itemDone)
completed =
if(talkingCompletesQuest && !talkDone)
completed =
if(completed){
isComplete =
private int numberOfQuestsNeeded = 0;
private int numberOfQuestsFound = 0;
public void CheckRequirements() {
numberOfQuestsNeeded = QuestIDReq.L
//Check Level
if(player.Level &= QuestLevelReq){
requirementStatus = RequirementsStatus.L
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.A
requirementStatus = RequirementsStatus.Q
numberOfQuestsFound = 0;
public string QuestInfo(){
string questInfo = ToolTipStyle.Blue + QuestName + ToolTipStyle.EndColor
+ ToolTipStyle.Break + QuestNPCN
return questI
public string QuestRewardString(){
string questRewardString = &Exp: & + QuestExpReward.ToString() + & Gold: & + QuestGoldReward.ToString();
return questRewardS
public void CancelQuest(){
talkDone = killDone = itemDone = isComplete = isAccepted =
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)
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)
player.QuestsInProgress.Add(this);
public enum RequirementsStatus {
using UnityE
using System.C
using System.Collections.G
public class MonsterAI : MonoBehaviour {
private PlayerN
public string NameOfMob = &Cube&;
public int LevelOfMob = 1;
MonsterType monsterType = MonsterType.N
public int Damage = 10;
public int expValue = 30;
public float RunSpeed = 2;
public float AttacksPerS
private float OriginalAttacksPerS
public float timeSinceLastA
public int MonsterH
public string NumberOfItemsToDrop = &random&;
public string ItemTypesToDrop = &random&;
public string ItemsDroppedRarity = &random&;
public bool inC
public bool isD
public bool EnableC
public GlobalPrefabs globalP
//From Player Procs
public bool isU //Won't do anything
public bool isS //can't move
public bool isS //Attack Speed is slowed
public float amountSlowedBy; //Attack speed reduction
public bool isKnockedB //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 = AttacksPerS
void Update () {
timeSinceLastAttack += Time.deltaT
float curHealth = GetComponent&Health&().CurrentH
if(curHealth &= 0 ){
MonsterHealth = 0;
if(isDead){
player.AddExp(expValue);
string nameOfMobToSend = monsterType == MonsterType.Normal ? NameOfMob : &BOSS& + NameOfM
Messenger&string&.Broadcast(&MonsterKilled&,nameOfMobToSend);
//Destroy all floating text attached to this
FloatingTextGUI[] floatingTexts = GetComponentsInChildren&FloatingTextGUI&();
for (int i = 0; i & floatingTexts.L i++) {
Destroy(floatingTexts[i].gameObject,0.5f);
//死亡掉落物品
DropLoot();
Destroy(gameObject);
if(inCombat){
EnableCombat =
EnableCombat =
if(isStunned){
EnableCombat =
if(isUseless){
if(EnableCombat){
float angleToTarget = Mathf.Atan2((player.transform.position.x - transform.position.x), (player.transform.position.z - transform.position.z)) * Mathf.Rad2D
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 :
if(canDealDamage){
timeSinceLastAttack = 0;
PlayerHealth php = player.GetComponent&PlayerHealth&();
if(php == null) Debug.Log (&No player health&);
DealDamage(php);
canDealDamage =
public void DropLoot(){
Debug.Log(&9999DropLoot,notsee9999&);
GameObject loot = GameObject.FindGameObjectWithTag(&ItemSpawner&);
Debug.Log(&loot&+loot);
loot.GetComponent&ItemSpawner&().positionToSpawn = transform.
if(ItemsDroppedRarity != null)
loot.GetComponent&ItemSpawner&().chestRarity = ItemsDroppedR
if(ItemTypesToDrop != null)
loot.GetComponent&ItemSpawner&().chestSpawnType = ItemTypesToD
if(NumberOfItemsToDrop != null)
loot.GetComponent&ItemSpawner&().itemsInChest = NumberOfItemsToD
loot.GetComponent&ItemSpawner&().chestItemLevel = LevelOfM
//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 =
int questIndex = 1000;
Debug.Log(&player.QuestsInProgress.Count&+player.QuestsInProgress.Count);
for (int i = 0; i & player.QuestsInProgress.C 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 =
questIndex =
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.C 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];
//Deal Damage
void DealDamage(PlayerHealth hp){
hp.DealDamage((int)Damage);
player.playerState =
player.CheckForExitCombat();
//KnockBack
public void KnockBackSelf(){
StartCoroutine(&KnockBack&);
private IEnumerator KnockBack(){
StopCoroutine(&KnockBack&);
isUseless =
isKnockedBack =
GameObject dmgTxt = (GameObject)Instantiate(globalPrefabs.floatingDamageText);
dmgTxt.transform.parent = this.
FloatingTextGUI dmgText = dmgTxt.GetComponent&FloatingTextGUI&();
dmgText.SetDmgInfo(ToolTipStyle.Purple + &Knockback!& + ToolTipStyle.EndColor,transform.position);
yield return new WaitForSeconds(0.5f);
isKnockedBack =
isUseless =
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.
FloatingTextGUI dmgText = dmgTxt.GetComponent&FloatingTextGUI&();
dmgText.SetDmgInfo(ToolTipStyle.Purple + &Stunned!& + ToolTipStyle.EndColor,transform.position);
isStunned =
yield return new WaitForSeconds(timeToStun);
isStunned =
public void SlowAttackSpeed(float amountToSlow){
AttacksPerSecond = OriginalAttacksPerS
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.
FloatingTextGUI dmgText = dmgTxt.GetComponent&FloatingTextGUI&();
dmgText.SetDmgInfo(ToolTipStyle.Purple + &Attack slowed!& + ToolTipStyle.EndColor,transform.position);
AttacksPerSecond += amountToReduceBy * AttacksPerS
yield return new WaitForSeconds(3.0f);
AttacksPerSecond = OriginalAttacksPerS
public void UseDot(string dotName, int damage,int ticks, float timeBetweenTicks){
for (int i = 0; i & currentDots.C i++) {
if(currentDots[i].Contains(dotName)){
Debug.Log (&Same DOT, will not cast&);
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 & i++) {
this.GetComponent&Health&().CurrentHealth -=
GameObject dmgTxt = Instantiate(globalPrefabs.floatingDamageText) as GameO
dmgTxt.transform.parent = this.
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 {
运行后的效果
EnemyController.cs中添加
monsterDeadAI中的nameOfMobToSend暂时测试直接写入,后面会改为通用。
杀怪任务修改完毕。。。。。。。。。。。。。。。。。。。。
在EnemyController中添加&&& privateMonsterAI M
在void Start () {}中添加 Monsterai=this.GetComponent&MonsterAI&();
void MonsterDeadAI(){}中修改代码为
string nameOfMobToSend=Monsterai.NameOfM
Messenger&string&.Broadcast(&MonsterKilled&,nameOfMobToSend);
注释掉void Update (){}中的
//&&&&&&&& floatcurHealth = GetComponent&Health&().CurrentH
//&&&&&&&&
//&&&&&&&& if(curHealth&= 0 ){
//&&&&&&&&&&&&& MonsterHealth= 0;
//&&&&&&&&&&&&& isDead=
//&&&&&&&& }
修改PlayerBase中LevelUpAnimation方法,确保只有一种升级
看看player.QuestsInProgress[i].nameOfMobThatDropsItem这个东东的值是什么,
一口气贴了这么多东西,其实这是我一周时间写的代码和调试信息,而且用到的类也是一个成熟的任务系统,我只是做了整合,
using UnityE
using System.C
using System.Collections.G
public class NPCDialog : MonoBehaviour {
public string T
public string NpcN
public TextMesh npcNameL
public GameObject npcB
public bool isV
public bool isB
public Light HighlightL
public NPCV
public NPCB
public GUISkin myS
private PlayerN
public bool _isN
public string[] npcT
public string[] npcTextO
public int textN
public string[] buttonText = new string[2];
public int buttonTextN
public List&NPCQuest& quests = new List&NPCQuest&(); //Quests
public int OptionNumber = 0;
public TextMesh hasQuestT
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 = npcT
textNum = 0;
if(HighlightLight != null)
HighlightLight.enabled =
if(npcNameLevel != null)
npcNameLevel.text = NpcN
vendor = GetComponent&NPCVendor&();
if(vendor != null) isVendor = else isVendor =
blacksmith = GetComponent&NPCBlacksmith&();
if(blacksmith != null) isBlacksmith = else isBlacksmith =
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.C i++) {
if(quests[i].isAccepted)
hasQuestText.text = ToolTipStyle.Grey + ToolTipStyle.Bold +
&!& + ToolTipStyle.EndBold + ToolTipStyle.EndC
//If has quests but none accepted or completed, show yellow !
for (int i = 0; i & quests.C i++) {
if(!quests[i].isAccepted)
hasQuestText.text = ToolTipStyle.Yellow + ToolTipStyle.Bold +
&!& + ToolTipStyle.EndBold + ToolTipStyle.EndC
//If has quests and one or more complete, show yellow ?
for (int i = 0; i & quests.C i++) {
if(quests[i].isComplete)
hasQuestText.text = ToolTipStyle.Yellow + ToolTipStyle.Bold +
&?& + ToolTipStyle.EndBold + ToolTipStyle.EndC
else if(isVendor){
hasQuestText.text = &$&;
hasQuestText.text = &&;
if(viewDist & distToBeActive){
npcNameLevel.text = NpcN
npcBorder.SetActive(true);
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.C i+=0) {
bool addedItem = player.AddItem(quest.QuestReward[i]);
if(addedItem){
quest.QuestReward.RemoveAt(i);
Debug.Log (&Stack is full&);
if(quest.QuestReward.Count == 0){
player.AddExp(quest.QuestExpReward);
player.ModifyGold(quest.QuestGoldReward);
quest.isFinished =
player.questsComplete.Add(quest);
if(quest.qego != null && !quest.EnableQuestGOPerm)
quest.qego.DisableGameObjects();
if(quest.numberToObtain & 0){
for (int i = 0; i & player.Inventory.C i++) {
if(player.Inventory[i].Name == quest.nameOfItem){
player.Inventory[i].CurStacks -= quest.numberToO
if(player.Inventory[i].CurStacks &= 0)
player.Inventory.RemoveAt(i);
player.QuestsInProgress.Remove(quest);
EnterDialog();
Debug.Log(&Inventory is Full!&);
void CheckQuests(){
npcText = npcTextO
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 =
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.npcR
OptionNumber = 1; //Force Conversation
public void EnterDialog(){
if(player.playerState != PlayerState.Normal)
player.playerState = PlayerState.NPCD
OptionNumber = 0;
textNum = 0;
CheckQuests();
NPCDialogGUI.openedNPCDialog =
Messenger.Broadcast (&DisplayNPCWindow&);
public void CloseDialog(){
player.playerState = PlayerState.N
Messenger.Broadcast (&CloseNPCWindow&);
void OnTriggerEnter(Collider other){
pareTag(&Player&) && other.GetType() != typeof(SphereCollider) && !_isNear){
EnterDialog();
CheckQuests();
void OnTriggerExit(Collider other){
pareTag(&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 =
void OnMouseExit () {
if(HighlightLight != null)
HighlightLight.enabled =
public enum NpcType {
}虽然贴出了代码,但说实话,就这么看,估计没人看得懂,而且任务系统还包括一段存储的部分,所以我建议这一篇大家先跳过吧,过段时间我整理一下代码,把整个工程文件发出来,否则这篇真的没法看了。建议大家跳过直接看下一篇。
注意要看上面提供了需要的代码包和任务Npc预制件。&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:43754次
积分:1063
积分:1063
排名:千里之外
原创:63篇
评论:15条
(1)(4)(11)(4)(16)(12)(18)(1)}

我要回帖

更多关于 饥荒联机版mod 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信