Unity3d client and Java service side use Protobuf

Source: Internet
Author: User

Original: http://blog.csdn.net/kakashi8841/article/details/17334493

A few days ago a netizen asked me about Unity3d inside use Protobuf method, a moment something dragged to now just write this article, sorry ha.

This article tests the environment:

System: WINDOWS 7 (3rd, 6 steps), OS X 10.9 (4th step)

Software: VS 2012 (3rd, 6 steps), Eclipse (5th, 6 steps)

Hardware: IPad 2 (4th step), Macbook Pro Mid 2012 (4th Step)

Article directory:

1, about PROTOBUF's C # implementation

2, why some protobuf released to iOS can not be used, and even some in the PC is not used?

3, manual processing C # version of Protobuf

3.1. Create a C # project by manually creating each data model class that you want to serialize or deserialize through PROTOBUF, and then export the DLL

3.2. Create a C # project for serialization and run the build DLL

3.3. Drag the DLLs generated by the above two projects into unity

4. Deserializing Protobuf in Unity

5, the service side Java also uses PROTOBUF

6, too annoying?! The client also has to handle protobuf automatically.

1, about PROTOBUF's C # implementation

First of all, the u3d inside Protobuf uses the C # implementation, so there are several optional C # implementations:

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/

I chose http://code.google.com/p/protobuf-net/here (you can https://code.google.com/p/protobuf-net/downloads/list Here to download to his code and tools), it is better to provide a variety of platform support, extracted in the "full" directory can see the support of each platform. (now Google is a variety of blocked, if you can't open the address above, you can download I upload to csdn, the inside of the CSharp folder is the PROTOBUF needs of each platform DLL, click to download protobuf-net).

See unity inside, and the protobuf-net.dll inside it will be what we're going to use.

2, why some protobuf released to iOS can not be used, and even some in the PC is not used?

A, Protobuf uses JIT, which is dynamically compiled at run time, and this feature is not supported when Unity is released to iOS. As a result, you will be able to run properly on your PC and publish to iOS with problems.

B, Protobuf is written based on the. NET 2.0 framework, and unity only supports. NET 2.0, or some uses more than 2.0 of the features, and you publish a subset of. NET 2.0 in Unity. The latter you just need to modify the settings in the player setting.

The above two can also be applied to other third-party libraries, if you download a PC or C # in the normal use of the library, in the u3d can not be used, then please check whether it is the above two causes.

3, manual processing C # version of Protobuf

Knowing the problem above, we just choose one. net2.0 's protobuf, then it is not JIT, it can be used normally.

The idea here is:

3.1. Create a C # project by manually creating each data model class that you want to serialize or deserialize through PROTOBUF, and then export the DLL

Take vs as an example, first create a class library project: File > New > Project > Class Library (Remember to select the. NET Framework 2.0)

Add Unity's Protobuf DLL to the project reference

Then suppose you have a class workerinfo that needs to be serialized and deserialized through PROTOBUF, then create a Workerinfo class that reads:

[CSharp]View Plaincopy
  1. Using System;
  2. Using System.Collections.Generic;
  3. Using System.Text;
  4. Using Protobuf;
  5. Namespace com.yourcompany.project.proto.module{
  6. [Protocontract]
  7. public class Workerinfo {
  8. [Protomember (1)]
  9. public int Workerid;
  10. [Protomember (2)]
  11. public int leftclosingtimesec;
  12. [Protomember (3)]
  13. public int buildingid;
  14. }
  15. }

Press SHIFT+F6 to generate the DLL, you can find ProtoModelDLL.dll in the project's bin\debug directory

3.2. Create a C # project for serialization and run the build DLL
Also take vs as an example, first create a console application: File > New > Project > Console Application (Remember to select the. NET Framework 2.0)

Add Protobuf and 3.1 generated DLLs to the reference

Write in the Program.cs of the project build:

[CSharp]View Plaincopy
  1. Using System;
  2. Using System.Collections.Generic;
  3. Using System.Text;
  4. Using Protobuf.meta;
  5. Using Protobuf;
  6. Using Protobuf.compiler;
  7. Using Com.YourCompany.Project.Proto.Module;
  8. Namespace Protomodelserializercreator
  9. {
  10. Class Program
  11. {
  12. static void Main (string[] args)
  13. {
  14. var model = Typemodel.create ();
  15. Model.  Add (typeof (object), true);
  16. Model.  Add (typeof (Workerinfo), true);
  17. Model.  Allowparseabletypes = true;
  18. Model.  Autoaddmissingtypes = true;
  19. Model.compile ("Protomodelserializer", "ProtoModelSerializer.dll");
  20. }
  21. }
  22. }


Then Ctrl+f5 run, and you can see ProtoModelSerializer.dll in the bin\debug.

3.3. Drag the DLLs (ProtoModelDLL.dll and ProtoModelSerializer.dll) and Protobuf-net.dll generated by the above two projects into unity

How to use it? Look at the 4th step.

4. Deserializing Protobuf in Unity

Since the amount of data requested by the general game client is relatively simple and relatively small, our front-end request is not a direct binary request. And the front end receives the back end to adopt the PROTOBUF, therefore. Only the deserialization of the PROTOBUF is discussed here.

The code is simple, here's a test code:

