Call Unity Function from Java

Call Unity function from Java

You can call C# function from Java with UnityPlayer.UnitySendMessage.

This is the what the parameters look like:

UnityPlayer.UnitySendMessage("GameObjectName", "MethodName", "parameter to send");

In order to have access to this function, you have to include classes.jar from the <UnityInstallDirectory>\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes directory into your Android Studio project then import it with import com.unity3d.player.UnityPlayer; in the Android Studio Project.

Your C# code:

bool rotate = false;

void startRotating()
{
rotate = true;
}

void stopRotating()
{
rotate = false;
}

void Update()
{
if (rotate)
transform.Rotate(10f, 50f, 10f);
}

Let's assume that the script above is attached to GameObject called "Cube".

To start rotation from Java:

UnityPlayer.UnitySendMessage("Cube", "startRotating", null);

To stop rotation from Java:

UnityPlayer.UnitySendMessage("Cube", "stopRotating", null);

How to call unity C# functions from Android plugin?

Try this:

UnityPlayer.UnitySendMessage("gameobjectname", "methodname", "message");

Access method from android plugin in unity

Unity Plugin development is a bit tricky to get setup at first but once you are able to it is pretty powerful.

Couple things.

1) You are using an AndroidJavaClass and trying to call a non static method in java. Your method in your plugin should be static if you are wanting to use that class.

2) Otherwise you will need to use an AndroidJavaObject to construct your class and then you should be able to call your function.

Hope this helps!

Example Using non Static Code:

Unity Code

   using (AndroidJavaObject leetPlugin = new AndroidJavaObject("alarm.company.com.unity.myPlugin")){
string s = leetPlugin.Call("myTest", 9);
print(s);
text.text = s;
}

Android Code

public void myTest(int value) {
return "Your value is " + value;
}

Unity: Call Android Kotlin Function Inside Companion Object from Unity

In order to understand what's wrong with your implementation actually you need to decompile your Kotlin code to Java code and implement the Unity part based on the Java code, not Kotlin.

Let's have a simple example of Kotlin code, which will print Logs, nothing more:

class MyKotlinClass(val name: String = "DEFAULT NAME") {
fun callNormalFunc() {
Log.d("UNITY", "callNormalFunc from Kotlin code")
}
companion object {
@JvmStatic
fun callStaticCompanionFunc(): MyKotlinClass {
Log.d("UNITY", "callStaticCompanionFunc from Kotlin code")
return MyKotlinClass("NEW NAME")
}
}
}

And the decompiled Java code looks like this:

public final class MyKotlinClass {
@NotNull
private final String name;
@NotNull
public static final MyKotlinClass.Companion Companion = new MyKotlinClass.Companion((DefaultConstructorMarker)null);

public final void callNormalFunc() {
Log.d("UNITY", "callNormalFunc from Kotlin code");
}

@NotNull
public final String getName() {
return this.name;
}

public MyKotlinClass(@NotNull String name) {
Intrinsics.checkNotNullParameter(name, "name");
super();
this.name = name;
}

// $FF: synthetic method
public MyKotlinClass(String var1, int var2, DefaultConstructorMarker var3) {
if ((var2 & 1) != 0) {
var1 = "DEFAULT NAME";
}

this(var1);
}

public MyKotlinClass() {
this((String)null, 1, (DefaultConstructorMarker)null);
}

@JvmStatic
@NotNull
public static final MyKotlinClass callStaticCompanionFunc() {
return Companion.callStaticCompanionFunc();
}

public static final class Companion {
@JvmStatic
@NotNull
public final MyKotlinClass callStaticCompanionFunc() {
Log.d("UNITY", "callStaticCompanionFunc from Kotlin code");
return new MyKotlinClass("NEW NAME");
}

private Companion() {
}

// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}

As we can see from the decompiled code actually we can call the function marked as @JvmStatic in two ways. First directly from our object and second using the Companion object.

Unity code this using this call will look like:

public class KotlinCallScript : MonoBehaviour {

private AndroidJavaObject _object;
private AndroidJavaClass _staticClass;
// Start is called before the first frame update
private void Start () {
_object = new AndroidJavaObject ("com.hardartcore.kotlin.MyKotlinClass");
_staticClass = new AndroidJavaClass ("com.hardartcore.kotlin.MyKotlinClass");
var defaultName = _object.Call<string> ("getName");
Debug.Log ("START GET DEFAUL NAME: " + defaultName);
}

public void CallNormalFunction () {
_object.Call ("callNormalFunc");
}

public void CallStaticFunction () {
var companionObject = _staticClass.GetStatic<AndroidJavaObject> ("Companion");
var newName = companionObject.Call<AndroidJavaObject> ("callStaticCompanionFunc").Call<string> ("getName");
Debug.Log ("CALL STATIC FUNCTION NEW NAME: " + newName);
}

public void CallSecondWay () {
var kotlinObject = _object.CallStatic<AndroidJavaObject> ("callStaticCompanionFunc");
var newName = kotlinObject.Call<string> ("getName");
Debug.Log ("CALL SECOND WAY NEW NAME: " + newName);
}

}

It's up to you which way you will prefer.

My suggestion is to look at your decompiled Java code, post it here so we can understand why it's not working.



Related Topics



Leave a reply



Submit