1. 程式人生 > >《大象無形:虛幻引擎程式設計淺析》讀書總結

《大象無形:虛幻引擎程式設計淺析》讀書總結

        建德若偷,質真若渝。大方無隅,大器晚成。
        大音希聲,大象無形。夫唯道善貸且成。

——老子,《道德經》

----------------------------------------------------------------------------------------------------------------------------------

註解

      “無聲”、“無形”本來是虛空的東西,談不上“大音”、“大象”。所謂“大音希聲,大象無形”,應是大音若無聲,大象若無形。至美的樂音,至美的形象已經到了和自然融為一體的境界,反倒給人以無音、無形的感覺。“大音”、“大象”至少有一個負載它們的實體,才能顯示其“大”。

    “大音希聲,大象無形”出自《老子》(又名《道德經》),是老子對“道”的闡釋,應解釋為“最美的聲音就是聽起來無聲響,最美的形象就是看不見行跡”。大音若無聲,大象若無形,至美的樂音、至美的形象已經到了和自然融為一體的境界,反倒給人以無音、無形的感覺。

        在現代,“大音希聲,大象無形”則更代表一種將美融入生活的智慧;情感熱烈深沉而不矯飾喧囂,智慧雋永明快而不邀寵於形。擁有這種智慧的人不用刻意地去想什麼、做什麼,便自然無形地把情感使用到最值得、最有意義的地方去,從而使自己更好地享受生活!

-----------------------------------------------------------------------------------------------------------------------------摘自百度知道

學習虛幻引擎引擎,抓住最核心的五個類:UObject、Actor、Pawn、Controller、Character

一、UObject類提供以下功能:

1、垃圾回收

    c++記憶體由程式設計師完成,不需要物件a的時候,該不該釋放該記憶體?如果釋放,萬一其他物件引用了,釋放後就產生野指標,當另一個物件訪問時,會看到空空如也,如果釋放,如果我已經是最後一個使用的人,這片記憶體就永遠無法被回收。

    對此虛幻這樣解決:

    (1)繼承UObject類,同時指向UObject類例項物件的指標成員變數,使用UPROPERTY巨集標記,虛幻引擎的UObject架構會自動被UProperty標記的變數考慮到垃圾回收系統中,自動進行物件生命週期管理。

     (2)採用智慧指標:只有非UObject型別才能使用智慧指標進行記憶體釋放。

2、反射

   反射的主要作用在於:執行時如何獲取一個類,如何獲取成員變數、成員函式。

c++沒有提供這樣一套機制,虛幻實現了這樣一套機制。

3、序列化

    希望把一個類的物件儲存到磁碟,下次無損載入,需要繼承UObject類。

4、和引擎編輯器的互動

    如果希望類的變數能被虛幻引擎編輯器Editor簡單編輯,需要繼承這個類。

5、執行時型別識別

    虛幻引擎中無法使用c++標準的dynamic_cast可以繼承UObject類,然後Cast<>函式完成

6、網路複製

    網路遊戲中伺服器、客戶端能夠自動處理變數的同步,被巨集標記的變數能自動完成網路複製功能,從伺服器端複製變數到客戶端。

二、Actor類

    它能夠被掛載元件,在Actor中,座標和旋轉量只是一個Scene Component元件,想讓Actor被渲染,掛載一個靜態網格元件,想讓Actor有骨骼動畫,掛載一個骨架網格物體元件,希望Actor能移動,掛在一個Movement元件,也即需要掛載元件的時候,才應該繼承Actor類。

三、Pawn類

    提供了被操控的特效能被一個Controller操縱,這個Controller可以是玩家Player Controller類,也可以是AI Controller類,Pawn類一旦脫離Controller就是無法行動的肉體。

四、Character

    Character類繼承Pawn類,它提供了一個特殊的元件,CharacterMovement,該元件提供了角色移動、跳躍等功能,如果不需要移動邏輯,可以不繼承Character類只繼承Pawn類。

