最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

UPBGE Python Scripting

2023-04-23 01:08 作者:緊果唄  | 我要投稿

UPBGE 游戲開(kāi)發(fā)系列教程:

#????UPBGE?- Blender 游戲引擎繼承者

## ?? UPBGE Python Scripting?

## ?? Logic Nodes (源代碼分析)

## ?? Script Lifecycle (源代碼分析)

## ?? UPBGE Python API (源代碼分析)


首先,UPBGE 編程環(huán)境就是一個(gè) Blender Python API 環(huán)境,通過(guò)嵌入 Python 腳本引擎以及導(dǎo)出內(nèi)部類型接口到腳本環(huán)境,就可以通過(guò) .py 腳本來(lái)調(diào)用 UPBGE 游戲引擎中的各種模塊、類型對(duì)象。同時(shí)這又是一個(gè)完整的 Python 解釋器提供的運(yùn)行環(huán)境,可以像在 Blender Python Console 那樣執(zhí)行腳本代碼:

Python 3.5 引入了新的 @ 運(yùn)算符,它與 numpy.dot() 等價(jià),是矩陣乘法,向量點(diǎn)積。

源文檔:https://github.com/Jeangowhy/opendocs/blob/main/upbge.md


了解 UPBGE 腳本編程環(huán)境,最基本的要求是熟練使用 Python 腳本編程,最好可以使用 C/C++ 開(kāi)發(fā)擴(kuò)展模塊。如果要開(kāi)發(fā)聯(lián)網(wǎng)對(duì)戰(zhàn)游戲,則還需要熟悉 TCP/IP/UPD 等協(xié)議棧,或者是基于現(xiàn)有的 RPC 框架開(kāi)發(fā)游戲客戶端之間的遠(yuǎn)程調(diào)用功能。


其次,從制作的角度來(lái)看,如果不需要處理上游的工序,包括游戲概念設(shè)計(jì)、藝術(shù)設(shè)計(jì)、故事劇本、地形、場(chǎng)景搭建、角色動(dòng)畫等等,單從功能出發(fā),可能涉及到游戲的經(jīng)濟(jì)系統(tǒng)、數(shù)值系統(tǒng)、玩法系統(tǒng)的開(kāi)發(fā),這些都需要對(duì) UPBGE Python API 導(dǎo)出的模塊功能非常熟悉,才可能根據(jù)需要開(kāi)發(fā)出相應(yīng)功能的最佳實(shí)現(xiàn)。


在編寫腳本代碼過(guò)程中,會(huì)經(jīng)常用到一個(gè)混入編程模式,Mixins And Traits,所謂混入即:不通過(guò)類繼承這種約束關(guān)系實(shí)現(xiàn)調(diào)用其它類型功能代碼,是一種代碼復(fù)用編程方法,Mixins 或者 Traits?就是這樣的一種類型實(shí)現(xiàn)。UPBGE 官方文檔 Python Scripting 部分提供了一系列基礎(chǔ)教程。

https://upbge.org/#/documentation/docs/latest/manual/manual/python/index.html


? ? According to a relevant Wikipedia article, a mixin is “a class that

? ? contains methods for use by other classes without having to be the

? ? parent class of those other classes”.


? ? Such a class is sometimes called a trait and often named as an

? ? adjective like Damageable or Openable to describe a specific aspect

? ? or characteristic of the target object.


Application Modules


- *bpy.context* [Context Access]

- *bpy.data* [Data Access]

- *bpy.msgbus* [Message Bus]

- *bpy.ops* [Operators]

- *bpy.types* [Types]

- *bpy.utils* [Utilities]

- *bpy.path* [Path Utilities]

- *bpy.app* [Application Data]

- *bpy.props* [Property Definitions]


Game Engine Modules


- *bge.types* [Game Types]

- *bge.logic* [Game Logic]

- *bge.render* [Rasterizer]

- *bge.texture* [Video Texture]

? ? - [FFmpeg Video and Image Status]

? ? - [Image Blending Modes]

- *bge.events* [Game Keys]

- *bge.constraints* [Physics Constraints]

- *bge.app* [Application Data]

- *bgui* [Game GUI]


Standalone Modules


- *bgl* [OpenGL Wrapper]

- *bl_math* [Additional Math Functions]

- *blf* [Font Drawing]

- *bmesh* [BMesh Module]

