ゲームから学ぶ - ドラゴンズドグマ2
- 一撃で倒したら戦闘BGMは再生されない
- ポーンがダメージを受けても戦闘BGM開始される
- 一定距離離れたら戦闘BGMが終了される
- ポーンが戦闘中でも無関係
- 戦闘に関係する敵HPUIも消える
- 大型のみ小型のみなので分かりにくいけど、大型の敵がいれば大型用の戦闘BGMが流れるように思われる
- プレイヤーとポーン関係なく、ダメージを与えるか・ダメージを受けたら戦闘BGMが開始されている
- 雨などの環境音よりも戦闘BGMが優先される、もしくは音量が大きい
【UE5】【CRI ADX LE v2】基礎からおさらいしてみる vol.4
概要
【UE5】【CRI ADX LE v2】基礎からおさらいしてみる vol.3 - プログラマーの卵の日記
こちらの続き
公式
こちらのNo.22から学習
Niagaraから再生
1. 「+」ボタンからAtom Playerを追加

2. Particle SpawnにD&Dして追加

3. Particle Spawnの「+」からPlay Persistent Atomを追加
標準だと「Plugins」が選択されていないためにAtomが出てこないので選択する

4. PlayAtomという変数が出来てるのでParticle SpawnにD&Dして追加

5. PlayAtomのDetailsからチェックをTrueにする

6. UpdateのほうにUpdate Persistent Atomを追加

7. Update Persisten AtomでAtom PlayerをセットしてLocationを設定する
Particle AttributesのPositionが自動的に設定される。
この時点でナイアガラのプレビューでも音が再生されるようになる。

.acfアセットから情報
カテゴリ
カテゴリグループが異なればキューに複数設定できる都合上、この表示だと誤解する可能性が出そうですね。


グローバルAISAC
![]()

上記だとPatch_Aisac_0をダブルクリックするとPatch_Aisac_0が表示される。
設定されているControlが表示されるのは良いね!

Aisac Controls


セレクター


.acbアセットから情報
キュー設定


ストリーミングを含むか
Wave Banksの設定可能有無で分かりそう


キューアセットから情報
選択すると右側で詳細が分かるようになります。

ダブルクリックすると多少見やすくなります。

簡易ですが、得られる情報
- キュー名
- キュータイプ
- ループ設定
- 3Dポジショニングかどうか
- カテゴリー設定
- AISAC設定
- 残響・反響
- ストリーミングかどうか
【UE5】【CRI ADX LE v2】基礎からおさらいしてみる vol.3
- 概要
- 公式
- カテゴリに関する関数
- AISACと関連する関数
- DSPバスは後回し…
- レベル移動しても再生を維持する
- キューシートのリソースのライフタイム
- 一つの音源が複数個所から再生(AtomMultiPositionComponentが正しく使えないので保留)
- 発音数制御
概要
【UE5】【CRI ADX LE v2】基礎からおさらいしてみる vol.2 - プログラマーの卵の日記
前回の続き的な立ち位置
公式
こちらのNo.15から学習始めます
カテゴリに関する関数
カテゴリを用意して、キューを用意して、それぞれにカテゴリを設定しておく

unreal側でもカテゴリ設定状態が見れます。

一時停止

停止

音量変更

ミュート
指定したカテゴリのものすべてをミュートにする

AISACと関連する関数
適当に、Atom Craftで音量を弄るAISACをキューに追加

1. Aisac Control型の変数を作成
2. 該当するコントロールを変数に設定
3. Set Aisac Control Valueを使用してキューとコントロールを紐づける

AISACだけ弄るとかいうのは出来なそう。
コードの方
-
void UAtomComponent::SetAisacControlValue(const FAtomAisacControl& AisacControl, float Value)
{
if (FAtomRuntime* AtomRuntime = GetAtomRuntime())
{
FAtomAisacControlParameterInfo ParamInfo;
ParamInfo.Control = AisacControl;
ParamInfo.Value = Value;DECLARE_CYCLE_STAT(TEXT("FAtomThreadTask.AtomSetAisacControlValue"), STAT_AtomSetAisacControlValue, STATGROUP_AtomThreadCommands);
AtomRuntime->SendCommandToActiveSounds(AtomComponentID, [ParamInfo](FAtomActiveSound& ActiveSound)
{
ActiveSound.SetAisacControl(ParamInfo);
}, GET_STATID(STAT_AtomSetAisacControlValue));
}
}
-
USTRUCT(BlueprintType)
struct CRIWARECORE_API FAtomAisacControl
{
GENERATED_BODY()public:
FAtomAisacControl()
: ID(INDEX_NONE)
{}FAtomAisacControl(FName InName, int32 InID)
: Name(InName)
, ID(InID)
{}bool operator==(const FAtomAisacControl& Other) const
{
return ID == Other.ID;
}bool operator!=(const FAtomAisacControl& Other) const
{
return !(*this == Other);
}/** Name of the AISAC control. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AISAC")
FName Name;/** Unique Atom Craft ID of the AISAC control. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AISAC")
int32 ID;
};inline uint32 GetTypeHash(FAtomAisacControl A) { return static_cast<uint32>(A.ID); }
AISACコントロールIDを渡せばいいように見える

DSPバスは後回し…
レベル移動しても再生を維持する
公式のやり方を記載。
要はGameInstanceにAtomComponentを所持して、ゲームが終了されるまで破棄されないようにするというもの。
1. GameInstanceを作成
2. GameInstance内でAtomComponentを所持
3. レベルでAtomSoundBaseからAtomComponentをSpawnさせる
4. GameInstanceをキャストして取ってきて先ほどSpawnしたAtomComponentを渡す
レベル移動してもGameInstance内で再生しているAtomComponentがあるので維持される
キューシートのリソースのライフタイム
?????それはどこで設定されてるんだ…??どっかのiniファイルなのかなぁ…。

Force Inline:
uassetが読み込まれるときにキューシートがロードされる。
Retain on Load:
再生命令の時にキューシートのロードが行われる。
Prime on Load:
uassetが読み込まれるときにキューシートのロードがされる。
Load on Demand:
再生命令の時にキューシートのロードが行われる。
uassetの破棄でアンロードとなるよう。
ちょっと書き方違うだけでForce InlineとPrime onLoadが同じだったりでわけわからん…。
一つの音源が複数個所から再生(AtomMultiPositionComponentが正しく使えないので保留)
CriWare Unreal Engine: ADX チュートリアル No.20 : 広範囲のエリアをカバーする距離減衰の作成方法
こちらの方法らしいが、SourceActorsが設定できないのでまだ試運転かな…?
以下途中メモ
同時再生のずれが起きないのと、複数個所から鳴るけど一音となるためメモリ節約となるそう。
1. AtomMultiPositionComponentをアタッチさせる

2. レベル上に配置する
3. 発生させる箇所に適当なアクターを配置する

4. 配置したアクターから発生するように設定する
設定できない!
発音数制御
カテゴリごとの制限設定
カテゴリ内のキュー数を制御できるようです。
近距離優先というので、新しく再生するキューはリスナーに近いキューから優先して再生するようになります。すでに再生済みのものには影響しないはずです。

キューごとの制限設定
キューごとで設定できます。
後着優先は、キュー制限数まで再生していた場合、一番古い再生を停止して新しく再生するものを必ず再生するようになります。

【UE5】【CRI ADX LE v2】基礎からおさらいしてみる vol.2
- 概要
- 公式
- C++で用意したAtomComponentで3D再生
- ループSEを再生しながら再生位置を動的に変化させる
- 再生をやめる
- BP側で距離減衰の設定を上書き
- リスナーの位置をカメラではなくキャラの位置と向きで連動
- アニメーションから音を再生
- Anim Notifyから音を再生
- シーケンサーから音を再生
- 生成してアタッチする
- 停止・一時停止
概要
【UE5】【CRI ADX LE v2】基礎からおさらいしてみる vol.1 - プログラマーの卵の日記
前回の続き的な立ち位置。
公式
今回はこれを主に見つつ勉強
C++で用意したAtomComponentで3D再生
Vol.1でC++から再生できるようにしたと思うのですが、3D音源だとアタッチもしていなければ座標も指定できていないので、0,0,0の座標から音が再生されるようになってしまいます。
変にハマったことですが、ループSEを再生しながら音源の位置移動は出来ないようで、位置移動したら再度停止して再生する必要があるみたいです。
アクター.h
publicにしてBPから弄れるようにします
-
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UAtomComponent> AtomComponent;
アクターBP
座標を常に更新するようにします。
Componentのノードとなり、AtomComponent特有のものではないです。
C++でもSetWorldLocation(FVector)で同じことができます。試行錯誤してBPに落ち着いただけです。

ループSEを再生しながら再生位置を動的に変化させる
とりあえず見つけたやり方なので、正しいかはわからないです。
そもそもループSEをそういう風に扱わないかも。

再生をやめる
Stop()という関数/ノードで止められます。
止める際には再生しているかチェックしたほうが安全かもしれない。

BP側で距離減衰の設定を上書き
簡易確認用とかデバッグ用としては良いかもしれない。
上書きとなりAtom Craftでいくら設定しても変わらないということになってしまうので、最終的にはやらない方がいいようには思う。
Override Attenuationを有効にしてAttenuation関係のパラメータを設定すればそれなりに起こせる。

リスナーの位置をカメラではなくキャラの位置と向きで連動
公式を見て行ってみたけど左右が逆…?一旦必要としていないのでスルー

アニメーションから音を再生
Add NotifyのPlay Atom Soundというのをくっつけることで、アニメーションのタイミングで再生が行える。
Followを有効にしてAttach NameをSkeleton Treeにある名前を入れれば、そこから再生されるようになる。

Anim Notifyから音を再生
専用のAnim Notifyを作成し、socketの位置に生成をして再生をさせる。
ちょっとした処理を加えたい場合に有効そうに思われる。
直前と同様にアニメーションにこのAnim Notifyを設定させる。

シーケンサーから音を再生
シーケンサー触ることないから色々雑。
TrackからAtom Trackを選択

Atomに右にある「+」からキューを選択して配置できる。
ただし、ループ設定の曲でもループされないようなので、終了までループしたければ最後まで個数分配置する必要があるように思われる。

生成してアタッチする
再生の生成は基本的にAtom Sound Baseから行います。
Spawn Sound AttachedでAtom Componentを生成しながらアタッチが行えるようです。

停止・一時停止
SetPausedがtrueで一時停止、falseで再開
Stopが停止(終了)
Atom Componentから命令が出来る。
-
/** Stop sound, issue any delegates if needed */
UFUNCTION(BlueprintCallable, Category = "Atom|Components|Sound")
void Stop();/** Cues request to stop sound after the provided delay, stopping immediately if delay is zero or negative */
UFUNCTION(BlueprintCallable, Category = "Atom|Components|Sound")
void StopDelayed(float DelayTime);/** Pause sound playing, issue any delegates if needed */
UFUNCTION(BlueprintCallable, Category = "Atom|Components|Sound")
void SetPaused(bool bPause = true);
【UE5】【CRI ADX LE v2】基礎からおさらいしてみる vol.1
概要
色々あって、unrealからもadxからも離れていたので基礎からおさらいをしてみる。
「1から行いつつまとめる」というよりも「行ったことをまとめる」という形で記載をします。自分への備忘録です。
コードを乗せる便利なやつが無いので箇条書きを利用して記載します。
環境
Unreal Engine 5.3.2
CRI ADX LE v2_01_00
Atom Craft v3.50.06
公式
.acfファイル

AtomCraftからビルドするプロジェクトに必ず1つ存在しているもの。
共通のデータとしてこういう部分の情報を保持している。
acbはacfを参照しているため、acfの更新があった場合はすべてのacbを再ビルドして再インポートする必要があります。

unrealプロジェクトでもProjectSettingで設定を必ずする必要がある。(インポート時に自動でされることが多い)

.acb

ストリーミングでない音データを保持しているものです。
以下のCueSheet_0とCueFirstなどがそれぞれ一つのacbファイルとして出力されます。

.awb
ストリーミング再生として指定された音の波形データです。
該当の音(acb)(キュー)を再生するためには必ず必要なものとなります。
ストリーミング設定にする方法としては、ターゲットコンフィグやマテリアルから設定ができます。

ストリーミング再生はちょっと手間いるので最後のほうに記載してます。
キューシート
キューシート=.acb
CueSheet_0というのが一つのキューシート

.acbのuassetが一つのキューシート

キュー
キューシートの中にあるのが基本的にキュー

unrealでキューシートを開くと中に入っているキューが表示される

ループ設定されるキュー
右上のループアイコンで表示されているのがループされるキュー

ループ指定はマテリアル側など

BPでキューの再生
アクターにAtomComponentを持たせて再生。


Playノードを呼ぶだけ

3Dポジショニング
パンタイプを3Dポジショニングにするだけ
範囲や残響などはAtomCraft側で細かく調整できるが面倒なので省略

unreal上でも範囲が表示される


C++でキュー再生
再生関係のものが欲しいのでモジュールを追加
プロジェクト名.Build.cs
-
public class EternalADXLEV2C : ModuleRules
{
public EternalADXLEV2C(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "CriWareCore" });
}
}
データはuassetとなるので、BPから再生するQを指定できるようにし、c++内で再生をしてみます。
アクター.h
- class UAtomComponent;
class UAtomSoundBase; - <<<
-
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UAtomSoundBase> Sound;private:
UPROPERTY(Transient)
TObjectPtr<UAtomComponent> AtomComponent;
アクター.cpp
- #include "Atom/AtomComponent.h"
#include "Atom/AtomSoundBase.h" - <<<
-
void ANormalActor::BeginPlay()
{
Super::BeginPlay();AtomComponent = NewObject<UAtomComponent>(GetWorld());
if (IsValid(Sound) && IsValid(AtomComponent))
{
AtomComponent->SetSound(Sound);
}if (IsValid(AtomComponent))
{
AtomComponent->Play(0.0f);
}
}
BPのアクター側で右のDetailsのほうでキューを設定できるようになるので、再生したいものを設定すれば完了です。

