[UE5.7][C++]遂に完成したC++プラグインUE用HLSL.EditorのMaterial作成機能

もうこれでノードスパゲッティから解放される

導入方法

0,以下のリンクをダウンロード
furcraeaHLSLEditor_UE5.7.3V4.zip
https://drive.google.com/file/d/1XhVZgV6FRiyGOOquqO5nJVFXbmg_8DA-/view?usp=sharing

furcraeaHLSLEditor_UE5.7.3V3.zip
https://drive.google.com/file/d/1Qmz5Y_uT0VGKkrk1wskvw2DRbnND6or4/view?
usp=drive_link

furcraeaHLSLEditor_UE5.7.3V2.zip
https://drive.google.com/file/d/1CSXmSebk7hLM02qM5jKDv2ndNJ4jhUi7/view?usp=sharing

1,Pluginsフォルダにzipを解凍して入れてください。

  パスの例:UEプロジェクトフォルダ\Plugins\furcraeaHLSLEditor\Shaders

2,プラグインで「furcraeaHLSLEditor」を有効化

使用方法

コンテンツブラウザで右クリック>Miscellaneous>Code Material Assetを作成

できた New Code Material AssetをダブルクリックでHLSL編集画面が開く

Saveをクリックすると。。。GeneratedフォルダーにM_NewCodeMaterialAssetが作成されます。


まだまだ、1つしかCodeMatUser.ushがないので一つしかマテリアルが成立しないなどの不備があるので更新していく予定です。<-以下の画像のように修正済みです。

furcraeaHLSLEditorをGitHub で公開しました。
https://github.com/nobolu-ootsuka-unrealengine/furcraeaHLSLEditor/commits?author=nobolu-ootsuka-unrealengine

修正履歴



1つしかCodeMatUser.ushがないので一つしかマテリアルが成立しないなどの不備を修正

furcraeaHLSLEditor_UE5.7.3V2

Projects と RenderCore を bBuildEditorをガード外に移動(ランタイムでも必要なモジュールのため)


furcraeaHLSLEditor_UE5.7.3V3

CodeMaterialAsset が吐くMaterialのフォルダを (固定)Generated から (ユーザーが作った)CodeMaterialAssetと同じフォルダに変更した

CodeMaterialCompiler.cpp に2箇所変更しました。

① MakeMaterialPackagePath 関数(生成先パスを決定)

  • 変更前:/Game/Generated/M_xxx 固定
  • 変更後:Asset->GetOutermost()->GetName() でアセット自身のパッケージパスを取得し、FPackageName::GetLongPackagePath()
    でフォルダ部分を抜き出して {同じフォルダ}/M_xxx を返す ② CreateOrLoadMaterial の MakeDirectory 呼び出し
  • 変更前:MakeDirectory(“/Game/Generated”) 固定
  • 変更後:MakeDirectory(FPackageName::GetLongPackagePath(MakeMaterialPackagePath(Asset))) —
    生成先パスからフォルダを算出して作成 これにより、例えば Content/0_furcraeaTokyo/CodeMaterialAsset/NewCodeMaterialAsset に保存された CodeMaterialAsset
    に対しては、生成マテリアルも同じ Content/0_furcraeaTokyo/CodeMaterialAsset/M_NewCodeMaterialAsset に出力されます。

furcraeaHLSLEditor_UE5.7.3V4

アウトライン表示用のVertexNormalを拡張のために

FragmentShader VertexShader(Optional)に分離しました!

安定性のためにincludeを辞めました。

Audio Radial Slider のデフォルトvalueの表示が1にならない件

Audio Radial Slider のデフォルトvalueの表示が1にならない件が3日かけてやっと解決した

