Window7
Unity3D 3.4.1
MB525defy Android 2.2.1
羽化的第二十一篇博客,这次一次发布三篇确实有点漫长。。。因为最近羽化一直很忙,没多少时间重新整理Android AdMob方面的东西,正好今天有空就把准备写的补上。其实羽化这方面也不是很熟悉,但知道的解决方法有两三种,这次就说一个最简单的解决方案,并送上代码,以后任何人开发都可以改改项目名称和ID就可以直接拿来用。很多方法来自官方的大牛们热议,大家可以可以借鉴下这些脚本写法。
最近通关了刺客信条启示录,作为Ezio和Altair时代的终结,本作应该算是前作兄弟会的延伸,创新点不多,但依然很有趣,刺客养成方面做得过于繁琐,也没有隐藏的装备了,这点实在是可惜。想当初羽化开始玩刺客信条系列的时候,大概读大一,XBOX360才刚买不久,家里还是一个纯平电视,第一次玩的时候感觉很兴奋,开阔的场景,密集的建筑,自由的攀爬,这就是游戏的乐趣,真正的次世代体验,但初代任务方面薄弱很多,幸运的是,刺客信条系列总是在不断改进和创新,可以看到开发团队在这方面的努力,这种开发游戏的态度值得游戏制作人学习,希望这个系列能做得更好,真正做到“万物皆虚,万事皆允”,应该下一作就是终结。
本次学习:
1. Eclipse报错解决方案
2. AdMob应用
1.Eclipse报错解决方案
本来不用写的,但羽化在打开Eclipse的时候遇到了几个蛋疼问题,下面羽化把这几个问题做个小小总结:(1)Error: Unableto open class file XXX/R.java错误
有两种解决方案:首先是Project -> clean 再勾上Build Automatically,可以解决一类常出现的脑抽问题。。。其次是Window -> Preferences -> Java -> Build Path 中选择Project -> Apply,可以解决些意外问题。。。
(2)error generating final archive 错误
这类错误一般新手是遇不到的,因为这是证书过期引起的,一般证书有效期只有1年,超过1年后,所有新建的Android工程都会无故报错,解决方法是来到Window -> Preferences -> Android -> Build中 Default debug keystore目录下,复制里面地址打开删除debug.keystore及 ddms.cfg两个文件,重启eclipse就可以解决。
2.AdMob应用
首先是Eclipse上Android项目的写法,导入羽化的项目AdMob(Import –> Existing Projects into Workspace),肯定会报错。。。
这时修改引用,选中项目文件单击鼠标右键-> Properties -> Java Build Path里面的Libraries,把admob-sdk-android.jar和classes.jar文件重新Edit到当前的libs里面,再到Order and Export里面勾选上。
注意: admob-sdk-android.jar是网上一个大牛封装的AdMob SDK,有一些自己的方法,但不是最新版本,下载最新版本的同学注意Android系统版本最好超过3.2,否则广告栏会显示一段错误。classes.jar是Unity里面自带的一个jar包,通过搜寻就可以知道位置,羽化就不再介绍。
如果不出意外,现在应该完全不会报错,报错了请看上面的注意和Eclipse报错原因。。。下面我们看代码
AdMob.java
package com.LB.AdMob; //必须改变 import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.animation.AccelerateInterpolator; import android.view.animation.AlphaAnimation; import android.widget.LinearLayout; import android.os.Message; import com.unity3d.player.*; import com.admob.android.ads.AdView; import com.admob.android.ads.SimpleAdListener; public class AdMob extends UnityPlayerActivity { public AdView adView; private boolean adVisible = true; protected void onCreate(Bundle savedInstanceState) { Log.i("AdMob", "onCreate"); super.onCreate(savedInstanceState); setupAds(); } private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 0: if(adVisible) { adView.setVisibility(View.GONE); adVisible = false; } break; case 1: if (!adVisible) { adView.setVisibility(View.VISIBLE); AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f); animation.setDuration(400); animation.setFillAfter(true); animation.setInterpolator(new AccelerateInterpolator()); adView.startAnimation(animation); adVisible = true; } break; default: break; } } }; public void EnableAds() { handler.sendEmptyMessage(1); } public void DisableAds() { handler.sendEmptyMessage(0); } private void setupAds() { LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); addContentView(layout, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); adView = new AdView(this); layout.addView(adView, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); adView.setBackgroundColor(0xff000000); adView.setPrimaryTextColor(0xffffffff); adView.setSecondaryTextColor(0xffcccccc); adView.setKeywords("kickoff Goal Pinball game spiel bundesliga male Flipper Bumper Parlotones kick off 3d soccer fussball football tor vuvuzela"); // adView.setRequestInterval(20); //设置自动出现频率 // add listener for easier debugging adView.setAdListener( new SimpleAdListener() { public void onFailedToReceiveAd(com.admob.android.ads.AdView adView) { Log.d("AdListener", "onFailedToReceiveAd: " + adView.toString()); super.onFailedToReceiveAd(adView); } public void onFailedToReceiveRefreshedAd(com.admob.android.ads.AdView adView) { Log.d("AdListener", "onFailedToReceiveRefreshedAd: " + adView.toString()); super.onFailedToReceiveRefreshedAd(adView); } public void onReceiveAd(com.admob.android.ads.AdView adView) { Log.d("AdListener", "onReceiveAd: " + adView.toString()); super.onReceiveAd(adView); } public void onReceiveRefreshedAd(com.admob.android.ads.AdView adView) { Log.d("AdListener", "onReceiveRefreshedAd: " + adView.toString()); super.onReceiveRefreshedAd(adView); } } ); adView.requestFreshAd(); } }
和AndroidMainifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.LB.AdMob" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".AdMob" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- The application's publisher ID assigned by AdMob //android:value中放入使用者ID --> <meta-data android:value="a14ddb78fc3babe" android:name="ADMOB_PUBLISHER_ID" /> <!-- AdMobActivity definition --> <activity android:name="com.admob.android.ads.AdMobActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation|keyboard|keyboardHidden" /> <!-- Track Market installs --> <receiver android:name="com.admob.android.ads.analytics.InstallReceiver" android:exported="true"> <intent-filter> <action android:name="com.android.vending.INSTALL_REFERRER" /> </intent-filter> </receiver> </application> <!-- AdMob SDK requires Internet permission --> <uses-permission android:name="android.permission.INTERNET" /> </manifest>
这是个典型的Android项目代码,有几点注意下,1.如果想用在自己的应用上,就照着羽化的引用结构自己新建一个工程,把这两个文件中所有的羽化自定义名称换掉即可。2. android:value中填入自己申请的AdMob ID。3.羽化把代码简化到最少,所以并没用使用res中的所有内容,若想自定义图标等就需要自己去修改AndroidManifests实现。4.这个可以加上阻止休眠命令,在羽化上一篇Android博客里面有提到。5.Unity中的Bundle Identifier必须与这里定义的package一致。6.这时把Eclipse项目运行肯定报错。7.这里只写了广告淡出效果,没写淡入效果- - 大家凑合看吧。。。
当上面的都没问题后就把AdMob.java打jar包,方法是选中AdMob鼠标右键 -> Export -> java -> JAR file -> Next
选择你的到处路径和名称JAR file,直接Finish,这样的jar包里面只包括编译后的AdMob.class,很小很干净。。。然后打开羽化的Unity工程AdMobTest(File- > Open Project),双击UnityAdMob这个Sence,可以看到只有一个相机。。。上面只有一个脚本Ad.cs。
Ad.cs
using UnityEngine; using System.Collections; using System; public class Ad : MonoBehaviour { void OnGUI() { if(Input.GetKey(KeyCode.Escape)) { Application.Quit(); } if(GUI.Button(new Rect(0,Screen.height-220,100,100),"EnableAds!")) { EnableAds(); } if(GUI.Button(new Rect(0,Screen.height-110,100,100),"DisableAds!")) { DisableAds(); } if(GUI.Button(new Rect(Screen.width-120,Screen.height-40,120,30),"Click to YUHUA!")) { Application.OpenURL("http://blog.csdn.net/libeifs"); } } public void EnableAds() { #if UNITY_ANDROID AndroidJNI.AttachCurrentThread(); // first we try to find our main activity.. IntPtr cls_Activity = AndroidJNI.FindClass("com/unity3d/player/UnityPlayer"); IntPtr fid_Activity = AndroidJNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;"); IntPtr obj_Activity = AndroidJNI.GetStaticObjectField(cls_Activity, fid_Activity); //Debug.Log("obj_Activity = " + obj_Activity); IntPtr cls_OurAppNameActivityClass = AndroidJNI.FindClass("com/LB/AdMob/AdMob"); //this has to be changed IntPtr startAdsMethod = AndroidJNI.GetMethodID(cls_OurAppNameActivityClass, "EnableAds", "()V"); //Debug.Log("m_startAdsMethod = " + startAdsMethod); if (AndroidJNI.IsInstanceOf(obj_Activity, cls_OurAppNameActivityClass) != false) { //Debug.Log("Activity IS a OurAppNameActivity"); jvalue[] myArray = new jvalue[1]; AndroidJNI.CallVoidMethod(obj_Activity, startAdsMethod,myArray); } #else m_adShowing = true; #endif //UNITY_ANDROID } public void DisableAds() { #if UNITY_ANDROID AndroidJNI.AttachCurrentThread(); // first we try to find our main activity.. IntPtr cls_Activity = AndroidJNI.FindClass("com/unity3d/player/UnityPlayer"); IntPtr fid_Activity = AndroidJNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;"); IntPtr obj_Activity = AndroidJNI.GetStaticObjectField(cls_Activity, fid_Activity); IntPtr cls_OurAppNameActivityClass = AndroidJNI.FindClass("com/LB/AdMob/AdMob"); //this has to be changed IntPtr stopAdsMethod = AndroidJNI.GetMethodID(cls_OurAppNameActivityClass, "DisableAds", "()V"); if (AndroidJNI.IsInstanceOf(obj_Activity, cls_OurAppNameActivityClass) != false) { jvalue[] myArray = new jvalue[1]; AndroidJNI.CallVoidMethod(obj_Activity, stopAdsMethod,myArray); } #else //UNITY_ANDROID m_adShowing = false; #endif //UNITY_ANDROID } }
看起很简单,确实也不难,首先建立Plugins -> Android -> bin | libs这个文件集,把Eclipse项目里面的AndroidManifest.xml放在Android目录下,把打包的UnityAdMob.jar放在bin下,把这个重写的AdMob SDK放在libs下,注意:把Bundle Identifier设置成和Eclipse项目包一样的名字,就算没有Ad.cs程序运行也会执行一次广告,这个C#类只是个广告开关,还有里面的两个AndroidJNI.FindClass("XXX")自行修改。。。
运行效果: (有空就帮羽化点下广告吧- -)
这个应该能满足大部分广告显示方式,置于显示位置就麻烦大家自行修改了,谢谢大家支持~ ~
老样子,项目送上:
http://dl.dbank.com/c0ya3iynro
下集预告:
Thinking inShader(5)