This commit is contained in:
2019-01-14 15:32:56 +01:00
76 changed files with 5876 additions and 661 deletions

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 4e7d9a07cc3f02a41a575406e7230846
timeCreated: 1466788421
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 9a6f8c7c1ea72ce46831c5e1b6150d0c
timeCreated: 1466790933
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -479,7 +479,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_IgnoreLayout: 0
m_MinWidth: 0.5
m_MinWidth: 0.85
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: -1
@@ -546,7 +546,7 @@ MonoBehaviour:
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 2
m_HorizontalFit: 1
m_VerticalFit: 2
--- !u!222 &222375422432509192
CanvasRenderer:

View File

@@ -289,7 +289,7 @@ GameObject:
m_IsActive: 1
--- !u!1 &1461557036225360
GameObject:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
@@ -556,7 +556,7 @@ Transform:
- {fileID: 4802536742996532}
- {fileID: 4501641520781714}
m_Father: {fileID: 224804495073354866}
m_RootOrder: 4
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!4 &4501641520781714
Transform:
@@ -777,6 +777,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
DetailsPanel: {fileID: 114451700018395534}
ProjectionEffect: {fileID: 114717549802739924}
Crosshairs: {fileID: 1466316426385876}
--- !u!114 &114116594606330924
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -2222,7 +2223,7 @@ RectTransform:
- {fileID: 224757765789199188}
- {fileID: 224017865803686938}
m_Father: {fileID: 224804495073354866}
m_RootOrder: 3
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -2370,8 +2371,9 @@ RectTransform:
- {fileID: 224781237586130416}
- {fileID: 224060988043194314}
- {fileID: 224272151730405692}
- {fileID: 224954540062687134}
m_Father: {fileID: 224804495073354866}
m_RootOrder: 2
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -2485,7 +2487,6 @@ RectTransform:
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 224632685815868688}
- {fileID: 224954540062687134}
- {fileID: 224620536568054620}
- {fileID: 224250538007241578}
- {fileID: 4112130633259944}
@@ -2638,8 +2639,8 @@ RectTransform:
m_Children:
- {fileID: 224567183914418614}
- {fileID: 224216194665817218}
m_Father: {fileID: 224804495073354866}
m_RootOrder: 1
m_Father: {fileID: 224620536568054620}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0.5}
m_AnchorMax: {x: 1, y: 0.5}

View File

@@ -913,8 +913,8 @@ MonoBehaviour:
m_TargetGraphic: {fileID: 114224566756848850}
m_HandleRect: {fileID: 224135889778237342}
m_Direction: 2
m_Value: 0.9999998
m_Size: 0.5452254
m_Value: 0.50000024
m_Size: 0.5452256
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
@@ -1343,7 +1343,7 @@ MonoBehaviour:
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 2100000, guid: 184173fb9a2399341882a894edcac032, type: 2}
m_Material: {fileID: 2100000, guid: a5b7496cf6d1ca34bab1a076f7b545e0, type: 2}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
@@ -1579,7 +1579,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -195.90994}
m_AnchoredPosition: {x: 0, y: -0.000076293945}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224254431283456606

View File

@@ -45,6 +45,23 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1093947357135468
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224330316150687214}
- component: {fileID: 222536103881524360}
- component: {fileID: 114428313277484686}
m_Layer: 0
m_Name: Icon
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1123889251050150
GameObject:
m_ObjectHideFlags: 1
@@ -56,6 +73,7 @@ GameObject:
- component: {fileID: 222257107596212176}
- component: {fileID: 114703351711471558}
- component: {fileID: 114099535585905582}
- component: {fileID: 114450829088306680}
m_Layer: 5
m_Name: TextMeshPro Text
m_TagString: Untagged
@@ -128,7 +146,7 @@ GameObject:
- component: {fileID: 222516432528614952}
- component: {fileID: 114312292318207176}
m_Layer: 5
m_Name: ButtonLanguage
m_Name: ButtonUpdate
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -180,6 +198,7 @@ GameObject:
- component: {fileID: 222236235550470454}
- component: {fileID: 114304727189119928}
- component: {fileID: 114761951126762250}
- component: {fileID: 114259177279469450}
m_Layer: 5
m_Name: TextMeshPro Text
m_TagString: Untagged
@@ -238,6 +257,25 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1559326554126414
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224403095676770094}
- component: {fileID: 222736219676448006}
- component: {fileID: 114575509895372660}
- component: {fileID: 114834531991525614}
- component: {fileID: 114855165548587684}
m_Layer: 5
m_Name: TextMeshPro Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1566260761276548
GameObject:
m_ObjectHideFlags: 1
@@ -249,6 +287,7 @@ GameObject:
- component: {fileID: 222430445161218842}
- component: {fileID: 114962239977612638}
- component: {fileID: 114191467112603124}
- component: {fileID: 114258570651376336}
m_Layer: 5
m_Name: TextMeshPro Text
m_TagString: Untagged
@@ -289,6 +328,23 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1613888947816932
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224898673201446374}
- component: {fileID: 222151895407047394}
- component: {fileID: 114021329305057850}
m_Layer: 5
m_Name: ButtonLanguage
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1622699956602756
GameObject:
m_ObjectHideFlags: 1
@@ -300,6 +356,7 @@ GameObject:
- component: {fileID: 222686667508429160}
- component: {fileID: 114993845510651576}
- component: {fileID: 114386162478351322}
- component: {fileID: 114567690225261020}
m_Layer: 5
m_Name: TextMeshPro Text
m_TagString: Untagged
@@ -318,6 +375,7 @@ GameObject:
- component: {fileID: 222633703844647490}
- component: {fileID: 114160009348696074}
- component: {fileID: 114427529426144796}
- component: {fileID: 114869981639449470}
m_Layer: 5
m_Name: TextMeshPro Text
m_TagString: Untagged
@@ -325,6 +383,24 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1733985940025502
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224068246739610406}
- component: {fileID: 222218005056313502}
- component: {fileID: 114529575306895444}
- component: {fileID: 114883595898678426}
m_Layer: 5
m_Name: Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1822126980603004
GameObject:
m_ObjectHideFlags: 1
@@ -482,6 +558,25 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114021329305057850
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1613888947816932}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: -1
m_FlexibleWidth: 1
m_FlexibleHeight: 1
m_LayoutPriority: 1
--- !u!114 &114023377107792378
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -624,17 +719,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2e7e534f013c7074aaec3f25f856d317, type: 3}
m_Name:
m_EditorClassIdentifier:
MenuEntries:
- Token: t_menu_button_color
TextMesh: {fileID: 114304727189119928}
- Token: t_menu_button_language
TextMesh: {fileID: 114993845510651576}
- Token: t_menu_button_tutorial
TextMesh: {fileID: 114160009348696074}
- Token: t_menu_button_fontsize
TextMesh: {fileID: 114962239977612638}
- Token: t_menu_button_credits
TextMesh: {fileID: 114703351711471558}
--- !u!114 &114140955474629306
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -892,6 +976,30 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
SizeClass: 1
--- !u!114 &114258570651376336
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1566260761276548}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 104796bd5a7a2434bb835da75350ba3f, type: 3}
m_Name:
m_EditorClassIdentifier:
LocalizationToken: t_menu_button_fontsize
--- !u!114 &114259177279469450
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1453184506351326}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 104796bd5a7a2434bb835da75350ba3f, type: 3}
m_Name:
m_EditorClassIdentifier:
LocalizationToken: t_menu_button_color
--- !u!114 &114304727189119928
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -1126,6 +1234,45 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
SizeClass: 1
--- !u!114 &114428313277484686
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1093947357135468}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: c5442431c660fb04187df8dfe3e1818e, type: 3}
m_Type: 0
m_PreserveAspect: 1
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114450829088306680
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1123889251050150}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 104796bd5a7a2434bb835da75350ba3f, type: 3}
m_Name:
m_EditorClassIdentifier:
LocalizationToken: t_menu_button_credits
--- !u!114 &114481541986733408
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -1270,6 +1417,157 @@ MonoBehaviour:
m_FlexibleWidth: 1
m_FlexibleHeight: 1
m_LayoutPriority: 1
--- !u!114 &114529575306895444
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1733985940025502}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 2100000, guid: b49170becc957054782e78d161ecef43, type: 2}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 9fa74bcade8d1ab4d8c93a63ac2cf0f7, type: 3}
m_Type: 1
m_PreserveAspect: 1
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114567690225261020
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1622699956602756}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 104796bd5a7a2434bb835da75350ba3f, type: 3}
m_Name:
m_EditorClassIdentifier:
LocalizationToken: t_menu_button_update
--- !u!114 &114575509895372660
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1559326554126414}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_text: Sprache
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 715b80e429c437e40867928a4e1fc975, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 715b80e429c437e40867928a4e1fc975, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_outlineColor:
serializedVersion: 2
rgba: 4278190080
m_fontSize: 25
m_fontSizeBase: 25
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_textAlignment: 513
m_isAlignmentEnumConverted: 1
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_firstOverflowCharacterIndex: -1
m_linkedTextComponent: {fileID: 0}
m_isLinkedTextComponent: 0
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_ignoreRectMaskCulling: 0
m_ignoreCulling: 1
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_firstVisibleCharacter: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_textInfo:
textComponent: {fileID: 114575509895372660}
characterCount: 7
spriteCount: 0
spaceCount: 0
wordCount: 1
linkCount: 0
lineCount: 1
pageCount: 1
materialCount: 1
m_havePropertiesChanged: 1
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_spriteAnimator: {fileID: 0}
m_isInputParsingRequired: 1
m_inputSource: 0
m_hasFontAssetChanged: 0
m_subTextObjects:
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &114596666055262414
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -1337,7 +1635,7 @@ MonoBehaviour:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 114126113914499456}
m_MethodName: SwitchToLanguageSelectView
m_MethodName: SwitchToUpdaterView
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
@@ -1521,7 +1819,7 @@ MonoBehaviour:
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 16
m_Spacing: 12
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
@@ -1617,6 +1915,30 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
SizeClass: 1
--- !u!114 &114834531991525614
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1559326554126414}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 8b136c9157840904ba79e96d50f494bc, type: 3}
m_Name:
m_EditorClassIdentifier:
SizeClass: 1
--- !u!114 &114855165548587684
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1559326554126414}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 104796bd5a7a2434bb835da75350ba3f, type: 3}
m_Name:
m_EditorClassIdentifier:
LocalizationToken: t_menu_button_language
--- !u!114 &114861247372160662
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -1652,6 +1974,70 @@ MonoBehaviour:
m_FlexibleWidth: 1
m_FlexibleHeight: 1
m_LayoutPriority: 1
--- !u!114 &114869981639449470
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1663770969281230}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 104796bd5a7a2434bb835da75350ba3f, type: 3}
m_Name:
m_EditorClassIdentifier:
LocalizationToken: t_menu_button_tutorial
--- !u!114 &114883595898678426
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1733985940025502}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 114529575306895444}
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 114126113914499456}
m_MethodName: SwitchToLanguageSelectView
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument: de
m_BoolArgument: 0
m_CallState: 2
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!114 &114891783888147370
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -1725,7 +2111,7 @@ MonoBehaviour:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: c5442431c660fb04187df8dfe3e1818e, type: 3}
m_Sprite: {fileID: 21300000, guid: 1957047573239854895a9ba2a69c12c8, type: 3}
m_Type: 0
m_PreserveAspect: 1
m_FillCenter: 1
@@ -1891,7 +2277,7 @@ MonoBehaviour:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_text: Sprache
m_text: Update
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 715b80e429c437e40867928a4e1fc975, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 715b80e429c437e40867928a4e1fc975, type: 2}
@@ -1958,7 +2344,7 @@ MonoBehaviour:
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_textInfo:
textComponent: {fileID: 114993845510651576}
characterCount: 7
characterCount: 6
spriteCount: 0
spaceCount: 0
wordCount: 1
@@ -1996,12 +2382,24 @@ CanvasRenderer:
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1008485180534478}
--- !u!222 &222151895407047394
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1613888947816932}
--- !u!222 &222153422494546844
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1042628125586808}
--- !u!222 &222218005056313502
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1733985940025502}
--- !u!222 &222236235550470454
CanvasRenderer:
m_ObjectHideFlags: 1
@@ -2050,6 +2448,12 @@ CanvasRenderer:
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1368374326299624}
--- !u!222 &222536103881524360
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1093947357135468}
--- !u!222 &222547030763414376
CanvasRenderer:
m_ObjectHideFlags: 1
@@ -2092,6 +2496,12 @@ CanvasRenderer:
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1964565221985070}
--- !u!222 &222736219676448006
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1559326554126414}
--- !u!222 &222755655188159418
CanvasRenderer:
m_ObjectHideFlags: 1
@@ -2162,19 +2572,37 @@ RectTransform:
m_GameObject: {fileID: 1368374326299624}
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_LocalScale: {x: 0.99999994, y: 0.99999994, z: 0.99999994}
m_Children:
- {fileID: 224261216574473414}
- {fileID: 224128338965173062}
- {fileID: 224480372276515010}
m_Father: {fileID: 224844527725026830}
m_RootOrder: 1
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224068246739610406
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1733985940025502}
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: 224898673201446374}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224082682870789258
RectTransform:
m_ObjectHideFlags: 1
@@ -2305,6 +2733,24 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224330316150687214
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1093947357135468}
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: 0}
m_Children: []
m_Father: {fileID: 224898673201446374}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 35, y: 0}
m_SizeDelta: {x: 50, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224360344833465170
RectTransform:
m_ObjectHideFlags: 1
@@ -2323,6 +2769,24 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 4, y: 4}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224403095676770094
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1559326554126414}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -1}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224898673201446374}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 35, y: 0}
m_SizeDelta: {x: -70, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224411256630293298
RectTransform:
m_ObjectHideFlags: 1
@@ -2502,9 +2966,10 @@ RectTransform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224696479351442688}
- {fileID: 224045114038880592}
- {fileID: 224898673201446374}
- {fileID: 224750414370576322}
- {fileID: 224877065014001232}
- {fileID: 224045114038880592}
- {fileID: 224969683658863468}
m_Father: {fileID: 224214707840811800}
m_RootOrder: 2
@@ -2512,7 +2977,7 @@ RectTransform:
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 0.5, y: 0}
m_AnchoredPosition: {x: 0, y: 300}
m_SizeDelta: {x: 400, y: 350}
m_SizeDelta: {x: 400, y: 420}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224877065014001232
RectTransform:
@@ -2573,6 +3038,27 @@ RectTransform:
m_AnchoredPosition: {x: -75, y: -75}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224898673201446374
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1613888947816932}
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:
- {fileID: 224068246739610406}
- {fileID: 224403095676770094}
- {fileID: 224330316150687214}
m_Father: {fileID: 224844527725026830}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224899198735757046
RectTransform:
m_ObjectHideFlags: 1
@@ -2641,7 +3127,7 @@ RectTransform:
- {fileID: 224562788853542486}
- {fileID: 224878574598484460}
m_Father: {fileID: 224844527725026830}
m_RootOrder: 4
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}

