エフェクトの新規追加例(その1)



・ぶひぃ
「エフェクトについて」で触れたFX_AddDiscreetLineFX_AddQuadの 2つのFX関数を利用して新規追加のエフェクトを発生させてみましょう。
お手軽にピストルを撃ったらエフェクトが発生するようにします。

・ソース改造
weapon_pistol.cppに手を加えます(サーバ、クライアント共有のソース)。コードの変更は client.dllのプロジェクト(client_sdk)で行い、 変更が終わったらserver.dllclient.dll共に ビルドしちまうのがいいですね。

最初はここを変更
weapon_pistol.cppの17行目
#ifdef CLIENT_DLL
	#include "c_hl2mp_player.h"
#else
	#include "hl2mp_player.h"
#endif

[ここだよ兄ちゃん]

#include "weapon_hl2mpbasehlmpcombatweapon.h"
上の[ここだよ兄ちゃん]に示した部分に以下のコードを挿入。
#ifdef CLIENT_DLL
// クライアント側にはさらにこの3つをincludeしときます
#include "c_te_effect_dispatch.h"
#include "fx_quad.h"
#include "ClientEffectPrecacheSystem.h"

#else
// サーバ側にはこれをincludeしときます
#include "te_effect_dispatch.h"

#endif

次はここを変更
weapon_pistol.cppの224行目(PrimaryAttackメンバ関数の最後)
	m_flAccuracyPenalty += PISTOL_ACCURACY_SHOT_PENALTY_TIME;

[ここだよ兄ちゃん]
}
上の[ここだよ兄ちゃん]に示した部分に以下のコードを挿入。
	// エフェクトをDispatch
	// とりあえずサーバ、クライアントどっちも処理実行
	if( pOwner )
	{
		//-----------------------------------------------
		// プレイヤーの発砲位置を得る
		Vector position = pOwner->Weapon_ShootPosition( );

		//-----------------------------------------------
		// プレイヤーの視線方向の単位ベクトルを得る
		Vector forward;

		// EyeVectorsにはそれぞれのベクトル格納先を指定する
		// 第1引数はプレイヤーの視線方向の単位ベクトル
		// 第2引数はプレイヤーの視線方向を基準にした直角右方向の単位ベクトル
		// 第3引数はプレイヤーの視線方向を基準にした直角上方向の単位ベクトル
		// 2、3はここでは不要なのでNULL指定にしておく
		pOwner->EyeVectors( &forward, NULL, NULL );

		//-----------------------------------------------
		// プレイヤーの発砲位置からちょっと前にずらしてみよう
		position = position + forward * 30.0f;

		//-----------------------------------------------
		// Dispatchにて渡すエフェクトデータを準備
		CEffectData	data;

		// 発射位置と方向だけでいい
		data.m_vOrigin = position;
		data.m_vNormal = forward;

		// エフェクトをDispatch
		DispatchEffect( "MyEffect", data );
	}

最後はここを変更
weapon_pistol.cppの末尾に以下をそのまま挿入
#ifdef CLIENT_DLL
// エフェクト用のスプライトのプリキャッシュ指定
// client.dll読込みのタイミングでキャッシュに読み込まれる
// CLIENTEFFECT_REGISTER_BEGINマクロに指定している名前は
// 他のCLIENTEFFECT_REGISTER_BEGINマクロの記述やnamespace
// と名前が重複しなければ何でもいい
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectMine )
CLIENTEFFECT_MATERIAL( "effects/gunshiptracer" )
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1_nocull" )
CLIENTEFFECT_REGISTER_END()