ややこしそうな変数名だったので二つの変数(UAtomSoundBase型 Sound/SoundVer2)作ってみてこんな感じ

ストリーミング設定のキュー再生
ストリーミング設定されると.awbが出力されます。こちらを利用しなければストリーミングを含むキューは再生がされません。
1. .acbと.acfが全て同じ階層に置いてあるとして、.awb用のAWBフォルダを用意します。

2. AWBフォルダの中に.awbをインポートさせます。
※acbとawbが同じ階層だと同名のuassetを作る都合でインポートエラーが起きますが、別階層のフォルダであればインポートできます。

3. ストリーミングのacbのWaveBanksにファイル指定が出来るようになっているので、先ほどのawbを指定します。

波形が無いのでわかりにくいですが、問題なく再生されるようになります。
パッケージの際にはawbのファイルも含めるようにしてください。
【UE5】Play As Clientについて学習
※誤っている可能性が非常に高いです。自分の考えをまとめることを目的としているため、それなりに順序不同・支離滅裂です。
Unreal Engineのサーバーについて

Net Modeでサーバーモードを選択できます。
「Play Standalone」はサーバーを用いないものと思ってください。
クライアントのいずれかをゲームサーバーのホストとするような考えが「Play As Listen Server」です。
クライアントとは別にサーバーがある状態を「Play As Client」となります。
「Play As Listen Server」では、ホストが終了されると全クライアントも終了されます。
ですが、「Play As Client」では、ホストが存在しないのでどのクライアントが終了されてもゲームは終了されません。
オブジェクト
オブジェクトを各クライアントで認識するためには、基本的にオブジェクトはサーバーで生成するようにする必要があります。
クライアントで生成したとしても、そのクライアントのみで描画され、ほかのクライアントでは描画されません。
仕組みとしては、サーバーで生成し、各クライアントにコピーされるという考えです。