五、Controller

    既然它是靈魂,通過Possess/UnPossess來控制/解除安裝一個肉體(Pawn)

六、建立C++類

工程目錄下的Source資料夾下,找到和你遊戲名稱一致的資料夾,會發現Public資料夾、Private資料夾、.build.cs檔案

我們將.h檔案放在public資料夾中,.cpp檔案放到private資料夾中

在.h中宣告你的類,如果類繼承UObject,類名上方加入UCLASS()巨集,同時在類的第一行加GENERATED_UCLASS_BODY()巨集,或者GENERATED_BODY()巨集,前者需要手動實現一個帶有const FObjectInitializer&引數的建構函式,後者手動實現一個無參建構函式,

七、虛幻引擎類命名規則

F:純c++類

U:繼承UObject但不繼承Actor

A:繼承Actor

S:Slate控制元件相關類

H:HitResult相關類

八、類物件的產生

如果類是一個純c++(F開頭),通過new產生物件

如果繼承UObject但不繼承Actor,需要通過NewObject函式產生出物件,NewObject<T>()會返回一個指向該類的物件,通過UWorld(可以通過GetWorld()獲得)的SpawnActor產生出物件。這樣呼叫:GetWorld()->SpawnActor<AYourActorClass>()

如果繼承AActor,通過SpawnActor函式產生出物件

九、類物件的銷燬

1、如果純c++類在函式體中建立,而且不是通過new來分配記憶體,如下:

FYourClass YourObject=FYourClass();   //通過函式拿到類

那麼類物件在函式呼叫結束後隨函式的釋放而釋放,不需手動

2、如果純c++類使用new來分配記憶體,而且直接傳遞類的指標,除非手動刪除,否則記憶體永遠不會釋放。如果忘記了,造成記憶體洩露。

3、如果純c++類使用new來分配記憶體,而且使用智慧指標TSharedPtr/TShared-Ref來管理,不應該再手動釋放,智慧指標會使用引用計數來自動釋放記憶體,使用MakeShareable函式將普通指標轉化為智慧指標。

十、UObject類

   藉助NewObject<T>函式產生,無法通過標準New操作符產生 

    無法使用智慧指標管理物件,它採取自動垃圾回收機制,當類成員變數包含UObject物件,帶有UPROPERTY巨集,這個成員變數會觸發引用計數機制。

    垃圾回收期會定時從根節點Root開始檢查,當一個UObject沒有被別的任何UObject引用就會被垃圾回收。可以通過AddToRoot函式讓一個UObject一直不被回收。

十一、Actor類

通過Destroy函式銷燬

十二、UPROPERTY巨集

將一個UObject類的子類成員變數註冊到藍圖中,需要該巨集,比如註冊一個變數到藍圖中:

UPROPERTY(BlueprintReadWrite,VisibleAnywhere,Category="Object")

十三、UFUNCTION巨集

註冊函式到藍圖中

UFUNCTION(BlueprintCallable,Category="Test")

BlueprintCallable表示函式可以被藍圖呼叫,可選的還有BlueprintImplementEvent表示這個成員函式由藍圖子類實現,不該在C++中給出函式的實現,BlueprintNativeEvent表示成員函式提供一個C++的預設實現,同時可以被藍圖過載,需要提供一個"函式名_Implementation"為名字的函式實現,放在.cpp中。

十四、行為樹

虛幻4中狀態機被行為樹代替,狀態機在動畫藍圖中保留,因為行為樹更簡化,更接近人的思維。

十五、同步

客戶端是對服務端的拙劣模仿:客戶端自己也執行著一個世界,不斷預測服務端的行為,從而不斷更新當前世界,最大程度接近服務端的世界,在延遲情況下,客戶端不在試圖同步伺服器,而是模仿伺服器,客戶端根據同步資料傳送時的當前物件位置和速度,猜測出當前物件在服務端的可能位置,並且通過修正當前世界,去模仿服務端的位置,如果服務端客戶端差距太大,強行閃現修正。

十六、預編譯

