ImageTracking_Targets

Demonstrate image tracking feature.

  • Demonstrate different methods to create targets

  • Demonstrate how to dynamically create targets

  • Demonstrate how to create a target from ImageTargetData

  • Demonstrate how to load and unload targets

  • Demonstrate how to use different center mode

  • Demonstrate how to use different horizontal flip mode

How to Use

../../_images/image_26.png
Mark 1: Whether open the camera.
Mark 2: Switch camera using device index.
Mark 3: Switch horizontal flip mode of the camera image rendering.
Mark 4: Switch world center mode.
Mark 5: Unload/load all image targets in the scene.
Mark 6: Stop/start tracking.
Mark 7: Display system status and operation hint.

How It Works

Targets in the scene

If you want to replace the image in the sample to your own, make sure to choose a .jpg or .png file with rich texture. It is also suggested to read this guide to help choosing a trackable image.

../../_images/image_s1_13.png

Target can be setup directly from the inspector of Unity editor.

  • Active Control: Targets and their children will hide when the target is not being tracked. If you need to keep it display when lost, change this value and write your own strategy.

  • Source Type: Targets are created from Image File or Target Data File depending on this value.

  • Path Type: StreamingAssets here, so the Path will use a path relative to StreamingAssets.

  • Path: Image path relative to StreamingAssets in this sample.

  • Name: Name of the target, choose a world easy to remember.

  • Scale: It is set according to physical size of the image width in real world.

  • Tracker: The Tracker to load ImageTarget.

Gizmo are displayed if not disabled in the global settings when the target setting is valid. This will not show in the game view. The namecard image in the game view is a quad in the scene under the ImageTarget-namecard node in the scene.

The transform of the cube and duck have been adjusted so that their bottom will be aligned with the target image. When you run this scene and track the target, the cube and duck will show just on top of the image.

Create targets in script – from images

You can create targets from images in the scripts. It is basically just moving the inspector setup to the script. You first need to create an empty GameObject and add ImageTargetController.

private ImageTargetController CreateTargetNode(string targetName)
{
    GameObject go = new GameObject(targetName);
    var targetController = go.AddComponent<ImageTargetController>();
    ...
}

Then set Tracker, SourceType, ImageFileSource.PathType, ImageFileSource.Path, ImageFileSource.Name, ImageFileSource.Scale value of ImageTargetController like what is done is the inspector.

var targetController = CreateTargetNode("ImageTarget-argame00");
targetController.Tracker = imageTracker;
targetController.SourceType = ImageTargetController.DataSource.ImageFile;
targetController.ImageFileSource.PathType = PathType.StreamingAssets;
targetController.ImageFileSource.Path = "sightplus/argame00.jpg";
targetController.ImageFileSource.Name = "argame00";
targetController.ImageFileSource.Scale = 0.1f;

Add a child object to the GameObject so it will be displayed when the target is tracked.

GameObject duck02 = Instantiate(Resources.Load("duck02")) as GameObject;
duck02.transform.parent = targetController.gameObject.transform;

Create targets in script – from list

You can also create targets from a list with detailed configurations in the scripts. You need to define the list description by your own, the obsolete interface of loading a json file are not supported in the new Sense release. This gives you the flexibility to define your own target description without losing performance.

A json definition like json configuration of EasyAR Sense 1.0 looks like

