- Home /
Access Unity Script Function From External Program
Hello,
I've been trying to create a simple, external C++ program that executes a specific script function in Unity. Using various example found on the forums, I started by creating a native plugin (c++ dll) and I'm able to execute a function in the plugin from Unity, but the only way I've been able to execute a Unity script function from the plugin is if Unity initiates the function call. I'll post the code, hopefully you can see what I'm doing:
.dll header
#pragma once
#if TESTDLL_EXPORTS
#define API extern "C" __declspec(dllexport)
#else
#define API extern "C" __declspec(dllimport)
#endif
typedef void(__stdcall* UnitySendMessageFunc)(const char* gameObjectName, const char* methodName, const char* message);
UnitySendMessageFunc UnitySendMessage;
API void __stdcall SetUnitySendMessageCallback(UnitySendMessageFunc sendMessageCallback);
API int test();
typedef int(__stdcall *ANSWERCB)();
static ANSWERCB cb;
API void TakesCallback(ANSWERCB fp);
.dll cpp:
//UnitySendMessage = nullptr;
API void __stdcall SetUnitySendMessageCallback(UnitySendMessageFunc sendMessageCallback)
{
UnitySendMessage = sendMessageCallback;
}
API int test()
{
std::cout << "test";
return 34;
}
API void TakesCallback(ANSWERCB fp)
{
UnitySendMessage("Sphere", "CallTest", "123456789"); //This only works if Unity calls TakesCallback
cb = fp;
}
Here is the Test.cpp that is to execute the Unity Function:
#include "stdafx.h"
#include "testdll.h"
#include <iostream>
#include <future>
#include <windows.h>
//#pragma comment (lib,"testdll.lib")
int main()
{
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
std::cout << clock() / 1000 << " seconds have passed" << std::endl;
UnitySendMessage("Sphere", "CallTest", "123456789"); //This Creates the Access Violation error/crash
//TakesCallback(cb);
//std::cout << test();
}
return 0;
}
And finally the Unity Script:
public class UnityPlugin2 : MonoBehaviour
{
public delegate int myCallbackDelegate();
int myCallback()
{
return 234;
}
public delegate void UnitySendMessageDelegate([MarshalAs(UnmanagedType.LPStr)]string gameObjectName, [MarshalAs(UnmanagedType.LPStr)]string methodName, [MarshalAs(UnmanagedType.LPStr)]string message);
private static UnitySendMessageDelegate s_SendMessageDelegate;
[DllImport("testdll")]
private static extern void SetUnitySendMessageCallback(UnitySendMessageDelegate sendMessage);
[DllImport("testdll")]
private static extern void TakesCallback(myCallbackDelegate fp);
// Use this for initialization
void Start ()
{
s_SendMessageDelegate = UnitySendMessageWrapper;
SetUnitySendMessageCallback(s_SendMessageDelegate);
TakesCallback(new myCallbackDelegate(this.myCallback));
System.Diagnostics.Process.Start("C:\\Users\\vferguson\\Downloads\\UnityPlugin-master\\UnityPluginTest\\Assets\\Plugins\\Test.exe");
}
private static void UnitySendMessageWrapper(string gameObjectName, string methodName, string message)
{
Debug.Log("This Happend"); //This should always get hit when message comes through
var gameObject = GameObject.Find(gameObjectName);
if (gameObject != null)
{
//gameObject.SendMessage(methodName, message);
}
}
void Awake()
{
}
// Update is called once per frame
void Update ()
{
}
}
The test.cpp program will crash at "UnitySendMessage", but when Unity calls "TakesCallback" then "UnitySendMessage" works like its suppose to. I might be going about doing this all wrong, any help would be appreciated.
Thanks
You know you can call C# functions in Unity project through command line parameters.
Answer by AurimasBlazulionis · Sep 14, 2016 at 04:30 AM
Unity is not thread safe. That means you can not call unity functions from another thread/program. To achieve what you want, you will need to somehow make your program run in the same thread as unity. This is a good place to start.
Your answer
Follow this Question
Related Questions
Using Native C++ dll in Unity 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
DirectX11 get handle to Unity Swapchain/Backbuffer 0 Answers
IUnityEventQueue - how do I use it? 2 Answers