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"

Creating unique actors and data tables.

Hi, I'm working on a card game and could use some help.

I'm creating my cards using widgets getting, title, art, description etc. from a data table.

alt text alt text

I have 3 copies of the widget displayed and a drag and drop operation so the player can choose the card he/she wants. Right now I'm kinda cheating by hiding and displaying a copy of the widget and have it displayed on Drop detected.

Here the question

  1. Is there a way i can create 3 different cards from the same widget? i know i can create 3 different widgets and randomly assign them Rows from the data table. but i think it would be better/cleaner if i could do it all from the same widget.

  2. I also need a way to pass the information along when i drop the card off in the player hand. but i guess if i get help with the above this will get figured out.

Product Version: UE 4.21
Tags:
card.png (116.3 kB)
more ▼

asked Mar 05 '19 at 12:02 PM in Blueprint Scripting

avatar image

Betag
24 1 1 5

avatar image Everynone Mar 05 '19 at 05:51 PM

Is there a way i can create 3 different cards from the same widget?

Do you mean to duplicate an existing widget? I think you mean something else.

if i could do it all from the same widget.

Do what exactly?

avatar image Everynone Mar 06 '19 at 01:43 PM

i’m wondering if I can create 3 different versions of the potion card out of 1 widget.

For experimenting with something simple, create a custom event inside the widget that can read and set information regarding its own elements from via a data table query.

This way you have 1 widget and create 3 (as many as you like) instances all with different statistics. The downside is that you can't possibly encapsulate all the necessary functionality needed by all cards in a single blueprint. (you can, sure, but it's gonna bite ya sooner rather than later)

If you consider growing this beyond simple, you need modularity.

avatar image Everynone Mar 18 '19 at 02:36 PM

The problem is this. I can't see the variables on the actor child anymore. Am i setting this up correctly?

Adding it here as it was getting tight up there.


A little confused regarding what you're trying to achieve now. Can you explain?

I can't see the variables on the actor child anymore.

The base actor class pulls data from a DT and holds onto the struct. It then pushes the data to the widget, right? You're sending self reference to the widget I assume?

So you started creating child actors?

Maybe you never store the struct data you pull from the DT? I can't see it in any of the pics. Also if you're doing stuff in the Construction Script, a child will need to manually call its parent's Construction Script (in the child right click the Construction Script node and Add Call To Parent Function).

avatar image Betag Mar 18 '19 at 05:27 PM

Yeah, the problem was my DT, i got it working as intended now. My Child actor has this in its Constructor. alt text is this the Call to parent function?

How should i handle the Spawning of cards?

3.png (21.7 kB)
avatar image Everynone Mar 18 '19 at 05:45 PM

Looks about right!

How should i handle the Spawning of cards?

You can expose the Card Fetch variable on the actor itself and fetch it by name. Although I see that your rows are numbers rather than actual names.

Not sure what mechanics you've got in mind.

avatar image Betag Mar 18 '19 at 06:15 PM

I've been using numbers just to test. i got row names as well. I would like to spawn 3 different copies of the actor when an action is called upon. Spawning 3 random cards every time.

avatar image Everynone Mar 18 '19 at 08:39 PM

This should work for indexes and/or names:

alt text

Since you've worked the the DT into the construction script, you should be able to get fetch it by name via an exposed Card Fetch like so:

alt text

capture.png (116.3 kB)
capture2.png (86.8 kB)
avatar image Betag Mar 18 '19 at 09:52 PM

Is this in the base card BP or in the child actor?

avatar image Everynone Mar 18 '19 at 11:12 PM

You asked:


How should i handle the Spawning of cards?

I would like to spawn 3 different copies of the actor when an action is called upon. Spawning 3 random cards every time.


The image I posted is a method to spawn cards. So it would sit outside of the card object - the SpawnActor node will create whatever you choose in the class dropdown. Spawning a card from inside of a card could create an infinite loop - not a good idea.

It's up to you if you want to create a base or one of the children; and it's up to you which blueprint will handle spawning of the cards. With a setup like this, you're free to do it pretty much anywhere. Maybe wrap it in a function that takes an int (number of cards) and returns an array of cards. Place the function in the GameInstance and it becomes available from anywhere.

I do not know how your game is supposed to work. You probably have a main game loop and conditions that grant the player / opponent cards - these could call the abovementioned GameInstance function. Difficult to advise without knowing more about how you envisioned it.

Is it more like this or more like this this?

avatar image Betag Mar 19 '19 at 09:27 AM

Yeah very much like slay the spire.

The player can pick between 3 cards he brings to the next phase. The cards will have costs between 1 to 3 and the player has 3 Mana to spend on cards each round. So i would like to spawn 3 cards at random for the player to drag and drop into his hand. then play them in the next phase.

alt text This is how i'm handling the spawning at this point. this is in the level blueprint.

1.png (81.6 kB)
avatar image Betag Mar 20 '19 at 10:14 AM

