Embedded Unity3d view in Android app (3D model)

Source: Internet
Author: User

Reprint Please indicate this article from Big Corn's blog (http://blog.csdn.net/a396901990 ), thank you for your support!

Effect Show:





Opening nonsense:

The team I'm in now needs one person a week to introduce you to a knowledge point, or a new technology. This week is my turn, because I work only a year, in the face of the old birds to tell the knowledge point feel a little dead. So I'm going to pick a new technology to introduce.

Since I have been self-taught in the university for some time Unity3d, so I would like to introduce the technology is it, but I do now is the application of development, can not do a small game to show you. So I thought it would be simpler, more intuitive, and probably really used to showcase 3D models in Android apps. For example, when the product is displayed, the 3D model of the product is displayed instead of a picture, the effect should be very good (OpenGL should also do).

the idea of the Unity3d after the discovery of the university when the content of the basic forgotten, although occasionally there are unity3d articles will be opened to see, but still have to re-learn. I remember when I learned unity3d when I saw a blog called the Rain Pine Momo. At that time Young, ignorant, can not find the direction of the rain I also sent an e-mail to ask the university how to learn and do game-related problems, the results of people did not return, resulting in my more lost so I went on to learn Android ... It's a long way off ... So I found his blog, the Unity3d basic part of the relevant articles have been read over.

But his blog shows how to call Android in Unity3d, and what I want to do is call Unity3d in Android and embed Unity3d in Android view. The last Dickens to make this demo.


Preparatory work:

Here is my summary of the process, the purpose is to make the idea of this article more clear:

1.Android Terminal code can be developed in eclipse (Androidstudio not tried, should also be possible)

2.unity3d-side code to be developed in unity

3.Android and Unity3d end, both sides need to add some code so that they can be associated with the interaction.

4. Compile the Android side code into a jar file and put it into the unity side in plug-in form

5. Build the entire project into an APK file in unity and then install it into the phone or emulator to run

This article mainly explains the. For 4,5 It is recommended that you go to the 17th and 18th articles of the Unity blog of the Rain Pine Momo.


Unityplay:

Before writing the Android and Unity3d-side code, it is necessary to understand the unityplay of the classes that can make the two parts interactive.

Personal Understanding Unityplay is an interface class that unity provides to external interactions.

Why is "personal understanding"? I'm going to have to foul up, TMD. There is no relevant API and documentation at all (if everyone has found someone who must give me a copy, just when I scold myself).

When associating Android, the jar packages that you want to get unityplay and related classes can be found at the following address:Unity installation Path \editor\data\playbackengines\androidplayer\bin There is a Classes.jar jar file under the Bin folder, which is what we want.

And in the bin directory there is a src file, click to the end there are 3 classes, Unityplayeractivity.java,unityplayerproxyactivity.java,unityplayernativeactivity.java, respectively. The first two open only one line of code, said Unityplayeractivity and Unityplayerproxyactivity are inherited from Unityplayernativeactivity. and open unityplayernativeactivity actually have code, and I estimate this should be unityplayernativeactivity source.

Because of the information about Unityplay I only found such a, so I put the code in the Unityplayernativeactivity , if I note there is not the place I want you to correct.

