Trying to understand casting

Hello,

I have had a very frustrating day trying to make blueprints talk with each other. The documentation doesn’t make sense to me and the video tutorials are fine for those specific instances…but otherwise I am totally lost.

Here are some questions:
-I made an pawn blueprint class. Why can I drag a reference of that to my level blueprint and not any other blueprints?
-Why do we have to reference something when we do casting? Why isn’t it enough to just go in blueprint2 and say “casting to blueprint1” and then get some variables from blueprint1? The only thing I can really cast to successfully is my player character.

In one blueprint, I have a class array with 20 references in it. In that same blueprint I generate a thing with 7 randomly chosen instances from the class array.
I want to make a widget that shows that randomly generated thing from my other blueprint. How can I find that array? When I try to reference that blueprint in my widget blueprint I am not able to drag it or call it up anywhere. I can get a cast to blueprint1 but in the blue node thing…I have no idea what to put there and why I would need to put anything there in the first place.

I think there is probably something fundamental I don’t understand. Any guidance would be very appreciated!

Hi Jeremy!

If you are someone who has recently jumped into blueprinting without having any previous experience with programming in general - or object-oriented programming (OOP) in particular - from using something like C++, Java, Python or (the list goes on) then I would imagine that a lot of this stuff must be very confusing and frustrating at times.

A full explanation would require a rather lengthy article, or indeed an entire book, and this isn’t really your typical AnswerHub material… but I’m having a slow morning here nursing a cup of tea, so I’ll try to clear some things up for you. Hopefully :slight_smile:

The main source of your problem is mostly down to the exact definition of what a Class is, versus what an Object (or an Instance) of a class is. It’s also about a core OOP concept known as Inheritance.

If we look at this from a Blueprint perspective: when you create a new Blueprint, let’s call it Robert, you are declaring a new Class. This class declaration, i.e. your blueprint, describes what a specific Robert could possibly know (data/variables) and what he could possibly do (methods/functions) if he is ever brought into existence.

That’s one key distinction: a blueprint class in itself will remain purely hypothetical and ethereal until an actual instance of it is created. As soon as you spawn a Robert, either by placing him in your level, or by dynamically spawning him at a later time in response to some in-game event, then you have an actual Robert that you can communicate with, but not until then.

Prior to spawning any Robert-instances, he will remain nebulous and impossible to talk to because he doesn’t exist yet. However, once you have spawned one or several Roberts, they are thought of as being objects or instances, or, in Blueprint lingo, references of the Robert type.

Next up we should look at inheritance. When you created the Robert blueprint, he was equipped with a lot of data and methods that you didn’t have to create yourself. If the blueprint was based on the built-in class called Actor, it means that any instance of the Robert class is not only that, but also an Actor. If it was based on Pawn, then any instance of your class is a Robert as well as a Pawn and also an Actor (again, because the Pawn class itself inherits from the Actor class). This means that any Robert-type object has all the capabilities that you have defined in your class, plus all the other capabilities inherited from Pawn and Actor. The most obvious way to think about this is to imagine a tree of different phyla, families, species and subspecies of animals: so… this dog I have next to me right now is a whippet. She’s also a canis domesticus, a mammal, a chordate, a tetrapod and an animal. A long list of classes upon classes, each one bringing in a specific set of abilities and properties. This means that I could theoretically cast my dog to a tetrapod or a chordate, but I would not be able to cast her to an arthropod for example, because she is not related to that class at all.

And that’s where casting comes in! Yes, this is going somewhere, mark my words…

Let’s say you have a reference to something in your level, that is a variable with some specific value identifying one particular actor that has been spawned somewhere in the world (that’s not a class per se, but an instance of a class). You know for sure that it is an Actor, on the most fundamental level, but you do not know what specific type it is. Let’s further assume that your blueprint logic needs to assume that it is in fact a Robert type actor, because it needs to call a certain function that only Roberts have.

The solution here is to use a Cast node. All that node does is simply to check the reference that you give it, look through its inheritance tree to see whether the Robert class is involved somewhere or not. If it is, then the cast is successful, and your Actor reference is now converted to a Robert reference, which in turn means you can call any function or look at any variable that has been defined in your Robert blueprint. On the other hand, if the original actor reference was spawned from some other class, say the DefaultPawn, then the cast will fail and you will not be able to call any Robert-specific functions on it, because, of course, it’s not actually a Robert at all.

You will have noticed by now that we always need a reference to a specific instance of a class in order to do any sort of casting. The class itself is not enough.


Anyway… before this goes totally out of hand - your specific questions:

I made a pawn blueprint class. Why can I drag a reference of that to my level blueprint and not any other blueprints?

The level blueprint is a bit special in that it can be made aware of all the objects that you have placed in your map at design time. So if you place an instance of your pawn in the level, the reference to it is already valid and known to the scene graph, which in turn is known by the level blueprint. All other blueprint types rely on a more dynamic approach. In a typical game, many actors are spawned as the game is played rather than being statically placed in the map from the beginning: enemies and projectiles are spawned and destroyed. That means that only the classes exist at the start, but there are no instances of them yet.

A typical Actor-based blueprint class, like your Pawn or Robert above, has no inherent knowledge of the world it will exist in, what level it might be spawned in or anything like that. An actor instance by default knows only its own functions and variables, and those that it has inherited from its base class. If you need it to know anything about some other actor, you must explicitly pass the information to it, typically by sending it a reference to some specific actor instance that you want it to be aware of or talk to.


