3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DXライブラリを使ってLive2Dモデルを動かし、描画しよう

Last updated at Posted at 2024-04-19

はじめに

本記事はかの有名なDirectX APIを簡易化したライブラリ「DXライブラリ」を使用して、現在流行のLive2Dモデルを描画し、さらにモーションを制御する簡単なやり方を紹介します。

目次

  1. Visual Studioの準備
  2. DXライブラリの導入
  3. Live2D Cubism 4 SDKとLive2Dモデルの導入
  4. コーディング
  5. 最終成果
  6. 参考文献

Visual Studioの準備

スクリーンショット 2024-04-18 232011.png

初期セットアップする時に必ず入れて欲しいのは「ユニバーサルWindowsプラットフォーム開発」

スクリーンショット 2024-04-18 232341.png

DXライブラリの導入

スクリーンショット 2024-04-18 233013.png

Live2D Cubism 4 SDKとLive2Dモデルの導入

スクリーンショット 2024-04-18 231552.png

  • サンプルデータをダウンロード
    元々私が使用するモデルは当時無料配布だった「ミアラ」だが、この記事を執筆した現在は有料になりましたので、他の無料モデルを使用してください。
    https://www.live2d.com/learn/sample/

スクリーンショット 2024-04-19 005434.png

  • Visual Studioの設定

▼DXライブラリSDKのパス設定(すべての構成に設定)
パスは相対パス、絶対パスどちらでも構いません

スクリーンショット 2024-04-18 224806.png

スクリーンショット 2024-04-18 224817.png

▼リンカーのシステムを「Windows(/SUBSYSTEM:WINDOWS)に設定」
スクリーンショット 2024-04-18 224826.png

▼Live2D Cubism 4 SDKをプロジェクトのディレクトリ下に入れる(プロジェクトディレクトリ以外のローカル外部でも良いですが、ファイルをどこかにクローンする時に参照がずれて、また再設定しないといけない)
スクリーンショット 2024-04-18 233650.png

コーディング

  • まずはLive2Dモデルを読み込む準備をします
Live2D.h
#pragma once
#include"DxLib.h"

class Live2D
{
public:
	Live2D(int modelHandle);
	~Live2D();
	void Initialize();
	void Load(const TCHAR *filePath);
	void Update(const TCHAR* motion);
	void DrawBegin();
	void DrawModel();
	void DrawEnd();
	void DeleteModel();

private:
	int ModelHandle;
};
Live2D.cpp
#include"Live2D.h"

Live2D::Live2D(int modelHandle)
	:ModelHandle(modelHandle)
{
	
}

Live2D::~Live2D()
{

}

void Live2D::Initialize()
{

#ifdef _WIN64
	Live2D_SetCubism4CoreDLLPath(L"../CubismSdkForNative-4-r.1/Core/dll/windows/x86_64/Live2DCubismCore.dll");
#else
	Live2D_SetCubism4CoreDLLPath(L"../CubismSdkForNative-4-r.1/Core/dll/windows/x86/Live2DCubismCore.dll");
#endif

}

void Live2D::Load(const TCHAR* filePath)
{
	// Live2Dモデルの読み込み
	ModelHandle = Live2D_LoadModel(filePath);
}

void Live2D::Update(const TCHAR* motion)
{
	// モーション再生が終了していたらアイドリングモーションをランダムで再生
	if (Live2D_Model_IsMotionFinished(ModelHandle) == TRUE)
	{
		Live2D_Model_StartMotion(ModelHandle, motion, GetRand(8));
	}

	// モデルの状態を60分の1秒分進める
	Live2D_Model_Update(ModelHandle, 1 / 60.0f);
}

void Live2D::DrawBegin()
{
	// Live2D描画の開始
	Live2D_RenderBegin();
}

void Live2D::DrawModel()
{
	// モデルの描画
	Live2D_Model_Draw(ModelHandle);
}

void Live2D::DrawEnd()
{
	// Live2D描画の終了
	Live2D_RenderEnd();
}

void Live2D::DeleteModel()
{
	// Live2D モデルの削除
	Live2D_DeleteModel(ModelHandle);
}
  • おまけに入力系のクラスも書いておきます
Input.h
#pragma once
#include"DxLib.h"

class Input
{
public:
	static char currentKey[256];
	static char previousKey[256];
	static int mousePosX, mousePosY, mouseLeftButt, mouseRightButt, mouseMidButt;
public:
	static void Mouse(int*, int*);
	static int MouseLeftButton();
	static int MouseRightButton();
	static int MouseMiddleButton();
	static int Key(int key);
	static bool KeyTrigger(int key);
	static void Update();
	static void Draw();
};
Input.cpp
#include"Input.h"

