Nuitrack 1.5.0
3D スケルトン トラッキング ミドルウェア
 すべて クラス 名前空間 関数 変数 Typedefs 列挙型 列挙子 プロパティ イベント グループ ページ
Unreal Engine チュートリアル

Nuitrack を UE 4.18 プロジェクトで使用 (Android のみ)

プロジェクトのセットアップ

  1. <Nuitrack>フォルダーを {SDK Root}/UnrealEngine からプロジェクトのソース フォルダーにコピーします。
  2. <Nuitrack>フォルダーを {SDK Root} からプロジェクトのソース/NuiTrack フォルダーにコピーします。
  3. Visual Studio プロジェクト ファイルを生成するために、.uproject file ファイルを右クリックします。 

    unity_generate_files.png

  4. 特別な許可を追加するには、[編集] > [プロジェクト設定] > [プラットフォーム] > [Android] > [高度な APKPacking]で設定を行います。

    android.permission.BLUETOOTH
    android.permission.BLUETOOTH_ADMIN
    android.permission.READ_EXTERNAL_STORAGE
    android.permission.WRITE_EXTERNAL_STORAGE
    android.permission.INTERNET
    unity_permissions.png

  5. Nuitrack ライブラリとヘッダーを Build.cs プロジェクトと依存関係にあるファイルに追加(Games/{ProjectName}/Source/{ProjectName}/{ProjectName}.Build.cs):
    PrivateDependencyModuleNames.AddRange(new string[] { "Nuitrack" });
    PrivateIncludePaths.AddRange(new string[] { ModuleDirectory + "Nuitrack/Nuitrack/include" });

Nuitrack の使用

  1. Nuitrack を初期化し、スケルトン トラッキングを生成し、イベントを登録するには、以下のコードを追加します (例えば、GameMode クラスの BeginPlay() メソッドに追加):

    Nuitrack::init();
    SkeletonTracker::Ptr skeletonTracker = SkeletonTracker::create();
    skeletonTracker->connectOnUpdate(std::bind(&ANuiSampleGameModeBase::OnSkeletonUpdate,
    this, std::placeholders::_1));
    Nuitrack::run();

  2. Nuitrack を終了するには、release() メソッドを呼び出します (GameMode クラスの BeginDestroy() メソッドに追加できます):

    Nuitrack::release();

  3. モジュールからの新しいデータを基にイベントを立ち上げるには、update() メソッドを呼び出します (GameMode クラスの Tick(float dt) メソッドに追加できます):

    Nuitrack::update();

  4. スケルトン トラッキング データは、OnSkeletonUpdate メソッド内で確認できます (SkeletonTrackerから OnUpdate イベントに登録 ):

    void ANuiSampleGameModeBase::OnSkeletonUpdate(SkeletonData::Ptr userSkeletons)
    {
    auto skeletons = userSkeletons->getSkeletons();
    ...
    }

