周末学习了下HybridCLR的原理和用法做了个FlyBrid小demo。记录一下
官网里写的原理:
对于这个我的理解是:
Unity引擎的代码使用还是AOT方式。对于项目业务这块打成多个程序集。运行时使用了解释器,解释执行。从而完成热更新。
一。环境安装
工作安装HyBridClr包如图
工程改成IL2CPP模式(如果报错,安装Unity对应平台的IL2CPP包)
点击多出来的菜单中的HyBrid的Install按钮进行环境安装。
二。Demo制作
看作者所说,这个工具如果是Prefab上挂脚本的方式,需要打成AssetBundle方式或者是项目运行时动态加载才能起到效果。这里我就使用第一种方式。
项目写的比较简单就贴一点关键代码吧:
游戏管理类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public enum GameState
{Start = 0,Begin = 1,Playing = 2,End = 3,
}
public class EntryManager :MonoBehaviour
{public GameObject m_StartBtn;public GameObject m_TryBtn;public GameObject m_SceneBg1;public SceneManager m_SceneBg2;public Bird m_BirdGo;public Text m_ScoreText;public GameState m_State = GameState.Start;private int m_Score = 0;private static EntryManager m_Instance;public static EntryManager Instance{get{return m_Instance;}}public void Start(){m_Instance = this;ToolHelper.SetClicked(m_StartBtn,OnStartClicked);ToolHelper.SetClicked(m_TryBtn,OnStartClicked);}public void GameInit(){}public void AddScore(){m_Score = m_Score + 5;m_ScoreText.text = m_Score.ToString();}public void OnStartClicked(){m_Score = 0;m_ScoreText.text = "0";m_ScoreText.gameObject.SetActive(true);BeginStart();}public void BeginStart(){m_BirdGo.BeginGame();m_StartBtn.gameObject.SetActive(false);m_TryBtn.gameObject.SetActive(false);m_SceneBg2.gameObject.SetActive(true);m_SceneBg2.BeginPlay();m_SceneBg1.SetActive(false);m_State = GameState.Playing;}public void GameOver(){Debug.Log("GameOver");m_State = GameState.End;//m_ScoreText.gameObject.SetActive(false);m_TryBtn.gameObject.SetActive(true);m_SceneBg2.gameObject.SetActive(false);m_SceneBg1.SetActive(true);}}
飞鸟类:
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Bird : MonoBehaviour
{public Rigidbody2D m_RigidBody;public Image m_Sprite;public int m_Index = 0;public List<Sprite> m_Sprite1;public List<Sprite> m_Sprite2;private List<Sprite> m_CurrentSprite;public int m_Frame = 0;public float m_CurSpeed;public float m_DownAdSpeed;public float m_UpAdSpeed;public void Awake(){m_CurrentSprite = m_Sprite1;}public void BeginGame(){transform.localPosition = Vector3.zero;m_CurSpeed = 0;}public void FixedUpdate(){++m_Frame;if (m_Frame >= 5){m_Frame = 0;m_Index = ++m_Index % m_CurrentSprite.Count;m_Sprite.sprite = m_CurrentSprite[m_Index];}if (transform.localPosition.y >= 520 || transform.localPosition.y <= -400){EntryManager.Instance.GameOver();}if (EntryManager.Instance == null)return;if (EntryManager.Instance.m_State == GameState.Playing){m_CurSpeed -= m_DownAdSpeed;if (m_CurSpeed < -6.5f){m_CurSpeed = -6.5f;}transform.localPosition += Vector3.up * m_CurSpeed;}}public void Update(){if (EntryManager.Instance == null)return;if (EntryManager.Instance.m_State == GameState.Playing){if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0)){m_CurSpeed = m_UpAdSpeed;}}}public void SetBirdImg(int index){if (index == 0){m_CurrentSprite = m_Sprite1;}else{m_CurrentSprite = m_Sprite2;}}
}
场景管理类:
using System.Collections;
using System.Collections.Generic;
//using System.Numerics;
using UnityEngine;public class SceneManager : MonoBehaviour
{public SingleScene m_Bg1;public SingleScene m_Bg2;public SingleScene m_Bg3;public float m_ScollSpeed = 10;//private bool m_IsFirstPass = false;public float m_LeftBorad = -750;public void BeginPlay(){//m_IsFirstPass = false;m_Bg1.transform.localPosition = Vector3.zero;m_Bg2.transform.localPosition = new Vector3(750,0,0);m_Bg3.transform.localPosition = new Vector3(1500,0,0);gameObject.SetActive(true);m_Bg1.ChangeScene();m_Bg1.ShowGuanzi(false);m_Bg2.ChangeScene();m_Bg3.ChangeScene();}// Update is called once per framevoid FixedUpdate(){if (EntryManager.Instance == null)return;if (EntryManager.Instance.m_State == GameState.Playing){float moveDis = m_ScollSpeed;MoveSingleScene(m_Bg1, moveDis);MoveSingleScene(m_Bg2, moveDis);MoveSingleScene(m_Bg3, moveDis);}}private void MoveSingleScene(SingleScene scene,float dis){scene.m_Tf.anchoredPosition += dis * Vector2.left;if (scene.m_Tf.anchoredPosition.x <= m_LeftBorad){//Debug.Log("Move:" + time);scene.m_Tf.anchoredPosition = new Vector2(1500, 0);scene.ChangeScene();if(scene == m_Bg1)m_Bg1.ShowGuanzi(true);}}
}
这些类一定是要放在一个程序集里进行执行,因为后来是要对程序集进行打包
三。打包Dll
点击菜单:
在对应目录下会生成Dll文件
加个后缀.bytes
放进工程的StreamAsset文件夹下,并且把之前做的入口管理Prefab打成AssetBundle也放进去。
修改官方demo中的loaddll代码。
如图:
最后build测试:
比较顺利,没什么问题。
总结下来:
在整个Demo开发的时候确实没有什么非要注意的潜规则,确实如作者所说几乎0成本接入。后续等如果有机会运用到项目中再说。