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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Pun2插件结合Xlua热更新开发 一、在lua中自定义PunRpc方法

發(fā)布時間:2023/12/18 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Pun2插件结合Xlua热更新开发 一、在lua中自定义PunRpc方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

需求

近有一個需求是在pun2聯(lián)網(wǎng)項目中結(jié)合純lua實現(xiàn)項目熱更新(這里使用的是xlua),起初在NetworkMgr框架搭建,房間搭建等非游戲操作邏輯中使用純lua開發(fā)一切正常,沒有發(fā)現(xiàn)什么問題。但是進入游戲角色邏輯開發(fā)時,就遇到了難題,眾所周知,pun2中有一個很好用的attribute,叫做[PunRpc]。
具體可看官方文檔:PunRpc標(biāo)簽官方描述
但是lua中貌似并不支持給lua方法添加Attribute,既然官方不支持,網(wǎng)上也幾乎沒有看到有人使用pun2結(jié)合xlua開發(fā)的,那我們只能選擇自力更生,曲線救國的方式了。

初次嘗試

我這里想到的方法一開始是使用委托結(jié)合事件中心的方式去實現(xiàn),但是報了一個錯誤**(LuaException: c# exception:Exception has been thrown by the target of an…)**
經(jīng)過百度,谷歌,必應(yīng)的搜索,都沒有解決,也許是我使用方式不對,其中還發(fā)現(xiàn)了一篇文章,可以在C#中不用頻繁添加PunRpc標(biāo)簽,有興趣的可以跳轉(zhuǎn)去看:使用委托調(diào)用PunRpc

第二種方法

于是我想到了官方例子中的第二個例子,在Lua中實現(xiàn)UnityMono,這里解釋一下大概的原理就是在Lua中注冊委托,再讓C#繼承Mono的腳本調(diào)用改委托
詳情可以到官方例子中名為《02_U3DScripting》的文件夾去看。

代碼詳情:

using UnityEngine; using System.Collections; using System.Collections.Generic; using XLua; using System;namespace XLuaTest {[System.Serializable]public class Injection{public string name;public GameObject value;}[LuaCallCSharp]public class LuaBehaviour : MonoBehaviour{public TextAsset luaScript;public Injection[] injections;internal static LuaEnv luaEnv = new LuaEnv(); //all lua behaviour shared one luaenv only!internal static float lastGCTime = 0;internal const float GCInterval = 1;//1 second private Action luaStart;private Action luaUpdate;private Action luaOnDestroy;private LuaTable scriptEnv;void Awake(){scriptEnv = luaEnv.NewTable();// 為每個腳本設(shè)置一個獨立的環(huán)境,可一定程度上防止腳本間全局變量、函數(shù)沖突LuaTable meta = luaEnv.NewTable();meta.Set("__index", luaEnv.Global);scriptEnv.SetMetaTable(meta);meta.Dispose();scriptEnv.Set("self", this);foreach (var injection in injections){scriptEnv.Set(injection.name, injection.value);}luaEnv.DoString(luaScript.text, "LuaTestScript", scriptEnv);Action luaAwake = scriptEnv.Get<Action>("awake");scriptEnv.Get("start", out luaStart);scriptEnv.Get("update", out luaUpdate);scriptEnv.Get("ondestroy", out luaOnDestroy);if (luaAwake != null){luaAwake();}}// Use this for initializationvoid Start(){if (luaStart != null){luaStart();}}// Update is called once per framevoid Update(){if (luaUpdate != null){luaUpdate();}if (Time.time - LuaBehaviour.lastGCTime > GCInterval){luaEnv.Tick();LuaBehaviour.lastGCTime = Time.time;}}void OnDestroy(){if (luaOnDestroy != null){luaOnDestroy();}luaOnDestroy = null;luaUpdate = null;luaStart = null;scriptEnv.Dispose();injections = null;}} }

理論可行,開始實踐

首先既然是Photon項目,那么游戲角色的腳本肯定是要繼承MonoBehaviourPun這個類的,于是仿照LuaBehaviour這個類,改造成LuaBehaviourPun,我也是剛學(xué)xlua沒多久的小白,寫的有點繁瑣,也請大家指證和優(yōu)化。

using Photon.Pun; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua;public class LuaBehaviourPun : MonoBehaviourPun { //由于改造LuaBehaviour不是重點,且篇幅太長,這里省略其他實現(xiàn)代碼,如果需要可以私聊我 .......public Action<string> punRpcAction;public void SetRpcAction(Action<string> action) => punRpcAction = action;public void ExecuteRpc(string key){this.photonView.RPC("RpcAction", RpcTarget.All, key);}[PunRPC]public void RpcAction(string key){punRpcAction?.Invoke(key);} ....... }

重點其實就是一個Action變量punRpcAction,一個注冊委托方法SetRpcAction,以及最后兩個方法,一個方法加上[PunRPC]屬性,再使用另外一個方法調(diào)用photonView上的Rpc方法去調(diào)用我們自定義的Rpc方法,這部分是C#中的邏輯,而在lua中則直接為punRpcAction添加委托事件即可。
lua中的業(yè)務(wù)邏輯為:

--通過鍵名區(qū)分要調(diào)用什么方法,這里的例子是顯示或隱藏武器 --注冊RpcAction,編寫委托內(nèi)邏輯self:SetRpcAction(function(key)if key=="ShowWeapon" thenlocal go=self.transform:GetChild(0).gameObjectgo:SetActive(not go.activeSelf)endend) --調(diào)用Rpc方法,重點為Input.GetKeyDown下的邏輯self:SetAction("update",function()if self.photonView.IsMine and PhotonNetwork.IsConnected thenself.transform:Rotate(Vector3.up*Input.GetAxis("Horizontal")*Time.deltaTime*50)if Input.GetKeyDown(KeyCode.Space) thenself:ExecuteRpc("ShowWeapon")endendend)

最后效果,完美實現(xiàn)兩邊武器的顯隱同步,正確接收房主和玩家的Rpc請求。
實現(xiàn)了需求,但是肯定有正確的方法實現(xiàn)該功能,只是由于我還夠了解Lua工作流程,沒有想到方便快捷的方法。

總結(jié)

以上是生活随笔為你收集整理的Pun2插件结合Xlua热更新开发 一、在lua中自定义PunRpc方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。