Right now, i spawn 3 different cards. But its only in the widget right now. How to i spawn a child actor thats linked to my DT?

avatar image Everynone Mar 20 '19 at 10:23 AM

I don't understand, sorry. What do you mean by linked to DT. There's nothing to link. DT is static. When you spawn an actor it just pull the relevant data from it.

If you're creating something similar to Slay the Spire, I think there are combat rounds, right (I never played the game)? The beginning of a combat round should be the trigger that spawns X cards and / or removes the ones in hand.

Or is that not how your game works?

avatar image Betag Mar 20 '19 at 10:38 AM

Sorry, linked was the wrong word to use. I'll try to be clearer.

I'm currently spawning my cards on a button press (later to be changed to spawn when entering the "combat" mode) The card displays the information drawn from my DT. If i am to add functionality to the cards i need to spawn the correct Child Actor to the card. I'm wondering how i can do this.

the plan is to make every card a child actor and add the required actor components to the child.

avatar image Everynone Mar 20 '19 at 07:26 PM

You can include that information in the Data Table itself, see the element at the bottom:

alt text

alt text

And then the child, once it has executed parent's Construction Script, can add its own components or override any functionality that the parent has - this is also a very common thing to do.

capture.png (64.2 kB)
cap2.png (39.6 kB)
avatar image Betag Mar 21 '19 at 10:19 AM

I'm now able to spawn the cards and the child actor. But it seams that the widget and the actor spawn does different things. My string for a certain card can pop up from the spawner, but nothing is displayed.

Right now i'm spawning the cards on a Key press from the level BP like this: alt text

And in my base card like this: alt text

This should have been The Midas pot. alt text

2.png (93.1 kB)
23.png (49.9 kB)
3.png (120.0 kB)
avatar image Betag Mar 21 '19 at 10:27 AM

I think the problem is that when the cards is spawned it picks random cards from the DT. Then when a card is spawned it picks another random drom the DT in the card construction script. I need a way for them to pick the same card. This is what i think is happening.

avatar image Everynone Mar 21 '19 at 07:52 PM

If I remember correctly, you access the DT (randomly?) in the Construction Script, too.

Since you've now incorporated class into the struct, do not let the card access the DT from inside of the construction script.

Essentially, make sure that card object passes the data it received when spawning to the widget.

avatar image Betag Mar 22 '19 at 11:02 AM

So I need someway to send the row name from my spawner to the card? The spawner is in the level bp right now. I'm using the name to feed information to the Widget.

avatar image Everynone Mar 23 '19 at 12:09 AM

Don't do anything in the Level Blueprint, unless you really must - it's difficult to communicate with. Why not use GameMode / Game Instance instead?

avatar image Betag Mar 25 '19 at 10:24 AM

And it works! I moved the card spawner to the game mode and did a cast from the card to get the same result! TY so much! I still have questions about the drag and drop but ill create a new thread for that!

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

1 answer: sort voted first

i’m wondering if I can create 3 different versions of the potion card out of 1 widget. I’m also wondering if I can pass along information from my data table when I drag and drop the card to the player hand.

more ▼

answered Mar 06 '19 at 01:03 PM

avatar image

Betag
24 1 1 5

avatar image Everynone Mar 06 '19 at 01:38 PM

I don't see a problem here. Although it depends on what makes it different. If it's 2 different potions and they heal for different amount - that's just a matter of setting a variable. That's easy. Giving them completely different functionality is a different story altogether.

I’m also wondering if I can pass along information from my data table when I drag and drop the card to the player hand

Yes, create a new widget and feed it data from the DT.


So are you using a separate widget for each card? The more I think about how you refer to it, the more I think it's true. And that's not the right way to do it. Having 50 cards is probably manageable, but makes it impossible to grow efficiently.

You should at least consider splitting them into categories:

  • healing cards

  • damaging cards

  • special cards

But this might not be enough for something that's a tad more than basic.


