[unity learning] RPG Leaning(七)
写这个文章的目的就是为了初学unity,然后更好的掌握unity中的内容【主要是代码】
学习unity的途径是Brackeys 的教程;
接上篇: unity learning RPG Leaning(六).
目的
伤害系统的搭建
过程
一、为属性「damage、armor等」搭建一个Stat类
二、为整体生物「player、enemy等」搭建一个CharacterStats类
三、给Player添加PlayerStats类,应用Equipment的damage等属性
具体步骤
一、搭建一个Stat类
using UnityEngine;
[System.Serializable]
public class Stat
{
[SerializeField]
private int baseValue;
public int GetValue(){
return baseValue;
}
}
这里需要注意的就是System.Serializable和SerializeField
原文链接:SerializeField和Serializable
1、[SerializeField] Attribute
强制unity去序列化一个私有域
这是一个内部的unity序列化功能,有时候我们需要Serialize一个private或者protected的属性,这个时候可以使用[SerializeField]这个Attribute:
[SerializeField]
protected int foobar = 0;
注意: 这样定义出的成员变量也是会在Inspector中显示出来。
2、Serializable是.Net自带的序列化
有时候我们会自定义一些单独的class/struct, 由于这些类并没有从 MonoBehavior 派生所以默认并不被Unity3D识别为可以Serialize的结构。自然也就不会在Inspector中显示。我们可以通过添加 [System.Serializable]这个Attribute使Unity3D检测并注册这些类为可Serialize的类型。
二、为整体生物「player、enemy等」搭建一个CharacterStats类
能想到的是,这个生物具有的功能:1、生命系统 ;2、死亡系统(需要被复用);3、被攻击时候的系统; 攻击系统(以后在写,,,先写前三个);
这里需要注意的是
public int currentHealth { get; private set; }
这句是C#的缩写 代表了currentHealth是一个可以被读取,不能被写入的公共变量;
三、给Player添加PlayerStats类,应用Equipment的damage等属性
这里为了应用Equipmen的属性,所以,在这里建立了一个PlayerStats类。
这里主要是在Player的Equipment改变的时候,触发EquipmentManager的delegate委托:onEquipmentChanged;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerStats : CharacterStats
{
void Start()
{
EquipmentManager.instance.onEquipmentChanged += OnEquipmentChanged;
}
void OnEquipmentChanged(Equipment newItem, Equipment oldItem)
{
if (newItem != null)
{
armor.AddModifier(newItem.armorModifier);
damage.AddModifier(newItem.damageModifier);
}
if (oldItem != null)
{
armor.RemoveModifier(oldItem.armorModifier);
damage.RemoveModifier(oldItem.damageModifier);
}
}
}
然后需要在Stat类里面加入一个列表来记录自己属性的变化
private List<int> modifiers = new List<int>();
public void AddModifier(int modifier)
{
if (modifier != 0)
{
modifiers.Add(modifier);
}
}
public void RemoveModifier(int modifier)
{
if (modifier != 0)
{
modifiers.Remove(modifier);
}
}
然后在修改GetValue()函数;
代码
Stat
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Stat
{
[SerializeField]
private int baseValue;
private List<int> modifiers = new List<int>();
public int GetValue()
{
int returnValue = baseValue;
foreach (var modifier in modifiers)
{
returnValue += modifier;
}
return returnValue;
}
public void AddModifier(int modifier)
{
if (modifier != 0)
{
modifiers.Add(modifier);
}
}
public void RemoveModifier(int modifier)
{
if (modifier != 0)
{
modifiers.Remove(modifier);
}
}
}
CharacterStats
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterStats : MonoBehaviour
{
public int maxHealth = 100;
public int currentHealth { get; private set; }
public Stat damage;
public Stat armor;
void Awake()
{
currentHealth = maxHealth;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.T))
{
TakeDamage(10);
}
}
public void TakeDamage(int damage)
{
damage -= armor.GetValue();
damage = Mathf.Clamp(damage, 0, int.MaxValue);
currentHealth -= damage;
Debug.Log(transform.name + " takes " + damage + " damafge.");
if (currentHealth <= 0)
{
Die();
}
}
public virtual void Die()
{
//
Debug.Log(transform.name + " Died!");
}
}
PlayerStats
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerStats : CharacterStats
{
void Start()
{
EquipmentManager.instance.onEquipmentChanged += OnEquipmentChanged;
}
void OnEquipmentChanged(Equipment newItem, Equipment oldItem)
{
if (newItem != null)
{
armor.AddModifier(newItem.armorModifier);
damage.AddModifier(newItem.damageModifier);
}
if (oldItem != null)
{
armor.RemoveModifier(oldItem.armorModifier);
damage.RemoveModifier(oldItem.damageModifier);
}
}
}
总结
waw,真的是感受到了面向对象程序的魅力,很多代码的复写和类的调用太棒了!!