摘要
上篇文章我们介绍了,Android和Unity3d调用的理论基础,那么这一篇我们就开始简单的实战一下。
准备工作
在编写开始,我们先做一下准备工作,这样我们就不会快完工的时候,还要等待下载Android SDK等比较费时的事情。
在你已经拥有了Android的SDK,NDK以及java的环境后,我们需要先在我们的Unity3d将其进行默认话。
Unity3D上部导航栏:Edit–>preference–>External Tools
将下面的对应SDK以及JDK设置为自己的目录。
开动喽
首先我们需要确定我们要操作的目标,这里我就以小女孩为目标。 从下图可以看到小女孩的名字为unitychan
接下来我们来看一下其中一个C#脚本是如何进行编写的。
using UnityEngine;
using System.Collections;
using System.Reflection.Emit;
//
// ↑↓キーでループアニメーションを切り替えるスクリプト(ランダム切り替え付き)Ver.3
// 2014/04/03 N.Kobayashi
//
// Require these components when using this script
[RequireComponent(typeof(Animator))]
public class IdleChanger : MonoBehaviour
{
private Animator anim; // Animator动画参照
private AnimatorStateInfo currentState; // 当前动画的状态信息
private AnimatorStateInfo previousState; // 上一个的动画状态信息
public bool _random = false; // 判定不行
public float _threshold = 0.5f;
public float _interval = 2f;
//private float _seed = 0.0f; // ランダム判定用シード
// Use this for initialization
void Start ()
{
// 组件的初始化和状态的初始化
anim = GetComponent<Animator> ();
currentState = anim.GetCurrentAnimatorStateInfo (0);
previousState = currentState;
// 设置我们的协同
StartCoroutine ("RandomChange");
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown ("up") || Input.GetButton ("Jump")) {
anim.SetBool ("Next", true);
}
if (Input.GetKeyDown ("down")) {
anim.SetBool ("Back", true);
}
if (anim.GetBool ("Next")) {
currentState = anim.GetCurrentAnimatorStateInfo (0);
if (previousState.nameHash != currentState.nameHash) {
anim.SetBool ("Next", false);
previousState = currentState;
}
}
if (anim.GetBool ("Back")) {
currentState = anim.GetCurrentAnimatorStateInfo (0);
if (previousState.nameHash != currentState.nameHash) {
anim.SetBool ("Back", false);
previousState = currentState;
}
}
}
void OnGUI()
{
GUI.Box(new Rect(Screen.width - 110 , 10 ,100 ,90), "Change Motion");
if(GUI.Button(new Rect(Screen.width - 100 , 40 ,80, 20), "Next"))
anim.SetBool ("Next", true);
if(GUI.Button(new Rect(Screen.width - 100 , 70 ,80, 20), "Back"))
anim.SetBool ("Back", true);
}
IEnumerator RandomChange ()
{
while (true) {
if (_random) {
float _seed = Random.Range (-1f, 1f);
if (_seed <= -_threshold) {
anim.SetBool ("Back", true);
} else if (_seed >= _threshold) {
anim.SetBool ("Next", true);
}
}
yield return new WaitForSeconds (_interval);
}
}
//用于Unity3d调用的
void Unload()
{
Application.LoadLevel(1);
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("makePauseUnity");
}
//用于Android调用的
void back()
{
anim.SetBool("Back", true);
}
//用于Android调用的
void next()
{
anim.SetBool("Next", true);
}
}
在编写好我们unity项目后,就要开始进行build了,但是我们需要的是可以二次开发使用的GoogleAndroidProgect项目,因此我们需要设置一下Build的响应属性。
File–>BuildSettings
按照如图所示进行勾选,之后我们需要配置一下导出的版本参数,点击Player Settings
然后选择目录export编译玩会得到如下eclipse的项目
我们将这个项目导入我们的AS,然后开始改吧改吧。首先我把布局发出来。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/showMain"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="back"/>
<Button
android:id="@+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="next"/>
</LinearLayout>
</LinearLayout>
里面只是一个LinearLayout和两个Button。接下来就开始我们的正经工作了。
package com.Iyunwen.robot;
import android.app.Activity;
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.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
public class UnityPlayerActivity extends Activity {
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);
setContentView(R.layout.mainactivity);
getWindow().setFormat(PixelFormat.RGBX_8888); // <--- This makes xperia play happy
LinearLayout
unityVIew = (LinearLayout) findViewById(R.id.showMain);
mUnityPlayer = new UnityPlayer(this);
unityVIew.addView(mUnityPlayer);
// setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
Button mBack = (Button) findViewById(R.id.back);
Button mNext = (Button) findViewById(R.id.next);
mBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
UnityPlayer.UnitySendMessage("unitychan", "back", "");
}
});
mNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
UnityPlayer.UnitySendMessage("unitychan", "next", "");
}
});
}
public void makePauseUnity() {
Toast.makeText(this, "unity3D调用Android的方法", Toast.LENGTH_LONG).show();
}
// 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);
}
}
大工搞成,卡哇伊的妹子在向我们招手哦。
该死的虚拟按键隐藏了我的连个button.