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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Replicate(网络复制),ActorRole(角色),Ownership(所有权)以及RPC(远程调用)等等...

發布時間:2025/4/14 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Replicate(网络复制),ActorRole(角色),Ownership(所有权)以及RPC(远程调用)等等... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

I. Replication

Replication指的是 從服務端向客戶端 傳遞數據和信息的行為。注意是單向的,不會從客戶端傳遞信息和數據到服務端。

假設一個Actor被設置為Replicates, 當且僅當它被服務端生成 ,那么它會被所有客戶端生成,并被Replicated。言外之意,即使是Replicates的Actor,如果在某個客戶端生成,它也只會在本客戶端生成,是 不會在其他客戶端或者服務端生成 的,自然也談不上Replication。

還有一種情況容易讓人糊涂:假設在Pawn類中的Authority端生成一個Actor,并且把它存為變量,那么這個變量的Replicates屬性和這個Actor本身的Replicates屬性是什么關系?實際上,這里變量只是指向這個Actor的一個引用/指針,掌握住這點就好理解了。如果這個Actor沒有Replicates,而讓這個指針Replicates,那么它在客戶端上就會指向一個NULL,這個并不會讓引擎崩潰,但是沒有任何意義。如果Actor Replicates,但是指針不是Replicated,那么在客戶端這個Actor是存在的,但是指針沒辦法指向正確的對象。所以這種情況下需要Actor和變量都是Replicates(ed)才能達到正確的效果

另外,GameMode是不會Replicates的,它只存在于服務端,所以對它存儲的變量設置Replicated沒有任何意義。

?

那么再考慮一下,如果這個Actor在編輯階段就被置于場景中呢,它在多人聯網的情形下是什么狀況?

我做了以下幾個實驗來逐步分析:

(以下實驗如無特殊說明,均采用默認的第三人稱場景,Play選項Number of Players選擇2,New Editor Window(PIE))

實驗1:Actor不勾選Replicates,直接放置于場景中,初始一個隨機速度運動

結果:客戶端和服務端都各自以各自的速度運動,證明這兩個物體在不同的instance上是獨立的,互無關聯的。

?

實驗2:Actor勾選Replicates,但不勾選Replicate Movement,直接放置于場景中,初始一個隨機速度運動

結果:和實驗1一樣。那么大家可能就會懷疑,這種情況下是不是和實驗1是完全一樣的?實際上和實驗1有很大的區別,這個Actor有了Replication,也就可以進行屬性的Replicates和RPC調用,而實驗1里的Actor就不可能進行這些操作。

?

實驗3:Actor勾選Replicates,勾選Replicate Movement,直接放置于場景中,初始一個隨機速度運動

結果:雖然初始化了不同的速度(print出來了),但是服務端和客戶端運動基本上是同步的,只是客戶端的運動會有些許“抖動”。出現這種情況的原因是客戶端“想”以自己的速度去運動,但是由于更新了Replicate Movement,服務端會以固定的頻率去把自身的位置同步給客戶端,因此客戶端會在更新的瞬間跳躍到服務器指定的位置,從而產生了抖動。

?

放置于場景中的Actor的情況我們搞清楚了,再來考慮一下更麻煩的——動態生成:

實驗4:我們先在LevelBlueprint的BeginPlay中直接生成Actor,這個Actor是實驗2的,也就是Actor勾選了Replicate,但并不同步移動。

結果:服務端有一個Actor,客戶端有2個Actor,并且3個Actor均以不同的速度在運動。不難理解,因為在LevelBP中生成,所以服務端生成了一個,但是這個Actor是Replicates的,所以被復制到客戶端,同時客戶端本身的LevelBP中也生成了一個,所以客戶端有兩個。

所以如果要在LevelBlueprint中生成Replicates的Actor,一定要在前面加上Switch has authority,并在Authority后面生成。

?上述幾個實驗的工程源碼存放在這里

?

II. Ownership

所謂“Own”(擁有)的主語其實是一個“連接”的實例或者PlayerController。

每個“連接”的實例肯定會Own(擁有)一個PlayerController

那么決定一個Actor是否被擁有,就是向上查找他的Ownership結構樹,找到最上層的擁有者,如果是個PlayerController,它就被這個PlayerController以及它的“連接”所擁有。

最典型的的例子,一個Pawn被PlayerController Possess的時候它就被Owned。如果它被Unposses了,Ownership也就丟失了。

那么一個普通的Actor能不能被“擁有”呢?答案是可以的,使用Set Owner方法就可以讓他被某個PlayerController擁有。

