Last active
November 17, 2024 23:23
-
-
Save HassakuTb/7141b2065210709399404c59e1846591 to your computer and use it in GitHub Desktop.
Reimplementation of UnityPlayerActivity with AppCompatActivity and Kotlin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="com.hassakulab.unitybridgesample" | |
xmlns:tools="http://schemas.android.com/tools"> | |
<application | |
android:allowBackup="true" | |
android:label="@string/app_name" | |
android:supportsRtl="true" | |
android:theme="@style/Theme.UnityBridgeSample"> | |
<activity android:name=".UnityPlayerActivity" | |
tools:node="merge" /> | |
</application> | |
</manifest> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
plugins { | |
id 'com.android.library' | |
id 'kotlin-android' | |
} | |
android { | |
compileSdkVersion 30 | |
buildToolsVersion "30.0.2" | |
defaultConfig { | |
minSdkVersion 24 | |
targetSdkVersion 30 | |
versionCode 1 | |
versionName "1.0" | |
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | |
} | |
buildTypes { | |
release { | |
minifyEnabled false | |
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | |
} | |
} | |
compileOptions { | |
sourceCompatibility JavaVersion.VERSION_1_8 | |
targetCompatibility JavaVersion.VERSION_1_8 | |
} | |
kotlinOptions { | |
jvmTarget = '1.8' | |
} | |
} | |
dependencies { | |
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" | |
implementation 'androidx.core:core-ktx:1.3.2' | |
implementation 'androidx.appcompat:appcompat:1.2.0' | |
implementation 'com.google.android.material:material:1.3.0' | |
// copy classes.jar to libs from \Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes | |
compileOnly fileTree(dir: "libs", includes: ['unity-classes.jar']) | |
testImplementation 'junit:junit:4.+' | |
androidTestImplementation 'androidx.test.ext:junit:1.1.2' | |
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.hassakulab.unitybridgesample | |
import android.content.ComponentCallbacks2 | |
import android.content.Intent | |
import android.content.res.Configuration | |
import android.os.Bundle | |
import android.util.Log | |
import android.view.KeyEvent | |
import android.view.MotionEvent | |
import android.view.Window | |
import androidx.appcompat.app.AppCompatActivity | |
import com.unity3d.player.IUnityPlayerLifecycleEvents | |
import com.unity3d.player.UnityPlayer | |
class UnityPlayerActivity : AppCompatActivity(), IUnityPlayerLifecycleEvents{ | |
// don't change the name of this variable; referenced from native code | |
protected var mUnityPlayer: UnityPlayer? = null | |
// Override this in your custom UnityPlayerActivity to tweak the command line arguments passed to the Unity Android Player | |
// The command line arguments are passed as a string, separated by spaces | |
// UnityPlayerActivity calls this from 'onCreate' | |
// Supported: -force-gles20, -force-gles30, -force-gles31, -force-gles31aep, -force-gles32, -force-gles, -force-vulkan | |
// See https://docs.unity3d.com/Manual/CommandLineArguments.html | |
// @param cmdLine the current command line arguments, may be null | |
// @return the modified command line string or null | |
protected fun updateUnityCommandLineArguments(cmdLine: String?): String?{ | |
return cmdLine | |
} | |
// Setup activity layout | |
protected override fun onCreate(savedInstanceState: Bundle?) { | |
requestWindowFeature(Window.FEATURE_NO_TITLE) | |
super.onCreate(savedInstanceState) | |
val cmdLine: String? = updateUnityCommandLineArguments(intent.getStringExtra("unity")) | |
intent.putExtra("unity", cmdLine) | |
mUnityPlayer = UnityPlayer(this, this) | |
setContentView(mUnityPlayer) | |
mUnityPlayer?.requestFocus() | |
} | |
// When Unity player unloaded move task to background | |
override fun onUnityPlayerUnloaded() { | |
moveTaskToBack(true) | |
} | |
// Callback before Unity player process is killed | |
override fun onUnityPlayerQuitted() { | |
} | |
protected override fun onNewIntent(intent: Intent?) { | |
super.onNewIntent(intent) | |
// To support deep linking, we need to make sure that the client can get access to | |
// the last sent intent. The clients access this through a JNI api that allows them | |
// to get the intent set on launch. To update that after launch we have to manually | |
// replace the intent with the one caught here. | |
setIntent(intent) | |
mUnityPlayer?.newIntent(intent) | |
} | |
// Quit Unity | |
protected override fun onDestroy(){ | |
mUnityPlayer?.destroy() | |
super.onDestroy() | |
} | |
// Pause Unity | |
protected override fun onPause() { | |
super.onPause() | |
mUnityPlayer?.pause() | |
} | |
// Resume Unity | |
protected override fun onResume() { | |
super.onResume() | |
mUnityPlayer?.resume() | |
} | |
// Low Memory Unity | |
override fun onLowMemory() { | |
super.onLowMemory() | |
mUnityPlayer?.lowMemory() | |
} | |
// Trim Memory Unity | |
override fun onTrimMemory(level: Int) { | |
super.onTrimMemory(level) | |
if(level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL){ | |
mUnityPlayer?.lowMemory() | |
} | |
} | |
// This ensures the layout will be correct. | |
override fun onConfigurationChanged(newConfig: Configuration) { | |
super.onConfigurationChanged(newConfig) | |
mUnityPlayer?.configurationChanged(newConfig) | |
} | |
// Notify Unity of the focus change. | |
override fun onWindowFocusChanged(hasFocus: Boolean) { | |
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 fun dispatchKeyEvent(event: KeyEvent?): Boolean { | |
if(event?.action == KeyEvent.ACTION_MULTIPLE){ | |
return mUnityPlayer?.injectEvent(event) ?: super.dispatchKeyEvent(event) | |
} | |
return super.dispatchKeyEvent(event) | |
} | |
// Pass any events not handled by (unfocused) views straight to UnityPlayer | |
override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { | |
return mUnityPlayer?.injectEvent(event) ?: super.onKeyUp(keyCode, event) | |
} | |
// Pass any events not handled by (unfocused) views straight to UnityPlayer | |
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { | |
return mUnityPlayer?.injectEvent(event) ?: super.onKeyDown(keyCode, event) | |
} | |
// Pass any events not handled by (unfocused) views straight to UnityPlayer | |
override fun onTouchEvent(event: MotionEvent?): Boolean { | |
return mUnityPlayer?.injectEvent(event) ?: super.onTouchEvent(event) | |
} | |
override fun onGenericMotionEvent(event: MotionEvent?): Boolean { | |
return mUnityPlayer?.injectEvent(event) ?: super.onGenericMotionEvent(event) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Manual for using AppCompatActivity in Unity
environments
make AAR
fix build process for Unity in UnityEditor
create custom template files via PlayerSettings
AndroidManifest.xml
gradleTemplate.properties
mainTemplate.gradle