[Unity3D] Unity3D game development: embedding Unity view in Android view, unity3dandroid

Source: Internet
Author: User

[Unity3D] Unity3D game development: embedding Unity view in Android view, unity3dandroid

Certificate ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

If you like my blog, please remember my name: Qin Yuanpei. My blog address is blog.csdn.net/qinyuanpei.

Reprinted please indicate the source, Author: Qin Yuanpei, the source of this article: http://blog.csdn.net/qinyuanpei/article/details/39380717

Certificate ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Hello everyone, I'm Qin Yuanpei. Welcome to follow my blog. My blog address is blog.csdn.net/qinyuanpei. Recently, bloggers found that their articles were illegally reposted by many websites (such as gaming manniu). During the reprinting process, the original author's articles and links were removed, what makes bloggers even more angry is that some people copy part of their articles and post them in the form of original articles on CSDN. In this way, when CSDN recommends related articles based on tags, some articles will be connected to other places outside the blog. the blog is not a stingy person, but these blogs are all written by the bloggers themselves, this practice will inevitably make the bloggers feel cold. From today on, all the articles and illustrations of the bloggers will be linked, hoping to warn those who illegally repost the author's articles to learn how to respect the work of the bloggers.

Now, I am not paying much attention to these people. Today we will continue to study the expansion of Unity on the Android platform. Through yesterday's learning, we know that Unity and Android can call each other, however, we can see from yesterday's article that we can achieve this simply by calling the Android interface. However, from the perspective of actual development, we just took a small step. Why do we say this? In actual development, we may not only need to connect to Unity through interfaces, but also through interfaces. For example, mainstream online games will give gamers a process of choosing to create roles at the beginning of the game. Generally, various types of role settings are displayed on the interface, players can learn the characteristics of each type of role on the interface, so as to select their own role. Technically speaking, this part can be fully implemented using the Unity3D GUI system. However, the purpose of this article is to discuss the connection between Unity and Android, therefore, we can assume that Android plays the role of interface rendering throughout the docking process, while Unity maintains the game logic. In this way, the question today arises. Can we embed Unity as part of the Android interface into an Android application? Of course, the answer is yes.


1. Compile Android plug-ins for Unity

First, let's take a look at the class file UnityPlayerNativeActivity. java provided for Android in Unity, which is located in the following location:

D: \ ProgramFiles \ Unity \ Editor \ Data \ PlaybackEngines \ androidplayer \ com \ unity3d \ player)

