Page 1 of 2

A few questions about "changing" some Love/Hate behaviors

Posted: Sun Dec 06, 2015 12:17 pm
by iDisagree
Hey -

While Love/Hate is super powerful, and has been immensely helpful to me, I'm in need of doing things differently than the way Love/Hate does them out of the box. For instance, when a deed occurs I don't want it to change the way those two actors view each other. Instead, I want to change the values of the personality traits of those actors. In "iDisagree", the way actors feel about each other is based solely on their personality traits and not some individual affinity towards each other. It's designed to be overly generalized :)

So, with that said, it looks I don't have to use FactionMember. Instead it seems like I can implement the event handler interfaces (i.e: IWitnessDeedEventHandler). Would that be the proper way to override the default Love/Hate behavior? Also, it looks like "CanSee" is a method on FactionMember. If I'm not using FactionMember, is there any way I can still have Love/Hate handle the "seeing" behavior or will I have to roll my own complete solution?

Also, it looks like ReportDeed requires a FactionMember. Is it possible to "do a deed" without a direct target? I.e: Someone said something on a social network. There is no direct target, however many different people may see that "deed" and react to it differently.

Thanks in advance!!! (full warning -- I'll likely have follow up questions, haha)

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Sun Dec 06, 2015 3:29 pm
by Tony Li
Hi,

It's actually easier than that. Here's what I recommend:

1. Create an "abstract" FactionMember GameObject for your social network. Use it as the target when someone says something on the social network. For social networks, you'll probably want to set the deed's Radius to 0, meaning it doesn't do distance checks. If you want to filter it some other way, you can always assign a new delegate function to CanSee.

2. Add a FactionMember to all people as normal. Assign your replacement function to the EvaluateRumor delegate. (All deeds are treated as rumors where the source of the rumor is the witness itself.) For example, you could add a script like this:

Code: Select all

public class MyRumorHandler : MonoBehaviour
{

    void Start()
    {
        GetComponent<FactionMember>().EvaluateRumor = MyEvaluateRumor;
    }
    
    Rumor MyEvaluateRumor(Rumor rumor, FactionMember source)
    {
        // Your code goes here to handle the rumor.
        // If this results in a new deed being added to the faction member's memory, 
        // return a new rumor if the impact is big enough to remember (otherwise null).
        // If it's a repeat deed that's already in memory, returns the existing rumor.
    }
}
You can scavenge FactionMember.cs's DefaultEvaluateRumor method for any bits of functionality you want to keep, and then just add in your custom stuff.

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Sun Dec 06, 2015 4:20 pm
by iDisagree
Okay cool, thanks! Would the EvaluteRumor be where I implement changing personality trait values rather than relationship?

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Sun Dec 06, 2015 5:30 pm
by Tony Li
iDisagree wrote:Okay cool, thanks! Would the EvaluteRumor be where I implement changing personality trait values rather than relationship?
Yup! Take a look at the DefaultEvaluateRumor method in FactionMember.cs. You could copy it into your own method, delete the code that works on relationships, and add your own code to change personality trait values.

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Sun Dec 06, 2015 10:22 pm
by iDisagree
Awesome!

One more question :) Could I do all this without using FactionMember? My reasoning is this - each one of my actors are distinct "things" and they each have their own unique personality. I know I could use a unique faction for each actor, but seems a little overkill. I'm wondering if I could just use the Traits component and then write my own component to handle some of the stuff Love/Hate needs (CanSee, EvaluateDeed, etc etc).

Is that possible, or are things pretty tightly coupled to FactionMember?

EDIT - I'm currently working under the assumption that sticking with FactionMember is the best approach. I'm merely exploring options to see if I can cut out some lifting I'll have to do later -- mainly saving and loading all these dynamically created Factions for each member (since they aren't added in the unity UI, but instead randomly and dynamically at runtime).

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Mon Dec 07, 2015 8:47 am
by Tony Li
Hi,

Using FactionMember is definitely the easiest solution since you won't have to replicate its functionality in a custom script of your own.

To save and load your dynamically-created factions, just call FactionManager.SerializeToString() and DeserializeFromString().

Similarly, call FactionMember.SerializeToString() and DeserializeFromString() to save and load faction members.

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Mon Dec 07, 2015 10:08 am
by iDisagree
To save and load your dynamically-created factions, just call FactionManager.SerializeToString() and DeserializeFromString().
I tried this, and I just end up with a string like "2,0,0,0,0," .. no faction names or anything seem to get serialized. Here's the code I wrote to test it out:

Code: Select all

    var user = new GameObject();
    user.AddComponent<FactionMember>();

    var factionMember = user.GetComponent<FactionMember>();
    factionMember.factionManager = _factionManager;
    factionMember.sightLayerMask = LayerMask.NameToLayer("Nothing");

    var factionId = _factionManager.factionDatabase.CreateNewFaction("Neutral", "");
    var faction = _factionManager.GetFaction(factionId);

    faction.traits[_factionManager.factionDatabase.GetPersonalityTraitID("Authoritarian")] = 0.0f;
    faction.traits[_factionManager.factionDatabase.GetPersonalityTraitID("Amenable")] = 0.0f;
    faction.traits[_factionManager.factionDatabase.GetPersonalityTraitID("Entitlement")] = 0.0f;
    faction.traits[_factionManager.factionDatabase.GetPersonalityTraitID("Grandiose")] = 0.0f;
    faction.traits[_factionManager.factionDatabase.GetPersonalityTraitID("Judgemental")] = 0.0f;
    faction.traits[_factionManager.factionDatabase.GetPersonalityTraitID("Collectivist")] = 0.0f;

    factionMember.SwitchFaction(factionId);
    Debug.Log(_factionMember.SerializeToString());

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Mon Dec 07, 2015 11:54 am
by Tony Li
Faction information is stored in the faction database. Save it using FactionManager.SerializeToString(). You'll also want to use Love/Hate version 1.8, which is being released today. Version 1.8 serializes faction names. Previous versions worked under the assumption that factions were created at design time. Version 1.8's serialization also includes dynamically-created faction names.

BTW, the first number in that "2,0,0..." string is the factionID, which is an index into the faction manager's faction database.

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Mon Dec 07, 2015 11:59 am
by iDisagree
Faction information is stored in the faction database. Save it using FactionManager.SerializeToString()
Right. The _factionMember.SerializeToString() above is a typo, it should be _factionManager :) Either way, it wasn't loading the factions when I deserialized that string. It would only load the factions that I had added through Unity's inspector.

It sounds like 1.8 may solve this for me, though :)

Re: A few questions about "changing" some Love/Hate behaviors

Posted: Mon Dec 07, 2015 12:01 pm
by Tony Li
Yes, sorry about that. I've been running 1.8 for a while and forgot that dynamic faction serialization was a new feature. :-)