int Input::mousePosX = 0;
int Input::mousePosY = 0;
int Input::mouseLeftButt = 0;
int Input::mouseRightButt = 0;
int Input::mouseMidButt = 0;
char Input::currentKey[256] = { 0 };
char Input::previousKey[256] = { 0 };

void Input::Update() 
{
	GetMousePoint(&mousePosX, &mousePosY);
	if ((GetMouseInput() & MOUSE_INPUT_LEFT) != 0) mouseLeftButt++;
	else mouseLeftButt = 0;
	if ((GetMouseInput() & MOUSE_INPUT_RIGHT) != 0) mouseRightButt++;
	else mouseRightButt = 0;
	if ((GetMouseInput() & MOUSE_INPUT_MIDDLE) != 0) mouseMidButt++;
	else mouseMidButt = 0;

	memcpy(previousKey, currentKey, sizeof(previousKey));

	GetHitKeyStateAll(currentKey);
}

void Input::Mouse(int* x, int* y) 
{
	*x = mousePosX;
	*y = mousePosY;
}

int Input::MouseLeftButton() { return mouseLeftButt; }
int Input::MouseRightButton() { return mouseRightButt; }
int Input::MouseMiddleButton() { return mouseMidButt; }
int Input::Key(int key) { return currentKey[key]; }
bool Input::KeyTrigger(int key) { return !previousKey[key] && currentKey[key]; }

void Input::Draw() {}

  • 次にゲームの環境を整う
Game.h
#pragma once
#include"DxLib.h"

class Game 
{
public:
	Game();
	~Game();
	void Initialize();
	void Load();
	void Update();
	void Draw();

public:
	int LoadTexture(TCHAR* fileName) 
	{
		int tex = LoadGraph(fileName);
		if (tex == -1) 
        {
			MessageBox(NULL, L"画像の読み込みに失敗しました", ERROR, MB_OK);
			return 0;
		}
	};
	
private:
	int texture;
	float texturePosX;
	float texturePosY;
	bool controllSwitch;
};

Game.cpp
#include"Game.h"
#include"Input.h"

Game::Game() 
{
	this->Initialize();
}

Game::~Game() 
{

}

void Game::Initialize() 
{
	texture = NULL;
	texturePosX = 600;
	texturePosY = 400;
	controllSwitch = false;
}

void Game::Load() 
{

}

void Game::Update() 
{
	if (!controllSwitch) 
	{
		texturePosX = 600;
		texturePosY = 400;
	}
	else
	{
		texturePosX = 800;
		texturePosY = 600;
	}
	if (Input::Key(KEY_INPUT_SPACE) == 1) 
    {
		controllSwitch = !controllSwitch;
	}

}

void Game::Draw() 
{

}
  • 最後にモデルを描画し、スペースキーで動作変えましょう
Main.cpp
#include"Game.h"
#include"Input.h"
#include"Live2D.h"

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
	// ウィンドウモードに設定
	ChangeWindowMode(TRUE);

	SetMainWindowText(L"Live2D Test Program");

	// 画面解像度を設定
	SetGraphMode(1280, 720, 0);

	// ウィンドウサイズを手動では変更できず、
    // かつウィンドウサイズに合わせて拡大できないようにする
	SetWindowSizeChangeEnableFlag(FALSE, FALSE);

	bool motionChange = false;

	int live2DHandle = 0;

	Live2D* live2D = new Live2D(live2DHandle);	

	live2D->Initialize();

	// DXライブラリ初期化処理
	if (DxLib_Init() == -1) return -1;

	Game game;
	game.Initialize();
	game.Load();

	live2D->Load(L"../Assets/miara_pro_jp/runtime/miara_pro_t04.model3.json");

	// 描画先を裏画面に変更
	SetDrawScreen(DX_SCREEN_BACK);

	// メインループ
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0)
	{
		Input::Update();

		game.Update();
		game.Draw();

		if (Input::KeyTrigger(KEY_INPUT_SPACE))
		{
			motionChange = !motionChange;
		}

		if (!motionChange)
		{
			live2D->Update(L"Idle");
		}
		else
		{
			live2D->Update(L"Flick");
		}

		live2D->DrawBegin();

		live2D->DrawModel();

		live2D->DrawEnd();

		if (CheckHitKey(KEY_INPUT_ESCAPE) != 0) break;
	}

	live2D->DeleteModel();

	delete live2D;

	// DXライブラリ使用の終了処理
	DxLib_End();

	// ソフトの終了
	return 0;
}
  • Live2Dモデルモーションに関してですが、ご自身がダウンロードしたサンプルデータのなかの「runtime」フォルダの中にある「OOO.model3.json」のような名前のファイルから見えます。

スクリーンショット 2024-04-19 002748.png

▲私の場合IdleとFlickを切り替えて使用してます

最終成果

miara.gif

参考文献

3
3
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
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?