- *bpy_extras* [Extra Utilities]

- *freestyle* [Freestyle Module]

- *gpu* [GPU Module]

- *gpu_extras* [GPU Utilities]

- *idprop.types* [ID Property Access]

- *imbuf* [Image Buffer]

- *mathutils* [Math Types & Utilities]


導(dǎo)入模塊時(shí)出錯(cuò),并且可能導(dǎo)致掛載組件時(shí)失敗也不給出提示信息,原因是 bgui 模塊未提供默認(rèn)安裝,可以在 Blender Python Console 中執(zhí)行 pip 命令安裝模塊,以下命令會(huì)將控制臺(tái)內(nèi)容輸出到日志,并使用系統(tǒng)默認(rèn)編輯器打開(kāi) log.md 文件:

Python 模塊手動(dòng)安裝,只需要將模塊代碼目錄復(fù)制到 lib 目錄下,模塊初始化腳本位置應(yīng)該如下所示:

? ? UPBGE-0.30-windows-x86_64\3.0\python\lib\bgui\__init__.py

UPBGE 通過(guò) `Game Object Properties` 向場(chǎng)景所有對(duì)象提供三種腳本屬性設(shè)置,以及邏輯節(jié)點(diǎn)編輯器側(cè)欄面板,也提供了一種全局?jǐn)?shù)據(jù)存儲(chǔ)功能:


1. `Game Objects` 繼承自 `bge.types.KX_GameObject`,每對(duì)象掛載一個(gè)實(shí)例。

2. `Game Components` 繼承自 `bge.types.KX_PythonComponent`,每對(duì)象掛載任意實(shí)例。

3. `Game Properties` 屬性數(shù)據(jù)服務(wù),來(lái)自 Blender 基礎(chǔ)功能,每對(duì)象單獨(dú)存儲(chǔ)屬性數(shù)據(jù)。

4. `GlobalDB` 邏輯節(jié)點(diǎn)樹(shù)全局字典數(shù)據(jù)對(duì)象,在邏輯編輯器側(cè)欄 Global 面板中添加的字典對(duì)象及數(shù)據(jù)。


游戲中的每個(gè) `GameObject` 可以存儲(chǔ)控邏輯組件的集合(Logic Bricks),可以組合邏輯塊來(lái)執(zhí)行用戶定義的動(dòng)作,這些動(dòng)作決定游戲模擬的進(jìn)度。


可以像腳本組件一樣在 Python 腳本文件(模塊)中定義多個(gè) `GameObject`,并且掛載到場(chǎng)景中不同的對(duì)象上使用。但是每個(gè)對(duì)象只能掛載一個(gè) `GameObject`,而不像腳本組件那樣任意掛載多個(gè)組件。不同的游戲?qū)ο髴?yīng)該派生具體的類型,例如掛載到 Camera 對(duì)象上的 GameObject,就應(yīng)該繼承 `KX_Camera`。


UPBGE 整個(gè)編程環(huán)境中,邏輯塊和腳本組件,以及游戲?qū)ο蟮念愋蛯哟谓Y(jié)構(gòu)之間的關(guān)系摘要如下,另外,邏輯節(jié)點(diǎn)編程模塊基于 Python 腳本實(shí)現(xiàn),另行分析:

1. `SCA_IObject` 是場(chǎng)景中的對(duì)象類型的接口;

2. `KX_GameObject` 游戲?qū)ο?,也就是?chǎng)景中的對(duì)象,是場(chǎng)景中的對(duì)象類型的基類;

3. `KX_Scene` 代表整個(gè)游戲場(chǎng)景,objects 集合引用所有游戲?qū)ο?,`EXP_ListValue<KX_GameObject>`;

4. `KX_PythonComponent` 腳本組件類型是游戲?qū)ο笊蠏燧d的腳本的類定義,通過(guò) object 屬性引用其所有者;

5. `SCA_ILogicBrick` 是邏輯塊的基類接口,它繼承了**重雙向循環(huán)鏈接**數(shù)據(jù)結(jié)構(gòu)用于處理節(jié)點(diǎn)連接關(guān)系;


之所以稱為為 python component,是因?yàn)槟_本中的功能會(huì)以 Blender UI 的方式顯現(xiàn)在 Game Object 屬性面板下的組件欄目中,所有 `args` 有序字典中保存的入口參數(shù)都會(huì)有相應(yīng)的 UI 設(shè)置界面。


