日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#程序员整理的Unity 3D笔记(十三):Unity 3D基于组件的思想

發布時間:2023/12/14 C# 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#程序员整理的Unity 3D笔记(十三):Unity 3D基于组件的思想 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如果你接觸過《設計模式》、軟件架構的編程思想,就會知道優秀的設計準則:“組合優于繼承的”。

????? 這句話很簡短,但開始學習OOP的時候,真切的是—-不太好理解(以我個人當初學習為例)。

?

OOP的繼承思想

在設計主角(Player)的時候,為了能夠復用A、B、C的功能,我開始把A、B、C按照繼承來寫,多了一些Virutal\Override\Protected等修飾符,功能沒有任何問題,就是有些別扭。如Start、Update方法,只能在A中采用模板方法處理,萬一B、C、Player中直接用了Start、Update方法,會導致奇奇怪怪的問題;同時在繼承的基類中,無形之間多了一些包袱,對于Player不得不使用A、B、C的函數、變量(非private的)。

整個關系變為了:

  • Player is a A
  • Player is a B
  • Player is a C

心理上疙疙瘩瘩的,總覺得有點別扭。

?

OOP的組合思想

以前使用組合思想較多的是構建樹、樹葉模型,例如電信中的網元模型。這種思想,屬于Unity 3D的核心思想–組件。在Player、A、B、C中可自由使用Start、Update函數(請不考慮執行順序,腳本組件的先后順序外部可調整,但是意義不大),最重要的是,關系理順了—主角變成更積極、主動。

  • Player have a A
  • Player have a B
  • Player have a C
  • 在Unity 3D中,可復用的幾乎全部為封裝為了組件,eg: transform、rigibody、render、camera、***.cs腳本;為了配合方便的使用非內置的組件,可使用gameObject.AddComponent<T>()、gameObject.GetComponent<T>()來添加、獲得組件(一般是自定義的腳本)。

?

這里我舉一個實際的例子,在《Unity 3D手機游戲開發》第二版的“太空射擊游戲”中,有一個需求,需要給游戲中可復用的GameObject添加自動銷毀的功能(通過時間計時器,或者觸發器添加),代碼很簡單,不到100行,要添加的GameObject有5、6個,雖然工作量不大,但總不能每個都拷貝一遍代碼吧。

開始我是按照OOP繼承做的,

?

看了幾天,很不爽,后來重構為如下圖:

這樣使得自動銷毀組件的功能發揮的更加靈活、機動,即不必拘泥于靜態的繼承思想來實現。

從這個重構過程中,我學到Unity 3D組件思想的閃閃發光……

附錄:完整的自動銷毀組件代碼:

public class AutoDestoryComponent : MonoBehaviour?
{?
??? #region ICanCache?
??? public ParticleSystem[] m_pss = null;?
??? public int m_life = 1; //3條命?
??? public float m_AutoDeadTime = 3;//3s自動銷毀

??? private int m_life_Base = 3; //3條命【恢復用】?
??? private float m_AutoDeadTime_Base = 3;//3s自動銷毀【恢復用】【-1:表示不自動銷毀,如Enemy】

??? void Update()?
??? {?
??????? //需要自動銷毀?
??????? if (m_AutoDeadTime_Base >= 0)?
??????? {?
??????????? m_AutoDeadTime -= Time.deltaTime;

??????????? if (m_AutoDeadTime <= 0)?
??????????? {?
??????????????? InnerDead();?
??????????????? return;?
??????????? }?
??????? }

??????? if (m_life <= 0)?
??????? {?
??????????? InnerDead();?
??????? }?
??? }

??? /// <summary>?
??? /// 設置自動銷毀數據?
??? /// </summary>?
??? /// <param name="life_base">默認生命值</param>?
??? /// <param name="autoDeadTime_base">-1不自動銷毀;其他數據代表銷毀時間(單位s)</param>?
??? public void SetBasePara(int life_base = 1, float autoDeadTime_base = -1)?
??? {?
??????? m_AutoDeadTime = m_AutoDeadTime_Base = autoDeadTime_base;?
??????? m_life = m_life_Base = life_base;?
??? }

??? //是否啟用?
??? public bool IsUse { get; set; }?
??? //死后位置?
??? public Vector3 DeathPosition?
??? {?
??????? get?
??????? {?
??????????? return new Vector3(2000, 2000, 2000);?
??????? }?
??? }

??? //復活?
??? public void Init(Vector3 position, Quaternion rotation)?
??? {?
??????? transform.gameObject.SetActive(true);?
??????? transform.position = position;?
??????? transform.rotation = rotation;?
??????? IsUse = true;?
??????? foreach (ParticleSystem item in m_pss)?
??????? {?
??????????? item.Play(true);?
??????? }

??????? //有些繞?
??????? m_life = m_life_Base;?
??????? m_AutoDeadTime = m_AutoDeadTime_Base;?
??? }

??? private void InnerDead()?
??? {?
??????? IsUse = false;?
??????? transform.position = DeathPosition;?
??????? foreach (ParticleSystem item in m_pss)?
??????? {?
??????????? item.Stop(true);?
??????? }

??????? this.gameObject.SetActive(false);?
??? }?
??? #endregion?
}

?

?

包括系統自帶的Audio、Transform、Camera、Image、Button等等。GameObject是一個容器,沒有Image的GameObject,只要新建一個空的GameObject,添加Image Component極為Image GameObject對象的。

也即是在Unity3D中,很少用GameObject.ID的概念,而是用GameObject.Tag、GameObject.name來區分不同的GameObject,且Tag、name不唯一。

?

結論:在Unity3D中,萬事萬物都是Component。

轉載于:https://www.cnblogs.com/xifarm/p/csharp_learnunity3d_component.html

總結

以上是生活随笔為你收集整理的C#程序员整理的Unity 3D笔记(十三):Unity 3D基于组件的思想的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。