1. 程式人生 > >unity dll實現熱更新

unity dll實現熱更新

大家都知道一談起熱更新的話首選是Ulua這個外掛, 其實Unity可以使用dll熱更新的,如果你實在不想用Lua來編寫邏輯,0.0請下看Dll+AssetBundle如何實現熱更新的.讓你看完這個文章之後只是認識DLL熱更新的方式和概念,掌握熱更新的實戰框架還需要你自己=。=

我們通常的做法是編譯成的DLL打成AssetBundle檔案, Unity通過WWW下載AB檔案獲取裡面DLL.通過反射的方式把裡面的C# 元件繫結到GameObject遊戲物體上面,這就是DLL熱更新的原理. 假設專案採用UGUI系統, 我們來看看通過以上思想編寫程式碼時候遇到的核心問題如下.

  1. 我需要如何編寫DLL?
  2. 我的DLL怎麼才能獲取到UnityEngine名稱空間類的引用?
  3. 我的DLL需要如何打成AssetBundle?
  4. 程式下載AssetBundle如何讀取裡面DLL?
  5. 如何把指令碼繫結起來,實現熱更新UI?

一、我需要如何編寫DLL?

首先你需要找到Unity幾個關鍵DLL. UnityEngine.dll,UnityEngine.UI.dll為了你編寫熱更新程式碼有UnityEngine核心類的引用吧.先建立一個C#3.5版本的類庫(點選專案右鍵->屬性->目標框架3.5), 然後引入UnityEngine.dll和UnityEngine.UI.dll的DLL

image

建立完工程之後,我們編寫一個MyClass繼承MonoBehaviour類

image

點選啟動編譯DLL,編譯成的DLL可以在專案右鍵->在檔案資源器中開啟資料夾->Btn目錄->Release和Debug目錄找到MyDll.dll(我的是在Realse目錄下)  我們把編譯好的DLL,拿到Unity裡面去打包成AssetBundle檔案. Unity預設貌似不允許把字尾名DLL打入AssetBundle,我們修改把MyDll.dll改成MyDll.bytes名字

image

把DLL打包成AssetBundle檔案程式碼如下,

