Playmaker Forum

PlayMaker Help & Tips => PlayMaker Help => Topic started by: Splankton on December 06, 2013, 01:11:20 PM

Title: Arraymaker help
Post by: Splankton on December 06, 2013, 01:11:20 PM
Hi,
I'm currently using boolean checks for items that are distance checked and the closest is set as the destination for my NPC so he goes over picks up the item, checks other items if they are still available, if they are, get the closest distance and set new destination.
I'm thinking even though this way works, Arraymaker is probably more efficient for this kind of thing, so I've set about putting my game on hold and to study the array samples Jean has made.

So, can someone tell me if this is the right way to do this -
1. on the items, Array List Add each one into an array, then listen for the NPC with a trigger.  When triggered, Array List Remove from the array
2. Get the distance to the items that are available in the array.

I know theres more to it, but I'm on the right track, yes?


Title: Re: Arraymaker help
Post by: Splankton on December 09, 2013, 12:50:29 PM
Jean?
Title: Re: Arraymaker help
Post by: Splankton on December 11, 2013, 10:23:33 AM
<bump>

Sorry, but looking at the Arraymaker samples, (the cube distance one) that seems to be kind of what I'm after.  But it has 3 temp arrays, I understand how each state works in the 2 FOR EACH loops, but can someone give me a bit of help on what I'd need for what I'm trying to do?
I'm thinking pretty much what I said earlier, but in the FOR loop is that where I'd add in my items (which are dynamic i.e either they are in or out of the array)
then iterate through each time getting the distance to each item and setting the destination to the closest one.
Is that the only loop I would need?

Thanks for any help!
Title: Re: Arraymaker help
Post by: mweyna on December 11, 2013, 11:27:12 AM
You have it pretty well sorted out as to how to do it.

So you'd need a loop on the NPC to basically, get the array count, get the item at Position i, check distance relative to the NPC, and then go to the closet one (either through the Closet Action or using your own distance sorting FSM). Then I'd have an FSM on the item itself that the NPC would send an event too when they pick them up with an ARRAY REMOVE function so the item disappears from the list. The FSM on the NPC would then reset and find the next closet one.

As for additional loops and functionality, it depends on performance and what you're trying to do. What you describe is a fairly cheap performance thing to add, but it will have a minimum cost since the loop is always running. You can build in some delays, so if Position i is equal to the Array Max Count in the INT Compare, Wait 3 seconds, etc. All depends on what you're trying to do with the game itself.
Title: Re: Arraymaker help
Post by: Splankton on December 11, 2013, 02:26:11 PM
Hi, thanks for you help.
I just have a little problem.  I have the array FSM and the array ref on the NPC. And another FSM on the pickup item.  When I try to use something like Array List Remove for example, I have no reference in the Set Up to my array on the NPC.
So I made it a global, so I can now reference it, but I get the same problem with the Data Type/Variables.  How do I reference my items that are sitting inside the NPC array?
Title: Re: Arraymaker help
Post by: jeanfabre on December 11, 2013, 02:39:37 PM
Hi,

 Sorry for the late reply, and thanks mweyna to step in, much appreciated  that share back your experience :)

You are on the right track indeed, and mweyna advices are spot on.

bye,

 Jean
Title: Re: Arraymaker help
Post by: mweyna on December 11, 2013, 03:33:11 PM
Two paths, you can either just manually type in the Reference Name "NPC_Item" or do what you did and use a global string variable. On the Array List Remove action for "Setup" specific the Object. You can get that through a Mouse Action (making it the hitObject), or a variety of ways. Targeting Arrays on other items is much the same as targeting anything else on other items. You define what Game Object is holding the Reference and then you can interact without issue.
Title: Re: Arraymaker help
Post by: Splankton on December 11, 2013, 03:57:12 PM
Two paths, you can either just manually type in the Reference Name "NPC_Item" or do what you did and use a global string variable. On the Array List Remove action for "Setup" specific the Object. You can get that through a Mouse Action (making it the hitObject), or a variety of ways. Targeting Arrays on other items is much the same as targeting anything else on other items. You define what Game Object is holding the Reference and then you can interact without issue.

