浏览代码

updated inspector and logic

changed name tracking to guid tracking, combined property drawer into custom editor, removed excessive features
/4.1
Shan Jiang 4 年前
当前提交
554ea55b
共有 8 个文件被更改,包括 1254 次插入179 次删除
  1. 31
      Assets/Scenes/ImageTracking/Multi Prefab - Image Tracking/Multi-Image Tracking.unity
  2. 201
      Assets/Scenes/ImageTracking/Multi Prefab - Image Tracking/MultiTrackedImageInfoManager.cs
  3. 8
      Assets/Scenes/ImageTracking/Prefabs/HatPrefab.meta
  4. 86
      Assets/Scenes/ImageTracking/Prefabs/HatPrefab/HatPrefab.prefab
  5. 7
      Assets/Scenes/ImageTracking/Prefabs/HatPrefab/HatPrefab.prefab.meta
  6. 990
      Assets/Scenes/ImageTracking/Prefabs/HatPrefab/VikingHelmet.fbx
  7. 110
      Assets/Scenes/ImageTracking/Prefabs/HatPrefab/VikingHelmet.fbx.meta

31
Assets/Scenes/ImageTracking/Multi Prefab - Image Tracking/Multi-Image Tracking.unity


- component: {fileID: 264295718}
- component: {fileID: 264295717}
- component: {fileID: 264295716}
- component: {fileID: 264295715}
m_Layer: 0
m_Name: AR Session Origin
m_TagString: Untagged

m_IsActive: 1
--- !u!114 &264295715
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 264295714}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 92dfcdbbdd0754f9fb947d3639ad91c4, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Images:
- m_Texture: {fileID: 2800000, guid: d1879707d69d24adfb421bde69c92c94, type: 3}
m_Name: One
m_Width: 0.1
- m_Texture: {fileID: 2800000, guid: 038b8a7b4862745aaadfd7c9f14e7bbd, type: 3}
m_Name: Two
m_Width: 0.1
--- !u!114 &264295716
MonoBehaviour:
m_ObjectHideFlags: 0

