2013-12-16 16:59:06 kakashi8841 阅读数 31538
  • Unity3D移动实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22591 人正在学习 去看看 姜雪伟

前几天有位网友问我关于Unity3D里面使用Protobuf的方法,一时有事拖到现在才写这篇文章,不好意思哈。

本文测试环境:

系统:WINDOWS 7(第3、6步)、OS X 10.9(第4步)

软件:VS 2012(第3、6步)、Eclipse(第5、6步)

硬件:iPad 2(第4步)、Macbook Pro Mid 2012(第4步)


文章目录:

1、关于Protobuf的C#实现

2、为什么有些Protobuf发布到iOS就用不了,甚至有些在PC都用不了?

3、手动处理C#版本的Protobuf

    3.1、创建一个C#工程,先手动创建每一个要通过Protobuf序列化或反序列化的数据模型类,然后导出dll

    3.2、创建一个用于序列化的C#工程,然后运行生成dll

    3.3、将上面两个工程生成的dll拖到unity中

4、在Unity中反序列化Protobuf

5、服务端Java也用Protobuf

6、太烦了?!客户端也要自动处理Protobuf


1、关于Protobuf的C#实现

首先,U3D里面Protobuf使用的是C#的实现,那么目前有几个可选的C#实现:

C#: http://code.google.com/p/protobuf-csharp-port
C#: http://code.google.com/p/protosharp/
C#: https://silentorbit.com/protobuf/
C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/


我这里选用的是http://code.google.com/p/protobuf-net/(你可以在https://code.google.com/p/protobuf-net/downloads/list 这里下载到他的代码和工具),它比较好的一点是,提供了各种平台的支持,解压后在“Full”目录中可以看到各个平台的支持。(现在google被各种封杀,如果你打不开上面的地址,可以下载我上传到CSDN的,里面的csharp文件夹就是各个平台的protobuf需要的dll,点击下载protobuf-net)。


看到里面的unity了吗,它里面的protobuf-net.dll将是我们准备用到的。


2、为什么有些Protobuf发布到iOS就用不了,甚至有些在PC都用不了?

a、Protobuf使用了JIT,即在运行时动态编译,而这个特性在Unity发布到iOS时候是不支持的。因此,会导致你在PC上可以正常运行,发布到iOS就有问题。

b、Protobuf是基于.net 2.0以上框架写的,而Unity仅支持.net 2.0,或者有些使用2.0中比较多的特性,而你在Unity中发布设置了.net 2.0的子集。后者你只需要在Player setting中修改设置就可以了。

上面两项也可适用于其它第三方类库,如果你自己下载了一个在PC上或C#里面能正常使用的类库,在U3D里面就不能用了,那么请检查是否是上面两条原因导致的。


3、手动处理C#版本的Protobuf

知道了上面问题,我们只要选一个.net2.0的Protobuf,然后它又不是JIT,那就可以正常使用了。

这里用的思路是:

    3.1、创建一个C#工程,先手动创建每一个要通过Protobuf序列化或反序列化的数据模型类,然后导出dll

        以VS为例,首先,创建一个类库工程:“文件”>"新建">"项目">"类库"(记得选择 .net framework 2.0)


将unity的protobuf的dll添加到项目引用


然后假设你有一个类WorkerInfo是需要通过Protobuf进行序列化和反序列化的,那么创建一个WorkerInfo类,内容如下:

using System;
using System.Collections.Generic;
using System.Text;
using ProtoBuf;
namespace Com.YourCompany.Project.Proto.Module{
    [ProtoContract]
    public class WorkerInfo { 


        [ProtoMember(1)]
        public int workerId;


        [ProtoMember(2)]
        public int leftClosingTimeSec;


        [ProtoMember(3)]
        public int buildingId;


    }
}
按下Shift+F6生成dll,在项目的bin\Debug目录下就可以找到ProtoModelDLL.dll了


    3.2、创建一个用于序列化的C#工程,然后运行生成dll
        也是以VS为例,首先创建一个控制台应用程序:“文件”>"新建">"项目">"控制台应用程序"(记得选择 .net framework 2.0)


