playMaker

Author Topic: Simple problem to be solved with Arraymaker  (Read 7169 times)

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Simple problem to be solved with Arraymaker
« on: February 07, 2017, 03:26:11 PM »
Hello,

I must admit that i've been running away from arrays for some time, but there comes a time when you simply can't do your thing without them. It came for me and i need your help to finally overcome one of the last obstacles in, well, some basic Playmaker functions (after that it's time for enums ;D).

As i said, it is simple but includes using arrays (i have been using them for some VERY basic stuff, nothing more).

Here's a simplified example:

- There are three weapons in the game, let's call them Sword, Axe and Spear.

- Every weapon has three upgrade levels which are basically separate objects. So we have Sword1, Sword2, Sword3, Axe1, Axe2, Axe3, Spear1, Spear2, Spear3.

- Player can only hold two weapons, and use one weapon at a time (let's call it currently active weapon).

- When player holds Sword and Axe and pickups Spear, currently used weapon is replaced by Spear.

- When player holds Sword1 and Axe1 and pickups Sword1, Sword1 is upgraded to Sword2.

How i think it should be done:

I have weapon objects themselves. They spawn on the player and do their thing (fire, deal damage...).

I have pickup objects which are basically empty objects with sprite renderer and collider.


Case 1:

Player is equipped with Axe1 and Sword1, they are added to the Weapons Equipped array - that's simple and i know how to do it.

Player stops on Sword1 pickup and clicks the button to pick it up.

Weapons Equipped array is be checked if it contains Sword1, Sword2 or Sword3. If it contains any of those three, Sword1 weapon object will be destroyed, removed from Weapons Equipped array, Sword2 weapon object will be created on player and added to Weapons Equipped array.

Pickup object will be destroyed.

Case 2:

Player is equipped with Axe1 and Sword1, they are added to the Weapons Equipped array.

Player stops on Spear1 pickup and clicks the button to pick it up.

Array is checked if it contains Spear1, Spear2 or Spear3. There are no such objects in the array, so the currently active weapon object (Sword1 or Axe1) is removed from array and destroyed. Spear1 weapon object will be created on player and added to Weapons Equipped array.

Pickup object will be destroyed.

I tried using the Arraymaker, and i suppose i should use Array Get Next to loop through all the array items, but i don't know how to use it. Ok, i can set it to loop through all of them, and then what? How do i compare the pickup object with all the array items? What does the result represent?

Ok, so there's Array Contains action, but the only way i can think of using it is like this:

- I pick up Sword1 pickup object
- I run Array Contains action and check if the array contains Sword1. If it doesn't the next state which checks is the array contains Sword2 is called, and so on.

Of course, the game is a bit more complicated than the example so it would take a few more events (which means more frames) to check for all weapon objects so i think this is not the right approach and can be done a lot simpler. I watched the Arraymaker GetNext tutorial by RezRezRez, but i don't quite get it, i'm more of a reading than watching guy.





« Last Edit: May 07, 2017, 01:10:56 PM by krmko »
Available for Playmaker work

elusiven

  • Full Member
  • ***
  • Posts: 233
  • Debt we all must pay...
Re: Simple problem to be solved with Arraymaker
« Reply #1 on: February 07, 2017, 05:56:18 PM »
Quote
How do i compare the pickup object with all the array items? What does the result represent?

- You could use ArrayList Get Next and then as a loop state use one of those actions: "Game Object Compare" or "Game Object Compare Tag" if they have tags. It will loop through all of the items and check if any of them is the same as the pickup object and it will send events true/false.

So for each item in the array, it will check if the item is the same as the picked object, and if yes it will send a true event and if no then it will send false event.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Simple problem to be solved with Arraymaker
« Reply #2 on: February 08, 2017, 01:38:49 AM »
Hi,

 you can use arrayListContains, don't loop through to check if an item is in an array. what you'll get is the index inside the array for that item.

Bye,

 Jean

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Simple problem to be solved with Arraymaker
« Reply #3 on: February 08, 2017, 02:32:38 AM »
First of all, i'd like to thank you all for your quick answers.

@Elusiven

Ahh, so that's how Get Next works actually. I thought it was an event where it loops through all the array items at once, which was stupid of me, nothing works that way. So basically i have to keep looping through back and forth from Get Next until the appropriate tag or whatever i'm using for checking is found. It will not take long since in the game i will be also using two weapons equipped with 5 levels, so there's only 10 loops to iterate.

For sake of knowledge only, what should one do if he is to check an array that has hundreds of items? If each loop is done in Update, not in FixedUpdate, and it takes a frame to do, wouldn't it take multiple seconds to process? Is Playmaker doing its thing in Update or FixedUpdate by default, or it depends how the action itself is written?

@Jean

As far as i can see, arrayListContains only looks if one value is contained in the array. When i get a Sword1, i have to check if Sword1, Sword2, or Sword3 are contained in the array, so multiple checks are to be done.

But! I suppose i could tag them, that would narrow it down to one search.

Thanks once again guys, this will do!
Available for Playmaker work

elusiven

  • Full Member
  • ***
  • Posts: 233
  • Debt we all must pay...
Re: Simple problem to be solved with Arraymaker [SOLVED]
« Reply #4 on: February 08, 2017, 09:51:54 AM »
Quote
If each loop is done in Update, not in FixedUpdate, and it takes a frame to do, wouldn't it take multiple seconds to process?

I've not seen a loop like "Get Next Child" in the update function in PlayMaker, they are normally called OnEnter(), which I assume is a Playmaker event, which is called when that state becomes active. And then the method to create loop is called within that.

Usually in Unity3D c# I wouldn't use loops very often in Update(), although there is nothing wrong with using for or foreach. While loop on the other hand though can lead to unity crash when used in Update().

It also doesn't mean that all loops take 1 second to execute, it might be less. If  you want to do something over-time, like over a couple of frames that's where Coroutines come in. The looping it self is actually VERY fast, but what you do with the item inside the loop, then that's what usually effects the performance of the loop. For example you can do a simple test, generate random entries in an array, and then loop through them with just debug.log or something and then change it to do something else too, like change it name or something - you will see that the time increases as you add on more instructions on what to do with the item inside the loop.

If you had everything executing at 1 second, then all your app would be very slow but majority of time, if you do have a heavy piece of code you normally use it in a different thread to increase the performance.
 
Good thing to do sometimes is when you don't understand certain action or if you are curious on how it's doing things, just right click on the settings icon and click on edit script, this will show you the action's code and then you can learn how things are done behind the scenes for you.
« Last Edit: February 08, 2017, 09:54:27 AM by elusiven »

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Simple problem to be solved with Arraymaker [SOLVED]
« Reply #5 on: February 08, 2017, 02:02:49 PM »
Oh yes, i often open the action code to learn more about scripting itself. I am usually surprised how simple things actually are and it helps me more than watching some video on youtube.

I didn't know that Playmaker uses OnEnter until you told me, maybe Jean can tell us where is it positioned compared to regular Unity's event execution order?

I don't plan to loop on too much stuff, it's a simple game i'm making, but it good and interesting to know some theoretical stuff.

Edit:

Hmm, it looks like i can't get my way around. I don't know if you and Jean understood me right, i'll try and explain it again.

Here's the complicated (and only) way i know how to handle it. Way too many states.



Player has an Acid Gun Level 4 weapon tagged with Acid Gun Level 4 equipped and stored into the array as a game object. He picks up Acid Gun Pickup object which should upgrade it from level 4 to level 5.

Iteration starts, the array loops and the tag of every array item is checked against Acid Gun Level 1 tag with Game Object Compare Tag. Since there's no Acid Gun Level 1 tag found on any of the array items, finished event (Compare Next Level) is triggered, and iteration and comparison with Acid Gun Level 2 tag begins and continues until Acid Gun Level 4 tag is found in the array. True Event is triggered, and weapon is upgraded to Level 5. If no matching tags are found in the last comparison event, it means that another weapon is equipped, Finished Event Replace is triggered, and the weapon is replaced.

Is there a way to avoid this spaghetti? I could use a Game Object Tag Switch that has a failed event is no matching tags are found or if i could change the Tag variable in the Compare Tag action on runtime each time the array finishes the loop.

I can shorten it by using Array List Contains, but i'd still have to run 4 events to check for Level 1, 2, 3, 4. Here's how that would look like.



If that's the quickest way to be done, i'll be disappointed in OOP :D
« Last Edit: February 08, 2017, 06:08:39 PM by krmko »
Available for Playmaker work

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Simple problem to be solved with Arraymaker
« Reply #6 on: February 09, 2017, 04:43:43 PM »
I decided to do it by checking if the array contains game object, and i'm quite satisfied with speed it all happens.

But, equipped weapon fails to add itself to the array. I save the array proxy into local gameobject variable for reference, and put the add to array action to equipped weapon, gameobject appears as an empty index item, but gameobject reference is not added.


Available for Playmaker work

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Simple problem to be solved with Arraymaker
« Reply #7 on: February 10, 2017, 12:58:50 AM »
Hi,

 in your screenshot, the value you add is null ( Acid Gun Level 1), it's in the ArrayListAdd action interface.

 Bye,

 Jean

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Simple problem to be solved with Arraymaker[SOLVED]
« Reply #8 on: February 10, 2017, 01:15:27 AM »
Hi Jean,

Well, that's exactly the problen, shouldn't it add Acid Gun Level 1 object to the array?
Available for Playmaker work

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Simple problem to be solved with Arraymaker
« Reply #9 on: February 10, 2017, 01:28:43 AM »
Hi,

 your variable named "Acid Gun Level 1" doesn't point to any GameObject, you either have to set that variable prior this action or manually drag and drop your GameObject inside this variable at edit time.

A variable named after a GameObject doesn't imply it has a pointer to it, the name of a FsmVariable is not related to the content of that FsmVariable, we do so so that it make sense, but for the computer it doesn't matter.

Bye,

 Jean

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Simple problem to be solved with Arraymaker
« Reply #10 on: February 10, 2017, 03:47:55 AM »
OMG, i forgot to populate the variable ::)

That's what you get when you try to work dead tired. Thanks Jean, that wraps it up, arrays are much less of a fuss now  8)
Available for Playmaker work

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Simple problem to be solved with Arraymaker
« Reply #11 on: March 02, 2017, 08:05:30 AM »
Hi guys,

i've got some questions about the array maker, array lists are very interesting, and now i see that they are truly necessary!

I use a small array consisting of two items. When a new item is added to the array, it is added to the next index number. If index 0 is populated, next item will be added as a number 1 index, that's all clear. I've got two questions:

1. If i delete the index 0 item, is the index 1 item going to be moved down to the index 0?

1. If i use Array List Insert, and try to add the item to the already occupied index number is it going to:

- Report failure
- Replace the item on the designated index number and (delete the old item)
- Insert the newly added item to the designated index number, and expand the array by moving everything further up the index (replace index 1, it becomes index 2, the index 2 becomes index 3, etc.)

I'm anxious to find out, but i won't be near my unity computer anytime soon :)




