需求

近有一个需求是在pun2联网项目中结合纯lua实现项目热更新(这里使用的是xlua),起初在NetworkMgr框架搭建,房间搭建等非游戏操作逻辑中使用纯lua开发一切正常,没有发现什么问题。但是进入游戏角色逻辑开发时,就遇到了难题,众所周知,pun2中有一个很好用的attribute,叫做[PunRpc]。
具体可看官方文档:PunRpc标签官方描述
但是lua中貌似并不支持给lua方法添加Attribute,既然官方不支持,网上也几乎没有看到有人使用pun2结合xlua开发的,那我们只能选择自力更生,曲线救国的方式了。

初次尝试

我这里想到的方法一开始是使用委托结合事件中心的方式去实现,但是报了一个错误**(LuaException: c# exception:Exception has been thrown by the target of an…)**
经过百度,谷歌,必应的搜索,都没有解决,也许是我使用方式不对,其中还发现了一篇文章,可以在C#中不用频繁添加PunRpc标签,有兴趣的可以跳转去看:使用委托调用PunRpc

第二种方法

于是我想到了官方例子中的第二个例子,在Lua中实现UnityMono,这里解释一下大概的原理就是在Lua中注册委托,再让C#继承Mono的脚本调用改委托
详情可以到官方例子中名为《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();// 为每个脚本设置一个独立的环境,可一定程度上防止脚本间全局变量、函数冲突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,我也是刚学xlua没多久的小白,写的有点繁琐,也请大家指证和优化。

using Photon.Pun;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;public class LuaBehaviourPun : MonoBehaviourPun
{
//由于改造LuaBehaviour不是重点,且篇幅太长,这里省略其他实现代码,如果需要可以私聊我
.......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]属性,再使用另外一个方法调用photonView上的Rpc方法去调用我们自定义的Rpc方法,这部分是C#中的逻辑,而在lua中则直接为punRpcAction添加委托事件即可。
lua中的业务逻辑为:

--通过键名区分要调用什么方法,这里的例子是显示或隐藏武器
--注册RpcAction,编写委托内逻辑self:SetRpcAction(function(key)if key=="ShowWeapon" thenlocal go=self.transform:GetChild(0).gameObjectgo:SetActive(not go.activeSelf)endend)
--调用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)

最后效果,完美实现两边武器的显隐同步,正确接收房主和玩家的Rpc请求。
实现了需求,但是肯定有正确的方法实现该功能,只是由于我还够了解Lua工作流程,没有想到方便快捷的方法。

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

  1. android:使用small一步步实现插件化与热更新

    由于插件化开发与热更新最近貌似越来越火,新开的项目准备也使用插件化进行开发!其中遇到不少坑,在这里写了一个小的例子,记录一下开发流程,有助于自己,同时希望能够帮助大家理解,并且对于自身项目接入插件化有 ...

  2. xLua热更新(二)实现热更新

    一.环境配置 要实现热更新功能,我们首先需要开启热更新的宏.操作方法是在「File->Build Settings->Player Settings->Player->Othe ...

  3. xLua热更新(一)xLua基本使用

    一.什么是xLua xLua为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用. xLua是用来实现Lua代码与C#代码相互调 ...

  4. XLua热更新入门教程

    导航 什么是XLua XLua与其他热更新方案比优势 XLua热更新流程 教程环境 安装过程 开始写代码 补充说明 什么是XLua XLua是腾讯开源的一款Unity热更新插件 XLua与其他热更新方 ...

  5. XLua热更新框架学习(二)

    欢迎加入Unity业内qq交流群:956187480 qq扫描二维码加群 原工程地址:https://download.csdn.net/download/qq_37310110/11812518 之 ...

  6. XLua热更新框架学习(一)

    欢迎加入Unity业内qq交流群:956187480 qq扫描二维码加群 Xlua源码地址:https://github.com/Tencent/xLua Xlua热更其实是补丁式的热更,跟其他的方式 ...

  7. android热更新插件,与Android热更新方案Amigo的再次接触

    Amigo 作为一个"过气"的的热修复框架,用来学习和了解一下热修复的基本原理还是很好的.本文是本系列的第三篇. 前两篇: 与Android 热更新方案Amigo的初次接触 原作者 ...

  8. ideadebug热更新_Spring Boot 在IDEA中debug时的hot deployment(热部署)

    因为Spring Boot的项目一般会打包成jar发布, 在开发阶段debug时, 不能像传统的web项目那样, 选择exploded resources进行debug, 也没有热更新按钮, 如果每次 ...

  9. 关于APP热更新,一个降本增效的好方法

    热更新是一种App软件开发者常用的更新方式.简单来说,就是在用户下载安装App之后,打开App时遇到的即时更新.这样的更新方法不仅利于开发者方的降本增效,而且对于用户方的体验也非常友好.下面我们就来详 ...

  10. Unity的学习笔记(XLua的初学用法并在lua中使用unity周期函数)

    自己最近也在研究怎么用lua控制UI,然后看着网上介绍,决定选用XLua,毕竟TX爸爸出的,有人维护,自己琢磨着怎么用,于是弄出来一个能用的作为记录. 当然,XLua主要是用于热更新,我自己是拿来尝试 ...

最新文章

  1. Linux文件系统2---VFS的四个主要对象
  2. matlab 数组元素连乘积prod
  3. cadence原理图封装pin名称重复_原理图设计篇|单片机设计项目实例分享
  4. 全网最具深度的三次握手、四次挥手讲解,稳进大厂
  5. 基于继承类的属性模版中无法绑定的原因和解决方法
  6. linux 扩展zhu分区,Linux分区调整(LVM和非LVM环境中扩容和缩小)
  7. Python与MySQL数据库连接
  8. string类的erase函数属于stl吗_探索STL容器:vector
  9. bzoj 1072: [SCOI2007]排列perm(状压dp)
  10. 数据结构与算法之美-字符串匹配(上)
  11. js让网页标题闪动效果(记)
  12. mt2503 用Dct tool打开codegen.dws提示版本 不match
  13. 初次联系导师短信模板_申博经验分享|如何联系导师?
  14. 小程序怎么接入机器人客服系统
  15. idv和vdi的优劣势_VDI和IDV两种桌面虚拟化的方案对比
  16. 计算机教程文档,计算机应用基础教程-20210323002444.doc-原创力文档
  17. python基础学习与应用
  18. python以图搜图_以图搜图(一):Python实现dHash算法(转)
  19. 换个姿势「模拟登录」
  20. 某大型合资企业审批系统上线经验教训总结

热门文章

  1. java实现 猜数字游戏
  2. 由连连看游戏作弊器想到的
  3. 【面试必过系列,15个经典面试问题及回答思路
  4. 如何在android lolipop中开启google now
  5. 简单教会按关键字搜索商品
  6. 我的世界java版的名字是独一无二吗_2018独一无二霸气网名,二字网名超拽霸气冷酷...
  7. 智能家居加速落地,景联文科技提供数据采集标注服务
  8. [数学 FFT] Codechef July Challenge 2017 #APRPS Irrational Root
  9. 微信网页授权(OAuth2.0) PHP 源码简单实现
  10. 借助Mendix打造敏捷开发和移动端应用的数字化维修服务平台