유니티와 자바스크립트의 만남: WebGL 통신 완전 정복

유니티로 만든 멋진 게임이나 인터랙티브 콘텐츠를 웹 브라우저에서 실행하고 싶으신가요? 유니티의 WebGL 빌드는 강력한 엔진의 결과물을 웹 환경으로 가져오는 훌륭한 방법입니다. 하지만 브라우저의 다양한 기능(예: HTML UI, 로컬 스토리지, 웹 API)을 활용하려면 유니티의 C# 코드와 웹 브라우저의 자바스크립트 코드 간에 원활한 대화가 필요합니다. 오늘은 두 언어가 어떻게 서로 소통하는지, 그 방법을 단계별로 쉽게 알아보겠습니다.


유니티에서 웹으로 메시지 보내기 (C# -> JS)

유니티의 C# 스크립트에서 웹 페이지의 자바스크립트 함수를 호출하려면, 유니티가 제공하는 특별한 ‘플러그인’ 기능을 사용해야 합니다.

1. 자바스크립트 플러그인 파일(.jslib) 준비

먼저 유니티 프로젝트에 자바스크립트 코드를 담을 파일을 생성합니다.

  • Assets/Plugins/WebGL 경로에 MyPlugin.jslib 파일을 만듭니다.
  • 이 파일은 mergeInto(LibraryManager.library, { ... }); 구문으로 시작해야 합니다. 이 구조는 유니티 빌드 시스템에 플러그인 함수를 등록하는 역할을 합니다.

MyPlugin.jslib

JavaScript

mergeInto(LibraryManager.library, {
  // C#에서 "ShowBrowserAlert"라는 이름으로 호출될 함수
  // 인자로 받은 문자열을 브라우저의 alert 창에 띄웁니다.
  ShowBrowserAlert: function (messagePointer) {
    // UTF8 문자열 포인터를 자바스크립트 문자열로 변환합니다.
    const message = UTF8ToString(messagePointer);
    alert("유니티에서 온 메시지: " + message);
  },

  // 인자 없이 호출될 함수
  OpenNewWindow: function () {
    window.open("https://unity.com", "_blank");
  }
});

2. C# 스크립트에서 함수 호출

이제 C# 스크립트에서 위에서 정의한 자바스크립트 함수를 마치 C# 함수인 것처럼 호출할 수 있습니다. System.Runtime.InteropServices[DllImport("__Internal")] 속성이 핵심입니다.

C#

using UnityEngine;
using System.Runtime.InteropServices;

public class UnityCommunicator : MonoBehaviour
{
#if UNITY_WEBGL && !UNITY_EDITOR
    [DllImport("__Internal")]
    private static extern void ShowBrowserAlert(string message);

    [DllImport("__Internal")]
    private static extern void OpenNewWindow();
#endif

    void Start()
    {
        // WebGL 빌드 환경에서만 실행됩니다.
#if UNITY_WEBGL && !UNITY_EDITOR
        ShowBrowserAlert("안녕, 웹 브라우저!");
        OpenNewWindow();
#endif
    }
}

[DllImport("__Internal")]은 외부(__Internal)에 있는 함수를 가져온다는 의미이며, 이 함수는 .jslib 파일에 정의된 함수와 이름이 동일해야 합니다. UNITY_WEBGL 전처리기를 사용하면 에디터 환경에서 컴파일 에러가 발생하는 것을 방지할 수 있습니다.


웹에서 유니티로 메시지 보내기 (JS -> C#)

이번에는 웹 페이지의 버튼 클릭 같은 이벤트가 발생했을 때, 유니티 게임 내의 특정 함수를 실행하는 방법입니다.

1. C# 스크립트에 수신 함수 작성

유니티에서 메시지를 받을 함수를 만듭니다. 이 함수는 public으로 선언되어 있어야 하며, 문자열, 숫자 등 단일 인자를 받을 수 있습니다.

C#

using UnityEngine;

public class WebCommunicator : MonoBehaviour
{
    // 자바스크립트에서 호출될 함수
    // "SendMessage"의 첫 번째 인자가 이 오브젝트의 이름과 일치해야 합니다.
    public void HandleWebMessage(string message)
    {
        Debug.Log("웹에서 받은 메시지: " + message);

        // 예시: 받은 메시지에 따라 게임 상태 변경
        if (message == "StartGame")
        {
            // 게임 시작 로직 실행
        }
    }
}

2. 웹 페이지 HTML/자바스크립트에서 함수 호출

유니티 WebGL 빌드를 완료하면 생성되는 index.html 파일에 아래와 같은 자바스크립트 코드를 추가하여 C# 함수를 호출할 수 있습니다. Unity.SendMessage 함수를 사용하며, 인자로는 “오브젝트 이름”, “함수 이름”, “인자”를 순서대로 전달합니다.

index.html

HTML

<!DOCTYPE html>
<html>
<body>
  ...
  <button onclick="startGameFromWeb()">게임 시작</button>
  ...

  <script>
    // Unity WebGL 빌드가 완료되면 'unityInstance' 전역 변수가 생성됩니다.
    // 만약 다른 이름으로 설정했다면 해당 이름을 사용해야 합니다.
    function startGameFromWeb() {
      // 'WebCommunicator' 스크립트가 부착된 'WebCommunicatorObject'라는 오브젝트를 찾아
      // 그 안에 있는 'HandleWebMessage' 함수를 호출합니다.
      unityInstance.SendMessage('WebCommunicatorObject', 'HandleWebMessage', 'StartGame');
    }
  </script>
  ...
</body>
</html>

'WebCommunicatorObject'는 C# 스크립트가 부착된 게임 오브젝트의 이름과 정확히 일치해야 합니다.


실용적인 활용 방안 및 주의사항

유니티와 자바스크립트 간의 양방향 통신은 다양한 시나리오에 활용될 수 있습니다.

  • 웹 기반 UI/UX: 유니티의 UI 시스템 대신 HTML/CSS로 복잡한 UI를 구성하고, 버튼 클릭 등의 이벤트를 유니티로 전달할 수 있습니다.
  • 웹 API 연동: 브라우저의 로컬 스토리지에 게임 데이터를 저장하거나, 소셜 미디어 공유 API를 호출하는 등 유니티에서 직접 구현하기 어려운 기능을 웹의 힘으로 해결할 수 있습니다.
  • 데이터 교환: WebGL 게임과 웹 서버 간에 데이터를 주고받을 때, JSON 데이터를 문자열로 변환하여 양쪽으로 전달하는 것이 일반적입니다.

주의사항:

  • 이 모든 기능은 WebGL 빌드에서만 동작합니다. PC나 모바일 빌드에서는 사용할 수 없습니다.
  • 자주 통신하는 경우 성능에 영향을 줄 수 있으니, 필요한 시점에만 호출하도록 설계하는 것이 좋습니다.
  • 민감한 사용자 정보는 웹이나 유니티 중 한쪽에서만 관리하거나, 서버를 통해 안전하게 주고받아야 합니다.

이러한 방법을 통해 유니티의 강력한 렌더링 및 로직 처리 능력과 웹 브라우저의 유연한 기능을 결합하여 더욱 풍부한 웹 경험을 만들어낼 수 있습니다.

댓글 남기기