階層とメソッド一覧

   hierarchy: AudioVolumeRadialSlider
   hierarchy: AudioRadialSlider
   hierarchy: Widget
   hierarchy: Visual
   hierarchy: Object
   UFunction: SetWidgetLayout
   UFunction: SetValueTextReadOnly
   UFunction: SetUnitsTextReadOnly
   UFunction: SetUnitsText
   UFunction: SetTextLabelBackgroundColor
   UFunction: SetSliderThickness
   UFunction: SetSliderProgressColor
   UFunction: SetSliderBarColor
   UFunction: SetShowUnitsText
   UFunction: SetShowLabelOnlyOnHover
   UFunction: SetOutputRange
   UFunction: SetHandStartEndRatio
   UFunction: SetCenterBackgroundColor
   UFunction: GetSliderValue
   UFunction: GetOutputValue
   UFunction: SetVisibility
   UFunction: SetUserFocus
   UFunction: SetToolTipText
   UFunction: SetToolTip
   UFunction: SetRenderTranslation
   UFunction: SetRenderTransformPivot
   UFunction: SetRenderTransformAngle
   UFunction: SetRenderTransform
   UFunction: SetRenderShear
   UFunction: SetRenderScale
   UFunction: SetRenderOpacity
   UFunction: SetNavigationRuleExplicit
   UFunction: SetNavigationRuleCustomBoundary
   UFunction: SetNavigationRuleCustom
   UFunction: SetNavigationRuleBase
   UFunction: SetNavigationRule
   UFunction: SetKeyboardFocus
   UFunction: SetIsEnabled
   UFunction: SetFocus
   UFunction: SetCursor
   UFunction: SetClipping
   UFunction: SetAllNavigationRules
   UFunction: ResetCursor
   UFunction: RemoveFromParent
   UFunction: OnReply__DelegateSignature
   UFunction: OnPointerEvent__DelegateSignature
   UFunction: K2_RemoveFieldValueChangedDelegate
   UFunction: K2_BroadcastFieldValueChanged
   UFunction: K2_AddFieldValueChangedDelegate
   UFunction: IsVisible
   UFunction: IsRendered
   UFunction: IsInViewport
   UFunction: IsHovered
   UFunction: InvalidateLayoutAndVolatility
   UFunction: HasUserFocusedDescendants
   UFunction: HasUserFocus
   UFunction: HasMouseCaptureByUser
   UFunction: HasMouseCapture
   UFunction: HasKeyboardFocus
   UFunction: HasFocusedDescendants
   UFunction: HasAnyUserFocus
   UFunction: GetWidget__DelegateSignature
   UFunction: GetVisibility
   UFunction: GetTickSpaceGeometry
   UFunction: GetText__DelegateSignature
   UFunction: GetSlateVisibility__DelegateSignature
   UFunction: GetSlateColor__DelegateSignature
   UFunction: GetSlateBrush__DelegateSignature
   UFunction: GetRenderTransformAngle
   UFunction: GetRenderOpacity
   UFunction: GetParent
   UFunction: GetPaintSpaceGeometry
   UFunction: GetOwningPlayer
   UFunction: GetOwningLocalPlayer
   UFunction: GetMouseCursor__DelegateSignature
   UFunction: GetLinearColor__DelegateSignature
   UFunction: GetIsEnabled
   UFunction: GetInt32__DelegateSignature
   UFunction: GetGameInstance
   UFunction: GetFloat__DelegateSignature
   UFunction: GetDesiredSize
   UFunction: GetClipping
   UFunction: GetCheckBoxState__DelegateSignature
   UFunction: GetCachedGeometry
   UFunction: GetBool__DelegateSignature
   UFunction: GetAccessibleText
   UFunction: GetAccessibleSummaryText
   UFunction: GenerateWidgetForString__DelegateSignature
   UFunction: GenerateWidgetForObject__DelegateSignature
   UFunction: ForceVolatile
   UFunction: ForceLayoutPrepass
   UFunction: ExecuteUbergraph
   hierarchy: AudioVolumeRadialSlider
   hierarchy: AudioRadialSlider
   hierarchy: Widget
   hierarchy: Visual
   hierarchy: Object
   UFunction: SetWidgetLayout
   UFunction: SetValueTextReadOnly
   UFunction: SetUnitsTextReadOnly
   UFunction: SetUnitsText
   UFunction: SetTextLabelBackgroundColor
   UFunction: SetSliderThickness
   UFunction: SetSliderProgressColor
   UFunction: SetSliderBarColor
   UFunction: SetShowUnitsText
   UFunction: SetShowLabelOnlyOnHover
   UFunction: SetOutputRange
   UFunction: SetHandStartEndRatio
   UFunction: SetCenterBackgroundColor
   UFunction: GetSliderValue
   UFunction: GetOutputValue
   UFunction: SetVisibility
   UFunction: SetUserFocus
   UFunction: SetToolTipText
   UFunction: SetToolTip
   UFunction: SetRenderTranslation
   UFunction: SetRenderTransformPivot
   UFunction: SetRenderTransformAngle
   UFunction: SetRenderTransform
   UFunction: SetRenderShear
   UFunction: SetRenderScale
   UFunction: SetRenderOpacity
   UFunction: SetNavigationRuleExplicit
   UFunction: SetNavigationRuleCustomBoundary
   UFunction: SetNavigationRuleCustom
   UFunction: SetNavigationRuleBase
   UFunction: SetNavigationRule
   UFunction: SetKeyboardFocus
   UFunction: SetIsEnabled
   UFunction: SetFocus
   UFunction: SetCursor
   UFunction: SetClipping
   UFunction: SetAllNavigationRules
   UFunction: ResetCursor
   UFunction: RemoveFromParent
   UFunction: OnReply__DelegateSignature
   UFunction: OnPointerEvent__DelegateSignature
   UFunction: K2_RemoveFieldValueChangedDelegate
   UFunction: K2_BroadcastFieldValueChanged
   UFunction: K2_AddFieldValueChangedDelegate
   UFunction: IsVisible
   UFunction: IsRendered
   UFunction: IsInViewport
   UFunction: IsHovered
   UFunction: InvalidateLayoutAndVolatility
   UFunction: HasUserFocusedDescendants
   UFunction: HasUserFocus
   UFunction: HasMouseCaptureByUser
   UFunction: HasMouseCapture
   UFunction: HasKeyboardFocus
   UFunction: HasFocusedDescendants
   UFunction: HasAnyUserFocus
   UFunction: GetWidget__DelegateSignature
   UFunction: GetVisibility
   UFunction: GetTickSpaceGeometry
   UFunction: GetText__DelegateSignature
   UFunction: GetSlateVisibility__DelegateSignature
   UFunction: GetSlateColor__DelegateSignature
   UFunction: GetSlateBrush__DelegateSignature
   UFunction: GetRenderTransformAngle
   UFunction: GetRenderOpacity
   UFunction: GetParent
   UFunction: GetPaintSpaceGeometry
   UFunction: GetOwningPlayer
   UFunction: GetOwningLocalPlayer
   UFunction: GetMouseCursor__DelegateSignature
   UFunction: GetLinearColor__DelegateSignature
   UFunction: GetIsEnabled
   UFunction: GetInt32__DelegateSignature
   UFunction: GetGameInstance
   UFunction: GetFloat__DelegateSignature
   UFunction: GetDesiredSize
   UFunction: GetClipping
   UFunction: GetCheckBoxState__DelegateSignature
   UFunction: GetCachedGeometry
   UFunction: GetBool__DelegateSignature
   UFunction: GetAccessibleText
   UFunction: GetAccessibleSummaryText
   UFunction: GenerateWidgetForString__DelegateSignature
   UFunction: GenerateWidgetForObject__DelegateSignature
   UFunction: ForceVolatile
   UFunction: ForceLayoutPrepass
   UFunction: ExecuteUbergraph

● AudioRadialSlider という独自クラスです。ソースを探します:

● わかりました。ではビルド・実行後のOutput Logで Cast OK が出ているか確認してください。それだけ教えてください。

LogTemp: Warning: AudioUI: Cast OK [AudioVolume_Master] before=1.000000
LogTemp: Warning: AudioUI: after=1.000000
LogTemp: Warning: AudioUI: Cast OK [AudioVolume_se] before=1.000000
LogTemp: Warning: AudioUI: after=1.000000
LogViewport: Display: Player bShowMouseCursor Changed, False -> True
PIE: Server logged in
PIE: Play in editor total start time 0.113 seconds.
LogTemp: Warning: AudioUI: Cast OK [AudioVolume_Master] before=1.000000
LogTemp: Warning: AudioUI: after=1.000000
LogTemp: Warning: AudioUI: Cast OK [AudioVolume_se] before=1.000000
LogTemp: Warning: AudioUI: after=1.000000

● before=1.0 — 値はすでに1.0になっています。 でも表示が違う?

これは表示テキスト(ラベル)の問題です。UAudioRadialSlider は Value(0〜1 正規化)を OutputRange
に変換して表示します。OutputRange の設定次第で表示が変わります。

● Searched for 1 pattern, read 1 file (ctrl+o to expand)

● SynchronizeProperties は Value を Slate に送っていません。RebuildWidget を確認します:

● Searched for 1 pattern (ctrl+o to expand)

● 原因判明。SynchronizeProperties が Value を Slate に送っていません。GetCachedWidget() で Slate
ウィジェットを取得して直接 SetValue します:

● Searched for 4 patterns, read 1 file (ctrl+o to expand)

● SAudioRadialSlider::SetSliderValue() を使います。Slate ウィジェットに直接セットします:

● Write(D:\Sandbox\UE573petit25Cl\UE573petit25Cl\Source\UE573petit25Cl\AudioUI.h)

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "AudioUI.generated.h"

/**
 *  Base class for Audio settings UI.
 *  Initializes AudioVolumeRadialSlider defaults and routes value changes to AudioManager.
 */
UCLASS(abstract)
class UE573PETIT25CL_API UAudioUI : public UUserWidget
{
	GENERATED_BODY()

protected:

	virtual void NativePreConstruct() override;
	virtual void NativeConstruct() override;

public:

	UFUNCTION()
	void InitSliderDefaults();

private:

	UFUNCTION()
	void OnMasterVolumeChanged(float Value);

	UFUNCTION()
	void OnSEVolumeChanged(float Value);
};

● Write(D:\Sandbox\UE573petit25Cl\UE573petit25Cl\Source\UE573petit25Cl\AudioUI.cpp)

// Copyright Epic Games, Inc. All Rights Reserved.

#include "AudioUI.h"
#include "AudioManager.h"
#include "AudioRadialSlider.h"
#include "SAudioRadialSlider.h"
#include "Blueprint/WidgetTree.h"
#include "TimerManager.h"
#include "Engine/World.h"

void UAudioUI::NativePreConstruct()
{
	Super::NativePreConstruct();
	InitSliderDefaults();
}

void UAudioUI::NativeConstruct()
{
	Super::NativeConstruct();

	// Bind slider delegates
	if (UAudioRadialSlider* Master = Cast<UAudioRadialSlider>(GetWidgetFromName(TEXT("AudioVolume_Master"))))
	{
		Master->OnValueChanged.AddDynamic(this, &UAudioUI::OnMasterVolumeChanged);
	}

	if (UAudioRadialSlider* SE = Cast<UAudioRadialSlider>(GetWidgetFromName(TEXT("AudioVolume_se"))))
	{
		SE->OnValueChanged.AddDynamic(this, &UAudioUI::OnSEVolumeChanged);
	}

	if (UWorld* World = GetWorld())
	{
		FTimerHandle Handle;
		World->GetTimerManager().SetTimerForNextTick(this, &UAudioUI::InitSliderDefaults);
	}
}

void UAudioUI::InitSliderDefaults()
{
	if (!WidgetTree) return;

	WidgetTree->ForEachWidget([](UWidget* Widget)
	{
		if (UAudioRadialSlider* Slider = Cast<UAudioRadialSlider>(Widget))
		{
			Slider->Value = 1.0f;

			TSharedPtr<SWidget> CachedWidget = Slider->GetCachedWidget();
			if (CachedWidget.IsValid())
			{
				StaticCastSharedPtr<SAudioRadialSlider>(CachedWidget)->SetSliderValue(1.0f);
			}
		}
	});
}

void UAudioUI::OnMasterVolumeChanged(float Value)
{
	if (UAudioManager* AM = GetGameInstance()->GetSubsystem<UAudioManager>())
	{
		AM->SetMasterVolume(Value);
	}
}

void UAudioUI::OnSEVolumeChanged(float Value)
{
	if (UAudioManager* AM = GetGameInstance()->GetSubsystem<UAudioManager>())
	{
		AM->SetSEVolume(Value);
	}
}

● ビルドして確認してください。

● よかったです!長い道のりでしたね。

原因のまとめ:

  • AudioVolumeRadialSlider は URadialSlider ではなく AudioWidgets プラグインの UAudioVolumeRadialSlider
  • SynchronizeProperties() が Value を Slate に送らない(プラグインの仕様)
  • Slate ウィジェット (SAudioRadialSlider) に直接 SetSliderValue() を呼ぶ必要があった

● お疲れ様でした!

今回の実装まとめ:

  • AudioVolume_Master → AudioManager::SetMasterVolume()
  • AudioVolume_se → AudioManager::SetSEVolume()
  • 初期値は両方 1.0(SAudioRadialSlider::SetSliderValue で Slate に直接セット)

おまけ

AudioManager.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "AudioManager.generated.h"

class USoundBase;
class UAudioComponent;

/**
 *  Game-wide audio manager — BGM playlist + volume control.
 *
 *  Access from anywhere:
 *    UGameInstance* GI = GetGameInstance();          // or GetWorld()->GetGameInstance()
 *    UAudioManager* AM = GI->GetSubsystem<UAudioManager>();
 *
 *  BGM asset note:
 *    USoundBase assets used as BGM tracks must have looping DISABLED so that
 *    OnAudioFinished fires when the track ends and the playlist advances.
 */
UCLASS()
class UE573PETIT25CL_API UAudioManager : public UGameInstanceSubsystem
{
	GENERATED_BODY()

public:

	// -------------------------------------------------------
	// Playlist
	// -------------------------------------------------------

	/** BGM tracks to play in order (or randomly when bRandomPlayback is true) */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="BGM")
	TArray<TObjectPtr<USoundBase>> BGMPlaylist;

	/**
	 *  If true, tracks are played in a random order.
	 *  A full cycle (every track plays once) is guaranteed before any track repeats.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="BGM")
	bool bRandomPlayback = false;

	// -------------------------------------------------------
	// Volume  (0.0 – 1.0)
	// -------------------------------------------------------

	/** Overall volume multiplier applied to all audio */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Volume", meta=(ClampMin=0, ClampMax=1))
	float MasterVolume = 1.0f;

	/** Volume multiplier applied to BGM on top of MasterVolume */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Volume", meta=(ClampMin=0, ClampMax=1))
	float BGMVolume = 1.0f;

	/** Volume multiplier applied to SE on top of MasterVolume */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Volume", meta=(ClampMin=0, ClampMax=1))
	float SEVolume = 1.0f;