c++中只編譯.cpp檔案,編譯成*.cpp檔案(\debug目錄下)c++中巨集展開:程式碼中出現的巨集用巨集實體代替

#define 定義常量、函式巨集

#undef 結束常量、函式巨集定義

c++的前處理器是在編譯器之前執行,將巨集定義、標頭檔案載入到.cpp也即#include檔案,將該檔案的程式碼全部拷貝替換了#include語句,理解為將標頭檔案的內容貼上到#include處

c++中標頭檔案是不被編譯的。cpp引用標頭檔案是當預編譯時將標頭檔案插入到cpp中,因此變數的定義、函式定義不寫在標頭檔案中,因為標頭檔案可能被多個cpp引用,連線的時候可能出現重複定義的情況

為了防止標頭檔案被重複引用,應當使用#if ndef #define ... #endif結構

十七、預編譯頭

一個工程中總有一大堆標頭檔案,幾乎所有cpp都必須包含,可不可以把這些標頭檔案提取出來,只編譯一遍然後其他cpp都能使用呢?這就是預編譯頭的由來。

在Debug或Release目錄中有一個很大的.pch檔案,這就是編譯之後的預編譯頭

十八、模組機制

1、快速完成模組建立檔案結構:

在c++工程的Source資料夾下,建立一個新的模組資料夾,結構如下:

1、模組名.Build.cs

2、模組名.h

3、模組名.cpp

模組名.Build.cs,該檔案來告知UBT如何配置編譯和構建環境,如下可見,這裡添加了Core,CoreUobject,Engine,InputCore這四個模組,.Build.cs模組告知UBT如何配置編譯和構建環境

using UnrealBuildTool;
public class pluginDev : ModuleRules
{
    public pluginDev(TargetInfo Target)
    {
        publicDependencyModuleNames.AddRange(new string[]{"Core","CoreUObject","Engine","InputCore"});
        PrivateDependencyModuleNames.AddRange(new string[]{});
    }
}

模組名.h

#pragma once
#include "Engine.h"

模組名.cpp

#include "pluginDev.h"   //由於.h檔案為預編譯標頭檔案,預編譯標頭檔案可以加速程式碼的編譯,只要是.cpp檔案都要包含預編譯標頭檔案
IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultGameModuleImpl, pluginDev, "pluginDev")

2、模組解除安裝、載入函式

在.h和.cpp中覆寫StartupModule和ShutdownModule函式,來書寫模組啟動和解除安裝時需要執行的內容。

3、預編譯標頭檔案

預編譯標頭檔案能加速程式碼的編譯,標頭檔案的標準命名方式為:“模組名PrivatePCH.h”放置於Private資料夾中,當前模組所有.cpp檔案都要包含預編譯標頭檔案

4、引入模組

引入當前模組的方式是在目錄下的Source資料夾中,找到工程名.Target.cs

public override void SetupBinaries(TargetInfo Target,ref List<UEBuildBinaryConfiguration>OutBuildBinaryConfigurations,ref List<string> OutExtraModuleNames)
{
    OutExtraModuleNames.AddRange(new string[]{"pluginDev"});   //在這裡新增引入的模組名稱
}

5、虛幻引擎模組載入順序

十九、記憶體分配

虛幻引擎是通過巨集來控制,在幾個記憶體分配器中選擇的

二十、垃圾回收

1、引用計數法:

優點:不需要程式暫停,垃圾回收的過程分配到執行中。

缺點:

(1)如果成千上萬個物件生成,那麼頻繁修改數值開銷很大

(2)環形引用:有相互引用的物件會出錯

2、標記-清掃演算法(追蹤式GC)

和引用計數法只關注單個物件的思路相反,遍歷每一個物件,看有沒有被引用,沒有就回收

優點:沒有環形引用問題

缺點:

(1)執行該演算法需要程式暫停,這會導致系統有明顯延遲

(2)只是丟掉垃圾而不整理,導致可用空間越來越細碎,導致大型物件無法被分配

虛幻引用的智慧指標採用引用計數演算法,使用弱指標解決環形引用。