Why do we have to reference something when we do casting? Why isn’t it enough to just go in blueprint2 and say “casting to blueprint1” and then get some variables from blueprint1?

This was hopefully answered in the general overview above, but the short summary is that without a reference, there is nothing to test for inheritance, so nothing can be cast.

On a tangent here though: in 4.9 (or thereabouts) there will apparently be a way to get access to the default values of some other blueprint class, presumably without explicitly spawning any instances, using a GetClassDefaults node. That could be helpful in some cases, and would not require a reference (if I understood things correctly, but I may very well be wrong) but it still wouldn’t be the same as having access to a specific, live instance of a particular class.


The only thing I can really cast to successfully is my player character

In UE, there is a bunch of classes that are referred to as Framework classes. These are fundamental classes of which at least one (sometimes exactly one) instance exists from the moment the game starts. These include GameMode, PlayerController and a couple of others, and anything related to them is typically always accessible from anywhere because they are created or generally available immediately after the game starts, before any other actors are spawned. The player character (technically the default pawn as specified by your GameMode) is therefore one of those things that you can easily get a reference to, and thereby the ability to cast to, just about anywhere. But that is an exception, and an ability that only the framework classes provide.

Generally speaking, you can successfully cast to anything anywhere, but only if 1) you have a valid reference to an instance of the class you want to cast to, and 2) it really is an instance of the class you are trying to cast to, or it is based on the class you are trying to cast to.


In one blueprint, I have a class array with 20 references in it. In that same blueprint I generate a thing with 7 randomly chosen instances from the class array. I want to make a widget that shows that randomly generated thing from my other blueprint. How can I find that array?

So, in this case you’ll probably see by now that you need to make at least one of these objects aware of the other, by a reference to the specific instance of the class you want to talk to. I don’t know exactly what you are trying to do here, so this will have to be a bit general:

You could go one way or the other here, either the blueprint with the 20 references (B20) would need a reference to the Widget, so it can call some function it has defined, say ShowTheseSevenThings(), or the Widget would need a reference to the B20 so it can call some function it has defined, say GiveMeSevenThings(). It’s either way.

In this case, someone must have created the Widget and placed it in the viewport. When that happens, it should have saved a reference to the widget. That reference could be passed on to the B20 instance, which in turn could use that to call the Widget and tell it to ShowTheseSevenThings(). All of it depends on an unbroken chain of references. Any actor that creates something should save a reference to what it has created so it can communicate with it or pass the reference to someone else for that same purpose.

As soon as some actor, any actor, has a reference to the B20 instance, it can easily cast to the B20 type and then just grab that array you were looking for. But if no such reference exists, you’re dead in the water.

A general approach (again, I don’t know what we’re talking about specifically, so this is a bit fuzzy) is to use some globally accessible class to handle the spawning of things like this. For example, in your scenario we are creating one object of the B20 type somewhere, and one Widget. Who should do this? One way is to let the PlayerController do it, maybe in response to some player input. If you do this, and make sure that the PlayerController saves the references to the things it spawned in a public, editable variable in your playercontroller blueprint, then any other actor can easily get the information because you can call GetPlayerController anywhere and cast that to your specific PlayerController class, at which point you can get the references it has stored for your Widget and your B20. Then they can all talk as much as they like, via those references once they have been cast to the proper type.


Oh well. I don’t know if this has helped you in any way, but my teacup is empty (had it refilled once though) and I have to get back to work.

Hopefully some things are clearer (or I’ve made it worse!)

At any rate, Blueprints are awesome and useful, but unfortunately they do not in any way negate the need to learn and understand the fundamental principles of programming in general. It’s just the way it is.

Nice.

and definitely this:

At any rate, Blueprints are awesome and useful, but unfortunately they do not in any way negate the need to learn and understand the fundamental principles of programming in general. It’s just the way it is.

That is an awesome breakdown. Thanks for taking the time to post such a thorough answer.

Thank you so much for taking the time on that! It helped so much and is a perfect starting point on going deeper into this stuff. The tutorials on blueprints on youtube are helpful but only go through programming basics and never really object oriented stuff so I felt pretty lost. But there is that new tutorial on making a HUD with UMG that goes into more detail on blueprint sharing workflow. That has been very helpful.
Thanks again!!!

Very useful :slight_smile:

So, if i have one HUD called “Timer” and a Blueprint Actor called “BP’” , and in my “timer” HUD i have one variable called “Change_Me”, i will not be able to communicate with that variable from my “BP” blueprint if i don´t have a bridge between both , like a function , for example?

buscas - here is what i think i have learned. you’ll need to make a structure blueprint with all the variables you want to share. right click on content browser, under blueprints, you’ll see “structure blueprint”
then:
-in your player character blueprint (the one that always gets called up on level start so it’s easy to cast to), make a structure variable that references the structure blueprint. so if your structure blueprint is called Robert, make a structure variable in your player character called “Robert” you’ll see in that variable a reference to all the ones you made in the structure blueprint.
-now in any other blueprint, you just cast to your player character, call up that variable you made in the player character, and then you can break it. once you break that variable you’ll see all the variables you made in the structure blueprint. from the break you can get any info.
-if you want to set anything to the structure blueprint variables cast to player blueprint, call up the structure variable you made there, and then you can use “set” to set any info you want.

i don’t know if this makes sense but this is what i’ve learned from reading all this. through this method i was able to have an array get passed through a few different blueprints. thanks again!