LoginSignup
3
1

More than 1 year has passed since last update.

[Unity]TextureをSwiftのNativePluginから送る

Posted at

Unity に Texture を Swift の Native Plugin から送る

  • UnityのTextureのポインタをSwiftだけで作ったNative Pluginに渡して処理するの逆の話です

  • ネイティブで作成した Texture を Unity へ送って表示させたい場合があります
  • 例えば、macOS のスクリーンキャプチャの映像を Unity で表示させる事ができます
  • macOS や iOS では、MTLTexture から Texture2D.CreateExternalTexture を使って Texture2D を取得可能です

今回のサンプル

  • リポジトリはこちらです

Texture2D.CreateExternalTexture

  • Texture2D.CreateExternalTexture を使うことで、ネイティブのテクスチャオブジェクトから Unity テクスチャを作成できます
  • iOS や macOS の場合は、ネイティブのテクスチャオブジェクトは MTLTexture です
  • そこで、MTLTexture のポインタ、テクスチャの高さと幅を用意します

Unityの実装

Native Plugin の定義

  • width と height のポインタを渡して、ネイティブに代入させます
  • 戻り値として、MTLTexture のポインタを IntPtr として受け取ります
[DllImport("mcDesktopCapture")]
private static extern IntPtr mcDesktopCapture_getCurrentFrame2(ref int width, ref int height);

Texture を取得する

  • 取得したポインタから、Texture2D.CreateExternalTexture を使って Texture を得て設定しています
int w = -1;
int h = -1;
IntPtr texturePtr = mcDesktopCapture_getCurrentFrame2(ref w, ref h);
Texture2D texture = Texture2D.CreateExternalTexture(w, h, TextureFormat.ARGB32, false, false, texturePtr);
Renderer m_Renderer = GetComponent<Renderer>();
m_Renderer.material.SetTexture("_MainTex", texture);

Swift の実装

  • @_cdecl を付けて、C# で作成した関数を実装します
  • ref を UnsafeMutablePointer として、IntPtr を UnsafeMutableRawPointer として読み替えます
  • width と height にテクスチャの大きさを設定します
  • retain してテクスチャのポインタを返します
@_cdecl("mcDesktopCapture_getCurrentFrame2")
public func mcDesktopCapture_getCurrentFrame2(_ width: UnsafeMutablePointer<Int64>,
                                              _ height: UnsafeMutablePointer<Int64>) -> UnsafeMutableRawPointer {
    let texture: MTLTexture = getTexture()
    width.initialize(to: Int64(texture.width))
    height.initialize(to: Int64(texture.height))
    return Unmanaged.passRetained(texture).toOpaque()
}
  • 破棄が必要な場合は、takeRetainedValue を使います
@_cdecl("mcDesktopCapture_clearFrame")
public func mcDesktopCapture_clearFrame(_ texturePtr: UnsafeMutableRawPointer) {
    _ = Unmanaged<MTLTexture>.fromOpaque(texturePtr).takeRetainedValue()
}

ライブラリの出力と設定

  • こちらの記事の Framework でビルドする の章以降と同じ手順で実行ビルド可能です

  • 作成した ライブラリ を Unity のプロジェクトにコピーして、Texture を取得できていることを確認します

おわりに

  • Texture2D.CreateExternalTexture を使うことで、Swift だけで作ったライブラリから、Unity へ Texture を送る仕組みを実装できました
  • CreateExternalTexture を関連する関数に、UpdateExternalTexture があり、Texture の作成だけでなく、更新も可能です
  • Swift から Unity に Texture を送る仕組みは、応用の幅が広いので、活用して行きたいです
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1