Call Unity3D Methods from Java Plugins using Reflection
How to call Unity Methods from Java Plugins that you write for Unity3D-Android.
Unity is a great game engine to develop mobile games. It brings a lot of functionality with easy to use tools. But as you go deeper in creating Android games with Unity there comes a time when you have to extend Unity by your own Android Java plugins.
Unity's documentation is decent enough to get started. Sometimes in your Java code You need to call a Unity method. Unity has a way to do it through UnitySendMessage which is available when you extend UnityPlayerActivity (Or UnityPlayerNativeActivity). But I didn't want to extend UnityPlayerActivity, instead I wanted to write plugins for different jobs and make them useful in other projects too. I wanted to have several plugins for different jobs and seperated from each other so extending UnityPlayerActivity was not a good choice.
By the way, you may have 3rd-party plugins that already extend UnityPlayerActivity. In this article you will learn how to do it in this way (not extending UnityPlayerActivity)
NOTE: I suppose you know already how to create a Java plugin for unity. If you don't please see Unity's Documentation.
Unity Part
In Unity you have to prepare a GameObject with a name. In this article I use the default GameObject that you have when you create a new scene in Unity, Main Camera. Rename "Main Camera" to "MainCamera" (We will use this name in Java to call a Unity Method in the future).
Then write a script that contains a public method which receives a string as input and returns nothing (void) This is the method that's going to be called. Its name is also important because it is also used in Java code. maybe some method like this:
public void OnJavaCall(string message)
{
Debug.Log(message);
} I kept it as simple as possible, the method just logs the message. Attach the script that you just wrote to the MainCamera.
The Java Part
In your Java code you can now call the method (OnJavaCall in this example). You have to write out code similar to what's shown below:
public static void CallUnityFunc(Activity activity)
{
Log.i(Tag, "Calling unity function");
try
{
Field UnityPlayer = activity.getClass().getDeclaredField("mUnityPlayer");
UnityPlayer.setAccessible(true);
Method method = UnityPlayer.getType().getDeclaredMethod("UnitySendMessage", String.class,String.class,String.class);
method.setAccessible(true);
method.invoke(activity, "MainCamera","OnJavaCall","Hello Unity , From Java");
}
catch(Exception e)
{
Log.e(Tag,e.getClass().toString()+" "+ e.getMessage());
}
} I wrote a static method that takes an Activity as input. We will pass the Unity player to this Method in the future. In the method declaration as you can see I use reflection to call the UnitySendMessage. UnitySendMessage takes three parameters : The GameObject's name (MainCamera in this example), Method's name (OnJavaCall here), and the message that is going to be sent as an arguement to our method (OnJavaCall).
To test it now you have to compile your plugin (which is an Android library project) to generate a .jar file. After that you know of course you have to copy the .jar file to your Unity project.
Back to Unity
Then in Unity, call that static method (CallUnityFunc here) we wrote in Java to see how it works. for example:
AndroidJavaClass classPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject activity = classPlayer.GetStatic("currentActivity");
AndroidJavaClass PluginClass = new AndroidJavaClass("com.helper.bazaarpayment.PluginClass");
// put your own package and class name accordingly to your Java plugin
//so let's call it
PluginClass.CallStatic("CallUnityFunc",activity); Note that this code will not work until you actually run it on an Android device. It's good to check for runtime platform through Application.platform. Note that when you make this call to Java, The MainCamera (containing the script that has OnJavaCall) that we created must be present, otherwise there won't be any GameObject with name MainCamera that has a OnJavaCall method.
You may want to use GameObject.DontDestroyOnLoad to ensure you have MainCamera in all places. Compile and run to see how it works. You can use the adb interface located at platform-tools folder in your Android sdk folder. With command: adb logcat -s Unity you can see Unity logs.
With this approach you don't have to extend UnityPlayerActivity. You can have self-contained plugins for distinct tasks. You can also leave 3rd-party plugins that extend UnityPlayerActivity to work untouched.
Recommended resources
Game Engines
Unreal Engine 5 Best Practices
Amazon · Book
Written by multi-award-winning Unreal generalist Tyson J. Butler-Boschma, Founder and Creative Director of Toybox Games Studios, this book addresses common challenges you face when advancing your expertise in lighting, environment design, and cinematic storytelling.
GameDev.net may earn a commission if you purchase through these links. This helps fund the site at no extra cost to you.
Related Tutorials
Ai image to 3D Game ready model and animation in 3 minutes
No 3D modeling or animation skills? No problem! In this video, a professional 3D artist, demonstrates how to create a f…
alex_cgw
Unreal Engine: Creation of Parallax Occlusion Mapping (POM) in details
Parallax Occlusion Mapping (POM) is a complex texture-based approach to add more details for meshes. With POM we get mo…
Generating a SoulerCoaster in Unity
Learn to create a basic SoulerCoaster effect in Unity.
Creating Promo Art: The Process | Hyperclass Ark
Our artist, Philip Bell, discussed the stages involved in creating promotional artwork for the project.
Lessons, Stages of drawing Digital illustration "Fairytale house in the forest"
At the beginning of this illustration, I did the rough sketch, then drawing the outline, then painting in color, applyi…
Lessons, Stages of drawing "Magic book"
At the beginning of this illustration, I did the rough sketch, then drawing the outline, then painting in color, applyi…
Discussion