創作內容

32 GP

【筆記】C# 使用 Interface 實作血量系統

作者:樂小呈│2020-10-06 17:44:46│巴幣:562│人氣:1228
Interface 筆記
透過介面來製作血量系統
分享一下主專案的程式心得

結論
不要使用 interface 實作血量系統,interface 適合用在要求不多但各自實作差異比較大的東西上
血量系統這種有大量差異不大重複功能的系統,用 abstract 會更適合

建立介面
命名使用I做前
public interface IHealthSystem
{
    
}

變量和函式只能是抽象的
int MaxmumHealth {get; }
int CurrentHealth {get; set;}
Action OnHealthChangeEvent {get; set;}

void SetHealth(int health);
void SendDamage(int damage, DamageType type, GameObject sender);
註: 函式結尾記得要分號

實作介面
一個class可以繼承並實作多個介面
public class PlayerStatus : MonoBehaviour, IHealthSystem, IHealthStatus, IOutherInterface
{
    int currentHealth;
    public int CurrentHealth
    {
        get => currentHealth;
        set
        {
            currentHealth = Mathf.Clamp(value, 0, MaxumnHealth);
            OnHealthChangeEvent?.Invoke();
        }
    }

    public int MaxumnHealth { get; private set; }
    public Action OnHealthChangeEvent { get; set; }

    public void SetHealth(int health)
    {
        CurrentHealth = health;
    }
    public void SendDamage(int damage, DamageType type, GameObject sender)
    {
        CurrentHealth -= damage;
    }

實作其他介面...略
}


取得介面並傳遞參數
在Unity一樣使用GetComponent就行,但取得的是介面而不是實作者
IHealthSystem targetHealth = target.GetComponent<IHealthSystem>();
targetHealth.SetHealth(100);
targetHealth.SendDamage(50, DamageType.None, gameObject);

使用上的好處
讓分工更清楚,實作時沒有限制,傳遞資料時也不必知道實作者是誰

而且可以根據不同需求實作內容
例如專案中的玩家會根據裝備有傷害減免
public void SendDamage(int damage, DamageType type, GameObject sender)
{
    int takeDamage = TakeDamageOfType(damage, type);
    CurrentHealth -= takeDamage;
}

有些敵人會有反傷
public void SendDamage(int damage, DamageType type, GameObject sender)
{
    CurrentHealth -= damage;
    sender.GetComponent<IHealthSystem>().SendDamage(damage, type, gameObject);
}

不需要的功能就不必繼承
專案中還有一些特殊狀態,像是電磁和護盾
但是把狀態傳遞也寫進 IHealthSystem就會讓分工有點混雜了,所以我另外建立了一個介面 IHealthStatus,用來傳遞狀態資料
本身只需要血量系統的就只繼承 IHealthSystem,需要進一步使用狀態的再繼承 IHealthStatus

就醬
使用難度不高,有物件導向繼承觀念應該就能懂,而且很有用


新版的申請書修得差不多了,接下來要想一下怎麼手寫自傳
下一篇筆記應該是距離場的,如果有寫

引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4939998
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:筆記|程式|C#

留言共 6 篇留言

玉子燒-瘋狂發春模式
我應該要再幾年才能看懂你在寫什麼

10-06 18:05

樂小呈
我也是學了幾年才知道這東西10-06 18:26
樂小呈
加U[e19]10-06 18:26
潘柏爾
而且在測試的時候也超好用
當初發現interface有多好用後就回不去了

10-06 19:06

樂小呈
是怎麼個測試法啊?10-06 19:09
蒼天落葉
之前也做過血量,算蠻簡單的

10-06 19:21

樂小呈
血量不難,作法千千百百種,這只是其中之一[e12]10-06 19:28
筒紙廁
以前的傷害系統是用SendMessage來做這種抽象的溝通... 究極累又效能超差XD

10-06 22:47

樂小呈
一開始不懂都是用這個來傳 XD10-07 07:02
潘柏爾

就比如說

只需要針對Interface來做一個測試工具/腳本之類的
萬一今天要測試怪物有沒有正常損血,血條UI有沒有正常運作,我只需要抓interface
改天如果換測試人類血量腳本或是物件血量腳本
可能只需要換個遊戲物件就能馬上測試

省一大堆時間

10-06 23:45

樂小呈
原來如此,學到了10-07 07:01
樂小呈
感謝分享[e12]10-07 07:01
燐火幽冥
本人菜機一隻,有個地方不太懂,IHealthSystem裡,函數SendDamage中的DamageType type是哪裡來的?

06-11 16:07

樂小呈
噢那個是enum,不是重點就沒寫進來了,只是一個概念而已06-11 16:20
樂小呈
然後我以為我加備註了,不要用 interface 做血量會比較好[e21]06-11 16:20
樂小呈
interface 適合用在要求不多但各自實作差異比較大的東西上[e8]06-11 16:20
我要留言提醒:您尚未登入,請先登入再留言

32喜歡★angus945 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:【紀錄】Shader -... 後一篇:【紀錄】Shader -...

追蹤私訊切換新版閱覽

作品資料夾

god44675566喜歡動畫的你
有許多動畫心得與點評出爐囉~ 可以上我的YT去看看,不知道會不會有你喜歡的呢?看更多我要大聲說昨天22:38


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】