Hey everyone!
I’m new to C++ and Unreal. I’ve been teaching myself C++ for about a month and then started learning Unreal. Ive been trying to wrap my head around the game engine and the UClasses to get some simple things working.
I followed the CountDown tutorial everyone seems to do. One of a few I’ve done. So I wanted to try and do my own thing. I’ve run into a lot of issues I’ve been able to read up on and solve. But I’m currently stuck on something I can’t see a solution to.
It may be my understanding of C++ or how to properly use Unreal’s classes.
I’m currently trying to “print” DeltaTime to the OnScreenDebugMessage, Which I got working.
I am no trying to do the same with the UTextRenderComponent created in the tutorial.
I rebuilt a new class and here is where I am at.
I’m trying to use UTextRenderComponent::SetText
but I’m getting the error ‘DeltaTime’: undelcared identifier
Would love some examples on how to properly accomplish this.
Thank you so much!
-K
ACounter::ACounter()
{
// 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;
//Creates a subObject
CounterText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("Counter"));
CounterText->SetWorldSize(150.0f);
RootComponent = CounterText;
}
// Called when the game starts or when spawned
void ACounter::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACounter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
UpdateCounterDisplay();
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::SanitizeFloat(DeltaTime));
}
void ACounter::UpdateCounterDisplay()
{
//This is where I'm having the issue
CounterText->SetText(FString::SanitizeFloat(DeltaTime));
}
Heya!
What the compiler is trying to tell you is that at this point of the code, the variable is not known - since the function call is its separate “scope”, the variables from the tick function do not really propagate into the function unless you pass them as a function argument. So, the simplest solution would be to add an argument in your Update… Function, like
void ACounter::UpdateCounterDisplay(float DeltaTime) And then pass the DeltaTime variable in your Call in Tick().
I was doing more reading and some things are making more sense.
I tried placing that as an argument and got a different error.
Error C2511 ‘void ACounter::UpdateCounterDisplay(float)’: overloaded member function not found in ‘ACounter’
// Called every frame
void ACounter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
UpdateCounterDisplay();
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::SanitizeFloat(DeltaTime));
}
void ACounter::UpdateCounterDisplay(float DeltaTime)
{
//This is where I'm having the issue
CounterText->SetText(FString::SanitizeFloat(DeltaTime));
}
I see how passing DeltaTime into the argument allows for it to recognize it within this function.
What I’m having a hard time with is understanding what is a BaseClass function or a DerivedClass function and how to manage them all.
All new concepts to me by the way.
Since ACounter is a derived class of the Unreal AActor base class, do I need to manage the base function of Tick into something manageable for all of my derived classes?
If you have ClassA with method Tick
And if you have ClassB that extends ClassA which overrides Tick
If you have a pointer to an instance of ClassB like this:
ClassA * myClass = new ClassB();
myClass->Tick() calls the ClassB version even though your variable myClass is declared as a pointer to ClassA.
It’s up to you in Tick to call Super::Tick() to also call the classA version, or it’ll never call.
You can also explicitly call ClassA::Tick() instead of Super::Tick(). This way if you have a heirarchy like: ClassA -> ClassB -> ClassC. Class C can call the ClassA method and skip ClassB.
C++ normally doesn’t have Super:: at all. Unreal added this as a convenience because they make multiple inheritance impossible, so there is no ambiguity about what Super is. In traditional C++ you might not always know what Super:: is if you inherit from multiple classes.
Basically if you really know what you’re doing and don’t want to call Super::Tick(DeltaTime) for whatever reason then don’t. But usually it’s almost always a good idea to call Super::FunctionGoesHere in all derived functions to ensure all of the functionality is run.
BTW this only works if the C++ function is marked virtual. There’s an added cost to having functions be overridable or virtual. If they’re not virtual, they can’t be overridden, but calling them is much simpler and just instantly happens. When functions are virtual, there’s a table of function addresses for each instance of a class. So when you have a pointer to ClassB it knows to call the ClassB version of the function no matter if your original pointer is to a super class or not.
Thank you for your response!
This really does help!
Before entering into Unreal c++, I was learning simple things in a solely C++ environment with a simple int main() function.
Unreal has forced me to learn a larger scope of c++ and the unreal libraries quicker than I expected to see stuff work.
I’m trying to update a UTextCompenent with the current DeltaTime every tick. I got it to work with…
What I’m not used to is… there is no int main() function within a class or function that I’m created in an unreal environment.
How do you tell things within your class to operate per tick?
Do you treat the U function Tick as your int main()?
Or is it simple how you handle any function within a class?
Also how do you then create an object of your class, or do you have to have a function within your class to create objects of it?
I have a separate function for updating the UTextComponent within my Counter Class based on the class AActor that I’m placing in the world manually.
void ACounter::UpdateCounterDisplay(float DeltaTime) { //This is where I'm having the issue CounterText->SetText(FString::SanitizeFloat(DeltaTime)); }
The problem here as someone mentioned before, DeltaTime is not within the scope of this function. I don’t see how I can share or include the scope of Tick(DeltaTime) from one function to another within my class. Especially since Tick seems to be a Base Class function that exists even outside of my class.
you have set up your new function to -recieve- delta time (also make sure its set this way in the .h) but look at the tick function, you have not actually passed in the delta time to it.
Your function should be passing deltatime to it within tick, the same way tick is passing deltatime to super::tick.
Updatecounterdisplay(deltatime);
An “overloaded function” is a function that is coded multiple times with to different input paramaters. That is what the error means, your function is set to recieve deltatime but you are passing in nothing so its looking for the overloaded version with nothing passed in which doesnt exist.
the tick function is what runs every frame, and as you are calling updatecounterdisplay inside it, all code/functions to be called per frame would be called from tick.
same with begin play which is run once when the game loads or object is spawned.
These are the main functions that drive the rest of your code.
–creating objects–
if it is based off an actor, something that can be placed in world you would use spawnactor (google it). This. Can be called from anywhere though you would only use it where needed to spawn something during gameplay. Simply place actors in your level manually by default.
to make things easier, look into creating blueprints off of classes, and then spawning them with tsubclassof variables. This will allow you to spawn actors with variables youve set for them.
Just add “ue4 cpp” to your google searches to easily find c++ unreal stuff.
Unreal has a main somewhere that starts the whole program and is the entry point into the app. So when the OS starts your program it calls main, and main calls a ton of other functions from there. It’s like a giant tree of functions that all originate from main. It can be as simple as a console app that prints helloworld, or as complex as a game engine or an operating system, or whatever.
A really simple game engine would look like this:
int main(int argc, const char ** argv) {
ActorManager * actorManager = new ActorManager();
actorManager->AddActor(new Actor());
actorManager->AddActor(new Actor());
actorManager->AddActor(new Actor());
// main game loop
while(true) {
actorManager->GameTick(); //Go through all actors that were added and call their GameTick functions.
actorManager->RenderFrame();
}
return 0;
}
Here actorManager calls GameTick every frame on all actors. And every Actor can do what it wants in its GameTick. It can either do nothing, or it can do a bunch of AI, or animations, or physics, or print HelloWorld.
And if you push the space bar key on your keyboard, the OS sends an event to the engine that this was pressed. Then the engine finds what actors were paying attention to the space bar key. And then those actors process the space bar event. And then maybe the space bar event will make your character jump.