夏休み勉強会 1日目

1日目では主に配布したライブラリの内部説明およびプレイヤーの仮実装を行っていきたい。


カメラを作成しよう

まずカメラを用意しないとそもそもどこを描画すればいいのかわからないのでゲーム開発の初めは固定でもいいのでカメラを作ろう。

固定カメラの作成

PlayScene.hに以下のインスタンスを作成してね。
(今日は使わないけどCommonResourcesは後々使います。)

	//	共通リソース
	CommonResources* m_commonResources;

	//	カメラ
	Develop::CameraObject m_camera;

では続いてPlayScene.cppを書いていこう!
Initializeに以下のコードを記述してね。

    //  共通リソースの取得
	m_commonResources = common;

    //	カメラのビュー行列の作成
	m_camera.CreateViewMatrix(
		SimpleMath::Vector3(0, 5, 5),
		SimpleMath::Vector3(0, 0, 0),
		SimpleMath::Vector3(0, 1, 0)
	);

	//	カメラの射影行列の作成
	m_camera.CreateProjMatrix(Screen::SIZE_RECT);

これだけだとちゃんとカメラが機能しているかわからないから描画するものも追加しよう!
ではまたPlayScene.hに戻って以下のインスタンスを生成しよう。

	//	グリッド床
	Grid m_grid;

そして生成するだけでは変化は起きないので、初期化処理と描画処理を記述していこう。
PlayScene.cppのInitializeに以下の関数を追記。

	//	グリッド床の初期化
	m_grid.Initialize(common);

Renderにはこの関数を記述

	//	グリッド床の描画
	m_grid.Render(m_camera);

こんな感じにきちんと機能していればOK!

成功したときの画面

Develop::Cameraについて

ビュー行列と射影行列の作成&保持を行ってくれるクラス。描画に必要な行列をサポートする役割を持っている。

ビュー行列:描画対象がどの位置からどのような角度で見られているかの情報をもつ行列。
射影行列:見ている描画対象をどうやって画面に映すかという情報を持つ行列。

プレイヤーを作成しよう

実際にプレイヤーを書いていこう

プレイヤークラスの枠組み

まずはプレイヤークラスの枠組みを作成しよう。
ということでPlayer.hに以下のコードを記述してね。

#pragma once

//	インクルード達
#include "Libraries/Development/Model3D.h"

//	前方宣言
class CommonResources;

/// <summary>
/// プレイヤー
/// </summary>
class Player
{
private:

	//	モデルのディレクトリパスと名前
	static constexpr wchar_t MODEL_DIRECTORY[]	= L"Resources/Models/";
	static constexpr wchar_t MODEL_NAME[]		= L"Player";

	//	モデルのスケール
	static constexpr DirectX::SimpleMath::Vector3 MODEL_SCALE{ 0.25f, 0.25f, 0.25f };

	//	初期値点
	static constexpr DirectX::SimpleMath::Vector3 START_POSITION{ 0, 0, 60.0f };

public:

	//	コンストラクタ
	Player();
	//	デストラクタ
	~Player() = default;

	//	開始関数
	void Initialize	(CommonResources* common);
	//	更新関数
	void Update		(float deltaTime);
	//	描画関数
	void Render		(const Develop::CameraObject& camera);
	//	終了関数
	void Finalize	();

private:

	//	共通リソース
	CommonResources* m_commonResources;

	//	モデル
	Develop::Model3D m_model;

};

では続いてPlayer.cppを書いていこう!

#include "pch.h"
#include "Player.h"

#include "../CommonResources.h"
#include "Libraries/MyLib/InputManager.h"

//	名前空間の使用
using namespace DirectX;

/// <summary>
/// コンストラクタ
/// </summary>
Player::Player()
{
}

/// <summary>
/// 開始関数
/// </summary>
/// <param name="common">共通リソース</param>
void Player::Initialize(CommonResources* common)
{
}

/// <summary>
/// 更新関数
/// </summary>
/// <param name="deltaTime">フレーム間秒数</param>
void Player::Update(float deltaTime)
{
}

/// <summary>
/// 描画関数
/// </summary>
/// <param name="camera">カメラ</param>
void Player::Render(const Develop::CameraObject& camera)
{
}

/// <summary>
/// 終了関数
/// </summary>
void Player::Finalize()
{
}

基本的な4つの関数(Initialize / Update / Render / Finalize)を記述してもらった。今回は引数にパラメータを設定しているが、この引数が2つ以上あるのは個人的にはあまり好みではない。

