I can't actually affect trait's data from custom effect

Hello everyone,

I’m trying to use a custom effect as described in the documentation to decrease values from a Needs trait that contains 3 fields:

6361785--707931--upload_2020-9-29_14-41-54.png

So I’ve made this class:

using Unity.AI.Planner.DomainLanguage.TraitBased;
using Generated.AI.Planner.StateRepresentation;
using Generated.AI.Planner.StateRepresentation.AgentPlan;
using UnityEngine;

public struct NeedsEffect : ICustomActionEffect<StateData>
{
    public void ApplyCustomActionEffectsToState(StateData originalState, ActionKey action, StateData newState)
    {
        TraitBasedObjectId moverObjectId = newState.GetTraitBasedObjectId(action[0]);
        TraitBasedObject moverObject = newState.GetTraitBasedObject(moverObjectId);
        Needs needs = newState.GetTraitOnObject<Needs>(moverObject);

        needs.Energy = Mathf.Max(0, needs.Energy - 1);
        needs.Fun = Mathf.Max(0, needs.Fun - 1);
        needs.Restroom = Mathf.Max(0, needs.Restroom - 1);
    }
}

And I affected this effect to a Move action like that:

But it doesn’t seem to work if I look at the graph in the plan visualizer.

From the state selected (before branching), I expect the needs (highlighted in red from the screen) to decrease by one in the next state if the “Move” action is used:

But only the Energy decreases (the last effect from the Move action asset file):

Do you know why? Did I do something wrong?

N.B: I generated the AI Planner assemblies with no error. No error neither in the console at runtime. I made a small project to show the issue here.

You’re modifying a local copy of the struct. You need to set the updated version back on the new state.

1 Like

My bad, that was a dumb mistake… Thank you for your help, here is the fixed code:

using Unity.AI.Planner.DomainLanguage.TraitBased;
using Generated.AI.Planner.StateRepresentation;
using Generated.AI.Planner.StateRepresentation.AgentPlan;
using UnityEngine;

public struct NeedsEffect : ICustomActionEffect<StateData>
{
    public void ApplyCustomActionEffectsToState(StateData originalState, ActionKey action, StateData newState)
    {
        TraitBasedObjectId moverObjectId = newState.GetTraitBasedObjectId(action[0]);
        TraitBasedObject moverObject = newState.GetTraitBasedObject(moverObjectId);
        Needs needs = newState.GetTraitOnObject<Needs>(moverObject);

        needs.Energy = Mathf.Max(0, needs.Energy - 1);
        needs.Fun = Mathf.Max(0, needs.Fun - 1);
        needs.Restroom = Mathf.Max(0, needs.Restroom - 1);

        newState.SetTraitOnObject(needs, ref moverObject);
    }
}