為什么要強調Ownership呢?

  • 后面我們將描述這個問題:RPC需要決定在哪個客戶端執行 Run on Client的 RPC
  • Actor網絡復制和連接的Rlevancy(相關性)
  • 牽扯到Owner時候的property Replication條件

?

III. Actor Role 和 Remote Role

Actor Role在我的 這篇文章里已經很詳細的描述過了,這里做一下補充:

Actor Role 和 Remote Role是一組相對的概念,Actor Role指的是在本地的角色,Remote Role指的是遠程端的角色。這里的“遠程端”有點tricky,容易誤解,我也是糊涂了很久才明白。

設想有一個服務端加兩個或兩個以上的客戶端,那么所謂的“遠程端”到底指的是在哪個“端”?實際上我們只需要分兩個“端”,一個服務端,一個客戶端,把所有的客戶端都看成一端,這個問題的答案就很顯而易見了。

另外 官方文檔專門說明了, “目前,僅服務端可以負責同步信息到客戶端,因此僅服務端可以看到Role=Authority,并且RemoteRole=Simulated_Proxy或者Autonomous_Proxy”,這個“目前”說的是目前的網絡構架。

總之,只有服務端才可能有Authority,所有Replicates的Actor在服務端的Role都是Authority,要牢記這點。(非Replciates的有沒有Authority?有待驗證)

實際上,Simulated_Proxy和Autonomous_Proxy講的是兩種同步模式(Mode of Replication),因為服務器不可能每一幀都去把信息同步給所有客戶端,而是以一定的頻率去下發信息,那么兩次下發之間的空白怎么填補呢?虛幻設計了兩種同步的模式:

Simulated_Proxy是標準模式,用最后的速度和位置去移動物體.(使用最后的速度只是一種算法,你也可以實施自己的算法)

Autonomous_Proxy基本上只會用于被PlayerController 所Possess的對象(那就是被Possess的Pawn啦),那么在空白期間就直接用用戶的操作來填補。

看到這里,我們需要明確兩點:

  • Autonomous_Proxy就是Pawn(當然說的是被Possess的)在本客戶端的Role——目前我能想到僅有這一種情況。它的RemoteRole——也就是在服務端的Role是Authority,它在其他客戶端的Role是Simulated_Proxy。
  • 而任何非Pawn的Actor,在服務端的Role都是Authority,他們的RemoteRole都是SimulatedProxy。

在C++中可以使用Role==XXX來判斷一個Pawn的Role,但是在藍圖中我們可能需要分兩步來進行:首先判斷是否has authority,如果是,則是服務端,如果否,還要繼續判斷pawn是否isLocallyControlled,如果是,則是Autonomous_Proxy,如果否則是Simulated_Proxy。

IV. Actor Role和Ownership的關系

很重要的一點, Actor Role 和 Ownership沒有任何關系 ,是不同的概念。

只是很巧合,Autonomous_Proxy肯定會被Own,但不能說被Own了就一定是Autonomous_Proxy,例如我們可以對一個非Pawn的Actor 設置所有者(Set Owner),但是它的Actor Role沒有改變。

V. RPC

  • RPC本質是用來調用在 另外一個游戲實例上的函數的
  • RPC無法獲取返回值 ,這就是為為什么沒辦法把藍圖中的Function設置為RPC的原因,因為Function是可以帶返回值的。而CustomEvent是沒法設置返回值的,所以RPC只能標記在CustomEvent上。
  • RPC分三種,Run on Server,Run on owning Client,NetMulticast
  • RPC必須在Actor或者其子類上調用
  • Actor必須是Replicated的(否則不存在RPC一說)

1. Run on Server

  表示在Actor的服務端實例上執行。

  如果RPC是從客戶端調用,讓其在服務端執行,客戶端必須 Own(擁有) 這個Actor。

2. Run on owning Client

表示在Actor的Owner上執行。

如果RPC是從服務端調用,讓其在客戶端執行,只有 Own(擁有) 這個Actor的客戶端才會執行。

注意Run on Server和 Run on owning Client的條件:客戶端必須Own這個Actor,也就是 這個Actor必須有Ownership

3. NetMulticast

表示在Actor的所有實例上執行。

如前所述,前兩種RPC模式都要求Actor必須有Ownership。 Multicast是個例外,它不需要OwnerShip

如果從服務端調用,服務端會本地執行,所有目前連接的客戶端也都會執行。

如果從客戶端端執行,則只會本地執行,服務端不會執行,其他客戶端也不會執行。

?

轉載于:https://www.cnblogs.com/AnKen/p/8602233.html

總結

以上是生活随笔為你收集整理的Replicate(网络复制),ActorRole(角色),Ownership(所有权)以及RPC(远程调用)等等...的全部內容,希望文章能夠幫你解決所遇到的問題。

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