将Protobuf和3.1生成的dll添加到引用


在项目生成的Program.cs中写入:

using System;
using System.Collections.Generic;
using System.Text;
using ProtoBuf.Meta;
using ProtoBuf;
using ProtoBuf.Compiler;
using Com.YourCompany.Project.Proto.Module;


namespace ProtoModelSerializerCreator
{
    class Program
    {
        static void Main(string[] args)
        {
            var model = TypeModel.Create();

            model.Add(typeof(object), true);
            model.Add(typeof(WorkerInfo), true);

            model.AllowParseableTypes = true;
            model.AutoAddMissingTypes = true;
            model.Compile("ProtoModelSerializer", "ProtoModelSerializer.dll");
        }
    }
}

然后ctrl+F5运行,这时候你就可以在bin\Debug中看到ProtoModelSerializer.dll。

    3.3、将上面两个工程生成的dll(ProtoModelDLL.dll和ProtoModelSerializer.dll)以及protobuf-net.dll拖到unity中

        怎么用?看第4步

4、在Unity中反序列化Protobuf

由于一般游戏客户端请求的数据量比较简单,也比较少,因此我们前端请求是不直接二进制请求。而前端收到后端返回才采用了Protobuf,因此。这里只讨论Protobuf的反序列化。

代码很简单,下面写个测试代码:

using UnityEngine;
using System.Collections;
using ProtoBuf.Meta;
using Com.YourCompany.Project.Proto.Module;
using System.IO;
using Com.Duoyu001.Proto.Building;
using Com.Duoyu001.Proto.Worker;

public class TestProto : MonoBehaviour
{

	// init
	void Start ()
	{
		byte[] dataFromServ = new byte[]{8, 233, 7, 16, 100, 24, 1};	//these bytes are generated by server
		
		RuntimeTypeModel serializer = ProtoModelSerializer.Create ();
		System.IO.MemoryStream memStream = new System.IO.MemoryStream ();
		WorkerInfo w = new WorkerInfo ();
		serializer.Deserialize (memStream, w, w.GetType ());	//asign value to proto model
		
		Debug.Log (w.workerId + ", " + w.buildingId + ", " + w.leftClosingTimeSec);
	}
}

运行后Unity控制台输出了worker的信息。代码中的dataFromServ字节数组的内容实际应该是通信时候后端返回的。这里测试就不涉及Socket通信的知识了。

5、服务端Java也用Protobuf

看到一个客户端用Protobuf这么麻烦,那后端会怎样呢?其实后端是比较简单的,有Google官方的支持。

下载:https://code.google.com/p/protobuf/downloads/list

下完解压是这样的(2.5.0):


进入“protobuf-2.5.0\java”文件夹,里面是一个maven项目,你直接用maven clean install在target目录就会生成一个protobuf-java-2.5.0.jar的jar包了,没maven的在这里下载吧,我用maven生成的http://download.csdn.net/detail/kakashi8841/6723689。这个要时候导入你的Java项目。就可以了。