複製程式碼
[MenuItem("Assets/Build Android DLL")]
    public static void BuildAssetsAndroidDll()
    {
        Object mainAsset 
= AssetDatabase.LoadMainAssetAtPath("Assets/Dll/MyDLL.bytes"); BuildPipeline.BuildAssetBundle(mainAsset, null, Application.dataPath + "\\Dll\\myassets.android", BuildAssetBundleOptions.None,BuildTarget.Android); if (File.Exists(androidStreamUrl)) { File.Delete(androidStreamUrl); } //拷貝到Stream目錄下方便程式下載AB檔案 File.Copy(Application.dataPath + "\\Dll\\myassets.android", androidStreamUrl); }
複製程式碼

再來看下我們Unity需要做那些操作,就是新建立一個場景新增一個Text文字即可

image

給Android下打包好的AssetBundle檔案,放入StreamAssetBundleAssets, 程式碼會自動幫你複製過去

image

Test核心類

複製程式碼
using UnityEngine;
using System.Collections;
using System.Reflection;
using System;
using System.IO;
using UnityEngine.UI;

public class Test : MonoBehaviour {


    public string url;
    public string str;

    public Text myAgeText;

    public void Awake() 
    {
        Application.logMessageReceived += Application_logMessageReceived;
    }

    void Application_logMessageReceived(string condition, string stackTrace, LogType type)
    {
        str += "\r\n" + condition;
    }

    public void OnGUI() 
    {
        GUI.Box(new Rect(0, 0, 800, 800), str);
    }

    // Use this for initialization
    IEnumerator Start () {
        yield return new WaitForSeconds(2);

        if (Application.platform == RuntimePlatform.WindowsEditor) 
        {
            url = @"file://"+Application.dataPath + "\\Dll\\myassets.windows";
        }else 
        if(Application.platform == RuntimePlatform.Android)
        {
            url = Application.streamingAssetsPath + "/myassets.android";
        }
        else if (Application.platform == RuntimePlatform.IPhonePlayer)
        {
            url = Application.streamingAssetsPath + "/myassets.iphone";
        }

        Debug.Log("url: " +  url);
        WWW www = new WWW(url);

        yield return www;

        if(www.error != null)
        {
            Debug.Log("載入 出錯");
        }

        if(www.isDone)
        {
            Debug.Log("載入完畢");
            AssetBundle ab = www.assetBundle;

            try
            {
                //先把DLL以TextAsset型別取出來,在把bytes給Assembly.Load方法讀取準備進入反射操作
                Assembly aly = System.Reflection.Assembly.Load(((TextAsset)www.assetBundle.mainAsset).bytes);

                //獲取DLL下全部的型別
                foreach (var i in aly.GetTypes())
                {
                    //除錯程式碼
                    Debug.Log(i.Name);
                    str += "\r\n" + i.Name;

                    //新增元件到當前GameObject下面
                    Component c = this.gameObject.AddComponent(i);

                    //然後類名是MyClass,就把文字引用賦值給MyClass.platefaceText屬性.
                    if (i.Name == "MyClass") 
                    {
                        FieldInfo info = c.GetType().GetField("platefaceText");
                        info.SetValue(c, myAgeText);
                    }
                }
            }
            catch (Exception e) 
            {
                Debug.Log("載入DLL出錯");
                Debug.Log(e.Message);
            }
        }
    }
}
複製程式碼

在Windows下檢視效果圖

image

以上只是一個拋磚引玉,希望想使用dll熱更新程式碼的能幫助到你.

相關推薦

unity dll實現更新

大家都知道一談起熱更新的話首選是Ulua這個外掛, 其實Unity可以使用dll熱更新的,如果你實在不想用Lua來編寫邏輯,0.0請下看Dll+AssetBundle如何實現熱更新的.讓你看完這個文章之後只是認識DLL熱更新的方式和概念,掌握熱更新的實戰框架還需要你自己=

Unity 程式碼編譯成dll 更新dll實現更程式碼

Unity 程式碼編譯成dll 更新dll實現熱更程式碼 實現流程 程式碼編譯成DLL DLL打包成AssetBundle 載入AssetBundle 載入程式碼程式集 獲取指定類 使用反射賦值 C#程式碼編譯成DLL 使用VS建立類庫專案 模版-&

Android 手動實現更新

前言 在上篇Android ClassLoader淺析中我們分析了安卓ClassLoader和熱更新的原理,這篇我們在上篇熱更新分析的基礎上寫個簡單的demo實踐一下。 概述 我們先回顧下熱更新的原理 PathClassLoader是安卓中預設的類載入器,載入類是通過fi

Cordova - 實現更新 !

原文: Cordova - 實現熱更新 ! Cordova版本:8.0.0 更新APP平臺:Android 作業系統:Windows Cordova的熱更新,作用是把www內的變動部分更新到APP中,實現主程式不動,完成更新!!這個熱更新功能,對於IOS APP更有意義,因為,可以避免繁瑣的蘋果稽核!

Unity中的更新

1、HelloWorldusing LuaInterface; public class HelloWorld : MonoBehaviour { void Start () { LuaState l = new LuaState(); // 在C#下使

Unity的二進位制更新 (二)unity的執行原理

今天講一下Unity引擎的執行原理。為什麼我們寫繼承了Monobehaviour的c#程式碼會在固定的時候執行Update,FixedUpdate等回撥呢?是什麼在背後驅動著引擎去找到你寫的指令碼並執行的呢? 回答這些問題自然是能看到Unity的程式碼就一目瞭然了,但是un

ReactNative基於CodePush實現更新整合詳解

安裝工具介紹 根據最新的官方文件和實際整合經驗整理 http://www.jianshu.com/p/54cd13ed9e95 工具名稱 描述 備註 Chocolatey Windows上的包管理器(需翻牆) 通常不安裝,使用 npm 即可 Pyth

unity之程式碼更新

1,程式碼熱更新是解決什麼問題的? 縮短使用者取得新客戶端的流程,改善使用者體驗。 沒熱更新: 下載app--》安裝--》啟動--》等待載入--》玩 有熱更新: 啟動--》等待熱更新--》等待載入--

React Native用CodePush實現更新(一)

本文介紹用微軟預設的CodePush Cloud和將code-push-server放在本地伺服器上,以local作為storageType實現熱更新。1. 安裝 CodePush CLI:npm in

Unity的二進位制更新

最近剛剛接觸Unity,發現在iOS上面熱更新出現了很大的限制。在網上查了一圈,大家主要是說是由於受到了iOS系統不允許在可讀記憶體記憶體頁上面執行的限制造成的,這好像跟熱更新並不矛盾。現在大家主要突破這個限制的方法是通過跑Lua虛擬機器,這樣改Lua程式碼就可以熱更新了,

手把手教你實現更新功能,帶你瞭解 Arthas 更新背後的原理

文章來源:https://studyidea.cn/java-hotswap 一、前言 一天下午正在摸魚的時候,測試小姐姐走了過來求助,說是需要改動測試環境 mock 應用。但是這個應用一時半會又找不到原始碼存在何處。但是測試小姐姐的活還是一定要幫,突然想起了 Arthas 可以熱更新應用程式碼,按照

Unity Dll更新

pac all bsp empty component instance oid config 最簡 最簡單的案例代碼,備後需使用 using System.Collections;using System.Collections.Generic;using System.

用ECMAScript4 ( ActionScript3) 實現Unity更新 -- 在腳本中使用MonoBehaviour

blog 腳本 tool urn 技術 build 右鍵 lan www. 繼上次分析了熱更新的Demo後,這次來介紹如何在熱更新代碼中使用MonoBehaviour。 MonoBehaviour掛載到GameObject對象上的腳本的基類。平常Unity開發時,簡單的做法

用ECMAScript4 ( ActionScript3) 實現Unity更新 -- 使用原型鏈和EventTrigger

rip sta untiy poi lib stat package 匿名 對象 原型鏈是JS的必備,作為ECMAScript4,原型鏈也是支持的。 特別說明,ActionScript3是支持完整的面向對象繼承支持的,原型鏈只在某些非常特殊的情況下使用。 本文旨在介紹如何使

用ECMAScript4 ( ActionScript3) 實現Unity更新 -- 使用FairyGUI (二)

src class 測試 資源 isp ola 物體 ddp onclick 上次講解了FairyGUI的最簡單的熱更新辦法,並對其中一個Demo進行了修改並做成了熱更新的方式。 這次我們來一個更加復雜一些的情況:Emoji. FairyGUI的 Example 04

用ECMAScript4 ( ActionScript3) 實現Unity更新 -- 更新Live2D

ini dma public lin img uil edi package module live2D是一個很強大的2D動畫組件。我們可以使用AS3腳本對它進行熱更新。 live2D在Unity中的使用請看這裏: 如何獲取Live2D 總得來說,我們可以先去live

webpack-dev-middleware 和 webpack-hot-middleware 實現express全棧更新

express 自動刷新 你在 fig evm inf targe target ddl 場景: node server.js 啟動後端服務器。 npm run dev 啟動前端服務器。 當你需要node的express框架和webpack結合的時候,就會用到題上的

Unity更新技術整理

nil 支持 -s 運行 ram 創建 color 腳本語言 更改 一、熱更新學習介紹 1、什麽是熱更新 舉例來說: 遊戲上線後,玩家下載第一個版本(70M左右或者更大),在運營的過程中,如果需要更換UI顯示,或者修改遊戲的邏輯,這個時候,如果不使用熱更新,就需要重新打

Unity編程筆錄--ulua+PureMVC框架簡單更新使用

ons data- 全部 lds center lin 腳本 mar 視圖 ulua+PureMVC框架簡單熱更新使用 前言: 1:作者官網論壇 首先介紹的是這個框架是一位大牛 駿擎【CP】 jarjin 寫的,據說原本是“非常多人不知道怎

Unity更新代碼

unity熱更新對資源的更新比較簡單,把資源打包成AB文件,然後放到資源服務器上,客戶端程序啟動時下載AB文件,程序加載AB文件就可以了,但對與C#程序來說如何進行更新呢,可以將C#打包到Dll裏,然後將Dll放到資源服務器上,客戶端下載DLL通過如下代碼加載Dll WWW www = new WWW (UR