レベル上に配置。サーバーで生成し、各クライアントと同期
オブジェクトを同期するため、アクターの詳細から「Replicates」を有効にします。
これにより、アクターの生成はサーバーと各クライアントで同期されます。

Actor Spawnでゲームに生成。サーバーで生成し、各クライアントと同期
アクターをスポーンする場合、スポーンはサーバーのみで行わせます。
そのため、UEC++の場合「UKismetSystemLibrary::IsDedicatedServer(this);」という関数を用い、これがtrueの時のみ生成をさせます。
BPの場合は以下のノードがtrueの時のみ生成処理を呼びます。

そうしなければ、サーバー+各クライアント数のアクターが生成され、判定が不正確になってしまいます。
オブジェクトの同期
ゲーム中、アクターに変化を与え、全クライアントに同期させたくなります。
オブジェクトは基本的にサーバーで生成します。そのため、そのオブジェクト内で処理を行うと、サーバーには影響しますが各クライアント上では見た目的な変化は起きません。
サーバーのみの実行ではなく、各クライアントでも処理をさせるように対応させます。
UEC++では、処理をさせたい関数は以下のように宣言させます。
DuFunctionは定義する必要ありません。緑波線はほっときましょう。
サーバーかクライアントか確認
オブジェクトのTickなどで適当に「PrintString」を接続させます。
そうすると出力表示に「Server: 」や「Client1: 」などと表示されます。これによりどこで生成され、どこで呼ばれているのか確認ができます。
生成した対象内のみで処理を実行
UEC++の場合は「HasAuthority()」という関数で判断できます。
BPの方でも「Has Auhority」というノードがあります。