m_Script: {fileID: 11500000, guid: 467eefdf66a9b4c24b9d89f2f71b2ce9, type: 3}
m_Name:
m_EditorClassIdentifier:
m_WorldSpaceCanvasCamera: {fileID: 579846251}
m_DefaultTexture: {fileID: 10305, guid: 0000000000000000f000000000000000, type: 0}
- m_ImageName: Rafflesia
m_Prefab: {fileID: 6916502901855112170, guid: e22b43a8fcdab413bb4f52f5076f759e,
- m_Prefab: {fileID: 6916502901855112170, guid: e22b43a8fcdab413bb4f52f5076f759e,
- m_ImageName: Logo
m_Prefab: {fileID: 2804028924010200506, guid: 379785de5e39005469c875710d3cc5a7,
- m_Prefab: {fileID: 2804028924010200506, guid: 379785de5e39005469c875710d3cc5a7,
- m_ImageName: QRCode
m_Prefab: {fileID: 3312728602301253215, guid: 5d81b097707c58e4b949537763ba4bbe,
- m_Prefab: {fileID: 3279860958548870494, guid: 2584331523bd14e8898965d93034efdb,
type: 3}
m_ImageLibrary: {fileID: 11400000, guid: c86e375d7e7430442a1104e88fa21f21, type: 2}
--- !u!114 &264295717

201
Assets/Scenes/ImageTracking/Multi Prefab - Image Tracking/MultiTrackedImageInfoManager.cs


public class MultiTrackedImageInfoManager : MonoBehaviour
{
[SerializeField]
[Tooltip("The camera to set on the world space UI canvas for each instantiated image info.")]
Camera m_WorldSpaceCanvasCamera;
[Serializable]
/// The prefab has a world space UI canvas,
/// which requires a camera to function properly.
/// It has an image guid and a GameObject for prefab.
public Camera worldSpaceCanvasCamera
public struct NamedPrefab
get => m_WorldSpaceCanvasCamera;
set => m_WorldSpaceCanvasCamera = value;
}
Guid m_ImageGuid;
[SerializeField]
[Tooltip("If an image is detected but no source texture can be found, this texture is used instead.")]
Texture2D m_DefaultTexture;
public Guid imageGuid
{
get => m_ImageGuid;
}
/// <summary>
/// If an image is detected but no source texture can be found,
/// this texture is used instead.
/// </summary>
public Texture2D defaultTexture
{
get => m_DefaultTexture;
set => m_DefaultTexture = value;
}
[Serializable]
/// <summary>
/// It has a string for name and a GameObject for prefab.
/// </summary>
public struct NamedPrefab
{
[HideInInspector]
[SerializeField]
string m_ImageName;
public string imageName
{
get => m_ImageName;
set => m_ImageName = value;
}
public GameObject prefab
{

public NamedPrefab(string imageName, GameObject prefab)
public NamedPrefab(Guid imageGuid, GameObject prefab)
m_ImageName = imageName;
m_ImageGuid = imageGuid;
m_Prefab = prefab;
}
}

set => m_PrefabList = value;
}
Dictionary<string, GameObject> m_PrefabsDictionary = new Dictionary<string, GameObject>();
Dictionary<Guid, GameObject> m_PrefabsDictionary = new Dictionary<Guid, GameObject>();
[SerializeField, ReferenceImageLibraryChanged]
[SerializeField]
[Tooltip("Reference Image Library")]
XRReferenceImageLibrary m_ImageLibrary;

for (int i = 0; i < prefabList.Count; i++)
{
m_PrefabsDictionary.Add(prefabList[i].imageName, prefabList[i].prefab);
m_PrefabsDictionary.Add(ImageLibrary[i].guid, prefabList[i].prefab);
}
}

void UpdatePrefabList()
{
if (m_PrefabList != null && m_PrefabList.Count == m_ImageLibrary.count)
if (m_PrefabList == null)
for (int i = 0; i < m_PrefabList.Count; i++)
m_PrefabList = new List<NamedPrefab>();
for (int i = 0; i < m_ImageLibrary.count; i++)
var pref = m_PrefabList[i];
pref.imageName = m_ImageLibrary[i].name;
m_PrefabList[i] = pref;
m_PrefabList.Add(new NamedPrefab(m_ImageLibrary[i].guid, null));
m_PrefabList = new List<NamedPrefab>();
var tempList = new List<NamedPrefab>();
var pref = new NamedPrefab(m_ImageLibrary[i].name, null);
m_PrefabList.Add(pref);
var idx = m_PrefabList.FindIndex(item => item.imageGuid == m_ImageLibrary[i].guid);
tempList.Add(new NamedPrefab(m_ImageLibrary[i].guid, (idx != -1) ? m_PrefabList[idx].prefab : null));
m_PrefabList = tempList;
}
}
void AssignPrefab(ARTrackedImage trackedImage)
{
if (m_PrefabsDictionary.TryGetValue(trackedImage.referenceImage.name, out GameObject prefab)){
Instantiate(prefab, trackedImage.transform);
}
}
void UpdateInfo(ARTrackedImage trackedImage)
{
switch(trackedImage.referenceImage.name)
{
case "Rafflesia":
// Disable the visual plane if it is not being tracked
if (trackedImage.trackingState != TrackingState.None)
{
// The image extents is only valid when the image is being tracked
trackedImage.transform.localScale = new Vector3(trackedImage.size.x/2, trackedImage.size.x/2, trackedImage.size.x/2);
}
break;
case "QRCode":
// Set canvas camera
var canvas = trackedImage.GetComponentInChildren<Canvas>();
canvas.worldCamera = worldSpaceCanvasCamera;
// Update information about the tracked image
var text = canvas.GetComponentInChildren<Text>();
text.text = string.Format(
"{0}\ntrackingState: {1}\nGUID: {2}\nReference size: {3} cm\nDetected size: {4} cm",
trackedImage.referenceImage.name,
trackedImage.trackingState,
trackedImage.referenceImage.guid,
trackedImage.referenceImage.size * 100f,
trackedImage.size * 100f);
var planeParentGo = trackedImage.transform.GetChild(0).gameObject;
var planeGo = planeParentGo.transform.GetChild(0).gameObject;
// Disable the visual plane if it is not being tracked
if (trackedImage.trackingState != TrackingState.None)
{
planeGo.SetActive(true);
// The image extents is only valid when the image is being tracked
trackedImage.transform.localScale = new Vector3(trackedImage.size.x, 1f, trackedImage.size.y);
// Set the texture
var material = planeGo.GetComponentInChildren<MeshRenderer>().material;
material.mainTexture = (trackedImage.referenceImage.texture == null) ? defaultTexture : trackedImage.referenceImage.texture;
}
else
{
planeGo.SetActive(false);
}
break;
}
}
}
void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)