二十一、UBT和UHT

UBT(Unreal Build Tool):

UHT(Unreal Header Tool):

一個引擎獨立應用程式,UBT會通過命令列引數告訴UHT,遊戲模組對應的定義檔案在哪,包含了編譯的相關資訊,然後UHT開始了自己的三道編譯:Public Classes Headers、Public Headers、Private Headers

經過三道編譯,最終生成.generated.cpp和generated.h兩種檔案,

同時對含有UProperty和UFunction字樣的資料型別進行登記。

二十二、虛幻引擎的垃圾回收機制

二十三、Actor物件

相關推薦

大象無形虛幻引擎程式設計淺析讀書總結

        建德若偷,質真若渝。大方無隅,大器晚成。         大音希聲,大象無形。夫唯道善貸且成。 ——老子,《道德經》 -------------------------------------------------------------------

大象無形_虛幻引擎程式設計淺析pdf

下載地址:網盤下載 《大象無形:虛幻引擎程式設計淺析》以兩位作者本人在使用虛幻引擎過程中的實際經歷為參考,包括三大部分:使用C++語言進行遊戲性程式設計、瞭解虛幻引擎本身底層結構與渲染結構、編寫外掛擴充套件虛幻引擎。提供了不同於官方文件內容的虛幻引擎相關細節和有效實踐。有助於讀者一窺虛幻引擎本身設計的精妙之處

產品讀書《讓大象激進創新,讓你一飛沖天的創業術》

《讓大象飛》被稱為是為中國創業者量身定做的創業指南,作者是史蒂文·霍夫曼,他是美國矽谷重量級的創業教父,培訓了全球數百家初創公司的創始人,同時還是一名天使投資人,《福布斯》雜誌排名第一的創業孵化器--Founders Space的創始人,人稱“霍夫曼船長”。 史蒂文.

《MySQL技術內幕SQL程式設計讀書筆記 -- 資料型別

一、資料屬性 1.1 UNSIGNED UNSIGNED是將數字型別無符號化,例如:INT類型範圍為 -2147483648 ~ 2147483647,INT UNSIGNED表示的範圍為 0 ~ 4294967295。 注意:UNSIGNED會有以下問題: mysq

《深入淺出MySQL》讀書筆記三儲存引擎選擇

綜述: 選擇MyISAM的場景:操作以 insert和select 為主,update和delete較少的場景            選擇InnoDB的場景:大量update的場景,需要 事務和行鎖的支援 來達到比較好的效能 一、MyISAM        訪問速度快

【UE4 全域性光照明】虛幻引擎學習之路渲染模組之全域性光照明 by UWA侑虎科技

◆◆◆◆◆ 全域性光照總結 Unreal 4引擎提供了完整的工具鏈來支援靜態和動態物體的全域性光照效果。在計算全域性光照時採用了Photon Mapping演算法,通過不同的引數設定可以達到不同質量的全域性光照效果。Unreal 4引擎提供了同一場景使用不同全域性光照設定的功能Light Scena

Java程式設計思想讀書筆記——第六章訪問許可權控制

第六章 訪問許可權控制 初學Java的時候很納悶,為什麼要提供各種訪問修飾,都用public不就行了,程式都能執行,還多省事 我感覺如果這個程式只有你自己去編寫,去維護,那麼其實訪問許可權可以忽略 但是,比如說我寫了一個第三方開源庫,有很多很多的人在使用我的庫,那麼如

虛幻引擎學習之路渲染模組之材質系統

上週的Unreal 4引擎文章介紹了渲染模組的光照系統,在本篇文章中,我們繼續介紹渲染模組的另一重要部分:材質系統。 在此,特別感謝Unreal中國團隊對於本篇文章中Unreal引擎相關內容的稽核,並在我們學習其引擎的道路上提供的大力支援。 材質系統 材質描述

《lua程式設計讀書筆記 第二章型別與值

lua是一種動態型別的語言。 在lua中有8中基礎型別:nil(空)、boolen、number、string、userdata(自定義型別)、function、thread、table。函式type可根據一個值返回其型別名稱,其返回值為string。