var imageJosn = JsonUtility.FromJson<ImageJson>(@"
{
    ""images"" :
    [
        {
            ""image"" : ""sightplus/argame01.png"",
            ""name"" : ""argame01""
        },
        {
            ""image"" : ""sightplus/argame02.jpg"",
            ""name"" : ""argame02"",
            ""scale"" : 0.2
        },
        {
            ""image"" : ""sightplus/argame03.jpg"",
            ""name"" : ""argame03"",
            ""scale"" : 1,
            ""uid"" : ""uid string will be ignored""
        }
    ]
}");

Just create the targets in a loop, all time-consuming procedures are handled in background threads.

foreach (var image in imageJosn.images)
{
    targetController = CreateTargetNode("ImageTarget-" + image.name);
    targetController.Tracker = imageTracker;
    targetController.ImageFileSource.PathType = PathType.StreamingAssets;
    targetController.ImageFileSource.Path = image.image;
    targetController.ImageFileSource.Name = image.name;
    targetController.ImageFileSource.Scale = image.scale;

    var duck03 = Instantiate(Resources.Load("duck03")) as GameObject;
    duck03.transform.parent = targetController.gameObject.transform;
}

Target events

Target events are used for custom operations, the sample use the events to output some logs. You can delete the logs if they are not used, and you can use the events to handle your game logic.

controller.TargetFound += () =>
{
    Debug.LogFormat("Found target {{id = {0}, name = {1}}}", controller.Target.runtimeID(), controller.Target.name());
};
controller.TargetLost += () =>
{
    Debug.LogFormat("Lost target {{id = {0}, name = {1}}}", controller.Target.runtimeID(), controller.Target.name());
};
controller.TargetLoad += (Target target, bool status) =>
{
    Debug.LogFormat("Load target {{id = {0}, name = {1}, size = {2}}} into {3} => {4}", target.runtimeID(), target.name(), controller.Size, controller.Tracker.name, status);
};
controller.TargetUnload += (Target target, bool status) =>
{
    Debug.LogFormat("Unload target {{id = {0}, name = {1}}} => {2}", target.runtimeID(), target.name(), status);
};

Target load and unload

Target load and unload is very easy. Set ImageTargetController.Tracker to null, the target will be unloaded, and set it to some tracker will make the target loaded into the tracker immediately.

public void UnloadTargets()
{
    foreach (var item in imageTargetControllers)
    {
        item.Key.Tracker = null;
    }
}

public void LoadTargets()
{
    foreach (var item in imageTargetControllers)
    {
        item.Key.Tracker = imageTracker;
    }
}

Tracking on/off

Image tracking can be turned on or off using ImageTrackerFrameFilter.enabled. You can turn the tracking off when it is not used to save performance, it will not turn off the camera or any other tracking features.

public void Tracking(bool on)
{
    imageTracker.enabled = on;
}

Camera on/off

Camera device can be turned on or off using VideoCameraDevice.enabled. If a camera has turned off, the tracker will not receive any frames and the whole AR chain will stop.

public void EnableCamera(bool enable)
{
    cameraDevice.enabled = enable;
}

Center mode

Three mode of ARSession.CenterMode are valid in object sensing.

In ARSession.ARCenterMode.Camera, the camera do not automatically move when the device moves.

../../_images/image_s1_2.gif

In ARSession.ARCenterMode.FirstTarget or ARSession.ARCenterMode.SpecificTarget, the camera will move automatically when the device moves, and the target stay.

../../_images/image_s1_3.gif

To show the differences between ARSession.ARCenterMode.FirstTarget and ARSession.ARCenterMode.SpecificTarget, we change the tracker settings to track two targets.

In ARSession.ARCenterMode.FirstTarget mode, the camera will always move when there is some target being tracked, and the center will be the first tracked target or any other target when it is lost.

../../_images/image_s1_4.gif

When the center target not changing, ARSession.ARCenterMode.SpecificTarget mode will always use the specified target as center when it is tracked, and the camera stay when the target is lost.

../../_images/image_s1_5.gif

ARSession.CenterMode can be modified at any time and it will take effect immediately.

../../_images/image_s1_6.gif

Flip camera image horizontally

ARSession.HorizontalFlipNormal and ARSession.HorizontalFlipFront controls how the camera is mirrored. When the camera image is mirrored, the camera projection or the target scale will change so that a tracking behavior continues.

ARHorizontalFlipMode.None do not make a flip.

../../_images/image_s1_72.png

In ARHorizontalFlipMode.World mode, the camera image will be flipped in rendering, the camera projection matrix will be changed to do flip rendering. Target scale will not change. Changing of projection matrix will have side effect to all other objects displayed in the scene, you can use ARHorizontalFlipMode.Target if it annoys you.

../../_images/image_s1_82.png

In ARHorizontalFlipMode.Target mode, the camera image will be flipped in rendering, the target scale will be changed to do flip rendering. Camera projection matrix will not change.

../../_images/image_s1_91.png

ARSession.HorizontalFlipNormal and ARSession.HorizontalFlipFront can be modified at any time and it will take effect immediately.

../../_images/image_s1_10.gif