diff --git a/Source/EventCenterPlugin/Private/SpawnableActor.cpp b/Source/EventCenterPlugin/Private/SpawnableActor.cpp index aa72af1..281d777 100644 --- a/Source/EventCenterPlugin/Private/SpawnableActor.cpp +++ b/Source/EventCenterPlugin/Private/SpawnableActor.cpp @@ -27,8 +27,14 @@ ASpawnableActor::ASpawnableActor() */ // NB: Only valid to call in the CTOR. - BaseMeshComponent = CreateDefaultSubobject(TEXT("BaseMesh")); - BaseMeshComponent->SetupAttachment(RootComponent); + //BaseMeshComponent = CreateDefaultSubobject(TEXT("BaseMesh")); + //BaseMeshComponent->SetupAttachment(RootComponent); + + // Attach a mesh to the object to try to turn on physics. + // Maybe not necessary... + //static ConstructorHelpers::FObjectFinder BaseMeshAsset(TEXT("StaticMesh'/Game/StarterContent/Props/MaterialSphere.MaterialSphere'")); + //BaseMeshComponent->SetStaticMesh(BaseMeshAsset.Object); + //BaseMeshComponent->SetSimulatePhysics(true); } ASpawnableActor::~ASpawnableActor() @@ -51,7 +57,7 @@ void ASpawnableActor::Tick(float DeltaTime) } // TODO: This doesn't work outside of constructor -void ASpawnableActor::SetMeshByString(const FString& meshName) +/*void ASpawnableActor::SetMeshByString(const FString& meshName) { // Attach a mesh to the object. // eg. TEXT("StaticMesh'/Game/StarterContent/Props/MaterialSphere.MaterialSphere'") @@ -64,14 +70,16 @@ void ASpawnableActor::SetMeshByString(const FString& meshName) BaseMeshComponent->SetStaticMesh(BaseMesh); BaseMeshComponent->SetSimulatePhysics(true); -} +}*/ -void ASpawnableActor::SetMesh(UStaticMesh* staticMesh) +// Works!! +/*void ASpawnableActor::SetMesh(UStaticMesh* staticMesh) { BaseMesh = staticMesh; BaseMeshComponent->SetStaticMesh(BaseMesh); BaseMeshComponent->SetSimulatePhysics(true); -} + BaseMeshComponent->UpdateCollisionFromStaticMesh(); +}*/ void ASpawnableActor::StartDestroyTimer(float seconds) { diff --git a/Source/EventCenterPlugin/Private/SpawnableSkeletalMeshActor.cpp b/Source/EventCenterPlugin/Private/SpawnableSkeletalMeshActor.cpp new file mode 100644 index 0000000..a766484 --- /dev/null +++ b/Source/EventCenterPlugin/Private/SpawnableSkeletalMeshActor.cpp @@ -0,0 +1,29 @@ +#include "SpawnableSkeletalMeshActor.h" + +#include "UObject/Object.h" +#include "Engine/EngineTypes.h" + + +DEFINE_LOG_CATEGORY(SpawnableSkeletalMeshActorLog); + +ASpawnableSkeletalMeshActor::ASpawnableSkeletalMeshActor() +{ + // Set this actor to call Tick() every frame. + // You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; + + BaseMeshComponent = CreateDefaultSubobject(TEXT("BaseMesh")); + BaseMeshComponent->SetupAttachment(RootComponent); +} + +ASpawnableSkeletalMeshActor::~ASpawnableSkeletalMeshActor() { +} + +void ASpawnableSkeletalMeshActor::SetSpawnableSkeletalMesh(USkeletalMesh* skeletalMesh) +{ + BaseMesh = skeletalMesh; + BaseMeshComponent->SetSkeletalMesh(BaseMesh); + BaseMeshComponent->SetSimulatePhysics(true); + BaseMeshComponent->SetAllBodiesCollisionObjectType(ECollisionChannel::ECC_PhysicsBody); +} + diff --git a/Source/EventCenterPlugin/Private/SpawnableStaticMeshActor.cpp b/Source/EventCenterPlugin/Private/SpawnableStaticMeshActor.cpp new file mode 100644 index 0000000..231ddda --- /dev/null +++ b/Source/EventCenterPlugin/Private/SpawnableStaticMeshActor.cpp @@ -0,0 +1,27 @@ +#include "SpawnableStaticMeshActor.h" + +#include "UObject/Object.h" + +DEFINE_LOG_CATEGORY(SpawnableStaticMeshActorLog); + +ASpawnableStaticMeshActor::ASpawnableStaticMeshActor() +{ + // Set this actor to call Tick() every frame. + // You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; + + BaseMeshComponent = CreateDefaultSubobject(TEXT("BaseMesh")); + BaseMeshComponent->SetupAttachment(RootComponent); +} + +ASpawnableStaticMeshActor::~ASpawnableStaticMeshActor() { +} + +void ASpawnableStaticMeshActor::SetSpawnableStaticMesh(UStaticMesh* staticMesh) +{ + BaseMesh = staticMesh; + BaseMeshComponent->SetStaticMesh(BaseMesh); + BaseMeshComponent->SetSimulatePhysics(true); + BaseMeshComponent->UpdateCollisionFromStaticMesh(); +} + diff --git a/Source/EventCenterPlugin/Private/SpawningActor.cpp b/Source/EventCenterPlugin/Private/SpawningActor.cpp index dc60178..9f4a30f 100644 --- a/Source/EventCenterPlugin/Private/SpawningActor.cpp +++ b/Source/EventCenterPlugin/Private/SpawningActor.cpp @@ -49,9 +49,85 @@ ASpawnableActor* ASpawningActor::Spawn() // Teleport actor randomly // TODO(bt): Put this in front of the camera, or on the (camera -> player) arc! - float x = FMath::RandRange(-100.0f, 100.0f); - float y = FMath::RandRange(-100.0f, 100.0f); - float z = FMath::RandRange(-100.0f, 100.0f); + float x = FMath::RandRange(-4000.0f, 4000.0f); + float y = FMath::RandRange(-4000.0f, 4000.0f); + float z = FMath::RandRange(3000.0f, 10000.0f); + + FVector location( + playerLocation.X + x, + playerLocation.Y + y, + playerLocation.Z + z + ); + + FRotator rotation; + spawnedActor->SetActorLocationAndRotation( + location, + rotation, + false, + 0, + ETeleportType::ResetPhysics + ); + + // We don't want to keep the actor around indefinitely since they may pile up unused. + // Optionally, we could maintain a queue and cull the oldest actors. + spawnedActor->StartDestroyTimer(10.0); + + return spawnedActor; +} + +ASpawnableStaticMeshActor* ASpawningActor::SpawnStaticMeshActor() +{ + // Spawn actor + // TODO(bt): This will memory leak. + ASpawnableStaticMeshActor* spawnedActor = (ASpawnableStaticMeshActor*)GetWorld()->SpawnActor(ASpawnableStaticMeshActor::StaticClass()); + + // Get player location + FVector playerLocation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation(); + + + // Teleport actor randomly + // TODO(bt): Put this in front of the camera, or on the (camera -> player) arc! + float x = FMath::RandRange(-4000.0f, 4000.0f); + float y = FMath::RandRange(-4000.0f, 4000.0f); + float z = FMath::RandRange(3000.0f, 10000.0f); + + FVector location( + playerLocation.X + x, + playerLocation.Y + y, + playerLocation.Z + z + ); + + FRotator rotation; + spawnedActor->SetActorLocationAndRotation( + location, + rotation, + false, + 0, + ETeleportType::ResetPhysics + ); + + // We don't want to keep the actor around indefinitely since they may pile up unused. + // Optionally, we could maintain a queue and cull the oldest actors. + spawnedActor->StartDestroyTimer(10.0); + + return spawnedActor; +} + +ASpawnableSkeletalMeshActor* ASpawningActor::SpawnSkeletalMeshActor() +{ + // Spawn actor + // TODO(bt): This will memory leak. + ASpawnableSkeletalMeshActor* spawnedActor = (ASpawnableSkeletalMeshActor*)GetWorld()->SpawnActor(ASpawnableSkeletalMeshActor::StaticClass()); + + // Get player location + FVector playerLocation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation(); + + + // Teleport actor randomly + // TODO(bt): Put this in front of the camera, or on the (camera -> player) arc! + float x = FMath::RandRange(-4000.0f, 4000.0f); + float y = FMath::RandRange(-4000.0f, 4000.0f); + float z = FMath::RandRange(3000.0f, 10000.0f); FVector location( playerLocation.X + x, diff --git a/Source/EventCenterPlugin/Public/SpawnableActor.h b/Source/EventCenterPlugin/Public/SpawnableActor.h index 8f2f909..7ac46fe 100644 --- a/Source/EventCenterPlugin/Public/SpawnableActor.h +++ b/Source/EventCenterPlugin/Public/SpawnableActor.h @@ -22,19 +22,19 @@ public: ~ASpawnableActor(); /** Mesh to use */ - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawnableActor", meta = (AllowPrivateAccess = "true")) - class UStaticMeshComponent* BaseMeshComponent; + //UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawnableActor", meta = (AllowPrivateAccess = "true")) + //class UStaticMeshComponent* BaseMeshComponent; /** Mesh to use */ - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawnableActor", meta = (AllowPrivateAccess = "true")) - class UStaticMesh* BaseMesh; + //UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawnableActor", meta = (AllowPrivateAccess = "true")) + //class UStaticMesh* BaseMesh; // FIXME: This won't work outside of the ctor :( - UFUNCTION(BlueprintCallable, Category = "SpawnableActor") - void SetMeshByString(const FString& meshName); + //UFUNCTION(BlueprintCallable, Category = "SpawnableActor") + //void SetMeshByString(const FString& meshName); - UFUNCTION(BlueprintCallable, Category = "SpawnableActor") - void SetMesh(UStaticMesh* staticMesh); + //UFUNCTION(BlueprintCallable, Category = "SpawnableActor") + //void SetMesh(UStaticMesh* staticMesh); /** Set a timer to destroy this actor. */ void StartDestroyTimer(float seconds); diff --git a/Source/EventCenterPlugin/Public/SpawnableSkeletalMeshActor.h b/Source/EventCenterPlugin/Public/SpawnableSkeletalMeshActor.h new file mode 100644 index 0000000..856978e --- /dev/null +++ b/Source/EventCenterPlugin/Public/SpawnableSkeletalMeshActor.h @@ -0,0 +1,38 @@ +#pragma once + +// Unreal Core +#include "CoreMinimal.h" +#include "UObject/NoExportTypes.h" +#include "Engine/EngineTypes.h" + +// EventCenterPlugin +#include "SpawnableActor.h" +#include "SpawnableSkeletalMeshActor.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(SpawnableSkeletalMeshActorLog, Log, All); + +// NB(bt): "Blueprintable" seems to remove the ability to add BP event nodes. +UCLASS() +class EVENTCENTERPLUGIN_API ASpawnableSkeletalMeshActor : public ASpawnableActor +{ + GENERATED_BODY() + +public: + + ASpawnableSkeletalMeshActor(); + ~ASpawnableSkeletalMeshActor(); + + /** Access to the skeletal mesh component */ + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawnableSkeletalMeshActor", meta = (AllowPrivateAccess = "true")) + class USkeletalMeshComponent* BaseMeshComponent; + + /** Set the skeletal mesh. */ + UFUNCTION(BlueprintCallable, Category = "SpawnableSkeletalMeshActor") + void SetSpawnableSkeletalMesh(USkeletalMesh* skeletalMesh); + +private: + /** Mesh to use */ + //UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawnableActor", meta = (AllowPrivateAccess = "true")) + class USkeletalMesh* BaseMesh; +}; + diff --git a/Source/EventCenterPlugin/Public/SpawnableStaticMeshActor.h b/Source/EventCenterPlugin/Public/SpawnableStaticMeshActor.h new file mode 100644 index 0000000..939f0e3 --- /dev/null +++ b/Source/EventCenterPlugin/Public/SpawnableStaticMeshActor.h @@ -0,0 +1,38 @@ +#pragma once + +// Unreal Core +#include "CoreMinimal.h" +#include "UObject/NoExportTypes.h" +#include "Engine/EngineTypes.h" + +// EventCenterPlugin +#include "SpawnableActor.h" +#include "SpawnableStaticMeshActor.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(SpawnableStaticMeshActorLog, Log, All); + +// NB(bt): "Blueprintable" seems to remove the ability to add BP event nodes. +UCLASS() +class EVENTCENTERPLUGIN_API ASpawnableStaticMeshActor : public ASpawnableActor +{ + GENERATED_BODY() + +public: + + ASpawnableStaticMeshActor(); + ~ASpawnableStaticMeshActor(); + + /** Access to the static mesh component */ + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawnableStaticMeshActor", meta = (AllowPrivateAccess = "true")) + class UStaticMeshComponent* BaseMeshComponent; + + /** Set the static mesh. */ + UFUNCTION(BlueprintCallable, Category = "SpawnableStaticMeshActor") + void SetSpawnableStaticMesh(UStaticMesh* staticMesh); + +private: + /** Mesh to use */ + //UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawnableActor", meta = (AllowPrivateAccess = "true")) + class UStaticMesh* BaseMesh; +}; + diff --git a/Source/EventCenterPlugin/Public/SpawningActor.h b/Source/EventCenterPlugin/Public/SpawningActor.h index 8f7c993..308cfdf 100644 --- a/Source/EventCenterPlugin/Public/SpawningActor.h +++ b/Source/EventCenterPlugin/Public/SpawningActor.h @@ -6,6 +6,8 @@ // EventCenterPlugin #include "SpawnableActor.h" +#include "SpawnableSkeletalMeshActor.h" +#include "SpawnableStaticMeshActor.h" #include "SpawningActor.generated.h" DECLARE_LOG_CATEGORY_EXTERN(SpawningActorLog, Log, All); @@ -25,13 +27,21 @@ public: UFUNCTION(BlueprintCallable, Category = "SpawningActor") ASpawnableActor* Spawn(); + /** Create actor. */ + UFUNCTION(BlueprintCallable, Category = "SpawningActor") + ASpawnableStaticMeshActor* SpawnStaticMeshActor(); + + /** Create actor. */ + UFUNCTION(BlueprintCallable, Category = "SpawningActor") + ASpawnableSkeletalMeshActor* SpawnSkeletalMeshActor(); + /** Create actor with delegation callback. */ UFUNCTION(BlueprintCallable, Category = "SpawningActor") void SpawnCallback(FString Channel, FString Message); /** Mesh to use */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawningActor", meta = (AllowPrivateAccess = "true")) - class UStaticMeshComponent* BaseMesh; + class UStaticMeshComponent* BaseMesh; protected: // Called when the game starts or when spawned