Hi, thanks again for your help :)
I have used the specify game object to the object that holds the array, but the reference just says "none" even though the array is there with a reference.
But like I said, a global fixes that.  But I still dont understand how under "Data" in Array List Remove I can use a GameObject variable that is populating my array in the NPC?
It either says "none" or ask for me to drag on the object.  But I dont want to specify just the one item, I want to use the items variable that is in the array. Does that make sense?
Again, thanks.
Title: Re: Arraymaker help
Post by: mweyna on December 11, 2013, 04:34:45 PM
The Array List Remove command just tosses whatever data you specific tossed. So you'd need to use the "Array List Get" function, store that into a Game Object variable, then plug that back in under DATA as the Game Object variable. You have a few choices of how to remove things, either at a specific index, or that specific item way. Either way with that Game Object now defined, it should properly be removed. If you want to remove an entire array of contents, you can always use the "Array List Clear" function.
Title: Re: Arraymaker help
Post by: Andy22 on December 12, 2013, 05:00:36 AM
Hi,

from my experience u want to keep the inter object relations and dependencies as simple as possible. So the pickups should actually only know they are "pickups" aka have a layer/tag or component with a IPickup interface. They should not fiddle with the logic that decides or filter when and what to pickup.
So using the "FindClosest" action in your Ai FSM is totally valid and i would always prefer this over adding more dependencies between the Ai and the Pickup.

As a rule of thumb, if "some" task/logic don't needs to-be done per frame and can be easily delayed/spaced out, don't premature make a system more complex because it "might" be more efficient.

bye Andy
Title: Re: Arraymaker help
Post by: Splankton on December 12, 2013, 02:30:42 PM
Ok thanks for your help.  I'll keep that in mind Andy, sounds good advice. 
Looks like the array is working fine at the moment.  Just going to test.  And test some more before I move on :)
Title: Re: Arraymaker help
Post by: Splankton on December 13, 2013, 02:18:17 PM
Ok, small problem, I'm using an item array and a temp distance array.  When I get the distances, they are sorted in the index, the smallest is always at index 0, for some reason.  So which action do I use to get the smallest float that is index (0) and store it as a Gameobject so I can then use it to set the destination of my NPC?
Title: Re: Arraymaker help
Post by: mweyna on December 13, 2013, 03:47:18 PM
Why not just use "Array List Get Closest Game Object" from the original Item Array? It should automatically return the closet item so you don't need to do any distance sorting yourself.
Title: Re: Arraymaker help
Post by: Splankton on December 14, 2013, 12:46:22 PM
Why not just use "Array List Get Closest Game Object" from the original Item Array? It should automatically return the closet item so you don't need to do any distance sorting yourself.

Ok, thanks for you help again.
That works now, but on closer inspection of what is actually happening, the incorrect item from the array is being removed on pick up. 
In fact, I had the item FSM set up wrong.  I had something like -

On trigger enter >
Array List Get (which was picking up an item at index 0) >
Array List Remove (which removed the wrong item because it was always going to be at index 0)

So, I cant work out how to remove the item from the array that has been picked up. I need to somehow get the items that are in the array (say item1, item2, item3) at index 0,1,2 and if item2 is picked, that item from the array is removed, i.e index 1.
Any help?

Title: Re: Arraymaker help
Post by: Splankton on December 14, 2013, 01:06:55 PM
When I use Array List Get before I want to remove the item, in the At Index, if I add in the correct index for that specific item, so say item2 is index 1, then it works, but then because when index 1 gets removed, item3 then moves to index 1 so obviously it doesnt work then.
I need to somehow have the index set so when one gets removed, it gets added back at the same index.  Maybe thats the way, or is there an easier solution?
Title: Re: Arraymaker help
Post by: Splankton on December 14, 2013, 01:12:59 PM
Ok, I think I've done it using Array List Insert.
So now I get the item from the Array using the correct index, then remove it using that index, then insert.  Makes senses, but looks like I'll have to do that manually adding/removing index numbers into each item.
Title: Re: Arraymaker help
Post by: Splankton on December 14, 2013, 01:20:06 PM
Ok, its driving me mad.  Inserting does not alter the position of the items.  So item1 at index0 when removed becomes item2.  So my manual setting for each item becomes invalid and doesnt work.
Any ideas anyone?
Title: Re: Arraymaker help
Post by: jeanfabre on December 14, 2013, 01:29:33 PM
Hi,
 
Inserting does alter the position of all items AFTER the index you inserted an onject into. Are you sure you are correctly using the "insert" method?

I think you are overcomplicating things here.

ArrayListGetClosestGameObject comes with two results, the gameobject AND the index.

 So use that index return to know what index to remove from the list. I am not sure where is the difficulty you are facing here. have you tried this already?