Initialize : オブジェクトの初期化処理を記述する関数。今回は初期化処理においてCommonResoucesの中身が欲しかったため引数に記述を行った。
Update : オブジェクトの更新処理を記述する関数。今回はフレーム間秒数を引数にもらってくることでどんなfpsでも対応しやすい形にしている。
Render : オブジェクトの描画処理を記述する関数。今回はカメラの参照型をもらってくることでどのカメラで描画されるのかを分かるようにしている。
Finalize : オブジェクトの終了処理を記述する関数。開放処理などを行いたいときに用いるが、スマートポインタなどを使いこなせるとほぼ記述することがないため省略してもよい。

Develop::Model3Dについて

スケール・回転・座標を保有しているクラス
モデルハンドルを送ることで、モデルを簡単に表示できる子だよ。
個人的にはまだまだ改良の余地があるクラスなので改良したりしてほしい。

モデルハンドルの中身:std::unique_ptr<DirectX::Model>型のポインタが入っている。わざわざスマートポインタのポインタにしているのはデバイスロストなどのモデルの再読み込みが発生する際の対応がしやすくなるため。

Develop::ResouceManagerについて

モデルとテクスチャの読み込み&保管をしてくれるクラス。
管理はstd::unordered_mapで行っており、キーはファイルパス、値はstd::unique_ptr<DirectX::Model>である。

辞書型配列について:通常配列の添え字([0]とか[1]とかのこと)は連続する数字でしかアクセスができない。そこで「添え字を数字以外でもアクセスできると便利だよね。」ということで生まれたのが辞書型配列である。
配列の添え字をキーと呼びそのキーに対応する値を格納していく方式である。一般的にはキーには文字列を用いることが多い。(多いというだけでそれ以外の型も存在はする)

プレイヤーのモデルを表示

Player.hに以下のインスタンスを作成しよう。

	//	共通リソース
	CommonResources* m_commonResources;

	//	モデル
	Develop::Model3D m_model;

Player.cppのInitialize関数にはこれらを追記

	//	共通リソースを取得
	m_commonResources = common;

	//	コンテキストの取得
	ID3D11DeviceContext* context = common->GetDeviceResources()->GetD3DDeviceContext();
	//	共通ステートの取得
	CommonStates* states = common->GetCommonStates();

	//	リソース管理クラスの取得
	Develop::ResourceManager* resourceManager = common->GetResourceManager();

	//	モデルハンドルを取得
	Develop::ResourceManager::ModelHandle modelHandle;
	modelHandle = resourceManager->LoadModelCMO(MODEL_DIRECTORY, MODEL_NAME);

	//	モデルの初期化
	m_model.Initialize(context, states, modelHandle);

Render関数でモデルの描画を行おう

	//	モデルの描画
	m_model.Render(camera);

実際にPlaySceneでインスタンスを生成して描画までやってみよう。
表示できたかな?

成功画面

細部の解説

ID3D11DeviceとID3D11DeviceContextについて

ID3D11Device:例えるなら画材屋さん。描画に必要なもの(モデルデータやシェーダー、テクスチャに至るまで)を作成するためのもの。という認識でOK。多分、先生とかにはCPUのことだよ、みたいに説明されたと思う。
ID3D11DeviceContext:例えるなら画家さん。描画に必要なものを受け取って、実際に画面に描画するのがお仕事。Develop::Model3Dではあらかじめその画家さんを渡してもらってRender関数で実際にお仕事を依頼してる。という処理を行っている。

DirectX::CommonStatesについて

描画を行う際には様々な設定(画家さんにディティールを注文する感じ)を行うことができる。その設定自体はかなり事細かに記載することができる。しかし、実際にゲームを作ろうとしたときにあまりに設定が細かいため初心者が困惑してしまう。そこでTKではこのDirectX::CommonStatesというのが提供されている。このクラスはあらかじめ細かい設定を保持している。この保持された設定を用いて描画設定を行うことで初心者が迷うことなくゲーム制作に取り組みやすくなるのだ。

DirectX::EffectFactoryについて

モデルのマテリアル設定を読み込むためのクラス。設定項目の1つにディレクトリパスを記述しなければならない。なぜかというとモデルにはテクスチャを張るものもあり、そのテクスチャ自体もマテリアルの設定のうちに入るのだ。テクスチャはモデルと同じ名前だろうという前提のもとどこにそのデータがあるのかを教えないといけない、だからディレクトリパスが必要なのだ。

この記事が気に入ったらサポートをしてみませんか?