playMaker

Author Topic: How to have prefabs reference game objects without global variables?  (Read 1649 times)

Thore

  • Sr. Member
  • ****
  • Posts: 332
    • View Profile
Re: How to have prefabs reference game objects without global variables?
« Reply #15 on: November 26, 2018, 04:16:22 PM »
Your setup seems convoluted. The suggestion of using a scene based manager is good for some game types: if you cannot for some reason use names or tags, to have something akin to global variables or “variable containers” in one place, to keep track of something without every frame checks etc. However, as I wrote, it is better to handle each part itself with as minimal spaghetti (cross referencing etc) as possible.

In your case, you need to think more atomistic. Each wolf manages its own health. Each arrow delivers the damage. See the method above.

Player is tagged as player, and wolf is tagged enemy. Each arrow’s collision/trigger detection looks for something with the tag enemy, and then stores the object it hit (the wolf). Then the arrow “knows” the wolf that was hit. It also has the event data action, that contains the damage values, and sends an event to the wolf’s health FSM on the wolf, telling it, that it was hit. The wolf’s health FSM gets the info (see a post above of mine) and then substracts this value from its own health, then checks if the wolf is still alive etc.

If you really want to use a battle manager to do the calculation, which looks like spaghetti to me, you can find the Battle Manager by name, or tag. Then, it has two game object variables I assume, one for damage dealer and one for damage receiver.

When the collision or trigger hits, the arrow knows what it hit and also knows itself (at least with get owner, executed at the start). It can then Set FSM Game Object , twice, into the Battle Managr, once for itself as the dealer and the target it hit as the receiver. Then the battle manager knows them, too, and can do whatever calculation it needs to do, and use those same game object variables plus Send Events or Set FSM viables to report back the outcome.

However, unless you have a compelling reason for doing it like this, I recommend to do the more robust, simpler approach without the battle manager.
« Last Edit: November 26, 2018, 04:19:36 PM by Thore »

Snowbird

  • Playmaker Newbie
  • *
  • Posts: 17
    • View Profile
Re: How to have prefabs reference game objects without global variables?
« Reply #16 on: November 26, 2018, 04:51:46 PM »
It also has the event data action, that contains the damage values, and sends an event to the wolf’s health FSM on the wolf, telling it, that it was hit.

This is the only thing I am asking. I don't understand how the arrow can communicate to the wolf. I don't know how to send an event from the instance of one prefab to the instance of another or to a scene object. That's what I am trying to figure out. I can tell the wolf that it has entered a collision with an arrow and therefore must subtract 10 health (not very useful). I can tell that arrow to disappear when it hits the enemy. What I have no idea about is how I can put a variable in the arrow that says it does 5 damage or 10 damage or whatever, and send that number to the instance of the wolf. I also don't know how to have that damage be adjusted based on a scene objects variables (characters attributes for example)

I appreciate the advice about cleaning it up and making it simpler, and will continue to work on making it better. But the thing that is confusing me is that. How can the instances of the prefabs send each other variables. You mention these actions like "send event", which work great for scene objects, but they don't work from prefabs to things outside of the prefabs.

Athin

  • Full Member
  • ***
  • Posts: 119
    • View Profile
Re: How to have prefabs reference game objects without global variables?
« Reply #17 on: November 26, 2018, 05:03:37 PM »
You need to use the action Set FSM Int.  If you know the object you hit, you can then send the info to that object using that action. 

For example, the arrow hits the wolf.  The arrow knows itself and and the object it hit (Get owner for the arrow and Trigger event to find the hit object.).  Using that info you can then use the action Set FSM Int to give its damage to the wolf and an action "Send Event" to then have the wolf calculate the damage it took. 

I think its this Action "Set FSM Int" you are getting confused on as that is how you can throw values and variables to other FSM for them to use.  It can be used on prefabs or game scene objects alike as long as you know who to send it to which in this case we do.

Thore

  • Sr. Member
  • ****
  • Posts: 332
    • View Profile
Re: How to have prefabs reference game objects without global variables?
« Reply #18 on: November 26, 2018, 05:12:12 PM »
Okay, I see now.

Read the post above about the Event Data & Event Info. In the arrow, place the Event Data, set a variable under e.g. float. Say, “damage”. Then find the FSMs variable pane, and select the damage float you created, and set the value there. Then, all arrows instantiated from this will use that setup and that value.

How to pass it on, I already explained above. Look in the ecosystem for an example scene on projectiles. Jean created it, and should be up there.

Snowbird

  • Playmaker Newbie
  • *
  • Posts: 17
    • View Profile
Re: How to have prefabs reference game objects without global variables?
« Reply #19 on: November 27, 2018, 01:48:16 AM »
Okay thank you two for the help. I'm finally able to get some communication going between these things and I am trying to do less cross referencing as well (such as damage calculation being done purely on the arrow and resistances being factored in on the enemy right be we subtract health).

My problem was I didn't understand what storing the game object did upon collision or spawning of a prefab instance, and how I could use that stored variable to send events.  Maybe I just needed to sleep on it as sometimes the brain gets jumbled after working for a while.

This is how I see I should move forward—does this sound better?
-Character spawns an arrow and stores it, then sends it some attributes (such as strength and agility)
-Arrow is spawned and quickly calculates its total damage it should deal based off of its base damage and the attributes it was sent, and flies toward the enemy.
-Arrow collides with enemy and stores the enemy as a gameObject, and sends it the total damage number.
-Enemy receives the collision and the number sent, and reduces that number by its 'armor', then reduces it's HP by that amount.

I have this working fine now. This seems like a better way to do it?
(I'm already thinking of some slight improvements)

Bonus question: When the enemy dies, I want to send experience to the character. Is the best way to do this "find game object" with tag, seeing as it doesn't need to be quick or anything? Once again, thank you for the help and being patient.

Athin

  • Full Member
  • ***
  • Posts: 119
    • View Profile
Re: How to have prefabs reference game objects without global variables?
« Reply #20 on: November 27, 2018, 03:55:26 AM »
It happens to all of us at times :)  I always find myself banging my head against the problem until one day it just hits me in the face with the answer.

What I'd do is have the enemy spawn in and find the player and store it.  Player shoots an arrow and the wolf detects that it got hit. When hit the wolf grabs the "Stats" needed from the player to do the calculations himself for the damage (Can also have the base arrow damage store in the player if needed).

That will be alot simpler to handle then player > arrow > enemy but also depends on how your game plays out too.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14592
  • Official Playmaker Support
    • View Profile
Re: How to have prefabs reference game objects without global variables?
« Reply #21 on: December 05, 2018, 12:41:33 AM »
Hi,

 ok, the solutions are multiple.

 - you tag your battle manager gameobject, and use FindGameObject ( using tag, not name) on all your prefab instances, then you can communicate with that directly, get values using GetFsmXXX, etc etc

- you send global events and you don't care about who is responsible for listenting to it ( the best option), fire "BATTLE MANAGER / DO SOMETHING" as a global event, now any fsm can catch that, your prefab instance is free from having to know who is the battle manager ( and maybe many fsm will be able to act upon that event.


- you reverse the second option and explain what's happening, your ennemy is doing something, don't talk to the battle manager, but actuall fire an event saying what your instance is doing, any one can act on this then, the player, the battel manager, the score manager anything. "ENNEMY / ON WILL START ATTACK", "ENNEMY / ON DAMAGE" etc etc. you can pass data to your event for additional data, etc etc.

 Bye,

 Jean