Particle Text Plugin

Support thread for the Particle Text plugin located here: Particle Text in Code Plugins - UE Marketplace
Issues or questions? Ask away.

**Update **[2020-05-22]: Version 1.0.3 is live! Android is officially supported! I don’t have an iOS device, so I can’t reasonably provide support for it, unfortunately.

Releases:

I Create Empty Project to 4.15.1 Release Version. And I Tested to Cook. So I Can See Cook Fail When I Use ParticleTextParamComponent in blueprint.

Thanks, I’ll take a look

Are You Seriously Tested To Build?? I Try Build Your Tutorial Project But isn’t Work…

EDIT: Sorry, one more change for a runtime issue:
change
if (!CanvasWriter && !HasAnyFlags(RF_ClassDefaultObject))
to
if (!CanvasWriter && !HasAnyFlags(RF_ClassDefaultObject | RF_NeedLoad))

vasio: Thanks for pointing this out!
I’ll be submitting a fix to Epic shortly.
In the meantime, could you change line 54 in ParticleTextParamComponent
from:
if (!GetWorld()->IsGameWorld())
to:
if (!GetWorld()->IsGameWorld() && !GIsCookerLoadingPackage)

I had tested packaging in 4.16, but not in 4.14/4.15.

In order to use a ParticleTextParamComponent in C++, I had to edit ParticleTextParamComponent.h

This:
class UParticleTextParamComponent : public USceneComponent

Changed to:
class PARTICLETEXT_API UParticleTextParamComponent : public USceneComponent

And then it worked.

Thanks!

I’ve submitted a fix to Epic for packaging ParticleTextParamComponents in 4.14/4.15 and for a crash in Packaged builds with changing params on the ParticleTextParamComponent at runtime in all versions.
vasio: I’ve sent you a PM with a patch for the source files that should get you up and running.
jvukovich: thanks for pointing this out, I’ve included it in the update as well.

If anyone else wants the patch ahead of the release, send me a PM.

Thanks everyone!

Cool, thanks!

With that said, I could not, for the life of me, get the particle text to change when calling SetTextParam() in C++. I created a standard particle component and attached it to my actor. I then created a ParticleTextParamComponent and attached that to my standard particle component. I created/initialized both and setup properties in my actor constructor. I checked my settings by creating a Blueprint class with a parent class of my C++ actor. All the settings in the Blueprint reflected what I did in C++.

But, when I’d try it in-game, none of the settings took effect.

I deleted all my code over the weekend and have fallen back on creating separate standalone particle effects with static text for what I need right now. But, thought I would share my experience.

Thanks!

jvukovich: do you have a small test project you could zip up and send my way? I’d be happy to take a look.

Sure thing, I put one together today. Here you go: odrive

There should be a cube in the map. Just shoot it and it fires an OnHit() event. The particle text is being set to a new random value on every hit, but, as you’ll see, it does not show it when the particle is created.

I could be doing something wrong?

It was built on UE4 4.15.2. Thanks!

Ah, the main problem was that you were using UGameplayStatics::SpawnEmitterAtLocation, which only spawns the emitter and not a new paramcomponent.
To preserve the paramcomponent->emitter relationship, you need to make a new actor type with that hierarchy defined like so:
You’d probably want some code to auto-destroy the AMyProjectDemoHitEffect actor after a delay, too, but that should be fairly trivial…



#pragma once 
#include "ParticleText/Public/ParticleTextParamComponent.h"
#include "MyProjectDemoOnHitActor.generated.h"

UCLASS()
class AMyProjectDemoOnHitActor : public AActor
{
	GENERATED_BODY()

public:
	AMyProjectDemoOnHitActor();

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = PrimaryStaticMesh, meta = (AllowPrivateAccess = "true"))
	UStaticMeshComponent* StaticMesh;

	UFUNCTION()
	void OnHit(UPrimitiveComponent* ThisComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
};

UCLASS()
class AMyProjectDemoHitEffect : public AActor
{
	GENERATED_BODY()

public:
	AMyProjectDemoHitEffect();

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = ParticleText, meta = (AllowPrivateAccess = "true"))
	UParticleTextParamComponent* DemoParticleTextParamComponent;
};




#include "MyProject.h"
#include "MyProjectDemoOnHitActor.h"