package com.unity3d.player;import android.app.NativeActivity;import android.content.res.Configuration;import android.graphics.PixelFormat;import android.os.Bundle;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.View;import android.view.Window;import android.view.WindowManager;public class UnityPlayerNativeActivity extends NativeActivity{protected UnityPlayer mUnityPlayer;// don't change the name of this variable; referenced from native code// Setup activity layout@Override protected void onCreate (Bundle savedInstanceState){requestWindowFeature(Window.FEATURE_NO_TITLE);super.onCreate(savedInstanceState);getWindow().takeSurface(null);setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);getWindow().setFormat(PixelFormat.RGB_565);mUnityPlayer = new UnityPlayer(this);if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,                       WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(mUnityPlayer);mUnityPlayer.requestFocus();}// Quit Unity@Override protected void onDestroy (){mUnityPlayer.quit();super.onDestroy();}// Pause Unity@Override protected void onPause(){super.onPause();mUnityPlayer.pause();}// Resume Unity@Override protected void onResume(){super.onResume();mUnityPlayer.resume();}// This ensures the layout will be correct.@Override public void onConfigurationChanged(Configuration newConfig){super.onConfigurationChanged(newConfig);mUnityPlayer.configurationChanged(newConfig);}// Notify Unity of the focus change.@Override public void onWindowFocusChanged(boolean hasFocus){super.onWindowFocusChanged(hasFocus);mUnityPlayer.windowFocusChanged(hasFocus);}// For some reason the multiple keyevent type is not supported by the ndk.// Force event injection by overriding dispatchKeyEvent().@Override public boolean dispatchKeyEvent(KeyEvent event){if (event.getAction() == KeyEvent.ACTION_MULTIPLE)return mUnityPlayer.injectEvent(event);return super.dispatchKeyEvent(event);}// Pass any events not handled by (unfocused) views straight to UnityPlayer@Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return mUnityPlayer.injectEvent(event); }@Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return mUnityPlayer.injectEvent(event); }@Override public boolean onTouchEvent(MotionEvent event)          { return mUnityPlayer.injectEvent(event); }/*API12*/ public boolean onGenericMotionEvent(MotionEvent event)  { return mUnityPlayer.injectEvent(event); }}
Those familiar with Android development must be familiar with this category. NativeActivity was launched by Google after Android3.0, the objective is to allow developers to use C/C ++ to manage the Activity lifecycle in the NDK environment, so we can boldly guess that the reason why Unity can interact with Android is that NDK provides a convenient portal. Indeed, the blogger found it in the Unity directory.
The libmain. so, libunity. so, and libmono. so files confirm that our conjecture is correct. In this class, we can see that Unity has done a lot of initialization work and rewritten the NativeActvity method. I don't know if you still remember that when we defined the main Activity in the previous article, we made it inherit from the UnityPlayerActivity instead of the Android Activity. So what is this UnityPlayerActivity? Open its file:

package com.unity3d.player;/** * @deprecated Use UnityPlayerNativeActivity instead. */public class UnityPlayerActivity extends UnityPlayerNativeActivity { }
At this time, I believe that everyone and the bloggers have a sudden feeling that it was originally inherited from UnityPlayerNativeActivity. In other words, Unity actually did two things in the Android part, initialize the Activity and override related methods. We noticed that the comments in the Code indicate that this class has already been deprecated. We recommend that you use UnityPlayerNativeActivity. We don't need to worry about this. We still use UnityPlayerActivity because it is essentially the same as UnityPlayerNativeActivity. So far, if you have understood all the content here, we can rush to Eclipse to write Android projects.

Like yesterday, we created an Android project and set it as a library. Here we set its package name to com. android. unityview4android. This name is very important. We will continue to use this name in Unity. First, create an Android layout file activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity" >    <Button        android:id="@+id/BtnPre"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:text="@string/BtnPre" />    <LinearLayout          android:id="@+id/UnityView"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:layout_above="@+id/BtnNext"          android:layout_below="@+id/BtnPre"          android:orientation="vertical" >      </LinearLayout>    <Button        android:id="@+id/BtnNext"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:text="@string/BtnNext" /></RelativeLayout>

Here we place two buttons to control the forward and backward switching models of Unity. There is a linear layout called UnityView in the middle of the screen, which serves as the parent control of Unity view, that is, we will put the Unity view in this control. We noticed in UnityPlayerNativeActivity. the java class contains the UnityPlayer type variable mUnityPlayer. This type of Blogger does not currently find any official instructions. The blogger assumes that it is a class responsible for rendering the Unity interface, there is a getView () method in this class. It will return a value of the View type. We can add it to the Android View through this method, because we have prepared a parent Control for UnityView, it is quite easy to implement it all:

Package com. android. unityview4android;/* import the class provided by Unity */import com. unity3d. player. unityPlayer; import com. unity3d. player. unityPlayerActivity; import android. OS. bundle; import android. view. menu; import android. view. view; import android. view. view. onClickListener; import android. widget. button; import android. widget. linearLayout; public class MainActivity extends UnityPlayerActivity {private Button BtnPre, BtnNext; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); // sets the current layout file setContentView (R. layout. activity_main); // obtain the parent control LinearLayout mParent = (LinearLayout) findViewById (R. id. unityView); // obtain the Unity View. mView = mUnityPlayer. getView (); // Add the Unity View to the mParent In the Android view. addView (mView); // The previous BtnPre = (Button) findViewById (R. id. btnPre); BtnPre. setOnClickListener (new OnClickListener () {@ Overridepublic void onClick (View arg0) {UnityPlayer. unitySendMessage ("GameObject", "ShowPrevious", "") ;}}); // The next BtnNext = (Button) findViewById (R. id. btnNext); BtnNext. setOnClickListener (new OnClickListener () {@ Overridepublic void onClick (View arg0) {UnityPlayer. unitySendMessage ("GameObject", "ShowNext", "") ;}}) ;}@ Overridepublic boolean onCreateOptionsMenu (Menu menu) {// Inflate the menu; this adds items to the action bar if it is present. getMenuInflater (). inflate (R. menu. main, menu); return true ;}}
Okay, so we can write the Jar library. We only need to import the Jar library to Unity, and follow the method described in the previous article to build the Android plug-in directory and organize relevant resources. Finally, we provide the AndroidManifest. xml file:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.android.unityview4android"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="9"        android:targetSdkVersion="17" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.android.unityview4android.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>


2. Create a Unity Project
Now let's create a Unity project. Here we create a simple scenario where there is only one empty game body and camera. We will control Unity rendering in the form of scripts, the main script code is as follows:

Using UnityEngine; using System. collections; public class ModelManager: MonoBehaviour {// Model public GameObject [] Models; // The current index private int index = 0; // The current object private GameObject mObject; void Start () {this. name = "GameObject"; // generate the first object mObject = (GameObject) Instantiate (Models [index]);} public void ShowNext () {// Add index + = 1 to the index; // if (index> Models. length-1) {index = 0 ;}// Destroy the original object Destroy (mObject); // generate a new object mObject = (GameObject) Instantiate (Models [index]);} public void ShowPrevious () {// reduce index-= 1; // if (index <0) {index = Models. length-1;} // Destroy the original object Destroy (mObject); // generate the new object mObject = (GameObject) Instantiate (Models [index]);}
This script is bound to the empty game body. The two methods of the script, ShowNext (), correspond to ShowPrevious () and communicate with each other through UnitySendMessage. Let's run the project ,:


We can note that when the program is opened, the Android view is loaded first, and then the Unity view is loaded. The overall feeling is that an Activity is nested in the Activity. However, the blogger immediately discovered a problem. The buttons in the Android view cannot get the focus, and the click event is invalid. Why? The solution found by the blogger is to add the following two lines of code to the activity subnode in the AndroidManifest. xml file:

            <meta-data android:name="android.app.lib_name" android:value="unity" />             <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
The problem is solved, but we have to understand why. In the official Unity documentation, we found the answer:

Note that NativeActivity is introduced after Android2.3 and does not support devices of the earlier version. Because touch/motion events are processed in the local code, the Java view usually does not see these events. However, the unified forwarding mechanism allows event propagation to DalvikVM. To use this mechanism, you need to modify the manifest file as follows:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product">  <application android:icon="@drawable/app_icon" android:label="@string/app_name">    <activity android:name=".OverrideExampleNative"             android:label="@string/app_name">    <meta-data android:name="android.app.lib_name" android:value="unity" />    <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />        <intent-filter>            <action android:name="android.intent.action.MAIN" />            <category android:name="android.intent.category.LAUNCHER" />        </intent-filter>    </activity>  </application></manifest> 
This section means that Android events run in the local code, and the Java view does not see these events. However, we can send these events to the Android virtual machine through the unified forwarding mechanism provided by Unity, to use this mechanism, we must modify Android's AndroidManifest. xml file. Bloggers feel that the Android plug-in is not doing very well at present, and it always gives people a feeling of cloudification. In addition, calling each other through various languages increases the difficulty of debugging. For more information about Android, you can refer to the official document: click here. well, today's content is like this. I hope you will like it. Finally, let's take a look at the program running effect.



Daily proverbs: This year's dream has a deadline. If you have the idea, you can do it. Even if you fail, it is better than you didn't do it. Because failure gives you at least experience, and if you don't do it, it will only bring you regret. -- Zhu deyong





Certificate ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

If you like my blog, please remember my name: Qin Yuanpei. My blog address is blog.csdn.net/qinyuanpei.

Reprinted please indicate the source, Author: Qin Yuanpei, the source of this article: http://blog.csdn.net/qinyuanpei/article/details/39348677

Certificate ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------






After Unity3D games are published on android phones, Chinese characters cannot be displayed. How can this problem be solved? Source code

I remember there is a solution for inserting advertisements in the U bar.

[Unity3D] mobile 3D Game Development: how to use gravity sensing in Unity3D

Wang wanghai's laboratory, Shanghai laboratory-various graphics experiments, data structure experiments, and other trivial little notes are all gathered here for 0-various graphics experiments and data structures the lab and all other trivial notes are gathered here for 0 error (s ), 0 warning (s) the arrival of this magic moment error (s), 0 warning (s) the arrival of this magic moment learning Unity script is recommended: unity3D indexing gravity sensing is very common in mobile game development. Unity3D is a collection of gravity sensing related content. A simple JS script demonstrates the use of gravity sensing. CSDNGravity. js: // object texture var round: Texture2D; // The x y coordinate var x = 0 displayed on the screen; var y = 0; // maximum x y range displayed on the Object Screen var cross_x = 0; var cross_y = 0; function Start () {// initialization value cross_x = Screen. width-round. width; cross_y = Screen. height-round. height;} function OnGUI () {// The overall x y z gravity sensing gravity component GUI is displayed. label (Rect (0,0, 480,100), "position is" + Input. acceleration); // draw the object GUI. drawTexture (Rect (x, y, 256,256), round);} function Update ( ) {// Modify the object position based on the gravity component. Multiply the value by 30 here to make the object move faster x ++ = Input. acceleration. x * 30; y + =-Input. acceleration. y * 30; // avoid an object exceeding the screen if (x <0) {x = 0;} else if (x> cross_x) {x = cross_x ;} if (y <0) {y = 0;} else if (y> cross_y) {y = cross_y ;}} the Input here refers to the Input in Unity, acceleration is its gravity, and x and y represent its gravity. After creating the image, you only need to add the texture image: 12

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.