[CSharp]View Plaincopy
  1. Using Unityengine;
  2. Using System.Collections;
  3. Using Protobuf.meta;
  4. Using Com.YourCompany.Project.Proto.Module;
  5. Using System.IO;
  6. Using Com.Duoyu001.Proto.Building;
  7. Using Com.Duoyu001.Proto.Worker;
  8. Public class Testproto:monobehaviour
  9. {
  10. //Init
  11. void Start ()
  12. {
  13. byte[] Datafromserv = new byte[]{8, 233, 7, 16, 100, 24, 1}; //these Bytes is generated by server
  14. Runtimetypemodel serializer = Protomodelserializer.create ();
  15. System.IO.MemoryStream Memstream = new System.IO.MemoryStream ();
  16. Workerinfo w = new Workerinfo ();
  17. Serializer.    Deserialize (Memstream, W, W.gettype ()); //asign value to Proto model
  18. Debug.Log (W.workerid + "," + W.buildingid + "," + w.leftclosingtimesec);
  19. }
  20. }

After running the Unity console outputs the worker information. The contents of the Datafromserv byte array in the code should actually be the back end of the communication time. The test here does not involve the knowledge of socket communication.

5, the service side Java also uses PROTOBUF

See a client with Protobuf so much trouble, what about the backend? In fact, the backend is relatively simple, with Google's official support.

Download: https://code.google.com/p/protobuf/downloads/list

After the decompression is like this (2.5.0):

Go to the "Protobuf-2.5.0\java" folder, which is a MAVEN project that you directly use Maven clean Install in the target directory will generate a Protobuf-java-2.5.0.jar jar package, no maven download it here, I use MAVEN generated http://download.csdn.net/detail/ kakashi8841/6723689. This is the time to import your Java project. You can do it.

Then you write a proto file, call "Protobuf-2.5.0\src" inside the protoc.exe to generate, it will help you to generate a Java file. (see https://developers.google.com/protocol-buffers/docs/javatutorial in detail), I have a bat here that calls Protoc to generate Java files, It's too much trouble to enter it manually. Save it to a. bat under Windows and then double-click to run it.

[VB]View Plaincopy
  1. @echo off
  2. echo * * Setting runtime variable
  3. REM _PROTOSRC is the location of your proto file directory
  4. Set _protosrc=f:\project_proto_src\trunk\xgame-controllers\protos
  5. REM Protoexe is the location of the Protoc.exe program used to generate Java from Proto
  6. Set Protoexe=c:\users\john\desktop\protobuf-2.5.0\src\protoc.exe
  7. REM Java_out_file location where the generated Java file directory is stored
  8. Set Java_out_file=f:\project_proto_src\trunk\xgame-controllers\src\main\java\
  9. FOR/R "%_protosrc%"%%i in (*) does (
  10. Set Filename=%%~nxi
  11. If "%%~xi" = = ". Proto" (
  12. %protoexe%--proto_path=%_protosrc%--java_out=%java_out_file%%%i
  13. )
  14. )


OK, so you just copy the generated Java to or generate it directly into your Java project source directory, then you can use it. Like what:
Take the Workerinfo as the example above.

[Java]View Plaincopy
  1. Package com.duoyu001.xgame;
  2. Import Java.util.Arrays;
  3. Import Com.duoyu001.xgame.worker.proto.WorkerInfoBuilder.WorkerInfo;
  4. Public class Testproto {
  5. public static void Main (string[] args) {
  6. Workerinfo w = Workerinfo.newbuilder (). Setbuildingid (1)
  7. . setleftclosingtimesec.Setworkerid (1001). Build ();
  8. byte[] ByteArray = W.tobytearray ();
  9. System.out.println (arrays.tostring (ByteArray));
  10. }
  11. }


The console will output:

Careful classmates will find here the bytes and above the "8, 233, 7, 16, 100, 24, 1" a bit different. The second number is-23 and 233, respectively.

In fact, this is only a byte of the unsigned representation of the difference.

Their binary representations are: 11101001

6, too annoying?! The client also has to handle protobuf automatically.

We see that the client does not add a class, and we need to add code to two vs projects, and the backend generates code directly from the proto file. In this way, it seems a bit unfair, and so the front and back can still write a different structure. In fact, with Protobuf I personally feel the greatest benefit:

A, small amount of data

b, generate code through proto template, reduce front and rear end

But now it's just the back end that reduces the work, the front end does not decrease, so the second benefit is not very obvious.

All right. I'm not so satisfied. Therefore, I decided that the front end should also be based on Proto to generate CS files.

So, I used Java to write a tool to parse the proto file, and generate a CS file based on Proto, and then use bat to call vs's command line to build the VS project, and finally build two DLLs.

I've integrated all of the above commands into a bat, so this bat's task is:

Execute the Java program and generate the CS file for the proto file.

Call the VS interface to build two vs projects and build two DLLs.

The two DLLs are submitted to the client's trunk via SVN.

Generate Java code by invoking a bat fragment that generates Java based on Proto.

The generated Java code is submitted to the server trunk via SVN.

So, for now, just write the proto file and double-click Bat to get the latest Protobuf data object by updating SVN at the front and back.

Bat Run

Generate CS files based on Proto and compile to execute two vs projects, then submit the generated DLL to SVN

Generate Java code and submit SVN

This step related to the operation of everyone is interested in self-test, there are questions welcome in this blog discussion.

Unity3d client and Java service side use Protobuf

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.