Page 1 of 1

Best way to access all relationships

Posted: Sat May 07, 2022 8:39 am
by theUnsigned
Good day, I'm new to Love/Hate and am trying to draw a line between each member to represent their relationship but am a bit confused about how to best access each relationship. I've experimented with the FactionMember, FactionManager, and FactionDatabase but have wound up with a lot of nested loops trying to iterate over each member, database, relationship, traitdefinition, etc.

In my project, each npc has their own faction, created at runtime, with an edited version of the MegaOCEAN database. I'm trying to represent affinity in a line with a linerenderer and use the affinity value to define the size and color of that line's start and end points. What is the best way to access all of the relationships and how should I conceptualize the relationships in the factionmember, database, etc because I'm definitely missing something (over/under-thinking it).

Particularly, I'm having trouble referencing the gameObject/ transforms of each npc from the relationships list.

Thank you!

Re: Best way to access all relationships

Posted: Sat May 07, 2022 12:14 pm
by Tony Li
Hi,

Relationships are all managed in the faction database:

factionsAndMembers.png
factionsAndMembers.png (41.1 KiB) Viewed 6989 times

If you want to draw all relationships, you only need to loop through FactionManager.instance.factionDatabase.factions:

Code: Select all

foreach (Faction judge in FactionManager.instance.factionDatabase.factions)
{
    foreach (Faction subject in FactionManager.instance.factionDatabase.factions)
    {
        if (judge == subject) continue; // Don't report relationship to self.
        float affinity = FactionManager.instance.factionDatabase.GetAffinity(judge.id, subject.id);
        Debug.Log($"{judge.name} has {affinity} affinity toward {subject.name}");
    }
}

Re: Best way to access all relationships

Posted: Sat May 07, 2022 1:03 pm
by theUnsigned
Thank you! As a counselor trying to make a game, this asset has really helped me improve my coding skills. I think I nest a loop in there to run through each object and compare faction to set the line start/end positions to the transform positions but please correct me if I'm wrong. Much appreciated!

Re: Best way to access all relationships

Posted: Sat May 07, 2022 4:24 pm
by Tony Li
Hi,

The FactionManager will let give you access to each faction's FactionMember via the members property, which is a dictionary. The dictionary key is a Faction. The dictionary value is a list of FactionMembers. So you can do something like this:

Code: Select all

foreach (Faction judge in FactionManager.instance.factionDatabase.factions)
{
    foreach (Faction subject in FactionManager.instance.factionDatabase.factions)
    {
        if (judge == subject) continue; // Don't report relationship to self.
        float affinity = FactionManager.instance.factionDatabase.GetAffinity(judge.id, subject.id);
        FactionMember judgeFactionMember = FactionManager.instance.members[judge][0];
        FactionMember subjectFactionMember = FactionManager.instance.members[subject][0];
        LineRenderer line = Instantiate<LineRenderer>(prefab);
        line.SetPositions(new Vector3[] { judgeFactionMember.transform.position, subjectFactionMember.transform.position });
    }
}
(To keep the code above simple to read, it's not doing any checking for null return values or empty lists.)

Re: Best way to access all relationships

Posted: Sun May 08, 2022 8:55 am
by Tony Li
Your use of Love/Hate -- a one-to-one correspondence of factions to faction members -- is pretty normal.

Maybe it would be simpler to go through the faction members instead:

Code: Select all

FactionMember[] allMembers = FindObjectsOfType<FactionMember>();
 foreach (FactionMember judge in allMembers)
{
    foreach (FactionMember subject in allMembers)
    {
        if (judge == subject) continue; // Don't report relationship to self.
        float affinity = judge.GetAffinity(subject);
        LineRenderer line = Instantiate<LineRenderer>(prefab);
        line.SetPositions(new Vector3[] { judge.transform.position, subject.transform.position });
    }
}
If that doesn't help, would you please reply with any error or warning messages you're seeing and/or behavior that isn't working the way you want?