はじめに

UnityからPythonファイルを実行する方法と、少し滑らかに動かす仕組みを作ったので紹介します☺️
顔や手が認識できなくなったとき、オブジェクトが残っていると違和感があるので、消すようにもしました。
UnityからPythonを実行することに伴い、UDP通信は双方向にしています。

Python

前回からの変更点は以下です。

  • cv2での画面表示を削除
  • UDP受信処理を追加

ソースコード

import time
import cv2
import mediapipe as mp
import numpy as np
from socket import socket, AF_INET, SOCK_DGRAM
import json
import queue
import threading

HOST = ''
PORT_UNITY = 65500
PORT_MEDIAPIPE = 65501
ADDRESS = "127.0.0.1"

face_model_path = './face_landmarker.task'
hands_model_path = './hand_landmarker.task'

# ... (ランドマーク取得・UDP送受信処理)

Unity

スクリプト

MediaPipe管理

using System.Diagnostics;
using UnityEngine;

public class MediaPipeManager : MonoBehaviour
{
    private Process process;
    [SerializeField] string pythonPath;
    [SerializeField] string scriptPath;

    void Start()
    {
        ProcessStartInfo psi = new ProcessStartInfo();
        psi.FileName = pythonPath;
        psi.Arguments = scriptPath;
        psi.UseShellExecute = false;
        psi.RedirectStandardOutput = true;
        process = Process.Start(psi);
    }

    private void OnApplicationQuit()
    {
        // UDP送信でPython停止を通知
    }
}

UDP管理

using System.Net;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;
using PartsData_face_ns;
using PartsData_righthand_ns;
using PartsData_lefthand_ns;

public class UDPManager : MonoBehaviour
{
    private UdpClient udpClient;
    private Thread receiveThread;
    private const int PORT = 65500;

    void Start()
    {
        udpClient = new UdpClient(PORT);
        receiveThread = new Thread(ReceiveData);
        receiveThread.IsBackground = true;
        receiveThread.Start();
    }

    private void ReceiveData()
    {
        while (true)
        {
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = udpClient.Receive(ref endPoint);
            string json = System.Text.Encoding.UTF8.GetString(data);
            // partsフィールドでルーティング
        }
    }
}

エディタ設定

動作確認

動作確認

顔と手のトラッキングがUnity上で動作するようになりました😁

課題:処理負荷が高い

MediaPipeの処理とUnityの描画が同じPC上で動作するため、処理負荷が高くなりやすいです。
フレームレートを下げるなどの対策が必要になる場合があります。

さいごに

それでは、今回はここまで。ありがとうございました😊