View File

@@ -379,7 +379,7 @@ GameObject:
m_IsActive: 1
--- !u!1 &1792505052625370
GameObject:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
@@ -606,6 +606,7 @@ MonoBehaviour:
reticuleHighlight: {fileID: 114430674035238108}
menuHighlight: {fileID: 114094662748965206}
selectHighlight: {fileID: 114425245405885838}
Crosshairs: {fileID: 1991900300183792}
--- !u!114 &114339554770605862
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -1704,8 +1705,9 @@ RectTransform:
- {fileID: 224257449048418606}
- {fileID: 224385246327759096}
- {fileID: 224882127646750572}
- {fileID: 224543001454646402}
m_Father: {fileID: 224386065082169650}
m_RootOrder: 4
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -1743,7 +1745,6 @@ RectTransform:
- {fileID: 224893231122565744}
- {fileID: 224773095307896718}
- {fileID: 224336834733934388}
- {fileID: 224543001454646402}
- {fileID: 224374825834825260}
m_Father: {fileID: 0}
m_RootOrder: 0
@@ -1802,8 +1803,8 @@ RectTransform:
- {fileID: 224020227865350692}
- {fileID: 224770383868184822}
- {fileID: 224845810070959288}
m_Father: {fileID: 224386065082169650}
m_RootOrder: 3
m_Father: {fileID: 224374825834825260}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0.5}
m_AnchorMax: {x: 1, y: 0.5}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ab149fbc9d7dc3d40ac85af2e411788a
timeCreated: 1546010792
licenseType: Free
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<colors>
<color name="t_color_name_light_blue">
<base color="#03A9F4"/>
<light color="#E1F5FE"/>
<dark color="#0277BD"/>
<transparency value="0.75"/>
</color>
<color name="t_color_name_light_green">
<base color="#8BC34A"/>
<light color="#F1F8E9"/>
<dark color="#558B2F"/>
<transparency value="0.75"/>
</color>
<color name="t_color_name_red">
<base color="#F44336"/>
<light color="#FFEBEE"/>
<dark color="#C62828"/>
<transparency value="0.75"/>
</color>
</colors>

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 39366101fc02f3b47a0df7508aa6ef1a
timeCreated: 1545484620
licenseType: Free
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,9 +1,10 @@
fileFormatVersion: 2
guid: 76f828f47ce26cc43991113c6a39dbbf
guid: 2bd6ad883b515814d9c8b932f563372d
folderAsset: yes
timeCreated: 1466010535
licenseType: Store
timeCreated: 1545490981
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<localization>
<language key="de" name="Deutsch" flagPath="localization/flag_de"/>
<language key="en" name="English" flagPath="localization/flag_uk_us" default="true"/>
<entry name="t_color_name_light_blue">
<text lang="de" type="inline" value="Hellblau"/>
<text lang="en" type="inline" value="Light Blue"/>
</entry>
<entry name="t_color_name_light_green">
<text lang="de" type="inline" value="Hellgrün"/>
<text lang="en" type="inline" value="Light Green"/>
</entry>
<entry name="t_color_name_red">
<text lang="de" type="inline" value="Rot"/>
<text lang="en" type="inline" value="Red"/>
</entry>
<entry name="t_tutorial_reticule">
<text lang="de" type="inline" value="Exponat anvisieren"/>
<text lang="en" type="inline" value="Aim at exhibit"/>
</entry>
<entry name="t_tutorial_settings">
<text lang="de" type="inline" value="Einstellungen öffnen"/>
<text lang="en" type="inline" value="Open settings"/>
</entry>
<entry name="t_tutorial_select">
<text lang="de" type="inline" value="Exponat auswählen"/>
<text lang="en" type="inline" value="Select exhibit"/>
</entry>
<entry name="t_menu_button_color">
<text lang="de" type="inline" value="Farbe"/>
<text lang="en" type="inline" value="Color"/>
</entry>
<entry name="t_menu_button_language">
<text lang="de" type="inline" value="Sprache"/>
<text lang="en" type="inline" value="Language"/>
</entry>
<entry name="t_menu_button_fontsize">
<text lang="de" type="inline" value="Textgröße"/>
<text lang="en" type="inline" value="Font size"/>
</entry>
<entry name="t_menu_button_tutorial">
<text lang="de" type="inline" value="Anleitung"/>
<text lang="en" type="inline" value="Tutorial"/>
</entry>
<entry name="t_menu_button_credits">
<text lang="de" type="inline" value="Credits"/>
<text lang="en" type="inline" value="Credits"/>
</entry>
<entry name="t_menu_button_update">
<text lang="de" type="inline" value="Update"/>
<text lang="en" type="inline" value="Update"/>
</entry>
<entry name="t_languageselect_Default">
<text lang="de" type="inline" value="Standard"/>
<text lang="en" type="inline" value="Default"/>
</entry>
<entry name="t_languageselect_Large">
<text lang="de" type="inline" value="Groß"/>
<text lang="en" type="inline" value="Large"/>
</entry>
<entry name="t_updater_header">
<text lang="de" type="inline" value="Updates"/>
<text lang="en" type="inline" value="Updates"/>
</entry>
<entry name="t_updater_updating">
<text lang="de" type="inline" value="Es wurden Inhaltsupdates gefunden. Bitte warten sie, bis diese heruntergeladen wurden."/>
<text lang="en" type="inline" value="Updates have been found. Please wait until they finished downloading."/>
</entry>
<entry name="t_updater_confirmUpdatesDialog">
<text lang="de" type="inline" value="Es wurden Inhaltsupdates gefunden. Hierbei handelt es sich um mehrere Megabytes an Daten. Wollen Sie diese mit mobilen Daten herunterladen?"/>
<text lang="en" type="inline" value="Updates have been found. This is several Megabytes of data. Do you want to download these using mobile data?"/>
</entry>
<entry name="t_updater_confirmUpdates">
<text lang="de" type="inline" value="Trotzdem herunterladen"/>
<text lang="en" type="inline" value="Download anyway"/>
</entry>
<entry name="t_updater_completed">
<text lang="de" type="inline" value="Updates heruntergeladen."/>
<text lang="en" type="inline" value="Updates downloaded."/>
</entry>
<entry name="t_updater_applyUpdates">
<text lang="de" type="inline" value="Updates anwenden"/>
<text lang="en" type="inline" value="Apply updates"/>
</entry>
<entry name="t_updater_failed">
<text lang="de" type="inline" value="Beim Herunterladen des Updates ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut."/>
<text lang="en" type="inline" value="An error occurred during the update. Please try again later."/>
</entry>
<entry name="t_updater_retry">
<text lang="de" type="inline" value="Erneut versuchen"/>
<text lang="en" type="inline" value="Try again"/>
</entry>
<entry name="t_updater_alreadyUpToDate">
<text lang="de" type="inline" value="Die Anwendungsinhalte sind auf dem neuesten Stand."/>
<text lang="en" type="inline" value="The application content is up to date."/>
</entry>
<entry name="t_updater_alreadyUpToDateOK">
<text lang="de" type="inline" value="OK"/>
<text lang="en" type="inline" value="OK"/>
</entry>
<entry name="t_updater_noInternet">
<text lang="de" type="inline" value="Die Anwendung verfügt aktuell über keinen Internetzugriff. Stellen Sie sicher, dass Ihr Gerät über eine Internetverbindung verfügt und starten Sie die App neu."/>
<text lang="en" type="inline" value="The application currently has no Internet access. Make sure your device has an internet connection and restart the app."/>
</entry>
<entry name="t_credits">
<text lang="de" type="file" value="localization/t_credits_de"/>
<text lang="en" type="file" value="localization/t_credits_en"/>
</entry>
<entry name="t_credits_version">
<text lang="de" type="file" value="localization/t_credits_version"/>
<text lang="en" type="file" value="localization/t_credits_version"/>
</entry>
</localization>

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 4652cedf37d935e46a26d6f44630a456
timeCreated: 1545484620
licenseType: Free
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 376 B