然后你写一个proto文件,调用“protobuf-2.5.0\src”里面的protoc.exe进行生成,它会帮你生成一个java文件。(详细看https://developers.google.com/protocol-buffers/docs/javatutorial),我这里有提供一个bat,用于调用protoc来生成java文件的,手动输入的话太麻烦了。在windows下把它保存到.bat然后双击运行就可以了。

@echo off
echo ** setting runtime variable

REM _protoSrc 是你的proto文件目录的位置
set _protoSrc=F:\project_proto_src\trunk\xgame-controllers\protos

REM protoExe 是用于从proto生成java的protoc.exe程序的位置
set protoExe=C:\Users\john\Desktop\protobuf-2.5.0\src\protoc.exe

REM java_out_file 存放生成的Java文件目录的位置
set java_out_file=F:\project_proto_src\trunk\xgame-controllers\src\main\java\

for /R "%_protoSrc%" %%i in (*) do ( 
	set filename=%%~nxi 
	if "%%~xi"  == ".proto" (
		%protoExe% --proto_path=%_protoSrc% --java_out=%java_out_file% %%i
	)
)

OK啦,这样你只要把生成的Java复制到或直接生成到你的Java项目源码目录中,然后就可以使用了。比如:
以前面说的WorkerInfo为例

package com.duoyu001.xgame;

import java.util.Arrays;

import com.duoyu001.xgame.worker.proto.WorkerInfoBuilder.WorkerInfo;

public class TestProto {

	public static void main(String[] args) {
		WorkerInfo w = WorkerInfo.newBuilder().setBuildingId(1)
				.setLeftClosingTimeSec(100).setWorkerId(1001).build();
		byte[] byteArray = w.toByteArray();
		System.out.println(Arrays.toString(byteArray));
	}
}

控制台就会输出:

细心的同学会发现这里的字节和上面的“8, 233, 7, 16, 100, 24, 1”有点不太一样。第二个数字分别为-23和233.

其实,这个只是byte的有无符号的表示差异而已。

他们的二进制表示都是:11101001


6、太烦了?!客户端也要自动处理Protobuf

我们看到客户端没加一个类,都需要在两个VS项目中增加代码,而后端是直接根据proto文件生成代码的。这样,好像有点不公平,而且这样前后端还是可能会写出不一样的结构。其实用protobuf我个人觉得最大的好处:

    a、数据量小

    b、通过proto模板生成代码,减少前后端联调

但是现在只是后端减少了工作,前端并没有减少,因此第二个好处不是很明显。

那好吧。我没有就这样满足。因此,我决定,前端也要根据proto来生成cs文件。

因此,我使用Java编写了一个解析Proto文件的工具,并且根据proto生成cs文件,然后用bat调用vs的命令行执行vs项目的构建,最后生成两个dll。

我把上面的命令都整合到一个bat中,因此这个bat的任务是:

执行java程序,把proto文件生成cs文件。

调用vs接口构建两个vs项目,生成两个dll。

通过svn把这两个dll提交到客户端的主干上。

调用上面根据proto生成java的bat片段,生成java代码。

通过svn把生成的java代码提交到服务端主干上。

因此,这样一来,现在只要编写好proto文件,然后双击bat,前后端就都可以通过更新svn来获取最新的Protobuf数据对象。


bat运行


根据proto生成cs文件并编译执行两个vs项目,然后把生成的dll提交到svn上


生成java代码并提交svn

这一步相关操作大家有兴趣可以自行试试,有问题欢迎在本博客讨论。

2014-01-07 00:16:10 mynewdays 阅读数 18575
  • Unity3D移动实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22591 人正在学习 去看看 姜雪伟

unity3d是一个跨平台的游戏开发引擎,可以使用c#开发各种平台上的游戏,如windows,Mac,Android,windows phone,IOS,Flash等。下面说下如何将开发好的unity3d游戏发布到Android手机上

1.安装unity3d

这是官网下载地址,这里能下载到最新版本的unity3d:http://unity3d.com/unity/download,安装的话一路默认就行

2.安装java sdk和Android sdk

unity3d中使用c#编写的代码如何才能在android手机上运行呢,答案是压根就不能运行,unity3d通过mono框架将c#代码转换成Android代码,所以若想发布Android程序,就需要安装Android sdk,而Android又是基于java运行环境的,所以也需要安装java sdk,下面附上下载地址。java sdk:http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u2-download-1377129.html;Android sdk下载地址:http://developer.android.com/sdk/index.html

java sdk的安装一路默认就好,默认路径为C:\Program Files (x86)\Java。

Androi sdk下载完毕后,解压,然后运行SDK Manager.exe,在弹出的界面中勾选需要的内容,如下图所示


其中最重要的是Android的版本,这里列出了很多版本,有些文章说,不能单独选择一个4.0以上的版本(不包括4.0),否则发布的时候会报错,但是通过实验,只勾选Android 4.4.2(API19),然后安装也能够成功发布到手机上。

勾选万选项后,然后点击安装,接下来就是等待的时间了。

3.发布

安装完毕之后,打开unity3d

1)配置发布时的Android sdk目录,在菜单中选择Edit---Preferences...,在弹出的对话框中选择“External Tools”,在最下面的“Android sdk location”中选择你的路径,其实就是你下载的Android sdk压缩包解压之后的sdk文件夹的路径,如下图