Properties 數(shù)據(jù)服務(wù)器 Blender 提供的一種基礎(chǔ)服務(wù),在各種面板上,可以使用右鍵復(fù)制、粘貼屬性數(shù)據(jù)。3D 視圖對(duì)象模式可以通過(guò) `Object -> Game` 菜單管理屬性數(shù)據(jù),`VIEW3D_MT_object_game(Menu)`。

可以對(duì)數(shù)據(jù)進(jìn)行清理,一次操作刪除對(duì)象上設(shè)置的 Game Properties 數(shù)據(jù),`game_property_clear` 操作可以在多個(gè)源代碼中,或者 bpy.ops.object API 文檔找到相關(guān)的信息。

邏輯節(jié)點(diǎn)編輯器側(cè)欄面板 Globals 可以添加全局字典對(duì)象,以存儲(chǔ)數(shù)據(jù)供所有節(jié)點(diǎn)樹(shù)使用。相關(guān)的設(shè)計(jì)時(shí)節(jié)點(diǎn)實(shí)現(xiàn)有 5 個(gè)類型,其中兩個(gè)為插槽實(shí)現(xiàn)類型,剩下 3 個(gè)是節(jié)點(diǎn),歸類在 `Value -> Global`。所謂 Category 即一個(gè)全局的存儲(chǔ)數(shù)據(jù)的 Dictionary 對(duì)象,這個(gè)字典對(duì)象存儲(chǔ)在 `GlobalDB`。

使用 List Global Category 節(jié)點(diǎn),可以讀取 `GlobalDB` 對(duì)象上存儲(chǔ)的數(shù)據(jù)。

使用 Get Property 節(jié)點(diǎn),就可以指定要讀取場(chǎng)景中那個(gè)對(duì)象上掛載的 Game Properties 數(shù)據(jù)。


除了使用腳本中的 `GlobalDB` 對(duì)象,還可以使用導(dǎo)出的 Python API 存儲(chǔ)字典數(shù)據(jù)到文件:

`Objects -> Properties` 分類下和屬性數(shù)據(jù)相關(guān)的 9 邏輯節(jié)點(diǎn)類型,其中一個(gè)為插槽。



在使用上,`KX_GameObject` 和 `KX_PythonComponent` 對(duì)象導(dǎo)出的腳本接口是很類似的,同樣的參數(shù)結(jié)構(gòu),和執(zhí)行方法。但是內(nèi)部實(shí)現(xiàn)上,前者比后者復(fù)雜得多。腳本組件對(duì)象導(dǎo)出了一個(gè) `object` 屬性,它引用當(dāng)前腳本組件所掛載的對(duì)象,如場(chǎng)景中的 Cube。


控制器對(duì)象從個(gè)父類 `SCA_ILogicBrick` 繼承了一個(gè) `owner` 屬性,引用一個(gè)當(dāng)前調(diào)用這個(gè)控制器的游戲?qū)ο?GameObject。因?yàn)橐粋€(gè)控制器可以掛載到多個(gè)對(duì)象上,不同的控制器掛載到不同對(duì)像,所掛載的游戲?qū)ο笠膊幌嗤?/p>


在腳本中導(dǎo)入模塊、符號(hào)時(shí),應(yīng)避免 * 通配式加載所有子模塊、符號(hào),可能導(dǎo)致的命名空間污染問(wèn)題。


組件保存所在的腳本中,還可以編寫由 Logic Bricks - bge.types.SCA_IController 運(yùn)行的代碼,這是兩種不同的腳本運(yùn)行方式。腳本組件由 Game Components 機(jī)制加載,可調(diào)用腳本內(nèi)所有繼承了 `KX_PythonComponent` 基類的類型對(duì)象。而通過(guò)邏輯塊 Python 控制器運(yùn)行,**Script** 模式下則是直接運(yùn)行整個(gè)腳本,或者 **Module** 模式下運(yùn)行外部腳本文件中的控制器方法,其函數(shù)參數(shù)接收一個(gè)控制器對(duì)象,即是當(dāng)前調(diào)用控制器方法的 `SCA_IController`。