Consider the following.

  • each card is an object, not just a plain widget

  • all cards inherit from base class

  • base class handles all the common functionality (casting cost | card name | card type | holds onto the details regarding the card's look | rarity | card in hand / playfield behaviour and so on)

That's a base card. It does not do much on its own. And this is where inheritance and actor components come in handy.

You create a bunch of actor components:

  • damaging component

  • healing component

  • a component that can draw cards

  • a component that can discard opponent's cards; and so on...

Whenever you want to design a new card, you create a child of the base class (so it can already do and behave like the parent) and start adding components you prepared - at this point it's a matter of drag & dropping as many as you need.

Only at the very end I'd worry about widgets - they should be visual clues only. The base class can create a widget and customise it based on the class defaults and/or any actor components that the children added.

avatar image Betag Mar 06 '19 at 02:29 PM

What i have been doing is this: - I have 1 widget for the potions. - When i enter the "play phase" of my game I run a function that selects a random row from my data table and casts it to the Widget. - I then had the cards run through another function who handled the variables. This gets messy quick.

Trying your method. Is the base class an actor or an object?

avatar image Everynone Mar 06 '19 at 02:42 PM

Actor = object. At least in UE4's blueprints.

Also, this should be fine for something smaller. You might be able to pull it off if you split your cards into categories. There's going to be a lot of repetition in the code, though :|

avatar image Betag Mar 07 '19 at 12:02 PM

Am i doing this right? this is my Base card widget. alt text and this is an actor component, i'm using functions to set the base functionality. alt text

1.png (88.9 kB)
2.png (76.8 kB)
avatar image Everynone Mar 07 '19 at 12:50 PM

Using functions for this is going to be tedious. It's OK in the base class, but for children you will be better off with actor components <- great intro material here.

They are reusable - chunks of functionality that you can add / remove on the go.

Imagine your opponent casting a damaging card at your face to which you respond with a counter effect that replaces the damaging component with a healing component. When the card connects, the whatever existing components of the card activate, delivering a result.

So rather than having a data table that lists everything that a card can have, it would list which components the card has, and how strong they are. The entire healing logic - the payload of the card - would be contained within that component. It would also hold text, images, sounds, special fx and more.

To visualise it, a widget would read a list of components a card has and set up its own text fields accordingly.


Also, you can expose variables to the constructor:

alt text

So you can do this (the DoMoreStuff could spawn any components the card may need) :

alt text

And, eventually, automagically spawn cards like so (top - base / bottom child):

alt text

It's going to take a while to get any of this going so just keep tinkering!

constr.png (105.5 kB)
morestuff.png (73.9 kB)
capture.png (52.1 kB)
avatar image Betag Mar 10 '19 at 12:50 PM

ok, am i going about this the right way? I created some variables in the base card i can edit in the child actor "Potion of Midas" alt text How should I fire of the Setup event? its in the event graph of my base card. alt text

1.png (663.4 kB)
2.png (65.1 kB)
avatar image Everynone Mar 10 '19 at 12:58 PM

You can do it in the constructor like in the very first image I attached. The event fires when you create a card, pulling data out of the data table.

avatar image Betag Mar 10 '19 at 01:06 PM

Ok, got it working! How can i get my newly set variables, such as card name to the widget controlling the text displayed on the card?

avatar image Everynone Mar 10 '19 at 01:23 PM

The event pulls a struct from a data table, so your object has access to the struct. Have a look at the the 2nd image I posted. It creates the widget in the sequence.

You can have an event in the widget similar to the one in your object and call it after widget creation; but there's an even better way:

Create a struct variable in the widget itself and Expose it on Spawn - the Create Widget node (refresh it by right clicking) will now show a new pin for the struct. Plug the struct there. Essentially:

Card object pulls data from a data table and feeds it to the widget via an exposed struct variable.


Alternatively, instead of feeding widget just the struct, you can feed the entire card object to the widget so it has full access in case you ever need it.


This method of the object spawning a widget also opens up for very efficient communication via Dispatchers later on. Quite handy once things get complex.

avatar image Betag Mar 12 '19 at 12:25 PM

alt text ok, is this what you meant? I'm creating the widget from the event graph, feeding the struct and using the struct to set the title of the card in the widget.

alt text

1.png (77.5 kB)
uten-navn-1.png (63.7 kB)
avatar image Everynone Mar 12 '19 at 05:08 PM

Looks fine, does it work the way you need?

avatar image Betag Mar 14 '19 at 10:56 AM

I would like to try and feed the entire card object. how do i set this up?

avatar image Everynone Mar 14 '19 at 04:13 PM

The same as you're doing it now, but instead of a struct you can plug in your actor into the widget's exposed pin. This way the widget can then get actor and get its struct.

avatar image Betag Mar 18 '19 at 12:59 PM

alt text This is how i setup the communication in the construct script. I don't quiet understand how to feed the actor to the widget. I would like all the variables in the actor to be visible to the widget.

uten-navn-1.png (55.0 kB)
avatar image Everynone Mar 18 '19 at 01:34 PM

In order to feed the struct to the widget, you created a variable of struct type and exposed it, right? You called it The Card Struct. It now shows on the Create Widget node. As seen in the pic you attached before.

Do the same for the actor - in the widget create a new variable (let's call it The Card Object) - make sure its type is the same as your card actor type, and then expose it and make it editable.

You can now plug in the entire actor into the widget Create node so the widget no longer needs its own struct; it can instead pull data directly from the actor's struct.

What's more, you can actually bind widget's fields to that actor's struct:

alt text

untitled.png (35.4 kB)
avatar image Betag Mar 18 '19 at 02:22 PM

So I got the actor to communicate with the widget as you described and I did bind the widget fields to the actors struct. and got this:

alt text

So its sending the variables to the widget.

The problem is this. I can't see the variables on the actor child anymore. Am i setting this up correctly? alt text

2.png (91.4 kB)
1.png (82.4 kB)
(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