2)配置完毕之后,在菜单中选择“File----Build Settings”,弹出如下图窗体,在左边选择Android,然后在右边选择“Build and run”或者“Build”,弹出对话框用来选择发布的位置和程序名称,设置之后,开始发布。

3)在发布过程中可能会报如下错误


这是因为Build Identifier的名称不是唯一的,不能使用默认的,在右边这是因为Build Identifier的名称不是唯一的,不能使用默认的,修改方法是在发布窗口点击“play settings”,然后设置Build Indentifier属性的值为"com.aaa.bbb"这种格式的,总之不能使用默认的就好了。




2018-10-22 13:09:48 VR851130674 阅读数 1541
  • Unity3D移动实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22591 人正在学习 去看看 姜雪伟

关于Unity发布PC端,程序运行充满整个屏幕并带有窗口任务栏


一:简单介绍

1,用Unity打包发布PC程序,有时候不充满整个屏幕,感觉效果不好,需要在打开程序时,窗口是充满整个屏幕的,且有窗口任务栏,简单来说,就是窗口最大化
先看效果图
在这里插入图片描述


二:一个脚本解决问题

把下面这个脚本挂在一个新建的场景空物体上,运行就可以看到想要的效果了
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
public class WindowMaxAndMin : MonoBehaviour
{
[DllImport(“user32.dll”)]
public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

const int SW_SHOWMINIMIZED = 2; //{最小化, 激活}
const int SW_SHOWMAXIMIZED = 3;//最大化
const int SW_SHOWRESTORE = 1;//还原
public void OnClickMinimize()
{ //最小化 
    ShowWindow(GetForegroundWindow(), SW_SHOWMINIMIZED);
}

public void OnClickMaximize()
{
    //最大化
    ShowWindow(GetForegroundWindow(), SW_SHOWMAXIMIZED);
}

public void OnClickRestore()
{
    //还原
    ShowWindow(GetForegroundWindow(), SW_SHOWRESTORE);
}

//测试
public void OnGUI()
{
    if(GUI.Button(new Rect(100,100,200,100),"最大化"))
        OnClickMaximize();
    if (GUI.Button(new Rect(100, 300, 200, 100), "最小化"))
        OnClickMinimize();
    if (GUI.Button(new Rect(100, 500, 200, 100), "窗口还原"))
        OnClickRestore();

}

}
上面有三种效果.根据自己需要选择
单独写的时候一定要把方法写在Star里面,这样打包出来,PC端才会执行


支持

服务器总有一天你会需要,详细的服务器教程尽在 Jacob 博客,点点下方链接,轻松马上学会!
阿里云Esc全解和建站方法--------------------------------------- 服务器建站

2018-12-14 22:46:27 jjjndk1314 阅读数 504
  • Unity3D移动实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22591 人正在学习 去看看 姜雪伟

Android

  1. 配置Java开发环境

  2. 指定AndroidSDK路径
    在这里插入图片描述

  3. 在unity中选择发布平台
    在这里插入图片描述

  4. 选择PlayerSettings… 在这里插入图片描述
    分别设置公司名,游戏名字(与专案名字相同),游戏Logo图案

  5. 在这里插入图片描述 -> 将公司名,游戏名与最上方名字对应上。

  6. Build生成APK格式即可。
    Remote远程调试

  7. 在手机安装Remote

  8. 电脑上安装手机驱动

  9. 注意:调试时将手机中的Remote打开,将Unity重开一次,将手机中的开发人员工具->USB调试连接上