組件首次加載是在 bge 模塊之前完成,此時(shí)bge 是一個(gè)偽模塊,因?yàn)樗话?`KX_PythonComponent` 這個(gè)組件基類類型,也就是說(shuō),此時(shí)只導(dǎo)出了這個(gè)組件類型定義到 Python 腳本空間,以以避免 import 語(yǔ)句導(dǎo)入所有 bge 模塊,此時(shí)只是加載過(guò)程中的一個(gè)階段狀態(tài)。源代碼代碼片段如下,`load_class()` 方法中只是導(dǎo)出了 `bge` 和 `bge.types` 模塊符號(hào),并沒(méi)有實(shí)質(zhì)性內(nèi)容。此時(shí)設(shè)置了一個(gè)布爾值標(biāo)識(shí) `__component__`,可用于檢測(cè)的 bge 的加載狀態(tài)。但當(dāng)用戶想要使用 bge 模塊中的其它函數(shù)或?qū)傩詴r(shí),檢測(cè)此標(biāo)記值,避免直接調(diào)用未加載的庫(kù)函數(shù)產(chǎn)生一些問(wèn)題。

? ? SystemError: bge.logic.getCurrentController(), this function is being run

? ? outside the python controllers context, or blenders internal state is corrupt.


Blender 定義了一套 Python Proxy 函數(shù),用來(lái)向腳本環(huán)境導(dǎo)入模塊定義:


upbge-0.30\doc\python_api\rst\bge.logic.rst

upbge-0.30\doc\python_api\rst\bge_types\bge.types.KX_PythonComponent.rst

upbge-0.30\source\blender\blenkernel\intern\python_proxy.c

打開(kāi) Blender 腳本編輯器,可以從 `Templates - Python Component templates` 菜單找到腳本組件模板,以供學(xué)習(xí)。這些模板腳本涉及場(chǎng)景對(duì)象列表、音頻播放、鼠標(biāo)鍵盤輸入、玩家控制器實(shí)現(xiàn)、相機(jī)鏡頭控制、時(shí)間軸動(dòng)畫、Minimap 紋理、渲染器調(diào)用、物理載具、AI 跟蹤等等,源代碼文件列表如下:

其中 **Python Component** 模板就是一個(gè)腳本組件的最基本結(jié)構(gòu)。**Bpytypes** 演示了 bpy 模塊所有的可用類型。

Python 腳本組件就是代碼復(fù)用的一種概念,也是定義 UPBGE 引擎中可能的一種類型定義,規(guī)則要求:


1. 需要繼承自 `KX_PythonComponent` 類型定義;

2. 包含一個(gè) Python 有序字典對(duì)象作為組件要傳入的參數(shù)名稱、類型等屬性說(shuō)明 **args**;

3. 兩個(gè)基本方法:**start()** 和 **update()**;

4. 另外,還有一個(gè)可選方法,**dispose()** 用于移除組件回收內(nèi)存時(shí)執(zhí)行清理工作;


腳本組件按 Python 模塊化組織,基本的命名規(guī)則是 `module.Component`,自行指定模塊名和類名。點(diǎn)擊創(chuàng)建,Blender 腳本編輯器中有會(huì)出現(xiàn)相應(yīng)的 `module.py` 模塊腳本,可以保存為外部腳本文件。UPBGE 提供了一個(gè)屬性面板用來(lái)添加腳本組件:`Game Object Properties -> Game Component` 提供了兩個(gè)方法創(chuàng)建腳本組件:**Add** 和 **Create**,對(duì)應(yīng)兩個(gè)按鈕。

設(shè)置好參數(shù)列表后并掛載腳本組件后,`Game Components` 面板就會(huì)添加對(duì)應(yīng)參數(shù)列表的面板設(shè)置選項(xiàng)。在游戲運(yùn)行時(shí),`start()` 方法接收到的字典對(duì)象將包含這些來(lái)自屬性面板配置過(guò)的參數(shù)值。


有序字典 OrderedDict 構(gòu)造函數(shù)接收一個(gè)數(shù)組,元素類型是 Tuple,可以指定參數(shù)名稱、默認(rèn)值,或者指針類型,像指定 `str` 這種字節(jié)串類型將觸發(fā)異常:**Unsupported pointer type**。

Python-3.10.2\Doc\library\collections.rst


Blender 中編寫的 Python 腳本模塊有兩種基本存儲(chǔ)方式:


1. 默認(rèn)方式為 .blend 文件內(nèi)嵌: `Text Editor -> File -> Make Internal`