Available for Playmaker work

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Simple problem to be solved with Arraymaker
« Reply #12 on: March 03, 2017, 06:33:41 AM »
Hi,

1. yes, else you need to set the value at index 0 to null or a default value that you know means "Empty"

2. it's going to Insert as the name implies, so no failure, not replacement, use "ArrayMakerSet" to replace a value at a specific index.

 Bye,

 Jean

 

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Simple problem to be solved with Arraymaker
« Reply #13 on: March 03, 2017, 09:35:53 AM »
Thanks Jean!
Available for Playmaker work

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Simple problem to be solved with Arraymaker [SOLVED]
« Reply #14 on: May 07, 2017, 01:10:42 PM »
Hi guys,

i don't want to open a new topic since it's arraylist related. Some simple stuff, but just want to make sure what's the best way to do it.

I'm having a game based on enemy waves. When an enemy appears, it adds an item to the arraylist, and when it goes offscreen or it is destroyed, it removes the item from the array. This serves a purpose of firing a custom event after a while if the arraylist is detected to be empty.

Now, what i want to do is simply add an irrelevant value to the arraylist (for example an integer with a value of 0) when an enemy appears. So, when 10 enemies appear, the arraylist will be filled with 10 zeroes. Now, what interests me actually: when an enemy goes offscreen or is destroyed and the array list remove action is triggered to remove the item type integer and the variable 0, will it just remove the random item, first item, last item, or it actually won't remove anything from the referenced arraylist?
Available for Playmaker work