Unity 5正式釋出支援21種平臺、個人版免費!釋出僅一年,虛幻引擎4宣佈完全免費!

Unity Technologies正式釋出了次時代多平臺引擎開發工具Unity 5,含有大量的圖形改進和擴充套件的編輯器功能集,支援移動、主機、虛擬現實等21種不同平臺,個人版完全免費,專業版售價1500美元,或以75美元進行月租。 http://unity3d.com/

Python讀書筆記008面向物件程式設計

編寫類:class Person: ''' Class to represent a person ''' def __init__(self): self.name = '' self.age = 0>&

虛幻4渲染程式設計【第一卷虛幻自身的延遲渲染管線】

    因為虛幻的架構,我們美術做一個效果只能使用材質編輯器。這讓我很不舒服,稍微想做點特別點的效果就沒辦法了。我又是天天在公司用自研引擎的人,這種限制讓人很不舒服。所以我開始修改了虛幻的shadingmode之類的。但是感覺自己還是不滿足,想調個多pass虛幻都不讓我做,所

《lua程式設計讀書筆記 第四章語句

4.1 賦值 Lua支援“多重賦值”,即可以一次性將多個值賦予多個變數。 a,b = 10, 2*x 在多重賦值中,Lua先對等號右邊所有元素求值,然後才執行賦值,這樣便可以進行交叉賦值 x,y = y,x a[i], a[j] = a[j],

UE427啟動虛幻引擎的步驟崩潰課程4

虛幻引擎4是一款完整的遊戲引擎; 這是非常廣泛的,可以壓倒一個完整的初學者。 常見的問題是:   “我哪裡甚至開始了?” 在下面的速成班是你現在需要知道要開始使用UE4什麼的概述。對於那些從未使用且非虛幻引擎非常深入的人來說,這是完美的,但需要一個快速的點概述來開始

虛幻引擎自帶的創建插件的插件

技術 his 之前 title 若有 新版本 detail ber asc 本文章由cartzhang編寫。轉載請註明出處。 全部權利保留。 文章鏈接:http://blog.csdn.net/cartzhang/article/details/51

(官網)虛幻3--虛幻引擎3命令行參數

加密 分辨率 sorted proc exec his oss nom cat 虛幻引擎3命令行參數 虛幻引擎3命令行參數 概述 模式 地圖/服務器/編輯器的URL 參數 一般選項 服務器選項 針對UTGame的特定選項 Switches(開關) 開發人

從唯品會財報看大象起舞品質成電商下半場制勝法寶

平臺 見證 自身 裏的 健康 啟動 以及 倉儲 left 8月入秋,美股上市公司迎來第二季度的豐收,各企業紛紛發布Q2財報。17日淩晨,國內特賣電商唯品會同樣公布了Q2財報,從財報來看,唯品會截至本季度已經連續保持了19個月的持續盈利,其Q2凈營收增至175.2億元,漲幅

JavaScript工作機制V8 引擎內部機制及如何編寫優化代碼的5個訣竅

with 由於 intern 但是 集成 項目 ssi 意義 實的 概述 JavaScript引擎是一個執行JavaScript代碼的程序或解釋器。JavaScript引擎可以被實現為標準解釋器,或者實現為以某種形式將JavaScript編譯為字節碼的即時編譯器。 下面是實

AI時代推薦引擎正在塑造人類

當前 意思 數據收集 沒有 匿名 永遠 的人 信息 多維 We shape our tools and afterwards our tools shape us. ------Marshall McLuhan 麥克盧

《python基礎教程》第4章字典當索引不好用時 讀書筆記

可能 none 存在 讀書筆記 一個 ear PC 類型 隨機   第四章 字典:當索引不好用時 1.通過名字來引用值的數據結構,這種數據結構叫做映射,字典是python中唯一內建的映射類型。 2.len():可以返回字典中的鍵-值對的數量。 3.del 關鍵字也可以刪除字