Home / Articles

【Unity】使用 Modiferty 管理遊戲的狀態【Modiferty】的文章圖片

【Unity】使用 Modiferty 管理遊戲的狀態【Modiferty】

發布日: 2020/05/21 更新日: 2020/05/27

前言

我在製作遊戲時做出了一個相當不錯的函式庫,所以便把 「Modiferty」 這個函式庫公開到了 GitHub!

這個函式庫可以廣泛導入到角色或武器具有「狀態值」概念的遊戲中。

GitHub: https://github.com/mackysoft/Modiferty

Modiferty 是什麼?

「Modiferty」很擅長管理遊戲中角色與武器狀態值的變化。

  • 可以知道究竟發生了哪一種變更,例如數值是變成 2 倍、增加了 1,等等。
  • 可以管理跨越多次的狀態值變更。

光這樣說大概還是會讓人覺得「?」吧,所以我先用具體例子來介紹。

實作能力值提升

當你想在遊戲裡實作「角色暫時提升能力值」時,會怎麼做呢?(像是寶可夢的「劍舞」,或《勇者鬥惡龍》的「倍攻」之類的)

我能想到的方法主要有兩種。

  1. 直接覆寫狀態值
  2. 準備像是「攻擊力倍率」這樣的變數,並在攻擊時套用倍率

1.直接覆寫狀態值


using UnityEngine;

public class Character : MonoBehaviour {

	public int health = 3;
	public int attackPower = 2;

	// 攻擊處理
	public void Attack (Character target) {
		// 造成等同於目前攻擊力的傷害
		target.health -= attackPower;
	}

	// 提升攻擊力
	public void PowerUp (int additionalAttackPower) {
		attackPower += additionalAttackPower;
	}
}

這個方法很單純,但缺點很多。

  • 因為無法得知究竟發生了哪一種狀態變化,所以不能做出像是「從初始值增加了 1」這類演出。
  • 一旦出現「加法和乘法混合的變更」或「複雜的變更」,就很難管理。

2.準備「攻擊力倍率」變數,並在攻擊時套用倍率


using UnityEngine;
using System.Collections.Generic;

public class Character : MonoBehaviour {

	public int health = 3;
	public int attackPower = 2;

	// 倍率清單
	public List<float> attackPowerMultiply = new List<float>();

	// 攻擊處理
	public void Attack (Character target) {
		int multipliedAttackPower = attackPower;

		// 將倍率套用到攻擊力上
		foreach (float multiply in attackPowerMultiply) {
			multipliedAttackPower *= multiply;
		}

		// 依照套用倍率後的攻擊力造成傷害
		target.health -= multipliedAttackPower;
	}
}

如果用這個方法,就能掌握「會發生哪一種狀態變化」,因此可以基於這點做出相應的演出。

但是這種方法只能處理乘法,所以擴充性很差。

Modiferty 就是能解決上述問題的函式庫。

  • 可以知道究竟發生了哪一種變更,例如數值是變成 2 倍、增加了 1,等等。
  • 可以管理跨越多次的狀態值變更。

具體實作範例

這裡我會介紹一個攻擊力會變動的角色實作範例。

1.用 ModifiableProperty 宣告 attackPower

首先,把像角色攻擊力這種「想讓它可變動的數值」,從 int 或 float 改用 ModifiableProperty 來宣告。


using UnityEngine;
using MackySoft.Modiferty;

public class Character : MonoBehaviour {

	// baseValue 是數值變動的基礎值
	public ModifiableInt attackPower = new ModifiableInt(baseValue: 2);

}

這次我們用 ModifiableInt 來取代 int。(如果是 float,就改用 ModifiableFloat)

如此一來,就能管理角色攻擊力的變化了。

2.加入 Modifier

接著,試著做一個「會增加碰撞到之角色攻擊力的道具」。


using UnityEngine;
using MackySoft.Modiferty;

public class PowerUpItem : MonoBehaviour {

	// 加算量
	public AdditiveModifierInt additiveAttackPower = new AdditiveModifierInt(amount: 1);

	void OnCollisionEnter (Collision collision) {
		Character target = collision.collider.GetComponentInParent<Character>();
		if (target != null) {
			// 在 attackPower.Modifiers 中加入一個讓數值 +1 的 Modifier
			target.attackPower.Modifiers.Add(additiveAttackPower);
		}
	}
}

你大概會在這裡想:「AdditiveModifierInt 到底是什麼?」

簡單來說,AdditiveModifierInt 是 Modiferty 中很重要的概念 「Modifier」 之一。

在這個例子裡,可以看到身為 Modifier 的 additiveAttackPower 被加入到了碰撞角色的 attackPower.Modifiers 中。(也可以刪除)

這個 Modifier 扮演的角色,就和前面介紹的「倍率」很相似。

這個例子使用的是 AdditiveModifier(加法),不過除了四則運算的 Modifier 以外,也實作了可以做特殊變更的 Modifier。(Modiferty - Modifier Types)

換句話說,Modiferty 可以說是 「能對數值執行複雜且複合的處理,並對其加以管理的函式庫」

3.把 Modifier 套用到 attackPower

接著,來寫「角色進行攻擊」的處理。


using UnityEngine;
using MackySoft.Modiferty;

public class Character : MonoBehaviour {

	public int health = 3;

	// baseValue 是數值變動的基礎值
	public ModifiableInt attackPower = new ModifiableInt(baseValue: 2);

	public void Attack (Character target) {
		target.health -= attackPower.Evaluate();
	}

}

這裡最重要的是 attackPower.Evaluate()

Evaluate 函式是實作在 ModifiableInt(以及 ModifiableProperty)上的函式,它所做的是 「把加入到自身的所有 Modifier 套用到基礎值(baseValue)上」

如果你把它想成前面介紹過的「套用倍率清單的處理」,應該就會比較好理解。

所以,假設現在是以下狀態:

  • attackPower 的基礎值是 2
  • attackPower 上加入了「加算量為 1 的 AdditiveModifier」

此時執行 attackPower.Evaluate(),

因為 「2(baseValue)+ 1(AdditiveModifier)」,所以回傳值就會是「3」。

這樣一來,使用 Modiferty 的實作就完成了。

結語

這個函式庫採用 MIT 授權,因此可以非常自由地使用。

我實際上也在自己的遊戲中使用它,而且基本上只要:

  • 用 ModifiableProperty 宣告數值
  • 變更數值時使用 Modifier

就能很輕鬆地導入,所以如果你覺得「好像派得上用場」,不妨試試看。

GitHub: https://github.com/mackysoft/Modiferty

分享

Twitter