public:

	// -------------------------------------------------------
	// BGM API
	// -------------------------------------------------------

	/**
	 *  Starts BGM playlist playback.
	 *  @param TrackIndex  0-based index of the first track to play.
	 *                     Ignored in random mode — a fresh shuffle is always started.
	 */
	UFUNCTION(BlueprintCallable, Category="Audio|BGM")
	void PlayBGM(int32 TrackIndex = 0);

	/** Stops BGM playback and destroys the internal audio component */
	UFUNCTION(BlueprintCallable, Category="Audio|BGM")
	void StopBGM();

	/** Pauses BGM playback */
	UFUNCTION(BlueprintCallable, Category="Audio|BGM")
	void PauseBGM();

	/** Resumes a paused BGM */
	UFUNCTION(BlueprintCallable, Category="Audio|BGM")
	void ResumeBGM();

	/** Skips to the next track immediately */
	UFUNCTION(BlueprintCallable, Category="Audio|BGM")
	void SkipTrack();

	// -------------------------------------------------------
	// Volume API
	// -------------------------------------------------------

	/** Sets the master volume and immediately applies it to the playing BGM */
	UFUNCTION(BlueprintCallable, Category="Audio|Volume")
	void SetMasterVolume(float Volume);

	/** Sets the BGM volume and immediately applies it to the playing BGM */
	UFUNCTION(BlueprintCallable, Category="Audio|Volume")
	void SetBGMVolume(float Volume);

	/** Sets the SE volume (applied to subsequent PlaySE calls) */
	UFUNCTION(BlueprintCallable, Category="Audio|Volume")
	void SetSEVolume(float Volume);

	// -------------------------------------------------------
	// SE API
	// -------------------------------------------------------

	/** Plays a non-spatialized sound effect at MasterVolume * SEVolume */
	UFUNCTION(BlueprintCallable, Category="Audio|SE")
	void PlaySE2D(USoundBase* Sound);

	/** Plays a spatialized sound effect at the given world location at MasterVolume * SEVolume */
	UFUNCTION(BlueprintCallable, Category="Audio|SE", meta=(WorldContext="WorldContextObject"))
	void PlaySE3D(USoundBase* Sound, const FVector& Location, UObject* WorldContextObject);

private:

	/** Currently active BGM audio component */
	UPROPERTY()
	TObjectPtr<UAudioComponent> BGMComponent;

	/** Index of the track that is currently playing */
	int32 CurrentTrackIndex = 0;

	/** Remaining track indices for random mode; rebuilt when the list is exhausted */
	TArray<int32> ShuffledIndices;

	/** Plays the track at the given playlist index */
	void PlayTrackAtIndex(int32 Index);

	/** Called when the current BGM track finishes — advances to the next track */
	UFUNCTION()
	void OnBGMFinished();

	/** Returns the index of the next track to play */
	int32 PickNextTrackIndex();

	/** Applies the current MasterVolume * BGMVolume to the active audio component */
	void RefreshBGMVolume();

	/** Fills ShuffledIndices with a fresh Fisher-Yates permutation of all track indices */
	void RebuildShuffledIndices();
};

AudioManager.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "AudioManager.h"
#include "Components/AudioComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Sound/SoundBase.h"

// -------------------------------------------------------
// BGM API
// -------------------------------------------------------

void UAudioManager::PlayBGM(int32 TrackIndex)
{
	if (BGMPlaylist.IsEmpty())
	{
		return;
	}

	// Stop any currently playing track before starting the playlist
	StopBGM();

	if (bRandomPlayback)
	{
		// Start a fresh shuffle so every track plays before any repeats
		RebuildShuffledIndices();
		PlayTrackAtIndex(ShuffledIndices.Pop(EAllowShrinking::No));
	}
	else
	{
		PlayTrackAtIndex(FMath::Clamp(TrackIndex, 0, BGMPlaylist.Num() - 1));
	}
}

void UAudioManager::StopBGM()
{
	if (BGMComponent)
	{
		// Remove delegate first so Stop() does not accidentally trigger OnBGMFinished
		BGMComponent->OnAudioFinished.RemoveDynamic(this, &UAudioManager::OnBGMFinished);
		BGMComponent->Stop();
		BGMComponent->DestroyComponent();
		BGMComponent = nullptr;
	}
}

void UAudioManager::PauseBGM()
{
	if (BGMComponent)
	{
		BGMComponent->SetPaused(true);
	}
}

void UAudioManager::ResumeBGM()
{
	if (BGMComponent)
	{
		BGMComponent->SetPaused(false);
	}
}

void UAudioManager::SkipTrack()
{
	if (BGMPlaylist.IsEmpty())
	{
		return;
	}

	PlayTrackAtIndex(PickNextTrackIndex());
}

// -------------------------------------------------------
// Volume API
// -------------------------------------------------------

void UAudioManager::SetMasterVolume(float Volume)
{
	MasterVolume = FMath::Clamp(Volume, 0.0f, 1.0f);
	RefreshBGMVolume();
}

void UAudioManager::SetBGMVolume(float Volume)
{
	BGMVolume = FMath::Clamp(Volume, 0.0f, 1.0f);
	RefreshBGMVolume();
}

void UAudioManager::SetSEVolume(float Volume)
{
	SEVolume = FMath::Clamp(Volume, 0.0f, 1.0f);
}

// -------------------------------------------------------
// SE API
// -------------------------------------------------------

void UAudioManager::PlaySE2D(USoundBase* Sound)
{
	if (!Sound)
	{
		return;
	}

	UGameplayStatics::SpawnSound2D(GetGameInstance(), Sound, MasterVolume * SEVolume);
}

void UAudioManager::PlaySE3D(USoundBase* Sound, const FVector& Location, UObject* WorldContextObject)
{
	if (!Sound || !WorldContextObject)
	{
		return;
	}

	UGameplayStatics::SpawnSoundAtLocation(WorldContextObject, Sound, Location,
		FRotator::ZeroRotator, MasterVolume * SEVolume);
}

// -------------------------------------------------------
// Private helpers
// -------------------------------------------------------

void UAudioManager::PlayTrackAtIndex(int32 Index)
{
	if (!BGMPlaylist.IsValidIndex(Index) || !BGMPlaylist[Index])
	{
		return;
	}

	CurrentTrackIndex = Index;

	// Tear down previous component and unsubscribe before spawning a new one
	if (BGMComponent)
	{
		BGMComponent->OnAudioFinished.RemoveDynamic(this, &UAudioManager::OnBGMFinished);
		BGMComponent->Stop();
		BGMComponent->DestroyComponent();
		BGMComponent = nullptr;
	}

	// Spawn a 2D audio component:
	//   bPersistAcrossLevelTransition = true  — BGM survives level loads
	//   bAutoDestroy                  = false — we control the lifetime manually
	BGMComponent = UGameplayStatics::SpawnSound2D(
		GetGameInstance(),
		BGMPlaylist[Index],
		MasterVolume * BGMVolume,
		1.0f,   // PitchMultiplier
		0.0f,   // StartTime
		nullptr,// ConcurrencySettings
		true,   // bPersistAcrossLevelTransition
		false   // bAutoDestroy
	);

	if (BGMComponent)
	{
		BGMComponent->OnAudioFinished.AddDynamic(this, &UAudioManager::OnBGMFinished);
	}
}