// Give the initial image a reasonable default scale
trackedImage.transform.localScale = new Vector3(0.02f, 0.02f, 0.02f);
trackedImage.transform.localScale = new Vector3(trackedImage.size.x/2, trackedImage.size.x/2, trackedImage.size.x/2);
}
foreach (var trackedImage in eventArgs.updated)
{
UpdateInfo(trackedImage);
void AssignPrefab(ARTrackedImage trackedImage)
{
if (m_PrefabsDictionary.TryGetValue(trackedImage.referenceImage.guid, out GameObject prefab)){
Instantiate(prefab, trackedImage.transform);
public class ReferenceImageLibraryChangedAttribute : PropertyAttribute { }
[CustomPropertyDrawer(typeof(ReferenceImageLibraryChangedAttribute))]
public class ReferenceImageLibraryChangedAttributePropertyDrawer : PropertyDrawer
[CustomEditor(typeof(MultiTrackedImageInfoManager))]
public class MultiTrackedImageInfoManagerInspector : Editor
{
List<XRReferenceImage> m_ReferenceImages = new List<XRReferenceImage>();

return false;
}
public override void OnInspectorGUI ()
{
var behaviour = serializedObject.targetObject as MultiTrackedImageInfoManager;
var library = serializedObject.FindProperty("m_ImageLibrary").objectReferenceValue as XRReferenceImageLibrary;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var behaviour = property.serializedObject.targetObject as MultiTrackedImageInfoManager;
var library = property.objectReferenceValue as XRReferenceImageLibrary;
serializedObject.Update();
GUI.enabled = false;
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Script"));
GUI.enabled = true;
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_ImageLibrary"));
ShowPrefabList(serializedObject.FindProperty("m_PrefabList"), library);
serializedObject.ApplyModifiedProperties();
EditorGUI.PropertyField(position, property);
if (EditorGUI.EndChangeCheck())
behaviour.OnLibraryChanged(library);

m_ReferenceImages.Add(referenceImage);
}
}
}
}
[CustomEditor(typeof(MultiTrackedImageInfoManager))]
public class MultiTrackedImageInfoManagerInspector : Editor {
public override void OnInspectorGUI () {
serializedObject.Update();
GUI.enabled = false;
SerializedProperty prop = serializedObject.FindProperty("m_Script");
EditorGUILayout.PropertyField(prop, true, new GUILayoutOption[0]);
GUI.enabled = true;
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_WorldSpaceCanvasCamera"), true);
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_DefaultTexture"), true);
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_ImageLibrary"), true);
Show(serializedObject.FindProperty("m_PrefabList"));
serializedObject.ApplyModifiedProperties();
public static void Show (SerializedProperty list) {
public static void ShowPrefabList (SerializedProperty list, XRReferenceImageLibrary library)
{
for (int i = 0; i < list.arraySize; i++) {
EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i));
if (list.isExpanded)
{
for (int i = 0; i < list.arraySize; i++) {
EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i).FindPropertyRelative("m_Prefab"), new GUIContent(library[i].name));
}
#endif
}
}

8
Assets/Scenes/ImageTracking/Prefabs/HatPrefab.meta


fileFormatVersion: 2
guid: 8c83a7bcc557e407e80ebe216e48aba2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

86
Assets/Scenes/ImageTracking/Prefabs/HatPrefab/HatPrefab.prefab


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3279860958548870494
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3279860958549105022}
- component: {fileID: 3279860958545680734}
- component: {fileID: 3279860958546680734}
m_Layer: 0
m_Name: VikingHelmet
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3279860958549105022
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3279860958548870494}
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &3279860958545680734
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3279860958548870494}
m_Mesh: {fileID: 4300002, guid: a20ea7771cebbda4696ef82ef45481a0, type: 3}
--- !u!23 &3279860958546680734
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3279860958548870494}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100012, guid: a20ea7771cebbda4696ef82ef45481a0, type: 3}
- {fileID: 2100024, guid: a20ea7771cebbda4696ef82ef45481a0, type: 3}
- {fileID: 2100016, guid: a20ea7771cebbda4696ef82ef45481a0, type: 3}
- {fileID: 2100018, guid: a20ea7771cebbda4696ef82ef45481a0, type: 3}
- {fileID: 2100020, guid: a20ea7771cebbda4696ef82ef45481a0, type: 3}
- {fileID: 2100022, guid: a20ea7771cebbda4696ef82ef45481a0, type: 3}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0

7
Assets/Scenes/ImageTracking/Prefabs/HatPrefab/HatPrefab.prefab.meta


fileFormatVersion: 2
guid: 2584331523bd14e8898965d93034efdb
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

990
Assets/Scenes/ImageTracking/Prefabs/HatPrefab/VikingHelmet.fbx
文件差异内容过多而无法显示
查看文件

110
Assets/Scenes/ImageTracking/Prefabs/HatPrefab/VikingHelmet.fbx.meta


fileFormatVersion: 2
guid: a20ea7771cebbda4696ef82ef45481a0
ModelImporter:
serializedVersion: 23
fileIDToRecycleName:
100000: //RootNode
400000: //RootNode
2100000: 01 - Default
2100002: 07 - Default
2100004: 02 - Default
2100006: 03 - Default
2100008: 05 - Default
2100010: 04 - Default
2100012: 01 - Default.010
2100014: 07 - Default.001
2100016: 02 - Default.005
2100018: 03 - Default.008
2100020: 05 - Default.004
2100022: 04 - Default.005
2100024: 07 - Default.002
2300000: //RootNode
3300000: //RootNode
4300000: cap-9
4300002: VikingHelmet
externalObjects: {}
materials:
importMaterials: 1
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 1
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
optimizeMeshForGPU: 1
keepQuads: 0
weldVertices: 1
preserveHierarchy: 0
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVPackMargin: 4
useFileScale: 1
previousCalculatedGlobalScale: 1
hasPreviousCalculatedGlobalScale: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
importAnimation: 1
copyAvatar: 0
humanDescription:
serializedVersion: 2
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
animationType: 0
humanoidOversampling: 1
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存