What is the difference between these two variables?

In the image you see two variables, they are both character object references (light blue), one is created from a cast output promoted to a variable, the other is simply a created variable that has been set to be a character obj ref.

Yet, these two are NOT the same, but why not? (Unreal seems to treat them differently)

My understanding is that the cast grants one access to THAT blueprint that you need things from, and from there they can get access to things within that BP, components and things, like the player’s capsule component.

Perhaps someone can explain this to me, I’m trying to learn, thanks.

Providing both variables are of the same type - Third Person Character Object Reference - there is only one difference:

  • the promoted one has value assigned, pointing at whatever character there happens to be with index 0. If that cast was successfully, that is.
  • the Char Ref is probably null as far as we tell from the pic; not pointing / rereferring to any instance of a Third Person Character Object

But there seems to some confusion in the attached pic regarding what’s what:

You’re pointing an arrow at the Char Ref but are highlining and showing the type of the Promoted Variable (green frame). If those 2 behave differently, are you certain they’re of the same type? Your image does not demonstrate this.


Yet, these two are NOT the same, but why not? (Unreal seems to treat them differently)

How come? Care to elaborate? Might be connected with the above.


the cast grants one access

Think of the cast as of a Test + Conversion rather than a method of communication. The cast asks a question:

  • is this object of the type I want
  • if Yes, let me treat this object as the requested type, so I can now manipulate the data inside (simplifying)
  • if No (cast fails), we cannot treat this object as the requested type, it’s something different

Thanks for the links, have read some of it.

Cast gets you a reference to a specific instance of that class, if the thing on the other end tests to actually be that type of things; that’s the expense, in the qualification.

The object reference is an empty reference of that type that has yet to be set.

Casting works but can be most-expensive in terms of the options. My 2cents is that I always include a function on the-thing, the anim-bp, the whatever i tied to a player, that just returns This(). Once I have that, I can just say, from the character, get the current anim-bp → ReferenceToSelf and assign from there. Cheaper to do it this way.

Past that, you can push this to an BPI and use the has-BPI test to further error-proof it so that only the items that have that specific BPI might return a reference to self, etc, etce,

“You’re pointing an arrow at the Char Ref but are highlining and showing the type of the Promoted Variable (green frame). If those 2 behave differently, are you certain they’re of the same type? Your image does not demonstrate this.” Naw that pic is correct, the one on the bottom is the created one hence the box on upper right. The one on top is a cast created variable.

“How come? Care to elaborate? Might be connected with the above.”
While experimenting with camera actors and separate movement, one works inside the level BP (the cast) and the other does not.

"Think of the cast as of a Test + Conversion rather than a method of communication. The cast asks a question:

is this object of the type I want
if Yes, let me treat this object as the requested type, so I can now manipulate the data inside (simplifying)
if No (cast fails), we cannot treat this object as the requested type, it’s something different"

Yes I think I understand this, however if both instances are referencing the third person character, then how exactly or why would UE4 treat them different? One can be used inside the level BP for cam movement and the other could not…at least for me.

“Cast gets you a reference to a specific instance of that class, if the thing on the other end tests to actually be that type of things; that’s the expense, in the qualification.”

Maybe then that is it…a specific instance

“The object reference is an empty reference of that type that has yet to be set.” Hmm…so I still need to set the created variable that is referencing third person character BP? Thought I tried that and got an error message but maybe not.

“Casting works but can be most-expensive in terms of the options. My 2cents is that I always include a function on the-thing, the anim-bp, the whatever i tied to a player, that just returns This(). Once I have that, I can just say, from the character, get the current anim-bp → ReferenceToSelf and assign from there. Cheaper to do it this way.”

Good to know.

“Past that, you can push this to an BPI and use the has-BPI test to further error-proof it so that only the items that have that specific BPI might return a reference to self, etc, etce,”

Ok thanks for letting me know.

You probably mean both variables are referencing the same instance of the Third Person Character.

How are you setting the value of the CharRef? We can’t see it in the pic, we can only see the type of the Promoted one (highlighted) - hence the confusion with the arrows.

Creating a reference variable does little on its own, you must point it at an object. It’s like creating a string var and forgetting to type the text, but worse. At least the empty string is valid. What is the type of CharRef?

If both references are of the same type, you could do this: (not even talking about inheritance)

There is no difference between a promoted variable and manually created one. All promotion does is create a reference variable of the correct type - automation & convenience. You could create one manually, call it Promoted, hook it up and it will work all the same.

A promoted float is a float just like a manually created float is a float. It’s just about the type.

image

I see nothing different with the variables other then you showing one being “Set”. At glance I’d say the Char Ref variable isn’t set and should be tested with IsValid.

This is correct. Cast is a test&set in one step, with execution paths on true/false, so it’s like a pot-sticker, a little bit of everything rolled into one.

