Best way to access all relationships

Announcements, support questions, and discussion for Love/Hate.
Post Reply
theUnsigned
Posts: 2
Joined: Sat May 07, 2022 8:30 am

Best way to access all relationships

Post 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!
User avatar
Tony Li
Posts: 22112
Joined: Thu Jul 18, 2013 1:27 pm

Re: Best way to access all relationships

Post by Tony Li »

Hi,

Relationships are all managed in the faction database:

factionsAndMembers.png
factionsAndMembers.png (41.1 KiB) Viewed 7319 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}");
    }
}
theUnsigned
Posts: 2
Joined: Sat May 07, 2022 8:30 am

Re: Best way to access all relationships

Post 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!
User avatar
Tony Li
Posts: 22112
Joined: Thu Jul 18, 2013 1:27 pm

Re: Best way to access all relationships

Post 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.)
User avatar
Tony Li
Posts: 22112
Joined: Thu Jul 18, 2013 1:27 pm

Re: Best way to access all relationships

Post 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?
Post Reply