your question is quite broad, I will try to give my contribution to some aspects of it:
first, I would start from the UserDefinedTarget sample and make the necessary changes to that;
second, you will need to enable the support of multiple simultaneous targets in your view; this can be done by increasing the Max Simultaneous Image Targets parameter in the QCARBehaviour (which is by default set to 1... so you need to set it set it to 2 or more); you can do that via the Unity Inspector in the Editor
third, if you look at the code in UserDefinedTargetEventHandler.cs, you will find a method called OnNewTrackableSource, which is called whenever a new User Defined Target is created; in that method, you can adjust the code so to add your custom 3D model as a child of the created ImageTarget; I show here below a simple example of that, which creates a simple Cube object and attach it to the target:
public void OnNewTrackableSource(TrackableSource trackableSource)
// deactivates the dataset first
// Destroy the oldest target if the dataset is full or the dataset
// already contains five user-defined targets.
if (mBuiltDataSet.HasReachedTrackableLimit() || mBuiltDataSet.GetTrackables().Count() >= 5)
IEnumerable<Trackable> trackables = mBuiltDataSet.GetTrackables();
Trackable oldest = null;
foreach (Trackable trackable in trackables)
if (oldest == null || trackable.ID < oldest.ID)
oldest = trackable;
if (oldest != null)
Debug.Log("Destroying oldest trackable in UDT dataset: " + oldest.Name);
// get predefined trackable and instantiate it
ImageTargetBehaviour imageTargetCopy = (ImageTargetBehaviour)Instantiate(ImageTargetTemplate);
// NEW CODE
// Disable predefined game object
imageTargetCopy.gameObject.active = false;
// Create a custom game object (for instance a cube)
// and attach it as child of the ImageTarget
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = "mycube";
cube.transform.parent = imageTargetCopy.transform;
cube.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f);
cube.transform.localPosition = new Vector3(0,0,0);
cube.transform.localRotation = Quaternion.identity;
cube.active = true;
Then, instead of creating a simple Cube object like in my sample code snippet, you can of course instantiate any custom Prefab of your desired 3D model.
Once you have done that, each newly created target will be kept in memory togetehr with its associated 3D model, as you defined it above, and so whenever one of those targets is detected again in the view, its associated augementation will show up consistently.
I hope this can help you to find your way in this project development.