How to reference a Third Person Character variable inside a different BP? (UE 4-27)

Hello,

I am building a 3rd person game in UE 4.27 and I would like to do a “simple” thing, but need your help because I am new to BP.

In my game, I have an IPAD BP (actor) with an ipad mesh and a collision sphere, so that a widget is shown over the IPAD, when my character overlaps the sphere. The widget shows a prompt to “Press E to take IPAD”.

Then, in my Third Person Character BP, I have the input action, when you press E, it attaches the IPAD to a socket inside the third person skeleton.

All works well until the part that the character gets the IPAD. The character still overlaps with the IPAD since it is in his arms and near his body, so the widget keeps showing and not turning on. I would like to have the IPAD BP reference the “is holding” variable inside the Third Person Character BP, so that if the player is holding the IPAD, the the widget gets hidden again, but I have not managed to do that. I tried implementing some blueprint interface as I saw in some tutorials, but still because I am new to all this, I didn’t know how to setup the functions to do what I am describing above. I tried also referencing the IPAD BP inside the Third Person BP by making a new variable (object reference to the IPAD BP), but when it runs the code, I get an accessed none log in the logging window.

I am attaching some screenshots and a recording, so that it gets more clear what I am trying to do.




#UE 4.27

If you wanted to do check the state of the player’s variable, it would be a matter of:

Any blueprint can do that.

The character still overlaps with the IPAD since it is in his arms and near his body, so the widget keeps showing and not turning on.

This makes be believe there is a simple solution to all this, revolving around enabling / disabling collision.


The above relies on you possessing the character (which you do) but in a more complex scenario another approach would be needed - an interface, as you’ve already discovered.

Create a simple BPI that gives back the reference to the object, then you can ping that for almost anything, and avoid the overhead of casting.

Casting isn’t BAD per-se, it’s just the most-expensive way to get to a thing.

1 Like

I believe this is incorrect, as you by returning the reference to the object (as its actual type) would equal the same hard bind as the cast. If you dont return the actual reference as its type, then you’d still need to cast.

An alternative use of the interface would be to query the actor for the variable value in question directly.

1 Like

You guys now must post an example for OP regarding the interface because they tried and couldn’t get it to work. :innocent:

2 Likes

The cast itself is a test of the object on the other side, whereas the BPI is more simple, you’d want to know what you are reaching for.

I THOUGHT I had an example for this in my stuff but I’ll have to mock one up… Might not be right away, sorry.

Yes, and it’s faster than an interface call to receive the same sort of reference :slight_smile: This is just a test on tick doing it 1000 times each

A bit off-topic here though.

Regarding the suggestion it would look something like this:
The BPI function

Then in the class that would receive the event, you must implement the interface in the Class Settings:
image

There also needs to be an implementation in the class that recieves the interface event, as an example showed here
image

Which leads you to the actual interface message in the actor you’d need to know this in:
image

2 Likes

I stand corrected then. All the literature I read had suggested Casting was muy-expensive, but if you have provably tested otherwise, I’d just go with that.

Thanks for the enlightenment. :smiley:

2 Likes

It would be expensive if the class was not loaded. @Squize can you run it against a class that is not loaded?

Cool example!

1 Like

Not sure how I’d be able to test that to be honest, since it would only not be loaded in the first attempt, while it would exist for the remaining 999 :stuck_out_tongue: Both hard references would have this ‘issue’, as the hard ref from the interface must also be loaded to memory…

2 Likes

Idk, an array of 1000 random engine classes and cast to whatever, let it fail :upside_down_face:

This would also depend on the class - dependencies that need loading.

Anyway. People demonize casting because folks put it where it doesn’t belong. Same with Tick.

Choose the right tool for the job. The impact of casting once is pretty much negligible.

3 Likes

This is what I do. It may not be the best; however, I think it could address your issue…

…so my player picks up a weapon which could be a sword, dagger or axe of which all of these have a collision box.

I did what you said in that I created multiple variables of class Actor called “Equip Weapon”, “Equip Shield”, etc.

When I press the “Interact” button, E in your case, this calls my interact event. I first loop thru all overlapping actors using “Get Overlapping Actors” with a “Class Filter” of “Actor”. My weapons implement an interface of which I check that loop instance for “Does Implement Interface”. If so, I then check the “Equip Weapon” to see if I already have that weapon. If so, I exit that loop instant. If not, I call an event to pick up that weapon and assign it to “Equip Weapon”.

1 Like

@Everynone @IlIFreneticIlI @Squize @vespineauto007 I thank you deeply for your time to response. I tried the casting solution and the BPI solution, which seem to worked, although I did not manage to do what I am trying to do and I came to the conclusion that the problem was not on the collision precisely.

Your solutions worked, but after the pick up the widget was still not hidden. After a lot of tests, I saw that the widget got hidden when the character collided once more with some collision blocks I had on the level. So I guess, the object did not collide with the character mesh, just the code to hide the widget was not executed again, after the object got attached.

One workaround, I could think of was to implement the BPI to check if the character is holding the IPAD and then add a tick event inside the blueprint, so that it always checks if the character is holding it or not, and hide the widget always if the character is holding it.

It worked but with having much experience, it seems a bit of overkill to always check for something, when you need it just once.

P.S vespineauto I did not have time to try your solution yet, because I will have to rebuild a bit the Blueprints, but I will definitely will, because it sounds very logic.

One could also toggle off the widget (by interface for example), when the item is picked up, if the character is aware of what they hold in their hand.

Where is the input processed?

The input is processed in the Third Person Character BP.

So this would be an opportunity to toggle off the widget of whatever got picked up :slight_smile:

Sounds great. Can you guide me on how to do it?

There’s a few questions i guess, to answer this in full…

  1. Are you casting to some Master_Pickup class (is the IPAD a child of a master pickup)?
  2. Are you using interfaces to achieve the pickup ?

Your screenshot doesnt provide this information … it would probably be on the right side of what is shown :slight_smile:

Edit: Seeing as you already implemented an interface, I would suggest doing the inverse if a master pickup class is not desired, so that you send a interface message to the picked up item that it has in fact been picked up. This can also be reversed when you put that item back in the worldafterwards