/** * unityplayeractivity,unityplayerproxyactivity all inherit from Unityplayernativeactivity * And unityplayernativeactivity inherits from Nativeactivity * Some callback methods with the same Android life cycle are defined in this class, leaving the custom activity subclass rewritten. */public class Unityplayernativeactivity extends Nativeactivity{//unityplayer reference, and we cannot change the name of this reference variable, it is native Code references protected Unityplayer munityplayer;protected void OnCreate (Bundle savedinstancestate) {requestwindowfeature ( Window.feature_no_title); super.oncreate (savedinstancestate);//Set Display window Parameters GetWindow (). Takesurface (null); SetTheme ( Android. R.style.theme_notitlebar_fullscreen); GetWindow (). SetFormat (pixelformat.rgb_565);//Create a Unityplayer object, and assign to the global reference variable Munityplayer = new Unityplayer (this);//Set some parameters for Unityplayer if (Munityplayer.getsettings (). Getboolean (" Hide_status_bar ", True)) GetWindow (). SetFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, Windowman Ager. layoutparams.flag_fullscreen); int glesmode = Munityplayer.getsettings (). GetInt ("Gles_mode", 1); Boolean trueColor8888 = false;//unityplayer.iThe NIT () method needs to be called before the view is attached to the layout. It will call native Codemunityplayer.init (Glesmode, trueColor8888);//get from Unityplayer to Unity's view view Playerview = Munityplayer.getview ();//Load Unity view onto root view Setcontentview (Playerview);//Make Unity View get focus Playerview.requestfocus ();} protected void OnDestroy () {///When the activity ends, call the Unityplayer.quit () method, which unloads the previously called Native Codemunityplayer.quit (); Super.ondestroy ();} The following methods are all Android-related callback methods to make sure that Unityplayer also calls the appropriate method protected void OnPause () {super.onpause () when Android executes the appropriate method; Munityplayer.pause ();} protected void Onresume () {super.onresume (); Munityplayer.resume ();} public void onconfigurationchanged (Configuration Newconfig) {super.onconfigurationchanged (newconfig); munityplayer.configurationchanged (newConfig);} public void Onwindowfocuschanged (Boolean hasfocus) {super.onwindowfocuschanged (hasfocus); Munityplayer.windowfocuschanged (Hasfocus);} public boolean dispatchkeyevent (KeyEvent event) {if (event.getaction () = = Keyevent.action_multiple) return Munityplayer.onkeymultiple (Event.getkeycode (), event.Getrepeatcount (), event); return Super.dispatchkeyevent (event);}} 
after reading this class, you will know why after you have inherited the Unityplayeractivity class in your custom activity, just rewrite the onCreate and call Super.oncreate () method does not require any additional code to automatically display the Unity3d view. Because the code that initializes the Unity view is implemented in the Unityplayernativeactivity parent class.

Android Side code:

When writing Android code, be sure to import the jar package that Unity3d provided to us, the location of the jar package I said above. Introducing jar packages to buildpath the most basic of these I will not say much.

To interact with unity, we cannot inherit the activity that Android provides to us, we need to inherit the activity class provided by unity that was introduced in the jar package, there are altogether 3:

Unityplayeractivity,unityplayerproxyactivity,unityplayernativeactivity. Specific differences do not know, because there is no documentation, no API, no source (here again despise). Just now we have seen the code of Unityplayernativeactivity (although very short, but I think this is the source), know that Unityplayeractivity,unityplayerproxyactivity is its sub-class, and eventually the parent class is nativeactivity. So we inherit the outermost subclass provided by Unity is the best choice, I choose unityplayeractivity here, because the name is the simplest, think that the package should be encapsulated.

public class Mainactivity extends Unityplayeractivity {private Button topbutton;private button bottombutton;@ overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);// Set test for our root layout setcontentview (r.layout.test);//through just the source analysis, know Munityplayer as a global reference variable, and has been set in the parent class, so directly to use it can be a view Playerview = Munityplayer.getview ();//Add Unity's view to the parent container we prepared for it linearlayout LL = (linearlayout) Findviewbyid ( R.id.unityviewlyaout); Ll.addview (Playerview);//button Set listener Topbutton = (button) Findviewbyid (R.id.topbutton); Topbutton.setonclicklistener (New View.onclicklistener () {@Overridepublic void OnClick (View v) {//Send message to unity side, The first parameter of the function is the class object that accepts the message, the second object uses the method that accepts the message, and the third argument is the message passed, so the following means: Call the previous method below the main camera, The transmitted message is an empty unityplayer.unitysendmessage ("Main Camera", "Previous", "" "); });//Set Listener Bottombutton = (button) Findviewbyid (R.ID.BOTTOMBTN) for the button below, Bottombutton.setonclicklistener (new View.onclicklistener () {@Overridepublic void OnClick (View v) {//calls the next method under main camera, sending the message asEmpty Unityplayer.unitysendmessage ("Main Camera", "Next", "" "); }});}}

Finally look at the Android layout file, the layout is very simple, up and down there is a button buttons, two buttons in the middle is Unity view.

<?xml version= "1.0" encoding= "Utf-8"? ><relativelayout xmlns:android= "http://schemas.android.com/apk/res/ Android "Android:layout_width=" Match_parent "android:layout_height=" match_parent "android:orientation=" vertical " > <button android:id= "@+id/topbutton" android:layout_width= "Match_parent" Android:layout_hei        ght= "Wrap_content" android:layout_alignparenttop= "true" android:text= "PREVIOUS"/> <linearlayout Android:id= "@+id/unityviewlyaout" android:layout_width= "match_parent" android:layout_height= "Match_pare NT "android:layout_above=" @+id/bottombtn "android:layout_below=" @+id/topbutton "android:orientation=" Horizontal "> </LinearLayout> <button android:id=" @+id/bottombtn "Android:layout_width=" Ma Tch_parent "android:layout_height=" Wrap_content "android:layout_alignparentbottom=" true "Android:text = "NEXT"/></relativelayout&Gt 
the code on the Android side is finished, very simple. The only difficulty is the use of unityplayeractivity and Unityplayer, the two broken things took me a few days of time, very simple thing do not know why the official not to give a document or API (or maybe I was too frustrated to find ...) )