bye,

 Jean
Title: Re: Arraymaker help
Post by: Splankton on December 15, 2013, 01:56:24 PM
Hi,
 
Inserting does alter the position of all items AFTER the index you inserted an onject into. Are you sure you are correctly using the "insert" method?

I think you are overcomplicating things here.

ArrayListGetClosestGameObject comes with two results, the gameobject AND the index.

 So use that index return to know what index to remove from the list. I am not sure where is the difficulty you are facing here. have you tried this already?

bye,

 Jean

Ok thanks.  It works great now, I didnt think to look at the index return from the ClosestGameObject.  By the way, is there a way to check if the Array is empty?  I need it because when all items are picked, the NPC needs to move on.
Title: Re: Arraymaker help
Post by: Splankton on December 15, 2013, 03:01:09 PM
Its ok, I've used Array List Contains.
Title: Re: Arraymaker help
Post by: mweyna on December 15, 2013, 05:51:35 PM
Get the ARRAY Count and then do an INT Compare, if Count <= Zero, move on.
Title: Re: Arraymaker help
Post by: Splankton on December 16, 2013, 12:21:30 PM
Get the ARRAY Count and then do an INT Compare, if Count <= Zero, move on.

Thanks mweyna, I think that'll probably be better for performance? Don't know if there is a way to just check that action against array list contains.
Title: Re: Arraymaker help
Post by: mweyna on December 16, 2013, 12:58:37 PM
There is to my knowledge no single action that just returns if an Array is empty or not, you always need to add an INT COMPARE. Nothing about it though should become a beast of a scene. In general though, the less actions you have running per frame, the faster your game will run.
Title: Re: Arraymaker help
Post by: jeanfabre on December 16, 2013, 01:08:54 PM
Hi,

mweyna has a good point here. I have added this to my tasks for the next arrayMaker update:

https://trello.com/c/FamlVQBD/31-arraymaker-update

Now, as for real impacts on performances, you should worry about this IF you are using too many actions or processed within your game loop ( the code and features that are constantly running, like user input and player movements), that's very important, but if you do that based on a button action or something, then this is definitly not as critical.

bye,

 Jean
Title: Re: Arraymaker help
Post by: Splankton on December 17, 2013, 10:42:51 AM
Hi again,
Sorry for another question, my array for the NPC is working perfect, he picks up an item, that item is then removed, then he moves to the next item.
So, now I have my player to also pick up these items in the same array.  It works ok, except when I pick up an item, say item4 index 3, the array is updated but the item at index 0 gets removed and not item4 for example.
I have 2 FSM's on each item.  One for the NPC the other for my player.  And they are triggered each time an item is picked up, which then updates my Array.
I just need to know how I can get the index for the item my player picks up.  The NPC works fine because I use GetClosestGameObject which returns the index, so I use that to remove from the Array. 
So in my player FSM on my item,  I Get Array List, I store the result in a GameObject. Then remove that object from the Array.  And this is where my problem is.  The result just returns the item at index 0, and I need the index to return the specific item the player has picked up.
Thanks for any help.
Title: Re: Arraymaker help
Post by: mweyna on December 17, 2013, 11:20:23 AM
The problem is kinda based on trying to track things with indexes. In my experience unless your using INT or FLOAT variables, if you're just interacting with gameobject variables you can just use REMOVE and not REMOVE AT INDEX type commands. When your NPC picks up the item, have it remove the Item rather then the index number.
Title: Re: Arraymaker help
Post by: Splankton on December 17, 2013, 12:19:24 PM
The problem is kinda based on trying to track things with indexes. In my experience unless your using INT or FLOAT variables, if you're just interacting with gameobject variables you can just use REMOVE and not REMOVE AT INDEX type commands. When your NPC picks up the item, have it remove the Item rather then the index number.

Thanks, thing is my NPC is working fine with REMOVE AT. But with my player, I simply just use REMOVE.  I don't quite understand what happens when I use Array List Get in the stored gameobject.  It looks like it just returns the object at index 0.
It's there no way I can get the index for the item my player picks up?
Title: Re: Arraymaker help
Post by: jeanfabre on December 17, 2013, 01:11:07 PM
Hi,

 Arrays are not very clever, so you need to do that logic yourself really. that is, if you want th eindex of the item your player picked up, you need the reference of that item, and then find it in the array. that's the only way. you could use a hashtable and have item's referenced with strings and when your player pick up an item, you only want that string reference, and then you can get an value straight from a hashtable using that string reference, this is maybe what you are missing in your system, Arrays are good for listing, not necessarly good for refering to items in general.

