Page 1 of 1

Creating FactionManager and FactionMember programmatically

Posted: Wed Sep 05, 2018 8:54 pm
by ClearlyDefectiv
Hello,

My first question is how can I create a new FactionManager GameObject from a script? I saw on an older thread (viewtopic.php?f=5&t=724) that you recommended doing something like this:

Code: Select all

// Create FactionManager:
var factionManager = new GameObject("LoveHate").AddComponent<FactionManager>();
factionManager.factionDatabase = myDatabase;
However when I do that, the Awake method for FactionManager logs a debug error since the faction database is not assigned yet. Is there a way to do this? My project is going to have several managers and I want to create them from the main GameManager so that I don't have to add a bunch of things to every scene.

My second question is what's the best way to do the same thing for FactionMembers? My project has a lot of procedural characters and I was hoping to just be able to create new factions for them and add them to the database at runtime.

From that same thread I saw an example of creating them: (although I think I'll be instantiating a prefab with the base character components and then either adding a FactionMember component or updating the existing component on the prefab)

Code: Select all

foreach (var character in myCharacters)
{
    var characterGO = new GameObject(character.factionName);
    characterGO.transform.SetParent(factionManager.transform);
    character.factionMember = characterGO.AddComponent<FactionMember>();
    character.factionMember.factionID = factionManager.GetFactionID(character.factionName);
    
    // Add other components:
    characterGO.AddComponent<StabilizePAD>();
    characterGO.AddComponent<EmotionalState>(); //etc.
}
and I just want to make sure that are not any hidden "gotchas" that I'm going to run into doing things this way.

Thanks!

Re: Creating FactionManager and FactionMember programmatically

Posted: Wed Sep 05, 2018 9:04 pm
by ClearlyDefectiv
Actually, going to reply to my own post here to ask a more general question. Seems like Love/Hate was designed with the idea that factions and their members would be created by the designer before hand, what would you recommend if I want to have the majority of these things be generated procedurally?

Re: Creating FactionManager and FactionMember programmatically

Posted: Thu Sep 06, 2018 10:23 am
by Tony Li
Hi,

Love/Hate fully supports runtime creation of factions and faction members.

It's true that adding a FactionManager component at runtime reports the error "Love/Hate: Assign a faction database to FactionManager". I've lowered this to a warning, but it will remain to help out devs who are creating their content at design-time and may have forgotten to assign a faction database.

Faction databases are ScriptableObjects. To create one, call ScriptableObjectUtility.CreateScriptableObject:

Code: Select all

using PixelCrushers;
using PixelCrushers.LoveHate;
...
var database = ScriptableObjectUtility.CreateScriptableObject<FactionDatabase>();
This is the same as Unity's built-in ScriptableObject.CreateInstance, but it also calls an Initialize() method to initialize the database.

To add a new faction, call FactionDatabase.CreateNewFaction:

Code: Select all

factionManager.factionDatabase.CreateNewFaction(factionName, factionDescription);
To add a new faction member, just add the component and set its faction ID:

Code: Select all

var member = myGameObject.AddComponent<FactionManager>();
member.factionID = factionManager.GetFactionID("Some Faction");
The FactionMember component's Start method registers the faction member's faction ID with the faction manager.

If you want to switch a faction member's faction after its Start method has run, use FactionMember.SwitchFaction:

Code: Select all

factionMember.SwitchFaction(newFactionID);
This will update its ID with the faction manager, too.

Re: Creating FactionManager and FactionMember programmatically

Posted: Tue Sep 11, 2018 12:03 pm
by ClearlyDefectiv
Thank you for the info. Personally I don't want to see any warnings/errors from the FactionManager creation, however I definitely understand you wanting to keep the warning since that can help people. Currently I've made a prefab out of the FactionManager with the database set and I just Instantiate that without any error messages, I think that I could also just extend the wrapper for FactionManager to override the Start method since you've helpfully made it virtual already.

I probably won't be creating the FactionDatabase at runtime, that way I can have some pre-built factions/members and then add my generated ones when they are created.

Thanks again!

Re: Creating FactionManager and FactionMember programmatically

Posted: Tue Sep 11, 2018 12:32 pm
by Tony Li
I've been thinking this over, and instead of reporting an error in Awake, I'll see if I can change it to report an error the first time the faction manager tries to access the factionDatabase. This will give you time to assign the factionDatabase, while still reporting helpful information to devs who might have unintentionally left it unassigned at design time.