Unity3d-Side code:

First look at the structure of my project:


JavaScript holds scripts.

Models is storing some of the free model files I downloaded in the Assert store.

Plugins is my Android project, specific practice reference online tutorial (recommended here for the 17th chapter of the Great God of rain)

Prefab I'm the prefab that was defined after the model was adjusted

In the scene, I have only one camera, and a direct light. Bind the script to the camera, and then add the previously adjusted 5 preset models to the appropriate objects in the script.


Here is the code of the script, about the model rotation scaling is directly using the Rain Pine Momo in an article of the code, and then add some of the logic in this example is composed.

#pragma STRICT//5 model, from the outside into the Var car:gameobject;var helicopter:gameobject;var Suv:gameobject;var Plane:gameobject;var tank:gameobject;//model Array Subscript private VAR index:int;//model Array Private var models:gameobject[];//current model object private var Mcurrentgam The variables below the eobject:gameobject;/******************************************//* split line are used for touch gesture lens control rotation and zoom *//*******************  Scaling factor var distance = 10.0;//left and right sliding move speed var xspeed = 250.0;var Yspeed = 120.0;//scaling limit factor var yminlimit = -20;var Ymaxlimit = 80;//The position of the camera var x = 0.0;var y = 0.0;//record the last phone touch location to determine whether the user is in the left or the zoom out gesture private var oldposition1:vector2;pri  vate var oldposition2:vector2;function Start () {//Initialize model array index = 0;models = new Gameobject[5];models[0] = car;models[1] = helicopter;models[2] = suv;models[3] = plane;models[4] = tank;//clones an initial model object Mcurrentgameobject = Instantiate (models[    Index], Vector3 (0,0,0), Quaternion.euler ( -20,0,0));//initialization of the lens parameter var angles = transform.eulerangles;    x = Angles.y; y = angles.x;} function Update () {//To determine the number of touches as a single tapTouch if (Input.touchcount = = 1) {//Touch type is mobile touch if (Input.gettouch (0). phase==touchphase.moved) {            calculates x and y position x + = Input.getaxis ("Mouse x") * XSpeed * 0.02 based on touch points;         Y-= Input.getaxis ("Mouse y") * yspeed * 0.02; }}//To determine the number of touches for multi-touch if (Input.touchcount > 1) {///top two finger touch type are all mobile touch if (Input.gettouch (0). phase== touchphase.moved| | Input.gettouch (1). phase==touchphase.moved) {//calculates the position of the current two-point touch point var TempPosition1 =                Input.gettouch (0). Position;                var tempPosition2 = Input.gettouch (1). Position;                    function returns true to enlarge, return false for narrowing if (Isenlarge (Oldposition1,oldposition2,tempposition1,tempposition2)) { Amplification factor of more than 3 is not allowed to continue to enlarge//The data here is adjusted according to the model in my project, you can modify if (distance & Gt                       3) {distance-= 0.5; }}else                {//Shrink wash back after 18.5 is not allowed to continue shrinking//The data here is based on the model in my project, and you can modify it yourself.                    if (distance < 18.5) {distance + = 0.5;            }}//backup the position of last touch point, used to compare oldposition1=tempposition1;        Oldposition2=tempposition2; The}}//function returns true for magnification, returning false for shrink function Isenlarge (OP1:VECTOR2,OP2:VECTOR2,NP1:VECTOR2,NP2:VECTOR2): boolean{//function passed in the previous    The position of the second touch two point and the position of this touch two point calculate the user's gesture Var leng1 =mathf.sqrt ((op1.x-op2.x) * (op1.x-op2.x) + (OP1.Y-OP2.Y) * (OP1.Y-OP2.Y));    var leng2 =mathf.sqrt ((np1.x-np2.x) * (np1.x-np2.x) + (NP1.Y-NP2.Y) * (NP1.Y-NP2.Y));    if (Leng1 < leng2) {//magnification gesture return true;    }else {//Zoom out gesture return false; }}//update method Once the call is completed enter here to calculate the position of the Reset camera function lateupdate () {//mcurrentgameobject is our current model object, scaling the rotated reference if (mcurrentgame Object.transform) {//Reset camera's position y = Clampangle (y, Yminlimit, ymaxlimit);        var rotation = Quaternion.euler (y, x, 0);         var position = rotation * VECTOR3 (0.0, 0.0,-distance) + mCurrentGameObject.transform.position;        Transform.rotation = rotation;    Transform.position = position;    }} static function Clampangle (Angle:float, Min:float, max:float) {if (angle < -360) angle + = 360;    if (angle > Angle)-= 360; return Mathf.clamp (angle, Min, max);} When you press Next on Android, the next model function next () {index = INDEX+1;IF (Index > models) is displayed. Length-1) {index = 0;} Debug.Log ("Next");//destroys the current object Destroy (Mcurrentgameobject);//Creates a new model object Mcurrentgameobject = Instantiate (Models[index]);} When Previous is pressed in Android, the previous model function Previous () {index = index-1;if (Index < 0) {index = models is displayed. Length-1;} Debug.Log ("previous");//destroys the current object Destroy (Mcurrentgameobject);//Creates a new model object Mcurrentgameobject = Instantiate (models[ Index]);}

The final thing is to build the project into an apk file in Unity3d, and then run it in the phone or simulator (if the phone or emulator is connected to eclipse, you can make the log easy to debug and find the error).

Finally, attach the code demo:

The Unity side code is too big, so I put the Android and Unity side code and apk file uploaded to the Baidu cloud.

Code click to download


Conclusion:

When I first went to college, I dreamed of going to the game after graduation, but when I volunteered, I chose Java-related, then I knew that Java was not suitable for games, then I learned C++,opengl, then I saw Unity3d but all did not adhere to it, and the university every day and classmates playing Wow, The result of graduation found that game-related things are not learned at all, and Dalian No game development work, although very want to go to Beijing to try, but at that time to Beijing internship too troublesome, and not necessarily can find, so in Dalian directly find an Android development so the original dream gave up. But I still want to go to Beijing next year to try to find the game development work, the middle of the year I will mainly learn Android and Java, the rest of the time to see the graphics and math knowledge, not like the University of what hot to learn what, because now understand gradually more after the discovery of programming is basically universal, So let's just learn a thing and learn it.



Embedded Unity3d view in Android app (3D model)

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.