# Calling C# code from Java and Kotlin plug-in code

> Call C# script code from your Java and Kotlin plug-in code.

Java and Kotlin plug-in code can call your C# scripts, for example, to notify Unity of an Android event or to return a result from your plug-in code. There are two ways to do this:

* Send a message to a GameObject with `UnitySendMessage`.
* Call a C# method through a callback interface with [AndroidJavaProxy](/engine/6000.6/script-reference/unityengine/androidjavaproxy.md).

For the equivalent C# to Java and Kotlin implementation, refer to [Calling Java and Kotlin plug-in code from C# scripts](/engine/6000.6/manual/platform-specific/android/developing/plugins-for/plugins-java-code-from-c-sharp.md).

> **Note:**
>
> To debug either approach, set [AndroidJNIHelper.debug](/engine/6000.6/script-reference/unityengine/androidjnihelper/debug.md) to `true` to log the JNI activity that Unity performs for each call.

## Send a message to a GameObject

Use `UnitySendMessage` to send a string from Java or Kotlin plug-in code to a method on a named GameObject. This is a one-way call where the C# method receives the string but doesn't return a value to the plug-in. Use it for simple notifications.

The plug-in calls `UnitySendMessage` with three arguments: the name of the target GameObject, the name of the method to call, and the string message.

The following Java example implements `UnitySendMessage`:

```lang-java
package com.example.androidplugin;

import com.unity3d.player.UnityPlayer;

public class MessageSender {
    public static void sendToUnity(String gameObjectName) {
        UnityPlayer.UnitySendMessage(gameObjectName, "OnMessageReceived", "Hello from Java");
    }
}
```

The following Kotlin example implements `UnitySendMessage`:

```lang-kotlin
package com.example.androidplugin

import com.unity3d.player.UnityPlayer

object MessageSender {
    @JvmStatic
    fun sendToUnity(gameObjectName: String) {
        UnityPlayer.UnitySendMessage(gameObjectName, "OnMessageReceived", "Hello from Kotlin")
    }
}
```

In your C# script, add the method that `UnitySendMessage` calls. Ensure the script is attached to a GameObject whose name matches the first argument.

```lang-cs
using UnityEngine;

public class MessageReceiver : MonoBehaviour
{
    void Start()
    {
        gameObject.name = "MessageReceiver";
        using var sender = new AndroidJavaClass("com.example.androidplugin.MessageSender");
        sender.CallStatic("sendToUnity", gameObject.name);
    }

    void OnMessageReceived(string message)
    {
        Debug.Log("Message from plug-in: " + message);
    }
}
```

This example:

1. Sets the GameObject's name to match the target name the plug-in sends.
2. Calls the plug-in, which uses `UnitySendMessage` to send a string back to the `OnMessageReceived` method on the named GameObject.
3. Logs the message that the plug-in sends.

> **Note:**
>
> In this example, C# calls the plug-in directly to trigger the message, so you can run the example without an Android event. In a real project, the plug-in calls `UnitySendMessage` in response to an Android event, such as a button tap or a lifecycle callback.

`UnitySendMessage` has the following limitations:

* You can only call C# methods with the signature `void MethodName(string message)`.
* Calls are asynchronous and have a delay of one frame.
* Multiple GameObjects with the same name can cause conflicts.

To send data other than a string, serialize it to a JSON string. For more information, refer to [Supported data types for Java/Kotlin and C# code](/engine/6000.6/manual/platform-specific/android/developing/plugins-for/plugins-java-code-from-c-sharp/datatypes-java-kotlin-csharp.md).

## Call a C# method through a callback interface

Use [AndroidJavaProxy](/engine/6000.6/script-reference/unityengine/androidjavaproxy.md) to implement a Java or Kotlin interface in C#. When the plug-in calls a method on the interface, Unity runs your C# implementation. Use this approach for typed callbacks, or to pass structured data or return values.

Define an interface in the plug-in and a class that calls it. The following plug-in code calls the interface method to pass a message back to C#.

### Java plug-in code

```lang-java
package com.example.androidplugin;

public class Greeter {
    public interface GreetingCallback {
        void onGreeting(String message);
    }

    public void requestGreeting(GreetingCallback callback) {
        callback.onGreeting("Hello from Java");
    }
}
```

\### Kotlin plug-in code

```lang-kotlin
package com.example.androidplugin

class Greeter {
    interface GreetingCallback {
        fun onGreeting(message: String)
    }

    fun requestGreeting(callback: GreetingCallback) {
        callback.onGreeting("Hello from Kotlin")
    }
}
```

In your C# script, create a class that derives from `AndroidJavaProxy` and implements the interface. Pass an instance of this class to the plug-in.

```lang-cs
using UnityEngine;

public class GreetingExample : MonoBehaviour
{
    class GreetingCallback : AndroidJavaProxy
    {
        public GreetingCallback() : base("com.example.androidplugin.Greeter$GreetingCallback") { }

        void onGreeting(string message)
        {
            Debug.Log("Greeting from plug-in: " + message);
        }
    }

    void Start()
    {
        using var greeter = new AndroidJavaObject("com.example.androidplugin.Greeter");
        greeter.Call("requestGreeting", new GreetingCallback());
    }
}
```

This example:

1. Creates a C# `GreetingCallback` class that derives from `AndroidJavaProxy` and passes the interface name to the base constructor. Because `GreetingCallback` is nested in the `Greeter` class, the name uses the `$` separator: `com.example.androidplugin.Greeter$GreetingCallback`.
2. Implements `onGreeting` with a signature that matches the interface method. Unity automatically routes calls on the interface to this C# implementation.
3. Creates an `AndroidJavaObject` for the `Greeter` plug-in class and calls `requestGreeting`, passing the proxy. The plug-in then calls `onGreeting`, which runs the C# implementation.

> **Note:**
>
> In this example, the plug-in calls the interface method on Unity's main thread. If your plug-in calls the method from a background thread, the C# implementation also runs on the background thread. In this case, use [AndroidApplication.InvokeOnUnityMainThread](/engine/6000.6/script-reference/unityengine/android/androidapplication/invokeonunitymainthread.md) to run any Unity API calls on the main thread.

For more information on writing the plug-in code, refer to [Java and Kotlin source plug-ins](/engine/6000.6/manual/platform-specific/android/developing/plugins-for/plugin-types/java-source-plugins.md).

## Additional resources

* [Java Native Interface APIs in Unity](/engine/6000.6/manual/platform-specific/android/developing/plugins-for/plugins-java-code-from-c-sharp/jni-apis-unity.md)
* [Supported data types for Java/Kotlin and C# code](/engine/6000.6/manual/platform-specific/android/developing/plugins-for/plugins-java-code-from-c-sharp/datatypes-java-kotlin-csharp.md)
* [Best practices for calling Java/Kotlin code](/engine/6000.6/manual/platform-specific/android/developing/plugins-for/plugins-java-code-from-c-sharp/call-java-kotlin-code-best-practices.md)