CharRef is just a var, unset; done. So until one actually goes out and finds a ref to a char and sticks it there, it’s an empty bucket.

The difference in overhead for just having the empty-bucket versus making it, checking the thing you want to put into it, and then actually filling it (the steps in the cast) is where the expense of the cast come in.

" You probably mean both variables are referencing the same instance of the Third Person Character." That is what I was hoping, yet inside the level BP, when considering movement of camera actor. The created TPC created variable doesn’t work. Even when I set it…

I see what you mean, that image didn’t show that set, let me try to add a second image if account lets me with that “new account error”

—nope…error again…no more than 1 pic a post for “new users” yet as you pointed out the account goes back to like 2016 and has over 100-150 threads and comments.

I don’t understand why that TPC created variable would still need an OBJ input, that seems irrelevant as the user is setting exactly what OBJ the variable is referencing.

“Creating a reference variable does little on its own, you must point it at an object. It’s like creating a string var and forgetting to type the text, but worse. At least the empty string is valid. What is the type of CharRef?” Yeah I forget that a variable without a set is for naught essentially. But that created variable, I chose the third person character - object reference, so then should it not know what it is?

Ok

" There is no difference between a promoted variable and manually created one. All promotion does is create a reference variable of the correct type - automation & convenience. You could create one manually, call it Promoted, hook it up and it will work all the same."

Ok, I must have not done something right if they were treated differently.

“A promoted float is a float just like a manually created float is a float. It’s just about the type.”

Again, thanks for all your help Everyone, your wisdom of UE4 is invaluable.

Ok, thanks RevOverDrive.

“This is correct. Cast is a test&set in one step, with execution paths on true/false, so it’s like a pot-sticker, a little bit of everything rolled into one.”

Ok thanks.

“CharRef is just a var, unset; done. So until one actually goes out and finds a ref to a char and sticks it there, it’s an empty bucket.” I think I know what you mean as a generic character OBJ ref (I have seen those before), but this one I did choose the third person character, should it not know then?

“The difference in overhead for just having the empty-bucket versus making it, checking the thing you want to put into it, and then actually filling it (the steps in the cast) is where the expense of the cast come in.”

Ok thanks.

That’s the thing! You SET the promoted one but not the other…

Actor references do not reference anything by default. The Third Person Character is a type, not an actual instance of an actor. The blueprint you’re scripting in is not an actor; it’s a template actors can be instantiated from. Once you instantiate, you’ll have an actor and a reference keeps track of it. But you need to tell the reference which instance you mean, there can be many.

If you tried to get to the actor now, you’ll Access None, it does not exist, is invalid, null:

None of the references above are valid. They cannot be assigned default values in the editor because no actors have been spawned yet.

Above, once we BeginPlay, we spawn a new actor of the Third Person Character class and reference it in NewVar_2. All other NewVar_X are still invalid, though.

You can point those references at the same spawned actor or other instances of this class.


You must SET values. The promoted is being SET - you assigned it value, the return of the Cast. It does not matter if you promote or create a variable manually. It must be given value.


One exception is the Level Blueprint - you can assign default values in the editor because the LB will construct an object from the blueprint template before we even start playing.

I could tell the TPC3’s NewVar 6 to reference any of those 3 three actors. And yes TPC3’s NewVar 6 can refence TPC3. A.k.a. Self references. But every actor can do that already anyway:

image

And just to confirm, there is nothing wrong with using cast, it’s more like Tick, it’s ‘convenient’ so can be overused which can lead to excessive overhead.

My two-cents, for myself, is that I try and always learn (the) most performant methods, that work for my project, so I can always try and make sure I’m on an ‘optimal’ path. I know I’m not going to get it a few times, but little things like this, that can tend to add up, are worth learning NOT to do, IMHO.

If you never go there, there isn’t anything to deal with; the surest path to victory is the battle-never-fought, etc…

1 Like

If you find that your casting often to the same Actor/class you’re better off just creating a reference variable at the beginning and being done with it.

1 Like

Sorry, What!? How is casting convenient???
Storing and re-using the value of a cast to reference is much preferable computation and overhead wise vs casting several times.

And cast can also be Pure. allowing you to just test with a branch yourself. So it can also Not be a pot-sticker as you claim. I think you need to revisit casts and their costs based on what you wrote.

As far as variables being different.
One could also be just the standard character, vs the other one actually being the cast.
Since a screenshot of the details of the second variable “CharRef” is absent, we can only infer as to what it might actually represent based on the icon it’s using…

This, essentially. Or it’s simply null.

Yes! One ought to always do it this way; agreed. Cast once, run the expense once; it can work. My point was that for those not so disciplined, you can tend to see it all over the place, casting on every bullet fired, etc, etc as not everyone knows more optimal coding techniques.

If you cast within the bullet BP, than that’s bound to happen. Goes to “knowing” how to properly leverage the engine VS just winging it…

pass ref on spawn to exposed var is a half decent approach.