View File

@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: fdb1754a808f9d445872e8ccd06f961f
timeCreated: 1497822839
guid: 25491ea9c6e1b7244b2d9cacdd154d8f
timeCreated: 1545490981
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
@@ -31,27 +31,27 @@ TextureImporter:
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
filterMode: -1
aniso: -1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 1
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 8
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
@@ -77,6 +77,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: 35b33f8eeb1cca541b1c6fc0c236fa0a
timeCreated: 1497822838
guid: 2c05577f49b120f4b8ee7b9733af5ad2
timeCreated: 1545490982
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
@@ -31,27 +31,27 @@ TextureImporter:
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
filterMode: -1
aniso: -1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 1
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 8
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
@@ -77,6 +77,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: 538cea92ef30ede40a354bae3e7eaeda
timeCreated: 1497822838
guid: c64690fd7ce0e5c4a8061babcfa165a6
timeCreated: 1545490982
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
@@ -31,27 +31,27 @@ TextureImporter:
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
filterMode: -1
aniso: -1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 1
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 8
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
@@ -77,6 +77,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0

View File

@@ -0,0 +1,17 @@
Diese Anwendung wurde als Projektarbeit im 6. Semester von Studenten der Hochschule für angewandte Wissenschaften Würzburg-Schweinfurt erstellt.
Entwicklerteam:
René Ziegler
Matthias Kleinhenz
Alexander Frühwald
Betreuer FHWS:
Prof. Dr. Frank Deinzer
Toni Fetzer
Besonderer Dank für die Aufnahme der 3D-Scans geht an Frank Ebner.
Verantwortlicher im Auftrag des Reichstadtmuseums in Rothenburg:
Dr. Hellmuth Möhring
Die in dieser App verwendeten Icons sind Teil der Google Material Icon Library, abrufbar unter https://material.io/icons/ und sind lizenziert unter der Apache License Version 2.0.

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5e33d40fce62ea349af0e5cb81a4058b
timeCreated: 1545490982
licenseType: Free
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
This app has been created as a project by 6th semester students at the University of Applied Sciences Wurzburg-Schweinfurt.
Developer Team:
René Ziegler
Matthias Kleinhenz
Alexander Frühwald
Project Monitoring FHWS:
Prof. Dr. Frank Deinzer
Toni Fetzer
Special thanks for taking the 3D-Scans go to Frank Ebner.
Responsible on behalf of the Reichstadtmuseum of Rothenburg:
Dr. Hellmuth Moehring
Icons used in this App are part of the Google Material Icon Library, available at https://material.io/icons/ and are licensed under the Apache License Version 2.0.

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7e87879c9f3136b4a8527b183fd599c8
timeCreated: 1545490982
licenseType: Free
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1 @@
Version RC3 - 05.10.2017

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: fe180226794a33a4fb817bbc80b657c6
timeCreated: 1545490982
licenseType: Free
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -79,10 +79,6 @@ namespace RothenburgAR
Assert.NotNull(testExhibit.Description);
Assert.IsTrue(testExhibit.Title.HasValue);
Assert.AreEqual(40f, testExhibit.Title.Value.FontSize);
Assert.AreEqual(45f, testExhibit.Title.Value.BoxHeight);
Assert.AreEqual(200f, testExhibit.Title.Value.BoxWidth);
}
}
}

View File

@@ -2,6 +2,7 @@
using RothenburgAR.Exhibition;
using RothenburgAR.PointOfInterest;
using RothenburgAR.UI;
using RothenburgAR.Updater;
using UnityEngine;
using Vuforia;
@@ -11,10 +12,20 @@ namespace RothenburgAR
{
public Camera UICamera;
public Camera UIObjectCamera;
private LogFileHandler logFileHandler;
// Use this for initialization
void Start()
{
#if !UNITY_EDITOR
logFileHandler = new LogFileHandler();
#else
Debug.Log("Found Unity Editor; Disabled logging into file.");
#endif
//OBJLoader.defaultShader = Shader.Find("Standard (Specular setup)")
OBJLoader.defaultShader = Shader.Find("Standard");
OBJLoader.defaultMaterial = new Material(OBJLoader.defaultShader);
LanguageManager.Instance.LoadLanguagesFromXml();
UIColorSchemeManager.Instance.Initialize();
@@ -23,14 +34,12 @@ namespace RothenburgAR
UIManager.Instance.Initialize();
UIManager.Instance.UICamera = UICamera;
UIManager.Instance.UIObjectCamera = UIObjectCamera;
UIManager.Instance.InitStartView();
StartCoroutine(UIManager.Instance.InitStartView());
InputManager.Instance.Initialize();
var init = DisplayManager.Instance;
//OBJLoader.defaultShader = Shader.Find("Standard (Specular setup)")
OBJLoader.defaultShader = Shader.Find("Standard");
OBJLoader.defaultMaterial = new Material(OBJLoader.defaultShader);
var initDisplayManagerSingleton = DisplayManager.Instance;
var initUpdaterSingleton = UpdateManager.Instance;
}
void InitializeData()
@@ -54,5 +63,10 @@ namespace RothenburgAR
" Exhibitions of Path " + currentPaths + " of " + maxPaths + " paths.</color>");
});
}
private void OnDestroy()
{
VuforiaARController.Instance.UnregisterVuforiaInitializedCallback(InitializeData);
}
}
}

View File