Bye,

 Jean
Title: Re: Arraymaker help
Post by: Splankton on December 17, 2013, 01:17:46 PM
Ok thanks again. I'll have a look at hashtables in your samples. Can I still use my array set up for the most part and just use a hash table to reference the items in my array?
Title: Re: Arraymaker help
Post by: jeanfabre on December 17, 2013, 01:32:14 PM
Hi,

 of course, I also sometime use several arrays combined to form a sort of table ( several fields per row).

so if for example several properties you would do this:

index | Weapon name | Weapon damage | Weapon Cost
0         gun                  100                     400
1         riffle                 200                     800
2         bazooka            1000                    2000

and you would have three arrays, each having the proper reference ( name, damage and cost), and so you could have some pretty powerful tables like that without having to resort to a database ( tho, it would be recommanded if you deal with a lot of tables.)

bye,

 Jean
Title: Re: Arraymaker help
Post by: Splankton on December 17, 2013, 02:50:57 PM
Well, all I need at the moment is to hold 5 items.  So I'm thinking a hashtable maybe is too much.  So if I created another array to hold the names of the items using strings, would that be inside the loop, or create another loop just for the names?
Title: Re: Arraymaker help
Post by: jeanfabre on December 18, 2013, 05:22:14 AM
Hi,

 hashtables make sense starting at 2 items :) having only five items is totally OK: I even use Hashtables for preferences and settings. It's always better than hardcoding these properties and values in the code or fsm themselves.

if using arrays, yes, use the same loop, because you must expect all arrays forming a table to be consistent, so same number of items, you delete an item only by its indexes and always on all arrays, you add items to all arrays as well, etc etc. And so you would then only use one loop to got through them.

Bye,

 Jean
Title: Re: Arraymaker help
Post by: Splankton on December 18, 2013, 12:23:21 PM
Hi,

 hashtables make sense starting at 2 items :) having only five items is totally OK: I even use Hashtables for preferences and settings. It's always better than hardcoding these properties and values in the code or fsm themselves.

if using arrays, yes, use the same loop, because you must expect all arrays forming a table to be consistent, so same number of items, you delete an item only by its indexes and always on all arrays, you add items to all arrays as well, etc etc. And so you would then only use one loop to got through them.

Bye,

 Jean

Thanks Jean, I had a look at using a hashtable, couldn't quite get it working because I dont fully understand which values I would need.  All my 5 items are the same, except I've named them item1 - item5.  I think I will have to take your expert advice though, because I've realised that because the player is taking out index 0 every time he picks an item, it shifts the other items up in the index, which then confuses my NPC and he goes for items that arent there.

I've even tried (for the player) removing the last index in the array on each pickup. This works because the index doesnt shift up, but again it confuses the NPC, because when say, item2 is picked, the item at the end of the index is removed which could be item4.

So I think hash tables are my only hope, but I dont know if I need to loop through one, or just set it up at the start, then loop through the array?
By the way, one more thing, if I set my global transition outside of the loop so the main loop isn't touched at all, it doesn't make any difference to my NPC picking the items. Items are removed, then added back in without a loop.  So do I need a FOR loop?  I only have one array, no temp ones and looking at the loop all I'm doing is getting the list and adding 1 to my count.  I dont know what else I need to do to each gameobject as it iterates?

Sorry for the trouble and the really long thread, but I'm so close!
thanks for any help.
Title: Re: Arraymaker help
Post by: mweyna on December 18, 2013, 01:24:55 PM
Why not just use 3 arrays? You have a Master Item List, an array on your player, and an array on your NPC. Upon start copy all items from the Master list to both Player and NPC. Then if you create a new item, have it add to all the respective lists on its own FSM. When a player interacts with it, have it remove from their respective array?
Title: Re: Arraymaker help
Post by: Splankton on December 18, 2013, 02:37:58 PM
Why not just use 3 arrays? You have a Master Item List, an array on your player, and an array on your NPC. Upon start copy all items from the Master list to both Player and NPC. Then if you create a new item, have it add to all the respective lists on its own FSM. When a player interacts with it, have it remove from their respective array?

