Unity3D伺服器端使用PhysX計算物理
本文的最終目的:
當設計師在Unity3D中製作好遊戲場景後(為Gameobject拖好Collider),通過我們寫的工具匯出這份場景的Collider配置,在伺服器端能夠生成一份一模一樣的物理世界,從而由權威伺服器去計算物理,諸如子彈有沒有擊中玩家等等。
PhysX最初是AGEIA公司開發的物理運算引擎,跟Havok,Bullet這兩款旗鼓相當,後來2008年AGEIA被NVIDIA收購,NVIDIA將PhysX保密,作為NVIDIA顯示卡的專利,這逐漸導致了其沒落,在封閉了相當長一段時間後,NVIDIA最終將其開源,目前原始碼已經託管在了Github上。
PhysX支援平臺和引擎如下:
硬體平臺:Windows, OSX, Linux, XBOX, PlayStation, Andriod, IOS
遊戲引擎:Unreal 3, Unreal 4, Unity
1. 安裝PhysX
1.1 獲取GitHub上PhysX原始碼的許可權
PhysX原始碼並不對所有人開放,需要向Repo的holder申請,操作步驟參考如下:詳細步驟
總的來說就是4步:
- 申請許可權,在最下面填上自己的GitHub Username就可以了。
- 1個小時後檢視github繫結的郵箱,就可以看到通過申請的回覆郵件了
- 訪問Github上PhysX的Repo, 就可以fork,clone下來了
1.2. PhysX安裝
- 原始碼clone下來之後, 按照根目錄下的README.md很容的找到 /PhysX-3.3/PhysXSDK/Source/compile/目錄下所需要的平臺,編譯出對應平臺下的靜態和動態連結庫。
- 整合/PhysX-3.3/Include 和 /PhysX-3.3/Lib 和 /PhysX-3.3/Bin到自己的程式使用。
備註:
在根目錄下,我們會看到另外一個APEXSDK, 這個是一套讀取設計師通過PhysX Lab等工具匯出的設計的資源的API(資源有自己定義的格式如 “.apb”).
例如:場景中物體的摧毀效果,布料,粒子等效果,比方說其中有一個模組: Destruction Module, 有興趣的可以看一下
2. Unity Editor中匯出物理場景的配置
Unity中基本的Collider分為:Box Collider, Sphere Collider, Capsule Collider,以及針對精度要求較高的Mesh Collider,還有其它的一些特定應用場景下會用到的諸如Wheel Collider,Terrain Collider等等。
我們今天主要目的搭建好整個流程,只用基本型別的Collider作為例子。
我們前後臺都統一使用Google Proto buffers定義場景匯出的格式,以二進位制格式序列化和反序列化場景。
2.1 定義Scene.proto
整個proto程式碼貼在了下方,我們簡單說明一下,很容易就明白了。
每一個戰鬥場景匯出一個檔案,格式如下:
- message U3DPhysxScene
- {
- optional int32 id = 1;
- optional string scene_name = 2;
- repeated U3DPhysxBox box_collider = 3;
- repeated U3DPhysxSphere sphere_collider = 4;
- repeated U3DPhysxCapsule capsule_collider = 5;
- repeated U3DPhysxMesh mesh_collider = 6;
- }
一個場景由若干個U3DPhysxBox,U3DPhysxSphere,U3DPhysxCapsule,U3DPhysxMesh組成.
每個collider的定義很容易理解, 其中Capsule Collider在PhysX的定義如下:
package killer.proto;
enum ColliderType
{
BOX = 1;
SPHERE = 2;
CAPSULE = 3;
MESH = 4;
}
message Position
{
optional double x = 1 [default = 0];
optional double y = 2 [default = 0];
optional double z = 3 [default = 0];
}
message U3DPhysxScene
{
optional int32 id = 1;
optional string scene_name = 2;
repeated U3DPhysxBox box_collider = 3;
repeated U3DPhysxSphere sphere_collider = 4;
repeated U3DPhysxCapsule capsule_collider = 5;
repeated U3DPhysxMesh mesh_collider = 6;
}
message U3DPhysxSphere
{
optional int32 id = 1;
optional ColliderType type = 2;
optional Position pos = 3;
optional double radius = 4;
}
message U3DPhysxBox
{
optional int32 id = 1;
optional ColliderType type = 2;
optional Position pos = 3;
optional double x_extents = 4;
optional double y_extents = 5;
optional double z_extents = 6;
}
message U3DPhysxCapsule
{
optional int32 id = 1;
optional ColliderType type = 2;
optional Position pos = 3;
optional double raduis = 4;
optional double height = 5;
}
message U3DPhysxMesh
{
optional int32 id = 1;
optional ColliderType type = 2;
optional int32 vertex_count = 3;
repeated Position vertices = 4;
}
2.2 修改Scene.proto
- 進入Editor/BuildProtocol/Protocal
- 修改Scene.proto, 然後執行 Editor/BuildProtocol/build.bat,這樣protobuf會在 Editor/ProtoGeneratedScrips 目錄下生成新的Scene.cs。
- 然後重新整理Unity,修改 Editor/SceneExtractor.cs 指令碼使用新的Scene.proto的欄位。
2.3 程式碼下載並執行
整個Unity Editor的程式碼(c#) 和 依賴的第三方庫(proto-net),都已經打包好了.
下載下來直接放到Unity的Assets目錄下,重新整理unity.
在選單欄中: Tools->SceneExtractor->ExtractColliders
即可匯出當前開啟的場景為一份物理配置給後臺使用。
程式碼託管在了Github上:
3. 伺服器端匯入場景的配置檔案,生成物理場景
因為後臺在跑的伺服器沒有顯示卡,所以我們伺服器端的工作,分為如下兩步
3.1 在windows平臺上,反序列化出場景,用OpenGL渲染測試正確性
1. 這部分工程程式碼也封裝好了,可以下載下來直接跑
程式碼託管在了Github上:
平臺:windows7 x64 + Visual Studio 2013 + OpenGL
語言: C++
具體每個資料夾的含義以及如何導proto,請看工程根目錄下的README.md檔案。
在跑工程的時候,有可能會遇到一些問題,比方說:OpenGL沒有安裝等,請移步 /external 目錄,裡面有兩張png是解決沒有安裝OpenGL問題的。
- 如果沒有安裝OpenGL,請將 /external/GL 目錄拷貝到 **/Program Files(x86)/Microsoft Visual Studio 12.0/VC/include/GL。對於Visual Studio的其它版本,放到對應的目錄下去就好了。
- 同樣如果在連結階段報lib檔案找不到的話,將external/*.lib 這3個lib放到 **/Program Files(x86)/Microsoft Visual Studio 12.0/VC/lib/amd64 這個目錄下去。
2. 程式碼結構說明
- PhysicsSceneManager是核心的類,管理了初始化PhysX,匯入場景等核心功能
- PhysicsSceneRender和ServerCooperationRender負責渲染
- PhysicsSceneCamera是控制相機鏡頭的類
- Main.cpp是工程入口,通過RENDERFORTEST巨集去控制是否開啟OpenGL渲染
我們開啟PhysicsSceneManager.cpp
看到最重要的兩個函式: InitiPhysics()和InitiSceneFromFile().
需要注意的是m_foundation, m_physics是在程式一啟動的時候就必須初始化的。
其它的程式碼配合PhysX的Documentation看,很容易就看明白了。
3.2 關閉OpenGL渲染,將Simulation部分的程式碼放到Linux上去
程式碼託管在了Github上:
最後關閉 RENDERFORTEST 巨集, 並刪除PhysicsSceneRender.h, PhysicsSceneRender.cpp和SeverCooperationRender.cpp,並將對程式碼進行簡單的封裝,就可以放到伺服器上運行了。
這一部分的程式碼部分可以在這裡下載,但是linux下的physx環境配置需要自行安裝,安裝過程也很簡單, 不能直接make。
目錄下有一個可執行的二進位制檔案 PhysXTestBinary,是我們編譯出來測試的。
4.執行測試
-
Unity製作測試場景
-
在Windows下伺服器端渲染的場景
-
在Linux伺服器上,利用PhysX的Raycast的API, 可以正確檢測其中一對點可以到達, 另外一對點由於中間Box collider的阻擋無法達到。
相關推薦
Unity3D伺服器端使用PhysX計算物理
本文的最終目的: 當設計師在Unity3D中製作好遊戲場景後(為Gameobject拖好Collider),通過我們寫的工具匯出這份場景的Collider配置,在伺服器端能夠生成一份一模一樣的物理世界,從而由權威伺服器去計算物理,諸如子彈有沒有擊中玩家等等。 Phy
Unity3D移動端HTTP無法訪問伺服器
原因: 近期在開發Unity移動端的專案時,發現通過HTTP無法請求伺服器(前期在編輯器中訪問正常,釋出到Android端就 涼涼了) using System.Collections; using
Unity3D 通過Get與Post方式與伺服器端進行互動
<p style="padding-top: 10px; padding-bottom: 10px; margin-top: 0px; margin-bottom: 0px; line-height: 25px; color: rgb(51, 51, 51); fon
Unity3D開發之網路遊戲中伺服器端的架構設計
最近在研究網路遊戲開發,感覺結構很好玩,所以就將自己學到了解到的記錄下來。部落格前幾篇的Socket通訊講的就是網路遊戲部分Socket的基本結構。上一篇的對MySql使用就是伺服器對資料庫的連線使用。今天要介紹的就是遊戲伺服器的設計架構以及一些核心程式碼。 通
無法向會話狀態伺服器發出會話狀態請求。請確保 ASP.NET State Service (ASP.NET 狀態服務)已啟動,並且客戶端埠與伺服器埠相同。如果伺服器位於遠端計算機上,請檢查。。。
無法向會話狀態伺服器發出會話狀態請求。請確保 ASP.NET State Service (ASP.NET 狀態服務)已啟動,並且客戶端埠與伺服器埠相同。如果伺服器位於遠端計算機上,請檢查HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspn
(轉)Unity3D 之插值計算
離開 http 分享 player oid 動畫 and stat etc 在unity3D中經常用線性插值函數Lerp()來在兩者之間插值,兩者之間可以是兩個材質之間、兩個向量之間、兩個浮點數之間、兩個顏色之間,其函數原型如下: Material.Lerp 插值 func
Unity3D移動端電量與wifi信號的獲取
ios 位置 wol file arp zhang logs code cit 移動端遊戲中無法看到電量與wifi信號對於玩家來說是很困擾的事。 關於這個問題安卓與iOS有不同的方法 電量 安卓 安卓獲取電量有兩種方法,一種是讀取安卓手機裏的一個文件,一種是利用安卓
netty伺服器端啟動
package com.imooc.netty.ch3; import com.imooc.netty.ch6.AuthHandler; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.ne
基於windows的簡單伺服器端和客戶端
伺服器端套接字建立步驟:1.呼叫socket函式建立套接字。2.呼叫bind函式分配IP地址和埠號。3.呼叫listen函式轉為可接收請求狀態。4.呼叫該accept函式受理連線請求。 客戶端套接字建立步驟:1.呼叫socket函式建立套接字。2.呼叫connect函式向伺服器端傳送連線請求。  
Ajax傳遞複雜引數到伺服器端的方法
我們大概都知道,使用Ajax傳遞簡單引數到伺服器端(SpringMVC)的方法,如下: $.ajax({ type : "POST", url : CONFIG.mec_otm.order + "/cancel", data : { "resu
DataTables的伺服器端(SpringMVC)分頁模式
Datatables是一款jquery表格外掛。它是一個高度靈活的工具,可以將任何HTML表格新增高階的互動功能。 分頁,即時搜尋和排序 幾乎支援任何資料來源:DOM, javascript, Ajax 和 伺服器處理 支援不同主題 DataTables, jQuery UI, Bo
Django-伺服器端物件-跨域請求
Django-伺服器端物件-跨域請求 在介面函式中配置 from django.http import HttpResponse,response,JsonResponse def login(request): todo_list = [ {"
Django-伺服器端物件
Django-伺服器端物件 request 通過request.method可以檢視提交方式 request 解析資料 get request.environ request.GET #如果提交資料方式為: http://localh
伺服器端解決跨域問題的三種方法
跨域是指html檔案所在的伺服器與ajax請求的伺服器是不同的ip+port,例如: - ‘192.168.1.1:8080’ 與 ‘192.168.1.2:8080’是不同的域。 - ‘192.168.1.1:8080’ 與 ‘192.168.1.1:8081’是不同的域。
PG客戶端連線伺服器端報Connection refused (0x0000274D/10061) 的問題分析
C:\Users\Administrator>psql -h 192.168.80.189 -U highgo -p 5899 psql: 無法聯接到伺服器: Connection refused (0x0000274D/10061)
基於windows的tcp伺服器端/客戶端
一個計算器的例子: 客戶端連線到伺服器端後以1位元組整數形式傳遞待算數字個數; 客戶端向伺服器端傳遞的每個整數型資料佔用4位元組; 傳遞整數型資料後接著傳遞運算子,運算子佔1個位元組; 伺服器端以4位元組整數型向客戶端傳回計算結果。 伺服器端: #includ
Socket-tcp協議客戶端與伺服器端互聯
客戶端 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.T
Linux 檢視伺服器端開啟情況及開啟或關閉一個埠(永開啟久關閉)
Linux 檢視伺服器端開啟情況及開啟或關閉一個埠(永久關閉等) 1.Linux CentOS7防火牆的基本操作,對firewalld-cmd操作和檢視 2.Linux CentOS7怎麼開啟外網訪問一個埠 1.Linux
基於windows的使用select的I/O複用回顯伺服器端
使用過select函式可以將多個檔案描述符集中到一起監視,集中時也要按照監視項(接收、傳輸、異常)區分。 伺服器端: #include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #de
Jersey 2.x 伺服器端應用支援的容器
基於 JAX-RS Servlet-based 部署的一部分標準,能執行在任何支援 Servlet 2.5 和更高標準的的容器上。Jersey 提供支援程式化部署在下面的容器中:Grizzly 2 (HTTP 和 Servlet), JDK Http server,Simple Http server 和 J