void UAudioManager::OnBGMFinished()
{
	if (BGMPlaylist.IsEmpty())
	{
		return;
	}

	PlayTrackAtIndex(PickNextTrackIndex());
}

int32 UAudioManager::PickNextTrackIndex()
{
	if (bRandomPlayback)
	{
		// Rebuild the shuffle pool when every track has been played once
		if (ShuffledIndices.IsEmpty())
		{
			RebuildShuffledIndices();
		}
		return ShuffledIndices.Pop(EAllowShrinking::No);
	}

	// Sequential: wrap around to the beginning after the last track
	return (CurrentTrackIndex + 1) % BGMPlaylist.Num();
}

void UAudioManager::RefreshBGMVolume()
{
	if (BGMComponent)
	{
		BGMComponent->SetVolumeMultiplier(MasterVolume * BGMVolume);
	}
}

void UAudioManager::RebuildShuffledIndices()
{
	const int32 Count = BGMPlaylist.Num();
	ShuffledIndices.Reset(Count);

	for (int32 i = 0; i < Count; ++i)
	{
		ShuffledIndices.Add(i);
	}

	// Fisher-Yates shuffle
	for (int32 i = Count - 1; i > 0; --i)
	{
		const int32 j = FMath::RandRange(0, i);
		ShuffledIndices.Swap(i, j);
	}
}

[UE5][C++] The following modules are missing or built with a different engine version: プラグイン名 Would you like to rebuild them now?

出る時の必殺リセット(確実)

UE を閉じてからプロジェクト直下で削除:

Binaries/

Intermediate/

(あれば)Plugins/furcraeaHLSLEditor/Binaries/

(あれば)Plugins/furcraeaHLSLEditor/Intermediate/

その後

.uproject 右クリック → Generate Visual Studio project files

VS で Development Editor / Win64 で Rebuild

起動

[UE5.7][C++]unrealengine5 C++プロジェクト VisualStudio いらないファイル消す Zipしたい時

これだけにする

プロジェクトフォルダ直下にある以下のフォルダを削除してください。

  • .vs: Visual Studio のキャッシュやユーザー設定が保存されている隠しフォルダ。
  • Binaries: コンパイルされた実行ファイルやライブラリが保存されるフォルダ。
  • Intermediate: ビルドプロセス中の中間ファイルが保存されるフォルダ。
  • Saved: セーブデータ、スクリーンショット、ログ、クラッシュレポートなどが保存されるフォルダ。
  • DerivedDataCache (DDC): エディタがアセットを処理したキャッシュデータが保存されるフォルダ。容量が非常に大きくなることがあります。 

注意点:

  • Content フォルダと .uproject ファイル、Source フォルダ (C++プロジェクトの場合) は絶対に削除しないでください。これらがプロジェクトの本体です。
  • これらのフォルダを削除した後、プロジェクトを開く前にVisual Studioのソリューションをクリーンアップし、必要に応じてソリューションを再生成.uproject ファイルを右クリックし Generate Visual Studio project files を選択)すると、より確実です。
  • その後、残った必要なファイル(ContentSource.uproject.slnConfig など)をZIP圧縮します。

[UE5.7][C++]自宅AI(Ollama)サーバーをUE5のC++プラグインで連携したよ


まず全体全体(おすすめ)

A.別途REST(非ストリーミング)で完了させる

  • UE → AIサーバへHTTP POST
  • AI → 問題JSON
  • UE → UIに反映(UMG)

メリット:実装が簡単/デバッグしやすいプレイ
:とにかくが長いと立つが出る


自宅AI側:エンドポイントの考え方

あなたが今 OpenWebUI を使っているなら、内部のモデル実体はおそらくOllama

  • Ollamaの代表的なAPI(例)
    • 生成:POST /api/generate
    • チャット:POST /api/chat

UEからは「どのURLに投げるか」だけ差し替えできるようにしておくのが正解。


UE5プラグイン設計(ほぼこれを入れる)

1) 設定(プロジェクトの設定を出す)

  • ベースURL(例:http://192.168.1.23:11434
  • モデル名(例:llama3.1
  • タイムアウト秒
  • オプション: API Key(OpenAI互換を使う場合)

UDeveloperSettingsを使うと綺麗。


実装:UE5 C++(RESTで会話させる最小セット)

(1) ビルド.cs

  • "HTTP"、、"Json""JsonUtilities"追加

(2) 送信受信用の構造体(JSON)

  • リクエスト: モデル / プロンプト(またはメッセージ)
  • 応答: 応答(または選択肢)

(3) ブループリント非同期ノード化(UIに優しい)

  • UBlueprintAsyncActionBase
    • OnSuccess
    • OnError
      を吐く

作った全コード

furcraHomeAIServerChat2.Build.cs

// Some copyright should be here...

using UnrealBuildTool;

public class furcraHomeAIServerChat2 : ModuleRules
{
	public furcraHomeAIServerChat2(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
		
		PublicIncludePaths.AddRange(
			new string[] {
				// ... add public include paths required here ...
			}
			);
			
		
		PrivateIncludePaths.AddRange(
			new string[] {
				// ... add other private include paths required here ...
			}
			);
			
		
		PublicDependencyModuleNames.AddRange(
			new string[]
			{
                "Core", "CoreUObject", "Engine", "UMG","HTTP", "Json", "JsonUtilities"
				// ... add other public dependencies that you statically link with here ...
			}
			);
			
		
		PrivateDependencyModuleNames.AddRange(
			new string[]
			{
				"CoreUObject",
				"Engine",
				"Slate",
				"SlateCore",
				"DeveloperSettings",
				// ... add private dependencies that you statically link with here ...	
			}
			);
		
		
		DynamicallyLoadedModuleNames.AddRange(
			new string[]
			{
				// ... add any modules that your module loads dynamically here ...
			}
			);
	}
}

AiChatTypes.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

/**
 * 
 */
class FURCRAHOMEAISERVERCHAT2_API AiChatTypes
{
public:
	AiChatTypes();
	~AiChatTypes();
};





#include "AiChatTypes.generated.h"

USTRUCT(BlueprintType)
struct FAiChatMessage
{
	GENERATED_BODY()

	// "system" | "user" | "assistant"
	UPROPERTY(BlueprintReadWrite, EditAnywhere) FString role;
	UPROPERTY(BlueprintReadWrite, EditAnywhere) FString content;
};

USTRUCT()
struct FOllamaChatRequest
{
	GENERATED_BODY()

	UPROPERTY() FString model;
	UPROPERTY() TArray<FAiChatMessage> messages;
	UPROPERTY() bool stream = false;
};

USTRUCT()
struct FOllamaChatMessage
{
	GENERATED_BODY()

	UPROPERTY() FString role;
	UPROPERTY() FString content;
};

USTRUCT()
struct FOllamaChatResponse
{
	GENERATED_BODY()

	UPROPERTY() FOllamaChatMessage message;
	UPROPERTY() bool done = false;
};

AiChatTypes.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "AiChatTypes.h"

AiChatTypes::AiChatTypes()
{
}

AiChatTypes::~AiChatTypes()
{
}



AiLinkAsyncChat.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "AiChatTypes.h"
#include "AiLinkAsyncChat.generated.h"

// Forward declarations for HTTP interfaces to avoid including HTTP headers in this public header
class IHttpRequest;
class IHttpResponse;

using FHttpRequestPtr = TSharedPtr<IHttpRequest, ESPMode::ThreadSafe>;
using FHttpResponsePtr = TSharedPtr<IHttpResponse, ESPMode::ThreadSafe>;

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAiChatSuccess, const FString&, AssistantText);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAiChatError, const FString&, Error);