AMyProjectDemoOnHitActor::AMyProjectDemoOnHitActor()
{
	StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
	StaticMesh->SetSimulatePhysics(true);
	StaticMesh->SetEnableGravity(true);
	StaticMesh->SetMassOverrideInKg(TEXT(""), 1000.f, true);
	StaticMesh->bGenerateOverlapEvents = true;
	StaticMesh->OnComponentHit.AddDynamic(this, &AMyProjectDemoOnHitActor::OnHit);
	StaticMesh->BodyInstance.SetCollisionProfileName(TEXT("PhysicsActor"));
	StaticMesh->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
}

void AMyProjectDemoOnHitActor::OnHit(UPrimitiveComponent* ThisComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	auto CurrentPlayer = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0);
	auto LookAtPlayerRotation = FRotationMatrix::MakeFromX(CurrentPlayer->GetActorLocation() - GetActorLocation()).Rotator();

	AMyProjectDemoHitEffect* Effect = GetWorld()->SpawnActor<AMyProjectDemoHitEffect>(AMyProjectDemoHitEffect::StaticClass(), GetActorLocation(), LookAtPlayerRotation);
	
	if (Effect != nullptr)
	{
		auto RandomText = FString::Printf(TEXT("Test %d"), FMath::RandRange(1, 4));
		Effect->DemoParticleTextParamComponent->SetParamText(RandomText);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor(168.f, 252.f, 0.f), FString::Printf(TEXT("OnHit(): SetParamText() to %s"), *RandomText));
	}
}

AMyProjectDemoHitEffect::AMyProjectDemoHitEffect()
{
	static ConstructorHelpers::FObjectFinder<UParticleSystem> DemoParticleComponentRef(TEXT("Demo'/Game/Demo/P_Demo.P_Demo'"));
	UParticleSystemComponent* DemoParticleComponent = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("DemoParticleComponent"));

	if (DemoParticleComponentRef.Succeeded())
	{
		DemoParticleComponent->SetTemplate(DemoParticleComponentRef.Object);
		DemoParticleComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
	}

	DemoParticleTextParamComponent = CreateDefaultSubobject<UParticleTextParamComponent>(TEXT("DemoParticleTextParamComponent"));
	DemoParticleTextParamComponent->AttachToComponent(DemoParticleComponent, FAttachmentTransformRules::KeepRelativeTransform);
}

Ah ha, thank you Matt! Everything is working perfectly now. Thanks again!

Hello Matt.
We are a very small team and working on a project via git.
The plugins we are using are usually project plugins. So, they come with the project and when I buy something on the market, every one get it through the git.
But your plugins is an engine one… How does it works in that case ?

Should every member of the team buy the plugin or is it a way to share it through the project ?
Can I share the plugins with other team members ?
If not, Can we use some place holder in the engine of team members that doesn’t own the plugins and keep it in the building engine only ?

Apologies for the very late response! For some reason, I didn’t get an email notification for your message, even though I’m subscribed to this thread.
Here’s an answerhub page that goes over the issue of sharing plugins:

Basically, your team does not need to each individually purchase the plugin. If you copy the plugin from your Engine/Plugins/Marketplace folder into your <projectname>/Plugins folder, you should be able to then check it into your git repo and share it with everyone.

Excellent !
I’m happy you’re Ok with this, Thanks a lot :slight_smile:

Work on mobile ?

Hi Calvin, Particle Text isn’t currently supported on mobile. Based on some brief testing on a single Android phone, the basic Particle Text module works, but the ParticleTextParamComponent does not (meaning: you can get static text, but can’t get the dynamic morphing text). This is about what I’d expect, as the basic Particle Text Module pre-allocates the particle positions in the editor, and the ParticleTextParamComponent calculates them at runtime by rendering out a texture on the GPU. If you’re interested, I can point you to how to compile the plugin for mobile, but I can’t officially guarantee any functionality or performance.

Can you please put a video tutorial together on how to properly create the particle emitter and get the plugin to work? I read the tutorial and did everything you said but I can’t seem to get the same results. Any help would be much appreciated :slight_smile:

Hi bigboy2k,
Did you get a chance to download the demo project and go through it? I’d also like to know more specifics about the problems you’re having.

I did download the demo project and the problem I am having is that I can’t replicate anything you did. I created a particle and opened up a particle you did and made sure that I used the exact same setting as you but I just can’t seem to get the same result. I am sure I am overlooking something simple but it would be really nice if you could create a quick tutorial video of you creating a basic particle with the word Text. Thank you :slight_smile: