Android游戏替换免费版Unity自带的启动页Logo

it2024-07-28  37

思路

使用免费版的Unity开发Android端游戏时,在启动游戏时会展示Unity自带的Logo动画。那有没有办法在不花钱的前提下把Unity自带Logo替换成自己的Logo呢?有两个思路:

破解Unity编辑器,然后使用Unity自带功能替换Logo使用障眼法,在Unity的Logo之上添加自定义的View,盖住Unity自带Logo。

理论基础

我们选择第二种方案。该方案的原理也不难理解,Unity的Logo动画应该是在Android层实现的,它其实也是一个SplashView,最早展现给我们看。那么我们就可以在SplashView之上添加自定义的满屏CustomSplashView盖在原理的SplashView之上,用户自然只能看到自定义的CustomeSplashView了。

Android Apk都必须有一个AndroidManifest.xml文件,该文件会指定第一个启动的Activity,Unity2018版本使用的AndroidManifest.xml模板路径为Unity安装路径下的Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Apk\AndroidManifest.xml。

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal"> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true"/> <application android:theme="@style/UnityThemeSelector" android:icon="@mipmap/app_icon" android:label="@string/app_name"> <activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> </activity> </application> </manifest>

以上配置文件可以看出,所有Unity Android游戏第一个被启动的Activity名字是UnityPlayerActivity,参考官方文档扩展UnityPlayerActivity Java代码,我们也扩展UnityPlayerActivity,在里面添加自定义的启动页CustomSplashView。

Android端实现

创建一个Module,在该Module下实现继承UnityPlayerActivity实现CustomSplashActivity,在SplashActivity 的onCreate方法中添加自定义SplashView,代码如下: package com.ccmm.lib; import android.content.res.Resources; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.Log; import android.view.ViewGroup; import android.widget.ImageView; import com.unity3d.player.UnityPlayerActivity; import androidx.annotation.Nullable; /** * Created by xujinping on 2020/10/20. */ public class SplashActivity extends UnityPlayerActivity { private ImageView bgView; private static String TAG = "XJP"; @Override public void onCreate(@Nullable Bundle savedInstanceState) { Log.i(TAG, "onCreate: start"); super.onCreate(savedInstanceState); WindowManager.LayoutParams lp = getWindow().getAttributes(); //设置水滴屏,刘海屏全屏显示,避免水滴屏,刘海屏顶部黑 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; } Log.i(TAG, "onCreate: end"); showSplashView(); } /** * 展示自定义启动页,简单实现该启动页直接贴一张图片 * 也可以加文字,动画等,如需要实现内容丰富的启动页,自定义一个layout布局比较方便 */ public void showSplashView() { Log.i(TAG, "showSplashView: start"); Resources r = getResources(); //动态创建ImageView bgView = new ImageView(this); // int splash_bg = R.drawable.splash; //动态获取splash.png图片资源的id。启动页图片的名字叫splash.png,图片放在Android工程的res/drawable/splash.png int splash_bg = r.getIdentifier("splash", "drawable", getPackageName()); //动态设置图片布局参数 ViewGroup.LayoutParams param = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); DisplayMetrics displayMetrics = r.getDisplayMetrics(); //设置图片宽为屏幕宽度 param.width = displayMetrics.widthPixels; //设置图片宽度拉伸/缩放至屏幕宽度(等比例缩放),高度居中显示,上下裁剪 bgView.setScaleType(ImageView.ScaleType.CENTER_CROP); //设置Imageview的图片资源 bgView.setBackgroundResource(splash_bg); //设置ImageView布局参数 bgView.setLayoutParams(param); //添加自定义的启动页,看源码mUnityPlayer是一个FrameLayout。 mUnityPlayer.addView(bgView); Log.i(TAG, "showSplashView: end"); } /** * 移除自定义启动页,这一方法在Unity端找合适时机条用, * 由于不能确定Unity调用该方法是否在UI线程,因此,此处移除操作放在UI线程,确保操作UI安全 */ public void removeSplashView() { if (bgView == null) { return; } runOnUiThread(new Runnable() { @Override public void run() { Log.i(TAG, "removeSplashView: start"); mUnityPlayer.removeView(bgView); bgView = null; } }); } }

以上代码注释写的很清楚每一步都是干嘛的。

splash.png图片资源放在res/drawable/splash.png。将Module打包成aar包,提供给Unity使用。

Unity端实现

将Android打包成的aar放在Unity工程 Assets/Plugins/Android/ 目录下。修改上面的AndroidManifest.xml配置文件,使得Android apk第一个启动的Activity 为我们重写的SplashActivity ,代码如下: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal"> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true"/> <application android:theme="@style/UnityThemeSelector" android:icon="@mipmap/app_icon" android:label="@string/app_name"> <activity android:name="com.ccmm.lib.SplashActivity " android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> </activity> </application> </manifest> 将修改过的AndroidManifest.xml文件放在Assets/Plugins/Android/ 目录下,Unity打包的使用就会使用这份配置文件。在Unity端找个合适的时机,当Unity的第一个场景加载完全可见时,移除自定义的启动页。Unity端代码如下: public void RemoveSplashView() { AndroidJavaClass ajc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = ajc.GetStatic<AndroidJavaObject>("currentActivity"); currentActivity.Call("removeSplashView"); }

总结

1.以上方案并没有真正替换掉Unity logo,只是添加一个新的SplashView来盖住Unity Logo 2.测试发现并没有找到很好的做到Android端的启动页SplashView和Unity端的第一个场景无缝切换。 3.以上部分内容参考网络上资源。

最新回复(0)