UCLASS()
class FURCRAHOMEAISERVERCHAT2_API UAiLinkAsyncChat : public UBlueprintAsyncActionBase
{
	GENERATED_BODY()
public:
	UPROPERTY(BlueprintAssignable) FAiChatSuccess OnSuccess;
	UPROPERTY(BlueprintAssignable) FAiChatError OnError;

	// Messagesは「system + 履歴 + 今回のuser」を含めて渡す
	UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
	static UAiLinkAsyncChat* SendChat(const TArray<FAiChatMessage>& Messages);

	virtual void Activate() override;

private:
	TArray<FAiChatMessage> MessagesInternal;
	void HandleResponse(FHttpRequestPtr Req, FHttpResponsePtr Resp, bool bOk);
};

AiLinkAsyncChat.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "AiLinkAsyncChat.h"

#include "UAiLinkSettings.h"
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
#include "JsonObjectConverter.h"

UAiLinkAsyncChat* UAiLinkAsyncChat::SendChat(const TArray<FAiChatMessage>& Messages)
{
	auto* Node = NewObject<UAiLinkAsyncChat>();
	Node->MessagesInternal = Messages;
	return Node;
}

void UAiLinkAsyncChat::Activate()
{
	const UAiLinkSettings* S = GetDefault<UAiLinkSettings>();
	if (!S)
	{
		OnError.Broadcast(TEXT("Settings not found"));
		return;
	}

	const FString Url = S->BaseUrl / TEXT("api/chat");

	FOllamaChatRequest Body;
	Body.model = S->Model;
	Body.messages = MessagesInternal;
	Body.stream = false;

	FString JsonStr;
	if (!FJsonObjectConverter::UStructToJsonObjectString(Body, JsonStr))
	{
		OnError.Broadcast(TEXT("Failed to serialize request JSON"));
		return;
	}

	TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Req = FHttpModule::Get().CreateRequest();
	Req->SetURL(Url);
	Req->SetVerb(TEXT("POST"));
	Req->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8"));
	Req->SetTimeout(S->TimeoutSeconds);
	Req->SetContentAsString(JsonStr);

	Req->OnProcessRequestComplete().BindUObject(this, &UAiLinkAsyncChat::HandleResponse);
	Req->ProcessRequest();

	UE_LOG(LogTemp, Warning, TEXT("[AI] Activate() called"));
	UE_LOG(LogTemp, Warning, TEXT("[AI] URL: %s"), *Req->GetURL());
	UE_LOG(LogTemp, Warning, TEXT("[AI] Payload: %s"), *JsonStr);
}

void UAiLinkAsyncChat::HandleResponse(FHttpRequestPtr Req, FHttpResponsePtr Resp, bool bOk)
{
	if (!bOk || !Resp.IsValid())
	{
		OnError.Broadcast(TEXT("HTTP request failed (no response)"));
		return;
	}

	const int32 Code = Resp->GetResponseCode();
	const FString Content = Resp->GetContentAsString();
	UE_LOG(LogTemp, Warning, TEXT("[AI] HTTP %d"), Code);
	UE_LOG(LogTemp, Warning, TEXT("[AI] Body: %s"), *Content);

	UE_LOG(LogTemp, Warning, TEXT("[AI] HandleResponse() called. bOk=%d RespValid=%d"),
		bOk ? 1 : 0, Resp.IsValid() ? 1 : 0);

	if (Resp.IsValid())
	{
		UE_LOG(LogTemp, Warning, TEXT("[AI] HTTP %d"), Resp->GetResponseCode());
		UE_LOG(LogTemp, Warning, TEXT("[AI] Body: %s"), *Resp->GetContentAsString());
	}



	if (Code < 200 || Code >= 300)
	{
		OnError.Broadcast(FString::Printf(TEXT("HTTP %d: %s"), Code, *Content));
		return;
	}

	FOllamaChatResponse Parsed;
	if (!FJsonObjectConverter::JsonObjectStringToUStruct(Content, &Parsed, 0, 0))
	{
		OnError.Broadcast(FString::Printf(TEXT("Failed to parse JSON: %s"), *Content));
		return;
	}

	UE_LOG(LogTemp, Warning, TEXT("[AI] Broadcasting Success: %s"), *Parsed.message.content);
	OnSuccess.Broadcast(Parsed.message.content);

}

AiLinkAsyncGenerate.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "AiLinkRequestTypes.h"
#include "AiLinkAsyncGenerate.generated.h"

// Forward declarations for HTTP interfaces to avoid including HTTP headers in this public header
class IHttpRequest;
class IHttpResponse;

using FHttpRequestPtr = TSharedPtr<IHttpRequest, ESPMode::ThreadSafe>;
using FHttpResponsePtr = TSharedPtr<IHttpResponse, ESPMode::ThreadSafe>;

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAiGenerateSuccess, const FString&, Text);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAiGenerateError, const FString&, Error);

UCLASS()
class FURCRAHOMEAISERVERCHAT2_API UAiLinkAsyncGenerate : public UBlueprintAsyncActionBase
{
	GENERATED_BODY()
public:
	UPROPERTY(BlueprintAssignable) FAiGenerateSuccess OnSuccess;
	UPROPERTY(BlueprintAssignable) FAiGenerateError OnError;

	UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
	static UAiLinkAsyncGenerate* GenerateText(const FString& Prompt);

	virtual void Activate() override;

private:
	FString PromptInternal;
	void HandleResponse(FHttpRequestPtr Req, FHttpResponsePtr Resp, bool bOk);
};

AiLinkAsyncGenerate.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "AiLinkAsyncGenerate.h"

#include "UAiLinkSettings.h"	
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
#include "JsonObjectConverter.h"

UAiLinkAsyncGenerate* UAiLinkAsyncGenerate::GenerateText(const FString& Prompt)
{
	auto* Node = NewObject<UAiLinkAsyncGenerate>();
	Node->PromptInternal = Prompt;
	return Node;
}

void UAiLinkAsyncGenerate::Activate()
{
	const UAiLinkSettings* S = GetDefault<UAiLinkSettings>();
	if (!S)
	{
		OnError.Broadcast(TEXT("Settings not found"));
		return;
	}

	const FString Url = S->BaseUrl / TEXT("api/generate");

	FOllamaGenerateRequest Body;
	Body.model = S->Model;
	Body.prompt = PromptInternal;
	Body.stream = false;

	FString JsonStr;
	if (!FJsonObjectConverter::UStructToJsonObjectString(Body, JsonStr))
	{
		OnError.Broadcast(TEXT("Failed to serialize request JSON"));
		return;
	}

	TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Req = FHttpModule::Get().CreateRequest();
	Req->SetURL(Url);
	Req->SetVerb(TEXT("POST"));
	Req->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8"));
	Req->SetTimeout(S->TimeoutSeconds);
	Req->SetContentAsString(JsonStr);

	Req->OnProcessRequestComplete().BindUObject(this, &UAiLinkAsyncGenerate::HandleResponse);
	Req->ProcessRequest();
}

void UAiLinkAsyncGenerate::HandleResponse(FHttpRequestPtr Req, FHttpResponsePtr Resp, bool bOk)
{
	if (!bOk || !Resp.IsValid())
	{
		OnError.Broadcast(TEXT("HTTP request failed (no response)"));
		return;
	}

	const int32 Code = Resp->GetResponseCode();
	const FString Content = Resp->GetContentAsString();

	if (Code < 200 || Code >= 300)
	{
		OnError.Broadcast(FString::Printf(TEXT("HTTP %d: %s"), Code, *Content));
		return;
	}

	FOllamaGenerateResponse Parsed;
	if (!FJsonObjectConverter::JsonObjectStringToUStruct(Content, &Parsed, 0, 0))
	{
		OnError.Broadcast(FString::Printf(TEXT("Failed to parse JSON: %s"), *Content));
		return;
	}

	OnSuccess.Broadcast(Parsed.response);
}

AiLinkRequestTypes.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

/**
 * 
 */
class FURCRAHOMEAISERVERCHAT2_API AiLinkRequestTypes
{
public:
	AiLinkRequestTypes();
	~AiLinkRequestTypes();
};


//#pragma once
//#include "CoreMinimal.h"
#include "AiLinkRequestTypes.generated.h"

USTRUCT()
struct FOllamaGenerateRequest
{
	GENERATED_BODY()

	UPROPERTY() FString model;
	UPROPERTY() FString prompt;
	UPROPERTY() bool stream = false;
};

USTRUCT()
struct FOllamaGenerateResponse
{
	GENERATED_BODY()

	UPROPERTY() FString response;
	UPROPERTY() bool done = false;
};

AiLinkRequestTypes.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "AiLinkRequestTypes.h"

AiLinkRequestTypes::AiLinkRequestTypes()
{
}

AiLinkRequestTypes::~AiLinkRequestTypes()
{
}

UAiLinkSettings.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Engine/DeveloperSettings.h"
#include "UAiLinkSettings.generated.h"

UCLASS(Config = Game, DefaultConfig, meta = (DisplayName = "Home AI Chat"))
class FURCRAHOMEAISERVERCHAT2_API UAiLinkSettings : public UDeveloperSettings
{
	GENERATED_BODY()

public:
	UPROPERTY(Config, EditAnywhere, Category = "AI")
	FString BaseUrl = TEXT("http://192.168.1.23:11434");

	UPROPERTY(Config, EditAnywhere, Category = "AI")
	//FString Model = TEXT("llama3.1"); 
	//FString Model = TEXT("deepseek-r1:32b");llama3.1:8b
	//FString Model = TEXT("llama3.1:70b");//llama3.1:8b
	FString Model = TEXT("llama3.1:8b");//
	UPROPERTY(Config, EditAnywhere, Category = "AI")
	float TimeoutSeconds = 120.0f;

	// 例: "You are NPC assistant in my game..."
	UPROPERTY(Config, EditAnywhere, Category = "AI")
	FString SystemPrompt = TEXT("You are a helpful in-game NPC. Keep replies concise.");
};

UAiLinkSettings.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "UAiLinkSettings.h"

BluePrintはこんなかんじ

以上。

ゲームプログラミングC++の14章に出てくる動かないサンプルソースを動かすためのメモ

1>D:\Sandbox\gameprogcpp_code\code-master\Chapter10\AudioSystem.cpp(11,10): error C1083: Cannot open include file: ‘fmod_studio.hpp’: No such file or directory

なので3つの設定をやってしまった。

ーーーーーーーーーーーーーーーーーーーーーー

Visual Studioの場合:
Gameプロジェクトを右クリックし、[プロパティ]を選択。
[C/C++] → [追加のインクルードディレクトリ] を選び、FMODのインクルードフォルダのパス
(例:
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\inc
)を追加。
変更後、プロジェクトを再ビルドしてみてください。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

1>LINK : fatal error LNK1104: cannot open file ‘fmodL_vc.lib’
1>LINK : fatal error LNK1104: cannot open file ‘fmodstudioL_vc.lib’
[リンカー] → [追加の依存ファイル]にFMODのライブラリを追加します。
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Build EventのPostを

xcopy "$(ProjectDir)\..\external\SDL\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "$(ProjectDir)\..\external\GLEW\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86\*.dll" "$(OutDir)" /i /s /y



AudioSystem.cpp(59,11)をコメントして
//mSystem->getLowLevelSystem(&mLowLevelSystem);

SoundEvent.cpp(83,10)をコメントして
//event->setParameterValue(name.c_str(), value);

SoundEvent.cpp(126,10)をコメントして
//event->getParameterValue(name.c_str(), &retVal);

できたー

ゲームプログラミングC++の13章に出てくる動かないサンプルソースを動かすためのメモ