Nuitrack サンプル プロジェクトを Unreal Engine 4.18 で作成 (Android のみ)

  1. Unreal Engine 4.18 をダウンロードして実行し、 CodeWorks for Android をインストールします。
  2. 新規プロジェクトを作成:C++ → 基本のコード。プロジェクトについて、以下の設定を行います。

    • ハードウェアのクラス:携帯 / タブレット
    • 画質のレベル:最大品質
    • 追加コンテンツ:スターター コンテンツなし。
      unity_new_project.png

  3. ワールドから、Player Start 以外のすべてのラベルを削除します。

    unity_myworld.png

  4. プレイヤーの位置、回転とスケーリングの値を設定します (以下のスクリーンショットを参照)。

    unity_player_position.png

  5. 現在のワールドを保存します。

    unity_save.png

  6. [編集] > [プロジェクトの設定] > [マップとモード]を選択します。

    • ワールドを[エディター スタートアップ マップ]また、[ゲーム デフォルト マップ]として設定します。

      unity_default_maps.png

    • [デフォルト ゲームモード]を設定します。
      unity_maps_modes.png

  7. [編集] > [プロズクトの設定] > [プラットフォーム] > [Android] で[今すぐ確認]をクリックし、[SDKライセンスを承認]、[Androidパッケージ名]を入力します。

    unity_android_package_name.png

  8. プロジェクトをセットアップします (Nuitrack と Unreal Engine 4.18 プロジェクトの統合 (Android のみ)の項目を参照)

  9. Visual Studio を開き、C++ コードを書き込みます。

    unity_cpp.png

  10. Unreal ProjectsProjectName}\{ProjectName} ディレクトリ内のファイルには、以下のコンテンツが必要です。

    • NuiSample.Build.cs ファイル:
      using UnrealBuildTool;
      public class NuiSample :ModuleRules
      {
      public NuiSample(ReadOnlyTargetRules Target) : base(Target)
      {
      PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
      PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
      PrivateDependencyModuleNames.AddRange(new string[] { "Nuitrack" });
      PrivateIncludePaths.AddRange(new string[] { ModuleDirectory +
      "Nuitrack/Nuitrack/include" });
      }
      }
    • NuiSample.h ファイル
      #pragma once
      #include "Engine.h"
      #include <iostream>
      #include <vector>
      using namespace std;
      #include "nuitrack/Nuitrack.h"
      #include "nuitrack/modules/SkeletonTracker.h"
      #include "nuitrack/types/Skeleton.h"
      #include "nuitrack/types/SkeletonData.h"
      using namespace tdv::nuitrack;
    • NuiSample.cpp ファイル
      #include "NuiSample.h"
      IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, NuiSample, "NuiSample" );
    • NuiSampleGameModeBase.h ファイル
      #pragma once
      #include "NuiSample.h"
      #include "GameFramework/GameModeBase.h"
      #include "NuiSampleGameModeBase.generated.h"
      UCLASS()
      class NUISAMPLE_API ANuiSampleGameModeBase : public AGameModeBase
      {
      GENERATED_BODY()
      UWorld* World;
      ANuiSampleGameModeBase();
      void Tick(float dt) override;
      void BeginPlay() override;
      void BeginDestroy() override;
      SkeletonTracker::Ptr skeletonTracker;
      void OnSkeletonUpdate(SkeletonData::Ptr userSkeletons);
      void DrawSkeleton(int skeleton_index, vector<Joint> joints);
      void DrawBone(Joint j1, Joint j2);
      static FVector RealToPosition(Vector3 real);
      };
    • NuiSampleGameModeBase.cpp ファイル
      #include "NuiSampleGameModeBase.h"
      ANuiSampleGameModeBase::ANuiSampleGameModeBase()
      {
      this->PrimaryActorTick.bCanEverTick = true;
      }
      void ANuiSampleGameModeBase::Tick(float dt)
      {
      Nuitrack::update();
      }
      void ANuiSampleGameModeBase::BeginPlay()
      {
      Super::BeginPlay();
      UE_LOG(LogTemp, Warning, TEXT("ANuiSampleGameModeBase::BeginPlay()"));
      World = GetWorld();
      if (World)
      {
      UE_LOG(LogTemp, Warning, TEXT("Nuitrack::init() CALLING..."));
      Nuitrack::init();
      UE_LOG(LogTemp, Warning, TEXT("SkeletonTracker::create() CALLING..."));
      skeletonTracker = SkeletonTracker::create();
      UE_LOG(LogTemp, Warning, TEXT(
      "skeletonTracker->connectOnUpdate() CALLING..."));
      skeletonTracker->connectOnUpdate(
      std::bind(&ANuiSampleGameModeBase::OnSkeletonUpdate,
      this, std::placeholders::_1));
      UE_LOG(LogTemp, Warning, TEXT("Nuitrack::run() CALLING..."));
      Nuitrack::run();
      }
      else
      {
      UE_LOG(LogTemp, Error, TEXT("NULL WORLD"));
      }
      }
      void ANuiSampleGameModeBase::BeginDestroy()
      {
      Super::BeginDestroy();
      Nuitrack::release();
      }
      void ANuiSampleGameModeBase::OnSkeletonUpdate(SkeletonData::Ptr userSkeletons)
      {
      auto skeletons = userSkeletons->getSkeletons();
      FlushPersistentDebugLines(World);
      if (!skeletons.empty())
      {
      for (auto skeleton : skeletons)
      {
      DrawSkeleton(skeleton.id, skeleton.joints);
      }
      }
      }
      void ANuiSampleGameModeBase::DrawSkeleton(int skeleton_index, vector<Joint> joints)
      {
      if (joints.empty())
      return;
      DrawBone(joints[JOINT_HEAD], joints[JOINT_NECK]);
      DrawBone(joints[JOINT_NECK], joints[JOINT_TORSO]);
      DrawBone(joints[JOINT_RIGHT_SHOULDER], joints[JOINT_LEFT_SHOULDER]);
      DrawBone(joints[JOINT_WAIST], joints[JOINT_LEFT_HIP]);
      DrawBone(joints[JOINT_WAIST], joints[JOINT_RIGHT_HIP]);
      DrawBone(joints[JOINT_TORSO], joints[JOINT_WAIST]);
      DrawBone(joints[JOINT_LEFT_SHOULDER], joints[JOINT_LEFT_ELBOW]);
      DrawBone(joints[JOINT_LEFT_ELBOW], joints[JOINT_LEFT_WRIST]);
      DrawBone(joints[JOINT_RIGHT_SHOULDER], joints[JOINT_RIGHT_ELBOW]);
      DrawBone(joints[JOINT_RIGHT_ELBOW], joints[JOINT_RIGHT_WRIST]);
      DrawBone(joints[JOINT_RIGHT_HIP], joints[JOINT_RIGHT_KNEE]);
      DrawBone(joints[JOINT_LEFT_HIP], joints[JOINT_LEFT_KNEE]);
      DrawBone(joints[JOINT_RIGHT_KNEE], joints[JOINT_RIGHT_ANKLE]);
      DrawBone(joints[JOINT_LEFT_KNEE], joints[JOINT_LEFT_ANKLE]);
      }
      void ANuiSampleGameModeBase::DrawBone(Joint j1, Joint j2)
      {
      DrawDebugLine(World, RealToPosition(j1.real), RealToPosition(j2.real),
      FColor::MakeRedToGreenColorFromScalar((j1.confidence + j2.confidence)*0.5),
      true, -1, 0, 4);
      }
      FVector ANuiSampleGameModeBase::RealToPosition(Vector3 real)
      {
      return FVector(-real.x, real.z, real.y)*0.1f;
      }

  11. プロジェクトを組み立てるには、[ファイル] > [パッケージ プロジェクト] > [Android]を選択します。