x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to cast an object to its interface using Blueprint Scripting?

I can't cast my GameState blueprint to IGameClock (the interface it implements). This is preventing me from passing my GameState object to an "exposed on spawn" class variable of type IGameClock.

Here's an overview of my blueprints:

  • BP_GameState: My game state blueprint that implements IGameClock.

  • IGameClock: An interface that guarantees public methods for retrieving GameClock information. This is implemented by BP_GameState, it keeps track of a replicated game clock across clients.

  • GameClockHud: A child blueprint of UMG.UserWidget that has one responsibility, display the game clock (Month, Date, Year, Hour, Minute, Second, etc.).

  • MasterHud: A master UMG.UserWidget HUD that has a primitive native widget host on the designer canvas which contains an instance of GameClockHud.

My GameState blueprint (BP_GameState) implements my IGameClock blueprint interface. (See below)

alt text

GameClockHud is a child of UMG.UserWidget, this widget's only responsibility is to display the game clock (Month, Date, Hour, Minute, etc.). On class spawn/construct I want to pass it an instance of my BP_GameState that implements IGameClock, but I would like the variable type to remain as IGameClock. I don't want the widget to worry about what the concrete object is called, just that it implements IGameClock. (See below)

alt text

I attempt to create a new instance of GameClockHud in the MasterHud event graph, but I get compiler errors because UE4 can't cast BP_GameState to IGameClock (it doesn't even provide me any nodes to do this).

alt text

Product Version: UE 4.11
Tags:
more ▼

asked Jun 02 '16 at 04:12 AM in Blueprint Scripting

avatar image

elitereloaded
694 24 24 55

avatar image jblaswu Jun 02 '16 at 04:18 AM

hi, what are you trying to achieve exactly?

avatar image elitereloaded Jun 02 '16 at 04:30 AM

So I figured out the problem.

I was dragging off my GameState variable and expecting to see "Cast to IGameClock" but instead I only saw "Cast to BP_GameState".

Turns out you need to right click the event graph canvas and search for "Cast to IGameClock" and when it's added to the canvas you can then plug in the GameState.

A future improvement to UE4 BPs could be to show a list of "Cast to " based off the concrete class and the interfaces it implements.

avatar image jblaswu Jun 02 '16 at 04:36 AM

no, that would make it more confusing. the options the default class gives you are from the parent class, thats why you cast, to have access to the child variables/functions.

avatar image jblaswu Jun 02 '16 at 04:34 AM

just an insight. interfaces and dispatchers are only useful if:

  • you want to send one signal to multiple destinations and, on the average case.

  • dont know the reciever (on a dispatcher) or dont know the sender (interface). i might be explaning this way too raw but you can get my point.

on this case, the HUD class (MasterHUD) is creating the widget i asume, that means you get a reference of the clock widget. if i understand correctly, you want the MasterHUD to make "some calculation" and tell the widget to show the result. just call the functions from the reference when you created the widget. IF its the other way, if you want to access the HUD class from the widget, you can still do it without interface. "Get Owning Player"->"Get HUD"->Cast to MasterHUD gives you access to the blueprint.

"IF" you still need/want/areObsessed with implementing interface, you are doing it wrong. you have to click on class Settings on the blueprint that is going to recieve the signal, and down on the settings you add the interface that you are going to use (you have to create it first as i think you already did). Compile the blueprint. and then, on the blueprint that you want to send the signal, you get the reference of the HUD (still need to know where you are sending the signal), and call the Event or Function (Interfaces calls become functions if you add an Output to the call) that you need.

avatar image elitereloaded Jun 02 '16 at 04:51 AM

I think you misunderstood my design/approach I was aiming for.

MasterHUD is given a GameState object which happens to implement IGameClock.

MasterHUD creates a new GameClockHUD widget.

GameClockHUD asks for an IGameClock (on spawn) so it can call the GetMonthAsText() method (as well as the other date time helper methods that return Text objects).

MasterHUD says "I have an IGameClock, let me cast BP_GameState to IGameClock because it implements it". MasterHUD hands the IGameClock to the GameClockHUD widget.

GameClockHUD received the IGameClock so it calls the IGameClock public methods that return Text objects. This way GameClockHUD is not doing any calculations, it can decide how it wants to display the date time in which every style/layout it wants.

MasterHUD is not doing any game clock calculations either. It just grabs the implementation of IGameClock (BP_GameState) from global namespace. I did not want GameClockHUD to reach into global namespace because that's programmer hell.

The purpose for an IGameClock interface that BP_GameState implements? I doubt I'm going to leave the GameClock processing in the GameState. My game is in early stages and I know I will find a better place to migrate the game clock calculations. Therefore I don't want to refactor occurrences of BP_GameState to be IGameClock (or what ever the game clock class name would be).

I'm following S.O.L.I.D principles so I use interfaces to reduce the amount of regression bugs caused by refactoring/changes.

I hope all this made sense :)

avatar image Nachtmahr Jun 02 '16 at 04:46 AM

Hmm intresting discussion you got going I like to simplyfy things when I think of a Interface.

Think of a Interface like a Contract or Promise. Where you basicly say I dont care if you are a Clock, a Rock a Human I just want you to be able to Fullfill your Contract/Promise you gave me.

Not Inhertance bound, Not type bound just a simple Promise even if its empty and does nothing ;P

avatar image elitereloaded Jun 02 '16 at 04:56 AM

Exactly. That is why my game state implements IGameClock (for now) and that's exactly why GameClockHUD wants an IGameClock and not a GameState, or a GameProcessorObject.

GameClockHUD only cares if it's given IGameClock because the object that implements IGameClock is gauranteed to have Get[Month,Date,Hour,Minute,Second]AsText() functions.

avatar image Nachtmahr Jun 02 '16 at 05:02 AM

Sure said nothing against it. Its a normal usecase of a Interface =)

avatar image jblaswu Jun 02 '16 at 05:02 AM

glad you got your concepts right.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Turn off Context Sensitive and the Cast_To_IGameClock will appear.

Have Fun =)

more ▼

answered Jun 02 '16 at 04:35 AM

avatar image

Nachtmahr
7k 143 28 172

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question