1>D:\Sandbox\gameprogcpp_code\code-master\Chapter10\AudioSystem.cpp(11,10): error C1083: Cannot open include file: ‘fmod_studio.hpp’: No such file or directory

なので3つの設定をやってしまった。

ーーーーーーーーーーーーーーーーーーーーーー

Visual Studioの場合:
Gameプロジェクトを右クリックし、[プロパティ]を選択。
[C/C++] → [追加のインクルードディレクトリ] を選び、FMODのインクルードフォルダのパス
(例:
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\inc
)を追加。
変更後、プロジェクトを再ビルドしてみてください。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

1>LINK : fatal error LNK1104: cannot open file ‘fmodL_vc.lib’
1>LINK : fatal error LNK1104: cannot open file ‘fmodstudioL_vc.lib’
[リンカー] → [追加の依存ファイル]にFMODのライブラリを追加します。
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Build EventのPostを

xcopy "$(ProjectDir)\..\external\SDL\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "$(ProjectDir)\..\external\GLEW\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86\*.dll" "$(OutDir)" /i /s /y



AudioSystem.cpp(59,11)をコメントして
//mSystem->getLowLevelSystem(&mLowLevelSystem);

SoundEvent.cpp(83,10)をコメントして
//event->setParameterValue(name.c_str(), value);

SoundEvent.cpp(126,10)をコメントして
//event->getParameterValue(name.c_str(), &retVal);

できたー

ゲームプログラミングC++の12章に出てくる動かないサンプルソースを動かすためのメモ

1>D:\Sandbox\gameprogcpp_code\code-master\Chapter10\AudioSystem.cpp(11,10): error C1083: Cannot open include file: ‘fmod_studio.hpp’: No such file or directory

なので3つの設定をやってしまった。

ーーーーーーーーーーーーーーーーーーーーーー

Visual Studioの場合:
Gameプロジェクトを右クリックし、[プロパティ]を選択。
[C/C++] → [追加のインクルードディレクトリ] を選び、FMODのインクルードフォルダのパス
(例:
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\inc
)を追加。
変更後、プロジェクトを再ビルドしてみてください。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

1>LINK : fatal error LNK1104: cannot open file ‘fmodL_vc.lib’
1>LINK : fatal error LNK1104: cannot open file ‘fmodstudioL_vc.lib’
[リンカー] → [追加の依存ファイル]にFMODのライブラリを追加します。
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Build EventのPostを

xcopy "$(ProjectDir)\..\external\SDL\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "$(ProjectDir)\..\external\GLEW\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86\*.dll" "$(OutDir)" /i /s /y

にした。

AudioSystem.cpp(59,11)をコメントして
//mSystem->getLowLevelSystem(&mLowLevelSystem);

SoundEvent.cpp(83,10)をコメントして
//event->setParameterValue(name.c_str(), value);

SoundEvent.cpp(126,10)をコメントして
//event->getParameterValue(name.c_str(), &retVal);

できたー

ゲームプログラミングC++の11章に出てくる動かないサンプルソースを動かすためのメモ

1>D:\Sandbox\gameprogcpp_code\code-master\Chapter10\AudioSystem.cpp(11,10): error C1083: Cannot open include file: ‘fmod_studio.hpp’: No such file or directory

なので3つの設定をやってしまった。

ーーーーーーーーーーーーーーーーーーーーーー

Visual Studioの場合:
Gameプロジェクトを右クリックし、[プロパティ]を選択。
[C/C++] → [追加のインクルードディレクトリ] を選び、FMODのインクルードフォルダのパス
(例:
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\inc
)を追加。
変更後、プロジェクトを再ビルドしてみてください。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

1>LINK : fatal error LNK1104: cannot open file ‘fmodL_vc.lib’
1>LINK : fatal error LNK1104: cannot open file ‘fmodstudioL_vc.lib’
[リンカー] → [追加の依存ファイル]にFMODのライブラリを追加します。
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Build EventのPostを

xcopy "$(ProjectDir)\..\external\SDL\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "$(ProjectDir)\..\external\GLEW\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86\*.dll" "$(OutDir)" /i /s /y

にした。

AudioSystem.cpp(59,11)をコメントして
//mSystem->getLowLevelSystem(&mLowLevelSystem);

SoundEvent.cpp(83,10)をコメントして
//event->setParameterValue(name.c_str(), value);

SoundEvent.cpp(126,10)をコメントして
//event->getParameterValue(name.c_str(), &retVal);

できたー

ゲームプログラミングC++の10章に出てくる動かないサンプルソースを動かすためのメモ

1>D:\Sandbox\gameprogcpp_code\code-master\Chapter10\AudioSystem.cpp(11,10): error C1083: Cannot open include file: ‘fmod_studio.hpp’: No such file or directory

なので3つの設定をやってしまった。

ーーーーーーーーーーーーーーーーーーーーーー

Visual Studioの場合:
Gameプロジェクトを右クリックし、[プロパティ]を選択。
[C/C++] → [追加のインクルードディレクトリ] を選び、FMODのインクルードフォルダのパス
(例:
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\inc
)を追加。
変更後、プロジェクトを再ビルドしてみてください。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

1>LINK : fatal error LNK1104: cannot open file ‘fmodL_vc.lib’
1>LINK : fatal error LNK1104: cannot open file ‘fmodstudioL_vc.lib’
[リンカー] → [追加の依存ファイル]にFMODのライブラリを追加します。
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86
D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Build EventのPreを

xcopy "$(ProjectDir)\..\external\SDL\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "$(ProjectDir)\..\external\GLEW\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "D:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86\*.dll" "$(OutDir)" /i /s /y

あとはコメント化して無効化の修正

1>D:\Sandbox\gameprogcpp_code\code-master\Chapter10\AudioSystem.cpp(59,11): error C2039: ‘getLowLevelSystem’: is not a member of ‘FMOD::Studio::System’
//mSystem->getLowLevelSystem(&mLowLevelSystem);にコメントして無効化

1>D:\Sandbox\gameprogcpp_code\code-master\Chapter10\SoundEvent.cpp(83,10): error C2039: ‘setParameterValue’: is not a member of ‘FMOD::Studio::EventInstance’
//event->setParameterValue(name.c_str(), value);にコメントして無効化


1>D:\Sandbox\gameprogcpp_code\code-master\Chapter10\SoundEvent.cpp(126,10): error C2039: ‘getParameterValue’: is not a member of ‘FMOD::Studio::EventInstance’
//event->getParameterValue(name.c_str(), &retVal);にコメントして無効化

できたー