Thanks mweyna, that makes sense. But when my player or NPC removes the item, should I remove from all 3 arrays so they have all the same array length?
Also, can you answer what I would iterate through. I understand you use the loop to get or change something to each count, but I dont know why I would need one?
Title: Re: Arraymaker help
Post by: mweyna on December 18, 2013, 06:00:56 PM
Just have the "OnPickup" action remove it from the individual array. As for the Master Array, depending on the scenario you could do it a couple ways depending on choice, but if I was crafting something like that, I'd ...

- Depending on the scene have the Master Array copy to both Player and enemy  arrays on load.
- On a new object creation, add to both player and enemy arrays.
- Have an FSM on the enemy/player that gets the object from an array and paths to it. Have a FAIL action set if the object cannot path to it.
- Upon pick up, remove the object from the individual array and de-spawn/delete the object as appropriate.
- Have the FAIL action on the locomotor remove the item from the Array.

I can see problems with this if you're doing a lot of items, but that kinda theory in some form.

Title: Re: Arraymaker help
Post by: Splankton on December 19, 2013, 01:52:40 PM
Just have the "OnPickup" action remove it from the individual array. As for the Master Array, depending on the scenario you could do it a couple ways depending on choice, but if I was crafting something like that, I'd ...

- Depending on the scene have the Master Array copy to both Player and enemy  arrays on load.
- On a new object creation, add to both player and enemy arrays.
- Have an FSM on the enemy/player that gets the object from an array and paths to it. Have a FAIL action set if the object cannot path to it.
- Upon pick up, remove the object from the individual array and de-spawn/delete the object as appropriate.
- Have the FAIL action on the locomotor remove the item from the Array.

I can see problems with this if you're doing a lot of items, but that kinda theory in some form.

Thanks again mweyna, I have set it up that way, I still cant get a reference of the item for the player though.  The enemy gets the index from GetClosestGameObject, so thats done, but its they same problem as before.  When my player picks up an item, I dont know how to reference to that item so I can remove it.

- Have an FSM on the enemy/player that gets the object from an array and paths to it. Have a FAIL action set if the object cannot path to it.

If I can do this for my player, I'm happy :) But I dont know how.
Can I ask for a little more help please ;)
Title: Re: Arraymaker help
Post by: mweyna on December 19, 2013, 02:11:26 PM
So in the GetClosestGameObject action there should be an output to a GameObject variable. Then in the Remove action, just feed that GameObject variable back in.

As for the second part, I believe I was assuming you were using A* pathfinding, so I apologize if you are not. I'm not too familiar with non A* pathfinders, so maybe someone else can speak to this.
Title: Re: Arraymaker help
Post by: Splankton on December 19, 2013, 02:32:07 PM
So in the GetClosestGameObject action there should be an output to a GameObject variable. Then in the Remove action, just feed that GameObject variable back in.

As for the second part, I believe I was assuming you were using A* pathfinding, so I apologize if you are not. I'm not too familiar with non A* pathfinders, so maybe someone else can speak to this.

Ah, pathfinding of course, yes I am using a navmesh so I know what you mean now lol.
But I have already done the ClosestGameObject action, I used the index from that and fed that into the Remove, so that works fine.  My problem is for my player I cant use ClosestGameObject for that, so I need another way of getting the item that has been picked up.
I know Jean mentioned using a hashtable to reference the items, but they are all the same, except the names i.e item1 - item5 so I dont know what to enter for the keys/values.
You know of a way I can get a reference to one of the items in the array for my player, so I can remove it and add the same one back in?
Title: Re: Arraymaker help
Post by: mweyna on December 19, 2013, 03:02:06 PM
I'm not understanding why you cant use the Closet Game Object variable for that? If you're using the GameObject to remove it, why not just quickly passed the ClosetGameObject to a new empty GO  - "Temporary_Game_Object" then use Get Position for that Vector 3?
Title: Re: Arraymaker help
Post by: Splankton on December 22, 2013, 11:51:14 AM
I'm not understanding why you cant use the Closet Game Object variable for that? If you're using the GameObject to remove it, why not just quickly passed the ClosetGameObject to a new empty GO  - "Temporary_Game_Object" then use Get Position for that Vector 3?

Yes, you are right, I used ClosestGameObject for my player, its not ideal but I finally have the array working.  I set it up like you suggested, a master array and 2 others arrays for the player and enemy, tweaked it a little - I remove the items from the master which triggers the 2 other arrays and updates.
Didn't take too long, my PC went down 2 days ago, had to format and reinstall :( but its all working now, so thanks for your help! I can relax and enjoy Christmas now :)