2. 外部腳本文件: `Text Editor -> File -> Save As...`


模塊是 Python 腳本的基本組織方式,它可以保存在獨(dú)立的文件中,也可以保存在某種數(shù)據(jù)庫(kù)中。而腳本模塊只是 Python 眾多支持模塊中的一種,它還支持 C/C++ 編寫的擴(kuò)展模塊等等。


比如,將 `module.py` 模塊保存到 .blend 同級(jí)的 `scripts/module.py`,那么導(dǎo)入腳本模塊就應(yīng)該使用 `script.module.Component` 這樣的點(diǎn)路徑。


使用外部腳本的一個(gè)好處是可以利用外部編程工具,如 VS Code/Sublime Text 等等,還可以使用語(yǔ)言服務(wù)器 LSP 提供語(yǔ)法提示等輔助功能。


腳本組件命名使用大小寫結(jié)合的駝峰拼寫法(CamelCase),比如 `MypyComponent` 就會(huì)在面板中顯示為 `Mypy Componnet`,可以使用全小寫,但是最好大寫開(kāi)頭表示一個(gè)類型定義,而不是變量。


注意:有幾個(gè)小問(wèn)題,如果已經(jīng)創(chuàng)建了腳本模塊文件,不能通過(guò)點(diǎn)擊 **Create** 往現(xiàn)有模塊添加新組件,會(huì)提示腳本模塊已經(jīng)存在。另外,不要使用二級(jí)占路徑,UPBGE 不支持。模塊名也不要與存在的目錄同名,否則創(chuàng)建模塊后,提示模塊沒(méi)有相應(yīng)的組件屬性,但腳本模塊依然會(huì)創(chuàng)建,只是不能正確使用:

? ? module 'xxx' has no attribute 'Component'

對(duì)于已經(jīng)保存到外部文件的腳本,還可以使用 Blender 腳本編輯器重新找打開(kāi),但此時(shí)注意,外部腳本模塊文件和 Blender 內(nèi)部腳本模塊名稱可以不一致,因?yàn)樗鼈兇藭r(shí)是兩個(gè)不同的腳本模塊。但是在執(zhí)行`Make Internal` 將腳本模塊明確為內(nèi)嵌模塊之前,保存腳本內(nèi)容還是保存會(huì)保存到外部腳本文件內(nèi)。掛載時(shí)組件時(shí),依然可以使用文件目錄路徑作為 Python 模塊的點(diǎn)路徑,同時(shí)又可以掛載內(nèi)嵌模塊。

如果腳本文件有語(yǔ)法錯(cuò)誤,則加載時(shí)會(huì)提示,應(yīng)該打開(kāi) Window -> Console 查看控制臺(tái)輸出信息:

? ? No mudules named "script.module" or script error at loading.

`Game Object Properties -> Game Object` 面板可以創(chuàng)建游戲數(shù)據(jù)對(duì)象,可以和腳本組件保存在相同腳本模塊文件中。但是加載時(shí),不能在 Game Object 面板中添加組件,也不能在 Game Component 面板中添加 Game Object。


組件腳本文件可以和 .blend 文件同級(jí)目錄存放,刷新已加載組件點(diǎn)擊下拉菜單 `Relaod Component`。首次添加腳本組件就會(huì)執(zhí)行 `start()` 初始化方法,刷新時(shí)不再執(zhí)行,但是模塊級(jí)代碼會(huì)被執(zhí)行。同一個(gè)腳本組件可以多次添加使用,也可以給場(chǎng)景中選中的多個(gè)對(duì)象添加。但是要移除已掛載的腳本組件,就需要單獨(dú)對(duì)每個(gè)對(duì)象進(jìn)行移除操作。


UPBGE Python Scripting的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
桓台县| 封丘县| 嘉祥县| 潜山县| 甘孜| 兴城市| 定边县| 漳平市| 湖州市| 开远市| 罗田县| 海安县| 封开县| 石嘴山市| 东港市| 贵阳市| 句容市| 郎溪县| 罗平县| 长宁区| 夏津县| 石狮市| 滨州市| 九龙城区| 肥西县| 修武县| 都昌县| 枞阳县| 四平市| 信阳市| 衢州市| 周宁县| 利川市| 德昌县| 彭阳县| 元谋县| 客服| 积石山| 德安县| 三亚市| 潢川县|