@@ -40,6 +40,11 @@ namespace RothenburgAR.Common
get { return Directory.Exists(ExhibitionPath); }
}
public static string SettingsFilePath
{
get { return Path.Combine(DataPath, "settings.json"); }
}
public static string GetXmlPathFromDirectoryPath(string poiDirectory)
{
string directoryName = new DirectoryInfo(poiDirectory).Name;

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using RothenburgAR.UI;
using UnityEngine;
namespace RothenburgAR.Common
{
@@ -32,7 +33,7 @@ namespace RothenburgAR.Common
{
if (_instance == null)
{
_instance = (T) FindObjectOfType(typeof(T));
_instance = (T)FindObjectOfType(typeof(T));
if (FindObjectsOfType(typeof(T)).Length > 1)
{
@@ -68,6 +69,12 @@ namespace RothenburgAR.Common
private static bool applicationIsQuitting = false;
public virtual void ResetInstance()
{
Destroy(_instance.gameObject);
_instance = null;
}
/// <summary>
/// When Unity quits, it destroys objects in a random order.
/// In principle, a Singleton is only destroyed when application quits.
@@ -77,6 +84,10 @@ namespace RothenburgAR.Common
/// So, this was made to be sure we're not creating that buggy ghost object.
/// </summary>
public void OnDestroy()
{
}
private void OnApplicationQuit()
{
applicationIsQuitting = true;
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEngine;
namespace RothenburgAR.Common
{
@@ -76,7 +77,18 @@ namespace RothenburgAR.Common
TextEntryType type = TextElement.GetTextEntryTypeFromString(typeStr);
var valueStr = xmlNode.Attributes["value"].Value;
if (type == TextEntryType.File)
valueStr = Path.Combine(basePath, valueStr);
{
var file = Resources.Load<TextAsset>(valueStr);
if (file != null)
{
valueStr = file.text;
type = TextEntryType.Inline;
}
else
{
valueStr = Path.Combine(basePath, valueStr);
}
}
textElement.AddTextElement(langCode, type, valueStr);
}
return textElement;

View File

@@ -40,13 +40,16 @@ namespace RothenburgAR.Exhibition
TitleBehaviour.Exhibit = this;
}
//TODO remove title rotation
if (newTitle.Rotation.HasValue)
TitleBehaviour.transform.localEulerAngles = newTitle.Rotation.Value + new Vector3(90, 0, 0);
TitleBehaviour.transform.localEulerAngles = new Vector3(90, 0, 0);
//TODO remove title position and calculate on the fly? if tracker is on a wall, below is best. if it sits on the ground, what?
//TODO remove title position property and calculate on the fly?
// if tracker is on a wall, below is best. if it sits on the ground, what?
// leave property alive for now and set title slightly below the bottom border for now
if (newTitle.Position.HasValue)
TitleBehaviour.transform.localPosition = newTitle.Position.Value;
else
TitleBehaviour.transform.localPosition = new Vector3(0, .05f, -.52f);
TitleBehaviour.DataText = newTitle.Text;
}

View File

@@ -16,6 +16,8 @@ namespace RothenburgAR.Exhibition
{
if (!Directory.Exists(exhibitionDirectory))
return false;
if (!File.Exists(Path.Combine(exhibitionDirectory, "version.txt")))
return false;
if (!File.Exists(Path.Combine(exhibitionDirectory, "tracker.xml")))
return false;
if (!File.Exists(Path.Combine(exhibitionDirectory, "tracker.dat")))
@@ -86,21 +88,9 @@ namespace RothenburgAR.Exhibition
}
newExhibit.Description = exhibitDescr;
//TODO calculate sizes dynamically and remove these default values
var position = new Vector3(0, .1f, -.52f);
var rotation = Vector3.zero;
var fontSize = .7f;
var boxHeight = .25f;
var boxWidth = .75f;
PreloadedExhibitTitle preTitle = new PreloadedExhibitTitle
{
Text = exhibitTitle,
Position = position,
Rotation = rotation,
FontSize = fontSize,
BoxWidth = boxWidth,
BoxHeight = boxHeight
Text = exhibitTitle
};
newExhibit.Title = preTitle;

View File

@@ -93,11 +93,7 @@ namespace RothenburgAR.Exhibition
PreloadedExhibitTitle preTitle = new PreloadedExhibitTitle
{
Text = exhibitTitle,
Position = GetVector3FromXmlNode(exhibitNode.SelectSingleNode("title/position")),
Rotation = GetVector3FromXmlNode(exhibitNode.SelectSingleNode("title/rotation")),
FontSize = fontSize ?? 20,
BoxWidth = boxWidth ?? 200,
BoxHeight = boxHeight ?? 25
Position = GetVector3FromXmlNode(exhibitNode.SelectSingleNode("title/position"))
};
newExhibit.Title = preTitle;
}

View File

@@ -31,11 +31,6 @@ namespace RothenburgAR.Exhibition
public struct PreloadedExhibitTitle
{
public TextElement Text { get; set; }
public Vector3? Rotation { get; set; }
public Vector3? Position { get; set; }
public Vector2? Dimensions { get; set; }
public float FontSize { get; set; }
public float BoxHeight { get; set; }
public float BoxWidth { get; set; }
}
}

View File

@@ -86,21 +86,21 @@ namespace RothenburgAR
public void LoadLanguagesFromXml()
{
var xmlFilePath = Path.Combine(PathHelper.DataPath, "localization.xml");
var file = Resources.Load<TextAsset>("localization");
Debug.Log("Loading languages from Resources");
Debug.Log("Loading languages from '" + xmlFilePath + "'");
if (!File.Exists(xmlFilePath))
throw new FileNotFoundException(xmlFilePath);
if (file == null)
throw new FileNotFoundException("Localization file Assets/Resources/localization.xml not found");
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
doc.LoadXml(file.text);
var languageNodes = doc.SelectNodes("//language");
foreach (XmlNode languageNode in languageNodes)
{
var langKey = languageNode.Attributes["key"].Value;
var langName = languageNode.Attributes["name"].Value;
var langFlagPath = Path.Combine(PathHelper.DataPath, languageNode.Attributes["flagPath"].Value);
var langFlagPath = languageNode.Attributes["flagPath"].Value;
AddLanguage(langKey, langName, langFlagPath);

View File

@@ -8,6 +8,12 @@ namespace RothenburgAR.UI
{
public DetailsPanelBehaviour DetailsPanel;
public ProjectionEffectBehaviour ProjectionEffect;
public GameObject Crosshairs;
public void Start()
{
Crosshairs.SetActive(InputManager.Instance.AllowCrosshairControls);
}
public void DisplayPoiDetails(PoiBehaviour poi, bool animated = true)
{

View File

@@ -35,5 +35,9 @@ namespace RothenburgAR.UI
{
UIManager.Instance.SwitchToView(ViewName.FontsizeSelectView);
}
public void SwitchToUpdaterView()
{
UIManager.Instance.SwitchToView(ViewName.UpdaterView);
}
}
}

View File

@@ -2,6 +2,7 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using RothenburgAR.Common;
namespace RothenburgAR.UI
{
@@ -11,6 +12,9 @@ namespace RothenburgAR.UI
void Start()
{
if (SettingsManager.Instance.Settings.ColorschemeID.HasValue && UIManager.Instance.StartingUp)
SwitchToFontsizeSelectView();
CreateColorSelectionCircles();
}
@@ -26,7 +30,11 @@ namespace RothenburgAR.UI
selectionCircle.GetComponentInChildren<Button>().onClick.AddListener(() =>
{
UIColorSchemeManager.Instance.SetUiColorScheme(id);
if (UIManager.Instance.StartingUp) SwitchToTutorialView();
SettingsManager.Instance.Settings.ColorschemeID = UIColorSchemeManager.Instance.CurrentColorSchemeID;
SettingsManager.Instance.PersistSettings();
if (UIManager.Instance.StartingUp) SwitchToFontsizeSelectView();
else SwitchToARView();
});
@@ -45,20 +53,5 @@ namespace RothenburgAR.UI
return selectionCircle;
}
private void AddSwitchViewEventListener(GameObject selectionCircle)
{
selectionCircle.GetComponentInChildren<Button>().onClick.AddListener(() =>
{
if (UIManager.Instance.StartingUp)
{
SwitchToTutorialView();
}
else
{
SwitchToARView();
}
});
}
}
}

View File

@@ -18,7 +18,10 @@ namespace RothenburgAR.UI
public readonly UnityEvent OnOrientationChange = new UnityEvent();
public ScreenOrientation ScreenOrientation;
private Vector2 resolution; // Current Resolution
public float ScreensizeInInches { get; set; }
private Vector2 lastKnownResolution; // Current Resolution
private ScreenOrientation orientation; // Current Screen Orientation
static void Init()
@@ -35,12 +38,16 @@ namespace RothenburgAR.UI
scaler.screenMatchMode = UnityEngine.UI.CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
scaler.matchWidthOrHeight = .5f;
instance.resolution = new Vector2(Screen.width, Screen.height);
instance.lastKnownResolution = new Vector2(Screen.width, Screen.height);
instance.orientation = Screen.orientation;
instance.ScreenOrientation = instance.resolution.x < instance.resolution.y
instance.ScreenOrientation = instance.lastKnownResolution.x < instance.lastKnownResolution.y
? ScreenOrientation.Portrait
: ScreenOrientation.Landscape;
// Screen diagonal in logical inches
instance.ScreensizeInInches = Mathf.Sqrt(Mathf.Pow(Screen.height, 2) + Mathf.Pow(Screen.width, 2)) / Screen.dpi;
Debug.Log("Screen Diagonal is approximately " + instance.ScreensizeInInches + " inches.");
}
private void Start()
@@ -53,12 +60,12 @@ namespace RothenburgAR.UI
private void OnRectTransformDimensionsChange()
{
if (orientation != Screen.orientation || !(resolution.x == Screen.width && resolution.y == Screen.height))
if (orientation != Screen.orientation || !(lastKnownResolution.x == Screen.width && lastKnownResolution.y == Screen.height))
{
orientation = Screen.orientation;
resolution = new Vector2(Screen.width, Screen.height);
ScreenOrientation = resolution.x < resolution.y
? ScreenOrientation.Portrait
lastKnownResolution = new Vector2(Screen.width, Screen.height);
ScreenOrientation = lastKnownResolution.x < lastKnownResolution.y
? ScreenOrientation.Portrait
: ScreenOrientation.Landscape;
OnOrientationChange.Invoke();

View File

@@ -1,4 +1,5 @@
using System;
using RothenburgAR.Common;
using System;
using System.IO;
using System.Linq;
using TMPro;
@@ -16,6 +17,9 @@ namespace RothenburgAR.UI
public void Start()
{
if (SettingsManager.Instance.Settings.Fontsize.HasValue && UIManager.Instance.StartingUp)
SwitchToTutorialView();
CreateLanguageSelectionFlags();
}
@@ -48,6 +52,9 @@ namespace RothenburgAR.UI
Debug.Log("Switching Font size to '" + Enum.GetName(typeof(FontsizeSetting), setting) + "'");
FontsizeManager.Instance.CurrentFontsizeSetting = setting;
SettingsManager.Instance.Settings.Fontsize = FontsizeManager.Instance.CurrentFontsizeSetting;
SettingsManager.Instance.PersistSettings();
StateManager sm = TrackerManager.Instance.GetStateManager();
foreach (var item in sm.GetActiveTrackableBehaviours())
{
@@ -55,7 +62,8 @@ namespace RothenburgAR.UI
teh.OnTrackableStateChanged(TrackableBehaviour.Status.NOT_FOUND, TrackableBehaviour.Status.TRACKED);
}
SwitchToARView();
if (UIManager.Instance.StartingUp) SwitchToTutorialView();
else SwitchToARView();
}
}
}

View File

@@ -14,10 +14,6 @@ namespace RothenburgAR.UI
if (tmproTextUI != null)
{
tmproTextUI.fontSize = FontsizeManager.Instance.GetFontsize(this.SizeClass);
//tmproText.enableAutoSizing = true;
//tmproText.fontSizeMax = FontsizeManager.Instance.GetFontsize(this.SizeClass);
//tmproText.fontSizeMin = tmproText.fontSizeMax * 0.8f;
}
var tmproText = gameObject.GetComponent<TMPro.TextMeshPro>();

View File

