AkRoomComponent.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. #pragma once
  16. #include "AkReverbDescriptor.h"
  17. #include "GameFramework/Volume.h"
  18. #include "AkGameObject.h"
  19. #include "AkRoomComponent.generated.h"
  20. class UAkLateReverbComponent;
  21. UCLASS(ClassGroup = Audiokinetic, BlueprintType, hidecategories = (Transform, Rendering, Mobility, LOD, Component, Activation, Tags), meta = (BlueprintSpawnableComponent))
  22. class AKAUDIO_API UAkRoomComponent : public UAkGameObject
  23. {
  24. GENERATED_BODY()
  25. public:
  26. typedef WwiseUnrealHelper::AkSpatialAudioIDKeyFuncs<UAkPortalComponent*, false> PortalComponentSpatialAudioIDKeyFuncs;
  27. typedef TMap<AkPortalID, UAkPortalComponent*, FDefaultSetAllocator, PortalComponentSpatialAudioIDKeyFuncs> PortalComponentMap;
  28. UAkRoomComponent(const class FObjectInitializer& ObjectInitializer);
  29. /**
  30. * Enable the Room Component to set this volume as a Spatial Audio Room. Additional properties are available in the Room and AkEvent categories.
  31. * Changing this property during runtime only has an effect if the Room is dynamic (see the Room Component category).
  32. */
  33. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="EnableComponent", meta = (DisplayName = "Enable Room"))
  34. bool bEnable = false;
  35. /**
  36. * If true, the portal connections for this room can change during runtime when this room moves.
  37. * For worlds containing many portals, this can be expensive. Note that this room's portal connections
  38. * may still change, even when Room Is Dynamic = false, when dynamic portals are moved (i.e. when portals
  39. * move who have bDynamic = true).
  40. * When Room Is Dynamic = true, enabling and disabling rooms will have immediate effect, without needing
  41. * to update emitters and/or listeners directly. */
  42. UPROPERTY(EditAnywhere, BlueprintSetter = SetDynamic, Category = "Room", meta = (DisplayName = "Room Is Dynamic"))
  43. bool bDynamic = false;
  44. UFUNCTION(BlueprintSetter, Category = "Room")
  45. void SetDynamic(bool bInDynamic);
  46. /**
  47. * The precedence in which the Rooms will be applied. In the case of overlapping rooms, only the one
  48. * with the highest priority is chosen. If two or more overlapping rooms have the same
  49. * priority, the chosen room is unpredictable.
  50. */
  51. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Room")
  52. float Priority = .0f;
  53. /**
  54. * Used to set the transmission loss value in wwise, on emitters in the room, when no audio paths to the
  55. * listener are found via sound propagation in Wwise Spatial Audio. This value can be thought of as
  56. * 'thickness', as it relates to how much sound energy is transmitted through the wall. Valid range 0.0f-1.0f,
  57. * and is mapped to the occlusion curve as defined in the Wwise project.
  58. */
  59. UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "Transmission Loss", Category = "Room", meta = (ClampMin=0.0f, ClampMax=1.0f, UIMin=0.0f, UIMax=1.0f))
  60. float WallOcclusion = .0f;
  61. /**
  62. * Send level for sounds that are posted on the room. Valid range: (0.f-1.f). A value of 0 disables the aux send.
  63. */
  64. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AkEvent", meta = (ClampMin = "0.0", ClampMax = "1.0"))
  65. float AuxSendLevel = .0f;
  66. /** Automatically post the associated AkAudioEvent on BeginPlay */
  67. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AkEvent", SimpleDisplay)
  68. bool AutoPost = false;
  69. /** Posts this game object's AkAudioEvent to Wwise, using this as the game object source */
  70. virtual int32 PostAssociatedAkEvent(
  71. UPARAM(meta = (Bitmask, BitmaskEnum = "/Script/AkAudio.EAkCallbackType")) int32 CallbackMask,
  72. const FOnAkPostEventCallback& PostEventCallback
  73. );
  74. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkRoomComponent")
  75. UPrimitiveComponent* GetPrimitiveParent() const;
  76. /**
  77. * Establishes a parent-child relationship between this Room and a parent Room and allows for sound propagation between them as if they were the same Room, without the need for a connecting Portal.
  78. * Setting a Room as a Reverb Zone is useful in situations where two or more acoustic environments are not easily modeled as closed Rooms connected by Portals.
  79. * Possible uses for Reverb Zones include: a covered area with no walls, a forested area within an outdoor space, or any situation where multiple reverb effects are desired within a common space.
  80. * Reverb Zones have many advantages compared to standard Game-Defined Auxiliary Sends (i.e. compared to the AkLateReverbComponent or the AkReverbVolume). They are part of the wet path, and form reverb chains with other Rooms;
  81. * they are spatialized according to their 3D extent; they are also subject to other acoustic phenomena simulated in Wwise Spatial Audio, such as diffraction and transmission.
  82. * A Reverb Zone needs to be a Room component with an associated geometry.
  83. *
  84. * @param InParentRoom - The parent Room component. A parent Room can have multiple Reverb Zones, but a Reverb Zone can only have a single Parent. If a Room is already assigned to a parent Room, it is first removed from the old parent (exactly as if RemoveReverbZone were called) before then being assigned to the new parent Room. A Reverb Zone can be the parent of another Reverb Zone. A Room cannot be its own parent. Defaults to the 'Outdoors' Room if left empty.
  85. * @param InTransitionRegionWidth - Width of the transition region between the Reverb Zone and its parent. The transition region acts the same as the depth of a Portal but centered around the Reverb Zone geometry. It only applies where transmission loss is set to 0. The value must be positive. Negative values are treated as 0.
  86. */
  87. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkRoomComponent")
  88. void SetReverbZone(const UAkRoomComponent* InParentRoom, float InTransitionRegionWidth);
  89. /**
  90. * Removes this Reverb Zone from its parent.
  91. * Sound can no longer propagate between the two rooms, unless they are explicitly connected with a Portal.
  92. */
  93. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkRoomComponent")
  94. void RemoveReverbZone();
  95. /** Register a room in AK Spatial Audio. */
  96. void AddSpatialAudioRoom();
  97. /** Modify a room in AK Spatial Audio. */
  98. void UpdateSpatialAudioRoom();
  99. /** Remove a room from AK Spatial Audio */
  100. void RemoveSpatialAudioRoom();
  101. bool HasEffectOnLocation(const FVector& Location) const;
  102. bool RoomIsActive() const;
  103. AkRoomID GetRoomID() const { return AkRoomID(this); }
  104. virtual void OnRegister() override;
  105. virtual void OnUnregister() override;
  106. #if WITH_EDITOR
  107. virtual void BeginDestroy() override;
  108. virtual void OnComponentCreated() override;
  109. virtual void InitializeComponent() override;
  110. virtual void PostLoad() override;
  111. virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
  112. #endif
  113. virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction) override;
  114. virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport) override;
  115. virtual bool MoveComponentImpl(
  116. const FVector & Delta,
  117. const FQuat & NewRotation,
  118. bool bSweep,
  119. FHitResult * Hit,
  120. EMoveComponentFlags MoveFlags,
  121. ETeleportType Teleport) override;
  122. FName GetName() const;
  123. virtual AkPlayingID PostAkEventByNameWithDelegate(
  124. UAkAudioEvent* AkEvent,
  125. const FString& in_EventName,
  126. int32 CallbackMask, const FOnAkPostEventCallback& PostEventCallback);
  127. // Begin USceneComponent Interface
  128. virtual void BeginPlay() override;
  129. virtual void EndPlay(EEndPlayReason::Type EndPlayReason) override;
  130. #if WITH_EDITOR
  131. virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
  132. void OnParentNameChanged();
  133. #endif
  134. /** Set the geometry component that will be used to send the geometry of the room to Wwise. For example, in a Blueprint that has a static mesh component with an AkGeometry child component, this function can be called in BeginPlay to associate that AkGeometry component with this room component.
  135. * If this room component has a sibling geometry component (or surface reflector set component), they will be associated automatically and there is no need to call this function.
  136. */
  137. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkRoomComponent")
  138. void SetGeometryComponent(UAkAcousticTextureSetComponent* textureSetComponent);
  139. void AddPortalConnection(UAkPortalComponent* in_pPortal);
  140. void RemovePortalConnection(AkPortalID in_portalID);
  141. const PortalComponentMap& GetConnectedPortals() const { return ConnectedPortals; }
  142. bool IsAReverbZoneInWwise() const { return bIsAReverbZoneInWwise; }
  143. AkRoomID GetParentRoomID() const { return ParentRoomID; }
  144. FString GetRoomName();
  145. UAkLateReverbComponent* GetReverbComponent();
  146. private:
  147. class UPrimitiveComponent* Parent;
  148. UPROPERTY(Transient)
  149. class UAkAcousticTextureSetComponent* GeometryComponent = nullptr;
  150. PortalComponentMap ConnectedPortals;
  151. void InitializeParent();
  152. void GetRoomParams(AkRoomParams& outParams);
  153. bool EncompassesPoint(FVector Point, float SphereRadius = 0.f, float* OutDistanceToPoint = nullptr) const;
  154. void BeginPlayInternal();
  155. void SendGeometry();
  156. void RemoveGeometry();
  157. float SecondsSinceMovement = 0.0f;
  158. bool Moving = false;
  159. bool bIsAReverbZoneInWwise = false;
  160. // Parent Room ID is valid if current Room is a Reverb Zone
  161. AkRoomID ParentRoomID = AK::SpatialAudio::kOutdoorRoomID;
  162. #if WITH_EDITOR
  163. void HandleObjectsReplaced(const TMap<UObject*, UObject*>& ReplacementMap);
  164. bool bRequiresDeferredBeginPlay = false;
  165. class UDrawRoomComponent* DrawRoomComponent = nullptr;
  166. void RegisterVisEnabledCallback();
  167. void InitializeDrawComponent();
  168. void DestroyDrawComponent();
  169. FDelegateHandle ShowRoomsChangedHandle;
  170. #endif
  171. };