2018-10-16 21:44:40 longroad1216 阅读数 2393
  • Unity3D移动实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22591 人正在学习 去看看 姜雪伟

这两天在研究如何将Unity3d项目发布为html,并将网页发布到服务器上使得外部网络/设备也能进行共享。

总结整个过程需要解决的2个关键问题是:

  1. 如何让移动端设备加载WebGL
  2. 如何构建并部署IIS

下面我结合个人实践和几篇可行的博客来将整个过程梳理一遍:

一、构建一个Unity的WebGL发布版本

首先是在安装unity的时候应该框选WebGL选项,如果在安装时漏了勾选也可以在build setting里找到WebGL模块,然后点击Platform Module Installation安装。

在项目完成后building的时候选择WebGL,直接build即可,完成后会生成一个名为index的html文件,一个Build文件夹,一个TemplateData文件夹。

对于早期版本(如unity5.4.0),build完成后会生成一个Release文件夹、一个TemplateData文件夹。

 

二、删除关键代码段

根据Unity3d的官方文档(目前是2018.9.12修改的版本)中的叙述,一些移动端是不支持WebGL的功能的

就我实验的设备(Samsung GALAXY S9)而言是可以用一些浏览器正常加载WebGL的,不过在加载前需要去掉.js文档中的一个关于移动端的判定。

这篇博文介绍了相关内容,只是因为经过版本更迭,.js文件进行了修改,现在需要删去的语句是Build/UnityLoader.js的770行左右的一个条件语句,即下图中注释掉的语句。

通过的实验,如果不注释掉相关语句,在移动端设备运行网页时将不会加载unity的WebGL模块。

 

三、构建IIS

构建IIS的过程在网上有很多帖子,感兴趣可以进行查阅。

这里我本着比较简洁和准确的原则做了整理,这篇博客的方法很细致,跟着做到输入http://localhost出现IIS欢迎界面即可。

 

四、创建网站并开放

在控制面板中切换成大图标,找到“管理工具”双击,打开Internet Information Services (IIS)管理器。

跟着博客做到第3步完成。注意添加MIME类型的时候要选中的是新建的网站,添加的名字和属性在博客的图片中(unity3d和unityweb那个)。修改完后会发现在项目物理位置下多了一个web.config。

对于早期版本(如unity5.4.0),还要对web.config进行的设置,否则会在加载前报一个头部检查的异常(incorrect header check ),根据unity论坛上的一个回答,设置方法如下:

在web.config文件中相应位置添加如下语句

<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".mem" />
<mimeMap fileExtension=".mem" mimeType="application/octet-stream" />
<remove fileExtension=".data" />
<mimeMap fileExtension=".data" mimeType="application/octet-stream" />
<remove fileExtension=".memgz" />
<mimeMap fileExtension=".memgz" mimeType="application/octet-stream" />
<remove fileExtension=".datagz" />
<mimeMap fileExtension=".datagz" mimeType="application/octet-stream" />
<remove fileExtension=".unity3dgz" />
<mimeMap fileExtension=".unity3dgz" mimeType="application/octet-stream" />
<remove fileExtension=".jsgz" />
<mimeMap fileExtension=".jsgz" mimeType="application/x-javascript; charset=UTF-8" />
</staticContent>
</system.webServer>
</configuration>

 

最后参考这篇文章对服务器进行开放即可。

 

五、运行

完成后用命令行(win+R,输入cmd)查询本机ip(ipconfig/all),最后的网址为:

                                                                   本机ip:开放的端口号

注意在加载时刷新,第一次往往加载较慢。通过实验现在已经可以运行的各种设备上的浏览器如下:

PC端:chrome、firefox

Android:firefox、360、chrome、qq

目前手头的ios设备(mini2、iPhone7P)可以加载但无法运行

 

欢迎交流和指正。

没有更多推荐了,返回首页