@@ -8,9 +8,14 @@ namespace RothenburgAR.UI
{
internal class InputManager : Singleton<InputManager>
{
public bool AllowCrosshairControls { get; private set; }
private static readonly float CrosshairControlsDisplaySizeThreshold = 7f;
internal void Initialize()
{
Input.simulateMouseWithTouches = false;
AllowCrosshairControls = DisplayManager.Instance.ScreensizeInInches >= CrosshairControlsDisplaySizeThreshold;
}
private void Update()
@@ -26,6 +31,15 @@ namespace RothenburgAR.UI
{
DoRaycast(screenPoint);
}
if (Input.GetKeyDown(KeyCode.Escape))
{
if (Application.platform == RuntimePlatform.Android)
{
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
activity.Call<bool>("moveTaskToBack", true);
}
}
}
public void DoRaycast(Vector2 screenPoint, bool denyBlockedHits = true)

View File

@@ -1,4 +1,5 @@
using System;
using RothenburgAR.Common;
using System;
using System.IO;
using TMPro;
using UnityEngine;
@@ -15,6 +16,9 @@ namespace RothenburgAR.UI
public void Start()
{
if (SettingsManager.Instance.Settings.Language != null && UIManager.Instance.StartingUp)
SwitchToColorSelectView();
CreateLanguageSelectionFlags();
}
@@ -32,13 +36,10 @@ namespace RothenburgAR.UI
{
var newFlag = GameObject.Instantiate(FlagPrefab, FlagContainer.transform);
newFlag.SetActive(true);
if (File.Exists(language.FlagImagePath))
{
var bytes = File.ReadAllBytes(language.FlagImagePath);
Texture2D texture = new Texture2D(4, 4, TextureFormat.RGBA32, false);
texture.LoadImage(bytes);
var texture = Resources.Load<Texture2D>(language.FlagImagePath);
if (texture != null)
{
var image = newFlag.GetComponentInChildren<Image>();
image.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
image.preserveAspect = true;
@@ -54,6 +55,9 @@ namespace RothenburgAR.UI
Debug.Log("Switching Language to '" + languageCode + "'");
LanguageManager.Instance.CurrentLanguageKey = languageCode;
SettingsManager.Instance.Settings.Language = LanguageManager.Instance.CurrentLanguageKey;
SettingsManager.Instance.PersistSettings();
StateManager sm = TrackerManager.Instance.GetStateManager();
foreach (var item in sm.GetActiveTrackableBehaviours())
{
@@ -61,14 +65,8 @@ namespace RothenburgAR.UI
teh.OnTrackableStateChanged(TrackableBehaviour.Status.NOT_FOUND, TrackableBehaviour.Status.TRACKED);
}
if (UIManager.Instance.StartingUp)
{
SwitchToColorSelectView();
}
else
{
SwitchToARView();
}
if (UIManager.Instance.StartingUp) SwitchToColorSelectView();
else SwitchToARView();
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace RothenburgAR.UI
{
public class LocalizationSelector : MonoBehaviour
{
public string LocalizationToken;
void OnEnable()
{
var tmproTextUI = gameObject.GetComponent<TMPro.TextMeshProUGUI>();
if (tmproTextUI != null)
{
tmproTextUI.text = LanguageManager.Instance.GetString(this.LocalizationToken);
}
var tmproText = gameObject.GetComponent<TMPro.TextMeshPro>();
if (tmproText != null)
{
tmproText.text = LanguageManager.Instance.GetString(this.LocalizationToken);
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 104796bd5a7a2434bb835da75350ba3f
timeCreated: 1546026587
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
using System.IO;
using Newtonsoft.Json;
using RothenburgAR.Common;
namespace RothenburgAR.UI
{
class SettingsManager : Singleton<SettingsManager>
{
public bool? IsInitialized { get; private set; }
public class AppSettings
{
public string Language { get; set; }
public FontsizeSetting? Fontsize { get; set; }
public int? ColorschemeID { get; set; }
}
public AppSettings Settings { get; private set; }
public void Start()
{
if (File.Exists(PathHelper.SettingsFilePath))
{
//load settings file into settings object if existent
var json = File.ReadAllText(PathHelper.SettingsFilePath);
Settings = JsonConvert.DeserializeObject<AppSettings>(json);
IsInitialized = true;
if (Settings.Language != null)
LanguageManager.Instance.CurrentLanguageKey = Settings.Language;
if (Settings.ColorschemeID.HasValue)
UIColorSchemeManager.Instance.SetUiColorScheme(Settings.ColorschemeID.Value);
if (Settings.Fontsize.HasValue)
FontsizeManager.Instance.CurrentFontsizeSetting = Settings.Fontsize.Value;
if (Settings.Language == null || !Settings.ColorschemeID.HasValue || !Settings.Fontsize.HasValue)
IsInitialized = false;
}
else
{
Settings = new AppSettings();
IsInitialized = false;
}
}
public void PersistSettings()
{
var json = JsonConvert.SerializeObject(Settings);
File.WriteAllText(PathHelper.SettingsFilePath, json);
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: d50764101604fa14d92f7523c16bdabc
timeCreated: 1546388554
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -6,24 +6,7 @@ using UnityEngine;
namespace RothenburgAR.UI
{
[Serializable]
public struct MenuEntry
{
public string Token;
public TextMeshProUGUI TextMesh;
}
public class SettingsViewBehaviour : BaseViewBehaviour
{
[SerializeField]
private List<MenuEntry> MenuEntries;
public void OnEnable()
{
foreach (MenuEntry entry in MenuEntries)
{
entry.TextMesh.SetText(LanguageManager.Instance.GetString(entry.Token));
}
}
}
}

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using RothenburgAR.Common;
using UnityEngine;
namespace RothenburgAR.UI
{
@@ -7,20 +8,23 @@ namespace RothenburgAR.UI
public TutorialHighlightBehaviour reticuleHighlight;
public TutorialHighlightBehaviour menuHighlight;
public TutorialHighlightBehaviour selectHighlight;
public GameObject Crosshairs;
void OnEnable()
{
reticuleHighlight.SetText(LanguageManager.Instance.GetString("t_tutorial_reticule"));
menuHighlight.SetText(LanguageManager.Instance.GetString("t_tutorial_settings"));
selectHighlight.SetText(LanguageManager.Instance.GetString("t_tutorial_select"));
Crosshairs.SetActive(InputManager.Instance.AllowCrosshairControls);
}
void Update()
{
if (Input.GetMouseButtonDown(0) == true ||
(Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Ended))
if (Input.GetMouseButtonDown(0) == true || (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Ended))
{
UIManager.Instance.SwitchToView(ViewName.ARView);
if (UIManager.Instance.StartingUp) SwitchToUpdaterView();
else UIManager.Instance.SwitchToView(ViewName.ARView);
}
}

View File

@@ -27,6 +27,8 @@ namespace RothenburgAR.UI
private Dictionary<UIMaterial, Material> _uiMaterials;
public List<UIColorScheme> AvailableUIColorSchemes { get; private set; }
public int CurrentColorSchemeID = 0;
internal void Initialize()
{
AvailableUIColorSchemes = new List<UIColorScheme>();
@@ -46,6 +48,7 @@ namespace RothenburgAR.UI
else
{
scheme = AvailableUIColorSchemes[uiColorSchemeId];
CurrentColorSchemeID = uiColorSchemeId;
}
_uiMaterials[UIMaterial.BaseOpaque].color = scheme.BaseColorOpaque;
@@ -95,13 +98,13 @@ namespace RothenburgAR.UI
private void InitializeUIColorSchemes()
{
var xmlFilePath = Path.Combine(PathHelper.DataPath, "colors.xml");
Debug.Log("Loading colors from '" + xmlFilePath + "'");
var file = Resources.Load<TextAsset>("colors");
Debug.Log("Loading colors from Resources..");
if (!File.Exists(xmlFilePath))
if (file == null)
{
// Set default colors, if not able to load
Debug.Log("File " + xmlFilePath + " does not exist - use default colors");
Debug.LogWarning("colors.xml does not exist in Resources folder - use default colors");
AvailableUIColorSchemes = new List<UIColorScheme>
{
new UIColorScheme("t_color_name_light_blue", "#03A9F4", "#E1F5FE", "#0277BD", 0.75f),
@@ -112,7 +115,7 @@ namespace RothenburgAR.UI
}
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
doc.LoadXml(file.text);
var colorNodes = doc.SelectNodes("//color");
if (colorNodes == null) return;

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using RothenburgAR.Common;
using UnityEngine;
@@ -14,7 +15,8 @@ namespace RothenburgAR.UI
LanguageSelectView,
ColorSelectView,
FontsizeSelectView,
FullscreenModelView
FullscreenModelView,
UpdaterView
}
public class UIManager : Singleton<UIManager>
@@ -25,7 +27,7 @@ namespace RothenburgAR.UI
public Boolean IsARViewVisible
{
get { return _currentView.ViewName == ViewName.ARView; }
get { return _currentView != null && _currentView.ViewName == ViewName.ARView; }
}
public ARViewBehaviour ARViewBehaviour
@@ -62,7 +64,6 @@ namespace RothenburgAR.UI
public UIManager()
{
_availableViews = new Dictionary<ViewName, View>();
StartingUp = true;
}
internal void Initialize()
@@ -123,12 +124,28 @@ namespace RothenburgAR.UI
ViewName = ViewName.FullscreenModelView,
PrefabName = "UI/FullscreenModelView"
});
_availableViews.Add(ViewName.UpdaterView,
new View()
{
ViewName = ViewName.UpdaterView,
PrefabName = "UI/UpdaterView"
});
}
public void InitStartView()
public IEnumerator InitStartView()
{
SwitchToView(ViewName.LanguageSelectView);
StartingUp = true;
yield return new WaitUntil(() => SettingsManager.Instance.IsInitialized.HasValue);
if (SettingsManager.Instance.IsInitialized.Value == true)
{
StartingUp = false;
SwitchToView(ViewName.ARView);
}
else
{
StartingUp = true;
SwitchToView(ViewName.LanguageSelectView);
}
}
public GameObject SwitchToView(ViewName nextViewName)
@@ -142,7 +159,7 @@ namespace RothenburgAR.UI
View nextView;
if (!_availableViews.TryGetValue(nextViewName, out nextView))
{
Debug.Log("Tried to switch to view '" + nextViewName + "', but it failed.");
Debug.Log("Tried to switch to view '" + nextViewName + "', but it was not found.");
return null;
}
@@ -156,7 +173,6 @@ namespace RothenburgAR.UI
Debug.Log("Switching to view '" + nextViewName + "'");
}
if (_currentView != null && _currentView.OnExit != null)
{
_currentView.OnExit();

View File

@@ -0,0 +1,117 @@
using RothenburgAR.Exhibition;
using RothenburgAR.PointOfInterest;
using RothenburgAR.Updater;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace RothenburgAR.UI
{
public class UpdaterViewBehaviour : BaseViewBehaviour
{
public UnityEngine.UI.Slider ProgressBar;
public GameObject UpdateProgressDialog;
public GameObject UpdateConfirmationDialog;
public GameObject UpdateCompletedDialog;
public GameObject UpdateFailedDialog;
public GameObject AlreadyUpToDateDialog;
public GameObject NoInternetDialog;
public GameObject ButtonBack;
private bool allowAbort = true;
private UpdateState lastUpdateState = UpdateState.UpdatesFound;
private void Start()
{
UpdateProgressDialog.SetActive(true);
UpdateConfirmationDialog.SetActive(false);
UpdateCompletedDialog.SetActive(false);
UpdateFailedDialog.SetActive(false);
ProgressBar.value = 0;
ProgressBar.maxValue = 1;
if (UIManager.Instance.StartingUp)
{
allowAbort = false;
ButtonBack.SetActive(false);
}
UIManager.Instance.StartingUp = false;
}
private void Update()
{
ProgressBar.value = UpdateManager.Instance.CurrentProgress;
ProgressBar.maxValue = UpdateManager.Instance.MaxProgress;
var state = UpdateManager.Instance.UpdateState;
if (state == lastUpdateState) return;
lastUpdateState = state;
UpdateProgressDialog.SetActive(false);
UpdateConfirmationDialog.SetActive(false);
UpdateCompletedDialog.SetActive(false);
UpdateFailedDialog.SetActive(false);
switch (state)
{
case UpdateState.ConfirmationPending:
UpdateConfirmationDialog.SetActive(true);
break;
case UpdateState.UpdatesFound:
case UpdateState.Downloading:
UpdateProgressDialog.SetActive(true);
break;
case UpdateState.Completed:
UpdateCompletedDialog.SetActive(true);
break;
case UpdateState.Failed:
UpdateFailedDialog.SetActive(true);
break;
case UpdateState.NoInternet:
NoInternetDialog.SetActive(true);
break;
case UpdateState.UpToDate:
AlreadyUpToDateDialog.SetActive(true);
break;
}
}
public void TriggerUpdate()
{
UpdateManager.Instance.TriggerUpdate();
}
public void ExitView()
{
UIManager.Instance.SwitchToView(ViewName.ARView);
}
public void ApplyUpdates()
{
//DisplayManager.ResetInstance(); // Not necessary
LanguageManager.Instance.ResetInstance();
InputManager.Instance.ResetInstance();
UIManager.Instance.ResetInstance();
UpdateManager.Instance.ResetInstance();
SettingsManager.Instance.ResetInstance();
PoiDataManager.Instance.ResetInstance();
ExhibitionManager.Instance.ResetInstance();
UIColorSchemeManager.Instance.ResetInstance();
FontsizeManager.Instance.ResetInstance();
SceneManager.LoadScene("mainScene");
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 49d9434809cb84c44ae021b275939980
timeCreated: 1546011854
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -65,11 +65,14 @@ namespace RothenburgAR.Updater
public UnityWebRequest Request { get; set; }
public UnityWebRequestAsyncOperation Operation { get; set; }
private bool isDone = false;
public bool IsError { get; set; }
public bool IsDone
{
get
{
return Operation.isDone && Request.isDone;
return Operation.isDone && Request.isDone && this.isDone;
}
}
@@ -79,6 +82,16 @@ namespace RothenburgAR.Updater
this.Download = download;
this.Request = request;
this.Operation = operation;
this.Operation.completed += (_) =>
{
this.isDone = true;
this.IsError =
request.isNetworkError
|| request.isHttpError
// Error when answer is empty except when it's a 300 error code
|| (!(request.responseCode >= 300 && request.responseCode < 400) && download.data.Length == 0);
};
}
}

View File

@@ -0,0 +1,466 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System;
using Newtonsoft.Json;
using RothenburgAR.Common;
using System.IO;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using RothenburgAR.UI;
namespace RothenburgAR.Updater
{
public enum UpdateState
{
UpToDate,
UpdatesFound,
ConfirmationPending,
Downloading,
Completed,
Failed,
NoInternet
}
public class UpdateManager : Singleton<UpdateManager>
{
public UpdateState UpdateState { get; private set; }
public int CurrentProgress { get; private set; }
public int MaxProgress { get; private set; }
private readonly int retriesUntilFailure = 4;
private readonly string trackerMainFile = "tracker.dat";
public ApiVersioncheckAnswer VersionAnswer { get; set; }
Dictionary<string, List<ApiExhibit>> ExhibitMetas = new Dictionary<string, List<ApiExhibit>>();
void Start()
{
if (Application.internetReachability == NetworkReachability.NotReachable)
{
// just continue to app
UpdatesCompleted();
UpdateState = UpdateState.NoInternet;
return;
}
CheckForUpdates();
}
private void CheckForUpdates()
{
// check for updates and ask for permission to download if there are any
string versionMap = GenerateVersionMap();
CheckForUpdates(versionMap, 0);
}
private void CheckForUpdates(string versionMap, int retries)
{
HttpHandler http = new HttpRequest(ApiInfo.VersionCheckEndpoint, HttpVerb.POST, versionMap).Send();
http.Operation.completed += ar =>
{
Debug.Log("VersionAnswer: " + http.Download.text);
var answer = JsonConvert.DeserializeObject<ApiVersioncheckAnswer>(http.Download.text);
if (http.IsError)
{
if (retries < retriesUntilFailure)
{
CheckForUpdates(versionMap, retries + 1);
return;
}
else
{
UpdateFailed(http);
return;
}
}
Debug.Log(string.Format("{1}-DONE with {0}", ApiInfo.VersionCheckEndpoint, Time.realtimeSinceStartup));
VersionAnswer = answer;
if (VersionAnswer.Data.TrueForAll(d => d.Meta.Status == VersionStatus.ok && d.Tracker.Status == VersionStatus.ok))
{
UpdateState = UpdateState.UpToDate;
StartCoroutine(CheckFiles());
return;
}
UpdateState = UpdateState.UpdatesFound;
if (Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork)
{
TriggerUpdate();
}
else
{
UpdateState = UpdateState.ConfirmationPending;
if (!UIManager.Instance.StartingUp)
UIManager.Instance.SwitchToView(ViewName.UpdaterView);
}
};
}
private string GenerateVersionMap()
{
string result = "{ ";
var rootDir = new DirectoryInfo(PathHelper.ExhibitionPath);
if (!rootDir.Exists)
{
rootDir.Create();
}
var exhibitionDirs = rootDir.GetDirectories().ToList();
foreach (var dir in exhibitionDirs)
{
var versionFilePath = Path.Combine(dir.FullName, "version.txt");
if (!File.Exists(versionFilePath)) continue;
var version = long.Parse(File.ReadAllText(versionFilePath));
result += @"""{id}"":""{version}"",".Replace("{id}", dir.Name).Replace("{version}", version.ToString());
};
result = result.Substring(0, result.Length - 1) + "}";
return result;
}
public void TriggerUpdate()
{
/*
* dir structure:
* data
* exhibition
* id
* tracker.dat
* tracker.xml
* de
* meta.json
* en
* meta.json
* id
* ...
* media
* ...
*/
UpdateState = UpdateState.Downloading;
if (VersionAnswer == null)
{
// try to get VersionAnswer first if that's what failed
CheckForUpdates();
return;
}
//TODO write languages to file the app can read (so that the languagemanager can decide which languages the user can choose from)
var updatedExhibitions = VersionAnswer.Data.Where(d => d.Meta.Status == VersionStatus.updated).ToList();
var updatedTracker = VersionAnswer.Data.Where(d => d.Tracker.Status == VersionStatus.updated).ToList();
updatedExhibitions.Union(updatedTracker).Distinct().ToList().ForEach(updatedExhibition =>
{
// create exhibition directories
var path = Path.Combine(PathHelper.ExhibitionPath, updatedExhibition.Id);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
});
updatedExhibitions.ForEach(d => UpdateExhibition(d, updatedExhibitions));
StartCoroutine(UpdateExhibitionsCoroutine(updatedExhibitions));
}
private IEnumerator UpdateExhibitionsCoroutine(List<ApiExhibitionVersion> updatedExhibitions)
{
yield return new WaitUntil(() => updatedExhibitions.Count == 0);
StartCoroutine(CheckFiles());
}
private void UpdateExhibition(ApiExhibitionVersion exhibition, List<ApiExhibitionVersion> updatedExhibitions)
{
var exhibitionDownloads = new List<HttpHandler>();
foreach (var lang in VersionAnswer.Languages)
{
var path = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibition.Id, lang);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
UpdateMetaFile(exhibition, path, lang, exhibitionDownloads);
}
var versionPath = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibition.Id, "version.txt");
var version = exhibition.Meta.UpdateVersion.ToString();
StartCoroutine(UpdateVersionFileCoroutine(exhibitionDownloads, versionPath, version, exhibition, updatedExhibitions));
}
private IEnumerator UpdateVersionFileCoroutine(List<HttpHandler> exhibitionDownloads, string versionPath, string version, ApiExhibitionVersion exhibition, List<ApiExhibitionVersion> updatedExhibitions)
{
// updates version file only if all sub files were downloaded successfully
yield return new WaitUntil(() => exhibitionDownloads.All(h => h.IsDone));
if (exhibitionDownloads.Any(http => http.IsError)) yield break;
File.WriteAllText(versionPath, version);
updatedExhibitions.Remove(exhibition);
}
private void UpdateMetaFile(ApiExhibitionVersion exhibition, string path, string lang, List<HttpHandler> exhibitionDownloads, int retries = 0)
{
var url = exhibition.Meta.UpdateUrl.Replace("{lang}", lang);
var http = new HttpRequest(url, HttpVerb.GET).Send();
exhibitionDownloads.Add(http);
http.Operation.completed += ar =>
{
if (http.IsError)
{
if (retries < retriesUntilFailure)
{
exhibitionDownloads.Remove(http);
UpdateMetaFile(exhibition, path, lang, exhibitionDownloads, retries + 1);
return;
}
else
{
UpdateFailed(http);
return;
}
}
File.WriteAllText(Path.Combine(path, "meta.json"), http.Download.text, System.Text.Encoding.UTF8);
Debug.Log(string.Format("{1}-DONE with {0}", url, Time.realtimeSinceStartup));
var exhibits = JsonConvert.DeserializeObject<List<ApiExhibit>>(http.Download.text);
if (exhibits == null)
{
Debug.LogError(string.Format("Exhibit could not be parsed from Json:\nurl: {0}\njson: {1}", url, http.Download.text));
http.IsError = true;
UpdateFailed(http);
}
};
}
private IEnumerator CheckFiles()
{
var usedFileList = new Dictionary<string, FileDownloadInfo>();
GenerateUsedFileList(usedFileList);
MaxProgress = usedFileList.Count;
foreach (var file in usedFileList)
{
var fileInfo = file.Value;
Dictionary<string, byte[]> data = new Dictionary<string, byte[]>();
yield return DownloadFile(fileInfo, data);
foreach (var item in data)
{
if (!Directory.Exists(fileInfo.directory)) Directory.CreateDirectory(fileInfo.directory);
File.WriteAllBytes(item.Key, item.Value);
}
}
var deletedData = VersionAnswer.Data.Where(d =>
d.Meta.Status == VersionStatus.deleted
|| d.Tracker.Status == VersionStatus.deleted).ToList();
deletedData.ForEach(d => DeleteExhibition(d));
CleanupMediaFiles();
UpdatesCompleted();
}
private void GenerateUsedFileList(Dictionary<string, FileDownloadInfo> downloadList)
{
ExhibitMetas.Clear();
var rootDir = new DirectoryInfo(PathHelper.ExhibitionPath);
var exhibitionDirs = rootDir.GetDirectories().ToList();
foreach (var dir in exhibitionDirs)
{
var versionFilePath = Path.Combine(dir.FullName, "version.txt");
if (!File.Exists(versionFilePath)) continue;
var exhibitionId = dir.Name;
foreach (var lang in VersionAnswer.Languages)
{
var metaFilePath = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibitionId, lang, "meta.json");
var metaFile = File.ReadAllText(metaFilePath);
var exhibits = JsonConvert.DeserializeObject<List<ApiExhibit>>(metaFile);
ExhibitMetas.Add(exhibitionId + "/" + lang, exhibits);
}
}
// would check for || d.Tracker.Status == VersionStatus.ok as well but we don't get an updateUrl for those so it's no use
var updatedTracker = VersionAnswer.Data.Where(d => d.Tracker.Status == VersionStatus.updated).ToList();
foreach (var exhibition in updatedTracker)
{
var url = exhibition.Tracker.UpdateUrl;
var directory = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibition.Id);
var filepath = PathHelper.CombinePaths(directory, trackerMainFile);
downloadList.Add(url, new FileDownloadInfo(url, filepath, directory));
}
var mediaList = ExhibitMetas.Values.ToList().SelectMany(m => m.SelectMany(i => i.Pois.Select(p => p.MediaId))).Where(m => m != null).Distinct().ToList();
foreach (var mediaId in mediaList)
{
var url = ApiInfo.FileEndpoint.Replace("{id}", mediaId);
var directory = PathHelper.CombinePaths(PathHelper.MediaPath, mediaId);
var filepath = PathHelper.CombinePaths(directory, mediaId + ".obj");
downloadList.Add(url, new FileDownloadInfo(url, filepath, directory));
}
}
private class FileDownloadInfo
{
public string url;
public string filepath;
public string directory;
public FileDownloadInfo(string url, string filepath, string directory)
{
this.url = url;
this.filepath = filepath;
this.directory = directory;
}
}
private IEnumerator DownloadFile(FileDownloadInfo info, Dictionary<string, byte[]> data)
{
if (!Directory.Exists(info.directory)) Directory.CreateDirectory(info.directory);
var eTag = GenerateETag(info.filepath);
yield return DownloadFile(info, eTag, data);
}
private IEnumerator DownloadFile(FileDownloadInfo info, string eTag, Dictionary<string, byte[]> data, int retries = 0)
{
var url = info.url;
var http = new HttpRequest(url, HttpVerb.GET)
.WithHeader("If-None-Match", eTag)
.WithHeader("Accept-Encoding", "gzip,deflate")
.Send();
yield return new WaitUntil(() => http.IsDone);
if (http.IsError)
{
if (retries < retriesUntilFailure)
{
yield return DownloadFile(info, eTag, data, retries + 1);
}
else
{
UpdateFailed(http);
yield return null;
}
}
if (http.Request.responseCode != 304)
{
if (!data.ContainsKey(info.filepath))
{
// gzipped files are un-gzipped automagically
data.Add(info.filepath, http.Download.data);
}
}
var subfilesHeader = http.Request.GetResponseHeader("subfiles");
var test = http.Request.GetResponseHeaders();
if (subfilesHeader != null)
{
var subfiles = subfilesHeader.Split(new string[1] { ";;" }, StringSplitOptions.RemoveEmptyEntries).ToList();
MaxProgress += subfiles.Count(subfileName => !data.Keys.Contains(Path.Combine(info.directory, subfileName)));
foreach (var subfileName in subfiles)
{
var subfileInfo = new FileDownloadInfo(
info.url + "/" + subfileName,
Path.Combine(info.directory, subfileName),
info.directory);
var subfileETag = GenerateETag(info.filepath);
// HACK to prevent infinite subfile loop
if (!data.ContainsKey(subfileInfo.filepath) && subfileName != "brick.png")
{
yield return DownloadFile(subfileInfo, subfileETag, data);
}
}
}
Debug.Log(string.Format("{1}-DONE with {0}", url, Time.realtimeSinceStartup));
CurrentProgress += 1;
}
private string GenerateETag(string filepath)
{
string eTag = "";
if (File.Exists(filepath))
{
var bytes = File.ReadAllBytes(filepath);
SHA256Managed hasher = new SHA256Managed();
byte[] hash = hasher.ComputeHash(bytes);
eTag = "sha256-";
foreach (byte x in hash)
{
eTag += String.Format("{0:x2}", x);
}
}
return eTag;
}
private void DeleteExhibition(ApiExhibitionVersion exhibition)
{
var path = Path.Combine(PathHelper.ExhibitionPath, exhibition.Id);
Directory.Delete(path, true);
}
private void CleanupMediaFiles()
{
var requiredMedia = ExhibitMetas.Values.ToList().SelectMany(m => m.SelectMany(i => i.Pois.Select(p => p.MediaId))).Where(m => m != null).Distinct().ToList();
var mediaDir = new DirectoryInfo(PathHelper.MediaPath);
var mediaDirs = mediaDir.GetDirectories().ToList();
foreach (var dir in mediaDirs)
{
// HACK to preserve passion media files
if (!requiredMedia.Contains(dir.Name) && Regex.IsMatch(dir.Name, "[0-9]"))
{
Directory.Delete(dir.FullName, true);
}
}
}
private void UpdateFailed(HttpHandler http)
{
Debug.LogError(String.Format("Error while downloading\nurl: {0}\nNetwork Error: {1}\nHttp Error: {2}\nHttp Response Code: {3}",
http.Request.url,
http.Request.isNetworkError,
http.Request.isHttpError,
http.Request.responseCode));
UpdateState = UpdateState.Failed;
if (!UIManager.Instance.StartingUp)
UIManager.Instance.SwitchToView(ViewName.UpdaterView);
}
public void UpdatesCompleted()
{
if (UpdateState == UpdateState.UpToDate) return;
UpdateState = UpdateState.Completed;
if (!UIManager.Instance.StartingUp)
UIManager.Instance.SwitchToView(ViewName.UpdaterView);
}
}
}

View File

@@ -1,435 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System;
using Newtonsoft.Json;
using RothenburgAR.Common;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
namespace RothenburgAR.Updater
{
public class UpdaterBehaviour : MonoBehaviour
{
public UnityEngine.UI.Slider ProgressBar;
public GameObject UpdateDialog;
public GameObject UpdateConfirmationDialog;
public GameObject UpdateCompletedDialog;
public GameObject UpdateFailedDialog;
private readonly float afterDownloadWaitTime = 10f;
public ApiVersioncheckAnswer VersionAnswer { get; set; }
private List<HttpHandler> httpHandlers = new List<HttpHandler>();
private LogFileHandler logFileHandler;
private readonly List<string> downloadingMedia = new List<string>();
void Start()
{
#if !UNITY_EDITOR
logFileHandler = new LogFileHandler();
#else
Debug.Log("Found Unity Editor; Disabled logging into file.");
#endif
InitUI();
if (Application.internetReachability == NetworkReachability.NotReachable)
{
// just continue to app
LoadMainScene();
return;
}
CheckForUpdates();
}
private void InitUI()
{
FindObjectsOfType<Camera>().First().enabled = true;
UpdateDialog.SetActive(false);
UpdateConfirmationDialog.SetActive(false);
UpdateCompletedDialog.SetActive(false);
UpdateFailedDialog.SetActive(false);
ProgressBar.value = 0;
}
private void CheckForUpdates()
{
// check for updates and ask for permission to download if there are any
string versionMap = GenerateVersionMap();
HttpHandler http = new HttpRequest(ApiInfo.VersionCheckEndpoint, HttpVerb.POST, versionMap).Send();
httpHandlers.Add(http);
http.Operation.completed += ar =>
{
if (CheckNetworkErrors(http))
{
return;
}
Debug.Log(http.Download.text);
VersionAnswer = JsonConvert.DeserializeObject<ApiVersioncheckAnswer>(http.Download.text);
Debug.Log(string.Format("{1}-DONE with {0}", ApiInfo.VersionCheckEndpoint, Time.realtimeSinceStartup));
var answer = VersionAnswer;
if (VersionAnswer.Data.TrueForAll(d => d.Meta.Status == VersionStatus.ok && d.Tracker.Status == VersionStatus.ok))
{
// no updates required, continue to app
LoadMainScene();
return;
}
UpdateDialog.SetActive(true);
if (Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork)
{
TriggerUpdate();
}
else
{
UpdateConfirmationDialog.SetActive(true);
}
};
}
private string GenerateVersionMap()
{
string result = "{ ";
var rootDir = new DirectoryInfo(PathHelper.ExhibitionPath);
if (!rootDir.Exists)
{
rootDir.Create();
}
var exhibitionDirs = rootDir.GetDirectories().ToList();
foreach (var dir in exhibitionDirs)
{
var versionFilePath = Path.Combine(dir.FullName, "version.txt");
if (!File.Exists(versionFilePath)) continue;
var version = long.Parse(File.ReadAllText(versionFilePath));
result += @"""{id}"":""{version}"",".Replace("{id}", dir.Name).Replace("{version}", version.ToString());
};
result = result.Substring(0, result.Length - 1) + "}";
return result;
}
public void TriggerUpdate()
{
/*
* dir structure:
* data
* exhibition
* id
* tracker.dat
* tracker.xml
* de
* meta.json
* en
* meta.json
* id
* ...
* media
* ...
*/
UpdateConfirmationDialog.SetActive(false);
UpdateFailedDialog.SetActive(false);
this.downloadingMedia.Clear();
if (VersionAnswer == null)
{
// try to get VersionAnswer first if that's what failed
CheckForUpdates();
return;
}
//TODO write languages to file the app can read (so that the languagemanager can decide which languages the user can choose from)
var updatedMeta = VersionAnswer.Data.Where(d => d.Meta.Status == VersionStatus.updated).ToList();
var updatedTracker = VersionAnswer.Data.Where(d => d.Tracker.Status == VersionStatus.updated).ToList();
updatedMeta.Union(updatedTracker).ToList().ForEach(updatedExhibition =>
{
// create exhibition directories
var path = Path.Combine(PathHelper.ExhibitionPath, updatedExhibition.Id);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
});
updatedMeta.ForEach(d => UpdateMeta(d));
updatedTracker.ForEach(d => UpdateTracker(d));
var deletedData = VersionAnswer.Data.Where(d =>
d.Meta.Status == VersionStatus.deleted
|| d.Tracker.Status == VersionStatus.deleted).ToList();
deletedData.ForEach(d => DeleteExhibition(d));
}
private void DeleteExhibition(ApiExhibitionVersion exhibition)
{
//TODO delete media as well if not used elsewhere?
var path = Path.Combine(PathHelper.ExhibitionPath, exhibition.Id);
Directory.Delete(path, true);
}
private void UpdateMeta(ApiExhibitionVersion exhibition)
{
var currentHandlers = new List<HttpHandler>();
foreach (var lang in VersionAnswer.Languages)
{
var path = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibition.Id, lang);
var url = exhibition.Meta.UpdateUrl.Replace("{lang}", lang);
var http = new HttpRequest(url, HttpVerb.GET).Send();
httpHandlers.Add(http);
currentHandlers.Add(http);
http.Operation.completed += ar =>
{
if (CheckNetworkErrors(http))
{
return;
}
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
File.WriteAllText(Path.Combine(path, "meta.json"), http.Download.text, System.Text.Encoding.UTF8);
Debug.Log(string.Format("{1}-DONE with {0}", url, Time.realtimeSinceStartup));
var exhibits = JsonConvert.DeserializeObject<List<ApiExhibit>>(http.Download.text);
foreach (var exhibit in exhibits)
{
UpdateMedia(exhibit);
}
};
}
var versionPath = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibition.Id, "version.txt");
var version = exhibition.Meta.UpdateVersion.ToString();
StartCoroutine(UpdateVersionFileCoroutine(currentHandlers, versionPath, version));
}
private IEnumerator UpdateVersionFileCoroutine(List<HttpHandler> currentHandlers, string versionPath, string version)
{
// updates version file only if all sub files were downloaded successfully
yield return new WaitUntil(() => httpHandlers.All(h => h.IsDone));
if (httpHandlers.Any(http => http.Request.isNetworkError || http.Request.isHttpError)) yield break;
File.WriteAllText(versionPath, version);
}
private void UpdateMedia(ApiExhibit exhibit)
{
var mediaIDs = exhibit.Pois.Select(p => p.MediaId).Except(new List<string> { null }).ToList();
foreach (var mediaId in mediaIDs)
{
if (downloadingMedia.Contains(mediaId)) continue;
downloadingMedia.Add(mediaId);
var path = PathHelper.CombinePaths(PathHelper.MediaPath, mediaId);
var filepath = Path.Combine(path, mediaId + ".med");
// create dir if nonexistent
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
//System.Security.Cryptography.SHA1CryptoServiceProvider
//System.Security.Cryptography.SHA256
var eTag = GenerateETag(filepath);
var url = ApiInfo.FileEndpoint.Replace("{id}", mediaId);
var http = new HttpRequest(url, HttpVerb.GET)
.WithHeader("If-None-Match", eTag)
.Send();
httpHandlers.Add(http);
http.Operation.completed += ar =>
{
if (CheckNetworkErrors(http))
{
return;
}
// do nothing if unchanged
if (http.Request.responseCode == 304) return;
// gzipped files are un-gzipped automagically
File.WriteAllBytes(filepath, http.Download.data);
var subfilesHeader = http.Request.GetResponseHeader("subfiles");
if (subfilesHeader != null)
{
string[] separator = new string[1] { ";;" };
var subfiles = subfilesHeader.Split(separator, StringSplitOptions.RemoveEmptyEntries);
foreach (var subfile in subfiles)
{
UpdateSubfile(path, mediaId, subfile);
}
}
Debug.Log(string.Format("{1}-DONE with {0}", url, Time.realtimeSinceStartup));
};
}
}
private string GenerateETag(string filepath)
{
string eTag = "";
if (File.Exists(filepath))
{
var bytes = File.ReadAllBytes(filepath);
SHA256Managed hasher = new SHA256Managed();
byte[] hash = hasher.ComputeHash(bytes);
eTag = "sha256-";
foreach (byte x in hash)
{
eTag += String.Format("{0:x2}", x);
}
}
return eTag;
}
private void UpdateSubfile(string path, string mediaId, string subfile)
{
var filepath = Path.Combine(path, subfile);
var eTag = GenerateETag(filepath);
var url = ApiInfo.FileEndpoint.Replace("{id}", mediaId) + "/" + subfile;
var http = new HttpRequest(url, HttpVerb.GET)
.WithHeader("If-None-Match", eTag)
.Send();
httpHandlers.Add(http);
http.Operation.completed += ar =>
{
if (CheckNetworkErrors(http))
{
return;
}
// do nothing if unchanged
if (http.Request.responseCode == 304) return;
// gzipped files are un-gzipped automagically
File.WriteAllBytes(filepath, http.Download.data);
Debug.Log(string.Format("{1}-DONE with {0}", url, Time.realtimeSinceStartup));
};
}
private bool CheckNetworkErrors(HttpHandler http)
{
if (http.Request.isNetworkError || http.Request.isHttpError)
{
Debug.LogError(String.Format("Error while downloading\nurl: {0}\nNetwork Error: {1}\nHttp Error: {2}\nHttp Response Code: {3}",
http.Request.url,
http.Request.isNetworkError,
http.Request.isHttpError,
http.Request.responseCode));
UpdateDialog.SetActive(true);
UpdateFailedDialog.SetActive(true);
//TODO decide on level of detail for user notification
//var all = UpdateFailedDialog.GetComponentsInChildren<TextMeshProUGUI>().ToList();
//var errorText = all.First(c => c.name == "ErrorText");
//errorText.text = string.Format("Fehlercode: {0}", http.Request.responseCode.ToString());
return true;
}
return false;
}
private void UpdateTracker(ApiExhibitionVersion exhibition)
{
//TODO test UpdateTracker
var path = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibition.Id);
var url = exhibition.Tracker.UpdateUrl;
var http = new HttpRequest(url, HttpVerb.GET).Send();
httpHandlers.Add(http);
http.Operation.completed += ar =>
{
if (CheckNetworkErrors(http))
{
return;
}
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
//TODO unzip, should be tracker.xml and tracker.dat files
var type = http.Request.GetResponseHeader("Content-Type");
File.WriteAllBytes(Path.Combine(path, "tracker.zip"), http.Download.data);
Debug.Log(string.Format("{1}-DONE with {0}", url, Time.realtimeSinceStartup));
};
}
public void LoadMainScene()
{
Debug.Log("Loading mainScene");
UnityEngine.SceneManagement.SceneManager.LoadScene("mainScene");
}
private DateTime downloadEndedTime = DateTime.Now.AddYears(1);
void Update()
{
// Update the download progress bar
if (httpHandlers.Count > 0)
{
float downloadProgress = 0f;
httpHandlers.ForEach(h =>
{
downloadProgress += h.Operation.progress;
});
downloadProgress /= httpHandlers.Count;
// operation.progress is bugged and goes all over the place:
// jumps from 0 to 1 and back despite not being done
// steadily increases from 0,5 to 0,99 and resets to 0,5 multiple times (5-15x) during a single download
// update progress bar and ignore all negative changes
ProgressBar.value = ProgressBar.value < downloadProgress ? downloadProgress : ProgressBar.value;
}
// Continue to Main Scene after all downloads are done and this.afterDownloadWaitTime seconds have passed without any new downloads triggering.
if (httpHandlers.All(h => h.IsDone) && !UpdateFailedDialog.activeInHierarchy)
{
if (downloadEndedTime > DateTime.Now)
{
Debug.Log("Done Updating");
UpdateCompletedDialog.SetActive(true);
downloadEndedTime = DateTime.Now;
}
if (downloadEndedTime.AddSeconds(afterDownloadWaitTime) < DateTime.Now)
{
LoadMainScene();
}
}
else
{
UpdateCompletedDialog.SetActive(false);
downloadEndedTime = DateTime.Now.AddYears(1);
}
}
}
}

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -87,6 +87,16 @@ TextureImporter:
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

View File

@@ -23,7 +23,7 @@ RenderSettings:
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientIntensity: 0
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
@@ -51,8 +51,8 @@ LightmapSettings:
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 9
m_Resolution: 2

View File

@@ -5,9 +5,6 @@ EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes:
- enabled: 1
path: Assets/updaterScene.unity
guid: 974eb12c09ab8804392cefb59d4a0de8
- enabled: 1
path: Assets/mainScene.unity
guid: 26344e586197d424bb80c37c69080abb

View File

@@ -39,6 +39,7 @@ GraphicsSettings:
- {fileID: 4800000, guid: 3a1c68c8292caf046bd21158886c5e40, type: 3}
- {fileID: 207, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16002, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}

View File

@@ -168,9 +168,9 @@ PlayerSettings:
AndroidPreferredInstallLocation: 1
aotOptions:
stripEngineCode: 1
iPhoneStrippingLevel: 0
iPhoneStrippingLevel: 1
iPhoneScriptCallOptimization: 0
ForceInternetPermission: 0
ForceInternetPermission: 1
ForceSDCardPermission: 1
CreateWallpaper: 0
APKExpansionFiles: 0
@@ -248,7 +248,7 @@ PlayerSettings:
AndroidKeystoreName:
AndroidKeyaliasName:
AndroidTVCompatibility: 0
AndroidIsGame: 1
AndroidIsGame: 0
AndroidEnableTango: 0
androidEnableBanner: 1
androidUseLowAccuracyLocation: 0

Binary file not shown.