Understanding Unreal serialization: platform between two points

Hello, so I was doing the unreal courses and I was trying to do my own thing at the same time, and I have been trying to do this and trying to find a solution but I cannot find anything online, so I’m obviously missing something. I’m sorry because I’m sure this is a stupid question but I’m starting to lose my mind, and I’m sure that with this figured out I will understand a lot of other things.

I’m working from c++, and I’m trying to do this Blueprint for a platform that moves between two points, so what came to my mind was to use an actor with a mesh and two additional scene components to have a “from” position and a “to” position. (I think that Unreal has type of actor for moving platforms, but that is not the point)

The thing is that I though I could just declare a UPROPERTY variable in the header file for the “from” and “to” positions, then assign the SceneComponents in the Details panel in the Blueprint, but I’m not even able to make even the UPROPERTY to show in the Details panel. What I am missing here? How can I get those SceneComponents in my cpp code and use them?

To give a little background, I come from Unity so maybe I’m totally wrong in the way to approach this.

Here is my header file:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SceneComponent.h"
#include "MovingPlatform.generated.h"

UCLASS()
class UNREAL_PLATFORM_TEST_API AMovingPlatform : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMovingPlatform();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	UPROPERTY(EditAnywhere)
	USceneComponent* FromPosition;

};

And here is my blueprint:

Thank you.

Hi and welcome to the community.

You’re actually not a million miles away. When you add a component like this, they aren’t initialised so in the class you have create the components using a call to CreateDefaultSubobject, and you also have to attach to the root component. This is one way but there’s a simpler approach and that is to use a vector.

You can then use the UProperty to make it editable but better than that, you can attach a widget to it which can be used to position in your map, something like this.

  UPROPERTY(EditAnywhere, Meta = (MakeEditWidget = true))
  FVector TargetLocation;

One really important aspect of this is the positions are relative to the Platform so you need to work out the world position and it gets a little complex as a result. What is normally done is your start position is where the platform is initially positioned and then you use a vector to determine the target position.

It is a really powerful and yet simple to use tool.

Lastly, and this may help you a little further is you calculate the positions in BeginPlay and store in private non-UPROPERTY variables which you can then use to bounce the platform between the two points.

    GlobalTargetLocation = GetTransform().TransformPosition(TargetLocation);
    StartLocation = GetActorLocation();

These are the world positions. If you don’t capture these, the target location keeps moving indetfinitely in the direction of the TargetLocation as you move the actor.

1 Like

Thank you so much! A lot of interesting information, and ways to do it.

So just to make it clear for me: the way to do what I wanted to make in the first place (even if it isn’t the best way) is to create the components using CreateDefaultSubobject in cpp, and then, if I want, modify them inside the BP, and not other way around (creating the components inside the BP and then try to retrieve them inside the cpp script), right?

If there is some course or reference/documentation to understand the way to interact between BP and cpp that should check out let me know, so I don’t make more stupid questions hahaha

Thank you again!

There are a number of different ways again. Making a C++ method a UFUNCTION(BlueprintCallable) at its simplest level lets you use it within Blueprint.

Have a look at these links.

Exposing C++ to Blueprints Visual Scripting in Unreal Engine | Unreal Engine 5.0 Documentation

Has a bit of a guide.

UFunctions in Unreal Engine | Unreal Engine 5.3 Documentation

Also
Unreal Engine UProperties | Unreal Engine 5.0 Documentation

1 Like

Thank you! Reading a lot of nice information already!

I tried to do it with CreateDefaultSubobject and this is what I achieved, pretty similar of what I had in my mind:

platform_test

And the code if someone is interested:

AMovingPlatform::AMovingPlatform()
{
 	// 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;

	Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
	RootComponent = Root;

	FromPosition = CreateDefaultSubobject<USceneComponent>(TEXT("From"));
	FromPosition->AttachToComponent(RootComponent,FAttachmentTransformRules::KeepRelativeTransform);

	ToPosition = CreateDefaultSubobject<USceneComponent>(TEXT("To"));
	ToPosition->AttachToComponent(RootComponent,FAttachmentTransformRules::KeepRelativeTransform);

	Platform = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Platform"));
	Platform->AttachToComponent(RootComponent,FAttachmentTransformRules::KeepRelativeTransform);
}

void AMovingPlatform::SetPlatformPosition(float T){
	Platform->SetRelativeLocation(
		FMath::Lerp(FromPosition->GetRelativeLocation(),
			ToPosition->GetRelativeLocation(),
			AnimationCurve->GetFloatValue(T)));   
}


float interpolationPoint;
float delay = -1;
bool backwards=false;

void AMovingPlatform::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	float delta = DeltaTime/AnimationTime;
	
	if(backwards)
	{
		delta= -delta;
	}

	delay-=DeltaTime;
	if(delay<0)
	{
		interpolationPoint+=delta;
	}

	SetPlatformPosition(interpolationPoint);

	if(interpolationPoint>=1 && !backwards)
	{
		interpolationPoint=1;
		backwards = true;
		delay = DelayTime;
	}
	else if(interpolationPoint<=0 && backwards)
	{
		interpolationPoint=0;
		backwards = false;
		delay = DelayTime;
	}
}
1 Like

There’s all sorts of cool stuff you can do with Unreal in this way, such as providing meshes and have it generate them between two points. You can even have these points be a spline.

From the other point of view, you just need 2 vectors for the start and end locations, almost identical to what you have. The advantage is, if I recall correctly, is that you can use a TArray to get multiple points and you can even use DrawDebugLine in the editor to show the connection between them. Here’s an example of the power of vectors. The generation is done via the construction script rather than the event graph You can also do this via C++ - no reason why you cannot.



image

Lastly, you could easily do this they way you’ve done it as well. The reason I wouldn’t use the scene components is even though they don’t show, they do have an overhead that a vector doesn’t.

Anyway, glad you got it working and enjoy.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms