AI Planner 0.2.4 Custom precondition InSightOfTarget

i have a few question about custom precondition and data access in general,
im using unity 2020.1.4f1 in a project using the default unity physics.
here is a very naive custom precondition that give an error on playtime (can use physicsscene only in main thread).

public struct TargetInSightPrecondition : ICustomActionPrecondition<StateData> {
    private static PhysicsScene physics = Physics.defaultPhysicsScene;
    public bool CheckCustomPrecondition(StateData state, ActionKey action)
    {
        Vector3 agentPos = ???;
        Vector3 targetPos =???:
        var targetDir = (agentPos - targetPos).normalize;
        return TargetIsInSight(agentPos, targetDir);
    }

    public static bool TargetIsInSight(float3 position, float3 dir)
    {
        return physics.Raycast(position, dir);
    }
}

also the “Attack” action using that precondition:

here the questions:

  1. how can i get the information relative to this action ? (agent data and target data being compared in the precondition)
  2. how can i know if i my agent can see a target while still using the AI planner ?
    is there any hope ?
    Thank you by advance !

1 Like

Yes

The code is not compatible with job system,You can use physicsscene in main thread only.

Hello,

I will probably need something similar in a near future, and I don’t really actually know how to do that for the moment.

But I can help you with what I know from now.

First thing, you have to keep in mind that pre-condition are executed when the AI planner is building the decision graph, so it’s used to determine in advance if the action will be possible. That’s why the raycast must be able to be done on a possible future state of your world. Even if your code was compatible with job system, I don’t think the PhysicsScene will actually represent the world in the state the AI Planner actually knows.

To get the position of both actors, you have to use their Location trait:

public struct TargetInSightPrecondition : ICustomActionPrecondition<StateData> {
    private static PhysicsScene physics = Physics.defaultPhysicsScene;
    public bool CheckCustomPrecondition(StateData state, ActionKey action)
    {
        Location agentLocation = state.GetTraitOnObject<Location>(state.GetTraitBasedObject(state.GetTraitBasedObjectId(action[0])));
        Location targetLocation = state.GetTraitOnObject<Location>(state.GetTraitBasedObject(state.GetTraitBasedObjectId(action[1])));

        return ProximityUtility.IsNear(moverLocation, targetLocation);
        Vector3 agentPos = agentLocation.Position;
        Vector3 targetPos = targetLocation.Position:
        var targetDir = (agentPos - targetPos).normalize;
        return TargetIsInSight(agentPos, targetDir);
    }
    public static bool TargetIsInSight(float3 position, float3 dir)
    {
        return physics.Raycast(position, dir);
    }
}

But as said before, your TargetIsInSight function must rely on the world state as seen by the AI Planner.

The solution could be to have a trait for physics data (radius, shape, etc…) for both parameters and re-compute the raycast from that. One thing is certain: all your calculations must rely on trait data.

1 Like