// エフェクトの処理でげす
void MyEffectCallback( const CEffectData &data )
{
	//-----------------------------------------------
	// 移動する線を描く
	//-----------------------------------------------
	// ・スタート地点
	// → data.m_vOrigin
	// ・線の移動方向
	// → data.m_vNormal
	// ・移動の速さ
	// → 100.0f
	// ・線の長さ
	// → 50.0f
	// ・線を描画可能な範囲の長さ
	// → 1000.0f
	// ・線のスケール(太さ)
	// → 5.5f
	// ・破棄されるまでの時間(秒)
	// → 5.0f
	// ・シェーダ指定(スプライト)
	// → "effects/gunshiptracer"
	FX_AddDiscreetLine(
		data.m_vOrigin,
		data.m_vNormal,
		100.0f,
		50.0f,
		1000.0f,
		5.5f,
		5.0f,
		"effects/gunshiptracer"
	);

	//-----------------------------------------------
	// 回転する平面を描く
	//-----------------------------------------------
	// ・描画地点
	// → data.m_vOrigin
	// ・法線ベクトル
	// → data.m_vNormal
	// ・開始時のサイズ
	// → 100.0f
	// ・終了時のサイズ
	// → 0.0f
	// ・サイズ補完値のバイアス指定
	// → 0.75f
	// ・開始時のアルファ値
	// → 1.0f
	// ・終了時のアルファ値
	// → 0.0f
	// ・アルファ補完値のバイアス指定
	// → 0.4f
	// ・初期回転角度のオフセット
	// → random->RandomInt( 0, 360 )
	// ・1秒あたりの回転角度
	// → random->RandomInt( -90, 90 )
	// ・色指定
	// → Vector( 1.0f, 1.0f, 1.0f )
	// ・破棄されるまでの時間
	// → 5.0f
	// ・シェーダ指定(スプライト)
	// → "effects/combinemuzzle1_nocull"
	// ・バイアス指定有効化フラグ
	// → (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA)
	FX_AddQuad(
		data.m_vOrigin,
		data.m_vNormal,
		100.0f,
		0.0f,
		0.75f,
		1.0f,
		0.0f,
		0.4f,
		random->RandomInt( 0, 360 ),
		random->RandomInt( -90, 90 ),
		Vector( 1.0f, 1.0f, 1.0f ),
		5.0f,
		"effects/combinemuzzle1_nocull",
		(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA)
	);
}

// エフェクト名称とコールバック関数登録
DECLARE_CLIENT_EFFECT( "MyEffect", MyEffectCallback );
#endif

ささ、チャッチャとserver.dllclient.dllをビルドしちゃって くらはい。

・実行
ゲームを開始してピストルを撃ってみてね。


バババンバン、しゅんしゅん、くるくる〜♪

まあ、そういうこった。

・クライアント側だけDispatchEffectを有効にしてみる
さて、DispatchEffectをクライアント側だけの実行にしたらどうなるでしょうか。

以下の変更を行い、server.dllclient.dllをビルドしちゃってくらはい。
weapon_pistol.cppの256行目でDispatchEffectの記述の前後へ以下の赤く記した部分を挿入
		// エフェクトをDispatch
#ifdef CLIENT_DLL
		DispatchEffect( "MyEffect", data );
#endif
	}

で、実行にゲームを開始してピストルを撃ってもさっきと何も変わりがないですね、そこで第一部の

第八章 (´・ω・`)おばあちゃん、武器クラスとプレイヤーモデルの関係について考えるわよ☆

を参考にBOTを有効にしたらBOTにピストルを発砲させてみます。


ハイ、結果は明らかですね、見えるのは自分のエフェクトだけで、他のプレイヤーのエフェクトは見えないっつーことです。

・サーバ側だけDispatchEffectを有効にしてみる
今度は逆に、DispatchEffectをサーバ側だけの実行にしたらどうなるでしょうか。

以下の変更を行い、server.dllclient.dllをビルドしちゃってくらはい。
weapon_pistol.cppのさっき追加した個所で以下の赤く記した部分を書き換える
		// エフェクトをDispatch
#ifndef CLIENT_DLL
		DispatchEffect( "MyEffect", data );
#endif
	}


今度は他のプレイヤーのエフェクトが見えるのに、自分のエフェクトが見えなくなりました。

プレイヤー自身のDispatchEffectはサーバ側からは配信してくれないみたいですね。

(´・ω・`)つもどる