Fencing

Background

Gameplay can be deemed inappropriate in some locations. For example, when players are inside of schools or shopping malls, they shouldn't be killing zombies in AR mode, or adding any user generated content. Fencing is a feature that guards against such situations, by enabling you to define rules to restrict gameplay under certain conditions.

How it works

Each time the MapService component loads a MapFeature, it forwards it to the FencingServiceComponent for processing. Whenever a MapFeature has an associated FencingRule, the FencingServiceComponent creates a fencing zone game object to cover it, and then adds it to the Unity scene graph.

The result

This results in the placement of invisible sphere colliders on top of particular kinds of map features, as demonstrated in the example scene from the Maps SDK for Unity (located in Assets > GoogleMaps > Examples > 30_Fencing).

In this scene, the green disks depict the fence sphere colliders. In this scenario, when the player fires their gun, the player game object first checks to see if it's inside of a fence sphere collider. When it is, the gun is prevented from firing. Additionally, projectiles fired from the gun can also collide with fencing spherical colliders, which means they too are prevented from entering fenced areas.

To use fencing

Follow this procedure to add fencing to your Unity scene.

Step 1: Attach FencingServiceComponent

  1. In the Unity hierarchy pane, select the same GameObject that your MapsService component is attached to (the Map Base).
  2. Click Add Component in the Inspector, and then add the FencingServiceComponent.

This allows the FencingServiceComponent instance to communicate with the MapsService component.

Step 2: Get a reference to the FencingServiceComponent

To programmatically access the FencingServiceComponent instance, call GetComponent().

FencingService = GetComponent<FencingServiceComponent>().FencingService;

Step 3: Create a fencing rule

Specify the type of map feature that you want to protect, and specify the margin distance (the distance beyond the building's border).

FencingRule fencingRule =
      FencingRule.NewRule()
          .StructureArea(StructureMetadata.UsageType.Shopping, 20f);

This fencing rule results in the creation of spherical colliders that cover every loaded shop, and it provides 20 meters of margin.

Step 4: Register the fencing rule

Call RegisterRule() on the FencingService object, passing the fencing rule and the fencing layer.

FencingService.RegisterRule(fencingRule, FENCING_LAYER);

Step 5: Detect fenced areas

You can detect whether a game object is inside of a fenced area by using Unity’s physics engine to search for colliders, as demonstrated here.

private bool InsideFencedZone() {
  Collider[] colliders =
      Physics.OverlapSphere(Player.transform.position, 5, 1 << FENCING_LAYER);
  return colliders.Length > 0;
}

Step 6: (Optional) Customize generated fencing objects

As the map loads, FencingService creates fencing objects (with attached colliders) that represent the fencing areas within the Unity scene graph. These are invisible by default, but in the fencing example scene, the zones are highlighted in green. You can accomplish this by subscribing to an event triggered when a fencing object is created—as demonstrated in the following code.

private void ZoneMarkerSetup() {
  FencingService.FencingServiceEvents.ObjectCreated.AddListener(args => {
    SphereCollider sphereCollider = args.GameObject.GetComponent<SphereCollider>();
    GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
    float radius = sphereCollider.radius;
    cylinder.transform.localScale = new Vector3(radius*2, 0.1f, radius*2);
    cylinder.transform.position = sphereCollider.center;
    cylinder.transform.SetParent(args.GameObject.transform);

    Collider cylinderCollider = cylinder.GetComponent<Collider>();
    Destroy(cylinderCollider);

    Renderer renderer = cylinder.GetComponent<Renderer>();
    renderer.material = FencedZoneMaterial;
  });
}