본문 바로가기

프로그래밍/WebGL

[WebGL] Unity에서 React 통신하기

이번 시간에는 Unity에서 React로 데이터 통신하는 방법에 대해 소개하고자 한다.

 

마찬가지로, react-unity-webgl을 이용하면 되지만 그 방법은 조금 복잡할 수 있다.

 

이 프로젝트에서는 다음을 구현하고자 한다.

 

Unity 텍스트 입력 후 React로 텍스트 보내기

React에서 Unity에 받은 Text를 화면에 표시하기

받은 Text를 다시 Unity 보내 Unity 화면에 표시하기

 

 

01. Unity에서 React에 보낼 Plugin 세팅하기

 

 Unity Assets 폴더에 Plugins라는 폴더 생성 후 TestCall.jslib 파일을 만들어 준다.

 

mergeInto(LibraryManager.library, {
  sendPrompt: function (prompt) {
    window.dispatchReactUnityEvent("sendPrompt", UTF8ToString(prompt));
  },
});

 

그리고 Visual Studio Code를 통해 파일을 연 후 다음과 같이 적어 준다.

 

우리는 sendPrompt 함수를 이용하여 prompt 데이터를 React로 보낼 예정이다.

 

 

02. Unity InputField GUI 구현 

Unity 프로젝트 InputField GUI 구현은 자유롭게 설정해도 된다.

 

● React에서 prompt 받을 Text Box

● Unity에서 prompt 보낼 InputField Box

 

필자는 다음과 같이 세팅하였다.

 

 

03. sendPrompt 함수 구현

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using System.Runtime.InteropServices;
using UnityEngine.UI;

public class PromptManager : MonoBehaviour
{
    [SerializeField]
    string prompt;

    [SerializeField]
    private TMP_InputField inputField;

    [SerializeField]
    private TextMeshProUGUI promptGUI;

    [DllImport("__Internal")]
    private static extern void sendPrompt(string prompt);

    public void Send()
    {
#if UNITY_WEBGL == true && UNITY_EDITOR == false
    prompt = inputField.text;
    sendPrompt(prompt);
#endif
    }

    public void ReceivePrompt(string _prompt)
    {
        prompt = _prompt;
        promptGUI.text = prompt;
    }
}

PromptManager.cs 스크립트 내 네이티브 플러그인에 활용할 sendPrompt를 선언해준다.

Send() 함수를 호출하면 sendPrompt() 호출하여 React에서 prompt 변수를 받을 수 있게 해준다.

 

자세한 내용은 이곳에서 확인하자.

https://docs.unity3d.com/kr/2018.4/Manual/NativePlugins.html

 

네이티브 플러그인 - Unity 매뉴얼

Unity는 C, C++, Objective-C 등으로 작성한 네이티브 코드의 라이브러리인 네이티브 플러그인 을 폭넓게 지원합니다. 플러그인은 (JavaScript 또는 C#로 작성한) 게임 코드가 이런 라이브러리에서 함수를

docs.unity3d.com

 

Send Button 클릭 시 PromptManager의 Send 함수 호출

 

 

04. React에서 Unity와의 통신 구현

import logo from './logo.svg';
import './App.css';
import React, { useCallback, useState, useEffect } from "react";
import { Unity, useUnityContext } from "react-unity-webgl";

function App() {
  const [prompt, setPrompt] = useState("Hello world");

  const { unityProvider, sendMessage, addEventListener, removeEventListener } =
    useUnityContext({
      loaderUrl: "Build/Build.loader.js",
      dataUrl: "Build/Build.data",
      frameworkUrl: "Build/Build.framework.js",
      codeUrl: "Build/Build.wasm",
    });

  const handleReactCall = useCallback((prompt) => {
    setPrompt(prompt)
  }, [prompt]);

  useEffect(() => {
    addEventListener("sendPrompt", handleReactCall);
    return () => {
      removeEventListener("sendPrompt", handleReactCall);
    };
  }, [addEventListener, removeEventListener, handleReactCall]);

  function send_prompt() {
    sendMessage("PromptManager", "ReceivePrompt", prompt);
  }

  return (
    <div className="App">
        <h1>{prompt}</h1>
        <button onClick={send_prompt}>Prompt Unity 전송</button>
        <br/>
        <Unity style={{
            width: '83%',
            height: '100%',
            justifySelf: 'center',
            alignSelf: 'center',
        }} unityProvider={unityProvider} />
    </div>
  );
}

export default App;

React에서 Unity 통신 시 사용한 sendMessage 함수 이외에 addEventListener, removeEventListener 함수를 추가로 설정하여 Unity에서 sendPrompt 플러그인이 호출 시 setPrompt(prompt)를 통해 Unity에서 보낸 prompt를 react 내 prompt로 세팅해준다. 이러면 Unity 내 플러그인 파일을 통해 얼마든지 react-unity 간 양방향 통신이 가능해진다.

 

Unity -> React 통신

 

React -> Unity 통신

 

 

참고자료

https://react-unity-webgl.dev/

 

React Unity WebGL

Bringing your Unity Games to the Web since 2017!

react-unity-webgl.dev