diff --git a/README.md b/README.md index d8f97c7..9eca677 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ If you want to use these assets, read chapter 5.1 | A / Left Arrow | Move the camera to the left | | S / Down Arrow | Move the camera backwards | | D / Right Arrow | Move the camera to the right | -| Escape | Go back to the main menu | +| Escape | Go back to the main menu or escape different camera view | | F4 | Open the debug console | | Left mouse button | When clicked on a building or vehicle it displays information | | Hold right mouse button| Rotate the camera around | @@ -467,6 +467,8 @@ To use chaos engineering there has been decided to let a tank drive around toget If a hit happens, a building will collapse and a docker container will real-time be destroyed. +If you click on the tank or the plane in the UI the camera will switch to the vehicle. You can switch back to the normal view by pressing the button again. + There are settings to disable the airplane or tank. There is also a setting where you can set the minimum required buildings. It is more safe to set this to 2. If you use this in a production environment it could happen that a service with only 1 instance is getting killed. @@ -564,19 +566,21 @@ For example, for the scooter the following settings were used: | Auto Re-path | Enabled | | Area Mask | Walkable | +5. If the prefab is a tank or a plane, add a camera to the object, align it correctly and give it the correct Tag `TankCamera` or `PlaneCamera`. + ## Important! Buildings & Vehicles These steps are necessary only if you intend to use the team selection. **The material must not contain any white spaces.** -5. Place the material you used in the Resources/Materials folder. +6. Place the material you used in the Resources/Materials folder. -6. Duplicate the material and rename the duplicated material to **Transparent-** *Material name*. (I know this is not a really nice thing, but it's because of WebGL limitations) +7. Duplicate the material and rename the duplicated material to **Transparent-** *Material name*. (I know this is not a really nice thing, but it's because of WebGL limitations) -7. Set the Rendering mode to **Fade** of the transparent material. +8. Set the Rendering mode to **Fade** of the transparent material. -8. Edit the `config.json` and set all the prefabs to the correct names. +9. Edit the `config.json` and set all the prefabs to the correct names. For performance reasons it is advised to **enable** GPU instancing for the transparent material and the original prefab material. diff --git a/img/simtainer.gif b/img/simtainer.gif index 30a55ea..8bcf6f7 100644 Binary files a/img/simtainer.gif and b/img/simtainer.gif differ diff --git a/innosetup.iss b/innosetup.iss index 858a44a..58377c1 100644 --- a/innosetup.iss +++ b/innosetup.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "SimTainer" -#define MyAppVersion "0.4b1" +#define MyAppVersion "0.5b1" #define MyAppPublisher "Wehkamp" #define MyAppExeName "SimTainer.exe" diff --git a/src/Assets/Editor/AssetsPropertiesApplier.cs b/src/Assets/Editor/AssetsPropertiesApplier.cs index f45f0ab..3bb2cbc 100644 --- a/src/Assets/Editor/AssetsPropertiesApplier.cs +++ b/src/Assets/Editor/AssetsPropertiesApplier.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; @@ -86,6 +87,7 @@ private enum ComponentType { NavMeshAgent, NotWalkable, + Camera, None } @@ -100,16 +102,16 @@ private enum ComponentType private static void ApplyPropertiesToPrefab(string prefabName, string assetBundle, string tag, ComponentType componentType = ComponentType.None, bool generateTransparentMaterials = false) { - string[] strings = AssetDatabase.FindAssets(prefabName); + string[] assetGuids = AssetDatabase.FindAssets(prefabName); - for (int i = 0; i < strings.Length; i++) + foreach (string assetGuid in assetGuids) { - string assetPath = AssetDatabase.GUIDToAssetPath(strings[i]); + string assetPath = AssetDatabase.GUIDToAssetPath(assetGuid); // Match exact name of prefab if (Path.GetFileName(assetPath) != prefabName + ".prefab") continue; Debug.Log($"Handling {prefabName}"); GameObject targetGameObject = - PrefabUtility.LoadPrefabContents(AssetDatabase.GUIDToAssetPath(strings[i])); + PrefabUtility.LoadPrefabContents(AssetDatabase.GUIDToAssetPath(assetGuid)); if (targetGameObject == null) { @@ -120,91 +122,87 @@ private static void ApplyPropertiesToPrefab(string prefabName, string assetBundl // Already done this one if (targetGameObject.CompareTag(tag)) continue; + // Mark the object as a dirty object so we can edit it EditorUtility.SetDirty(targetGameObject); PrefabUtility.RecordPrefabInstancePropertyModifications(targetGameObject); - switch (componentType) - { - case ComponentType.NavMeshAgent: - if (targetGameObject.GetComponent() == null) - { - NavMeshAgent n = targetGameObject.AddComponent(); - n.obstacleAvoidanceType = ObstacleAvoidanceType.NoObstacleAvoidance; - n.avoidancePriority = 0; - n.baseOffset = 0.1f; - n.radius = 1.0f; - } - - break; - case ComponentType.NotWalkable: - if (targetGameObject.GetComponent() == null) - { - NavMeshModifier navMeshModifier = targetGameObject.AddComponent(); - navMeshModifier.overrideArea = true; - navMeshModifier.area = NavMesh.GetAreaFromName("Not Walkable"); - } - - break; - } + // Set the correct tag of the object targetGameObject.tag = tag; + AddComponent(componentType, targetGameObject); Renderer[] renders = targetGameObject.GetComponents(); - foreach (Renderer t in renders) - { - if (t.sharedMaterial == null) continue; - ApplyMaterialProperties(assetBundle, t.sharedMaterial); - - if (generateTransparentMaterials) - { - CreateTransparentMaterial(assetBundle, t.sharedMaterial); - } - } - Renderer[] childRenderers = targetGameObject.GetComponentsInChildren(); - foreach (Renderer t in childRenderers) - { - if (t.sharedMaterial == null) continue; - ApplyMaterialProperties(assetBundle, t.sharedMaterial); - if (generateTransparentMaterials) - { - CreateTransparentMaterial(assetBundle, t.sharedMaterial); - } - } + FixRenderers(renders, assetBundle, generateTransparentMaterials); + FixRenderers(childRenderers, assetBundle, generateTransparentMaterials); // Finally save the asset. Unload the scene, destroy the objects - PrefabUtility.SaveAsPrefabAsset(targetGameObject, assetPath); - SetAssetBundles(assetBundle, assetPath); - PrefabUtility.UnloadPrefabContents(targetGameObject); - AsyncOperation unloading = SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene(), - UnloadSceneOptions.UnloadAllEmbeddedSceneObjects); - - int ticks = 0; - while (unloading != null && !unloading.isDone && ticks < 30) + FinishObject(targetGameObject, assetBundle, assetPath); + } + } + + private static void FinishObject(GameObject targetGameObject, string assetBundle, string assetPath) + { + PrefabUtility.SaveAsPrefabAsset(targetGameObject, assetPath); + SetAssetBundles(assetBundle, assetPath); + PrefabUtility.UnloadPrefabContents(targetGameObject); + AsyncOperation unloading = SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene(), + UnloadSceneOptions.UnloadAllEmbeddedSceneObjects); + + int ticks = 0; + while (unloading != null && !unloading.isDone && ticks < 30) + { + Thread.Sleep(100); + ticks++; + } + } + + /// + /// Function to apply all material properties of the given renderers. + /// + /// + /// + /// + private static void FixRenderers(IEnumerable renderers, string assetBundle, bool generateTransparentMaterials) + { + foreach (Renderer renderer in renderers) + { + if (renderer.sharedMaterial == null) continue; + + // Apply all material properties + ApplyMaterialProperties(assetBundle, renderer.sharedMaterial); + + // Generate a transparent material if required + if (generateTransparentMaterials) { - Thread.Sleep(100); - ticks++; + CreateTransparentMaterial(assetBundle, renderer.sharedMaterial); } } } - private static void ApplyMaterialProperties(string assetBundleName, Material m) + /// + /// Function to apply default properties to a material. + /// + /// + /// + private static void ApplyMaterialProperties(string assetBundleName, Material material) { - if (m.enableInstancing) return; - EditorUtility.SetDirty(m); - m.enableInstancing = true; - SetAssetBundles(assetBundleName, AssetDatabase.GetAssetPath(m.GetInstanceID())); + if (material.enableInstancing) return; + EditorUtility.SetDirty(material); + material.enableInstancing = true; + SetAssetBundles(assetBundleName, AssetDatabase.GetAssetPath(material.GetInstanceID())); } /// /// Function to create a transparent material based on an existing material /// /// - /// - private static void CreateTransparentMaterial(string assetBundleName, Material m) + /// + private static void CreateTransparentMaterial(string assetBundleName, Material originalMaterial) { - string path = AssetDatabase.GetAssetPath(m); + // Get the original path of the material + string path = AssetDatabase.GetAssetPath(originalMaterial); string newFileName = path.Split('/').Last().Insert(0, "Transparent-"); @@ -216,10 +214,12 @@ private static void CreateTransparentMaterial(string assetBundleName, Material m return; } - Material newMaterial = new Material(Shader.Find(m.shader.name)); + Material newMaterial = new Material(Shader.Find(originalMaterial.shader.name)); - newMaterial.CopyPropertiesFromMaterial(m); + // Copy the properties from the original material + newMaterial.CopyPropertiesFromMaterial(originalMaterial); + // Set new properties of material to enable transparency newMaterial.SetInt("_SrcBlend", (int) UnityEngine.Rendering.BlendMode.SrcAlpha); newMaterial.SetInt("_DstBlend", (int) UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); newMaterial.SetInt("_ZWrite", 0); @@ -229,7 +229,11 @@ private static void CreateTransparentMaterial(string assetBundleName, Material m newMaterial.color = new Color(newMaterial.color.r, newMaterial.color.g, newMaterial.color.b, 0.3f); newMaterial.renderQueue = 3000; newMaterial.enableInstancing = true; + + // Finally create the material as an asset AssetDatabase.CreateAsset(newMaterial, newPath); + + // And set the correct asset bundle of the material SetAssetBundles(assetBundleName, newPath); } @@ -243,5 +247,76 @@ private static void SetAssetBundles(string assetBundleName, string assetPath) if (!string.IsNullOrEmpty(assetPath) && !string.IsNullOrEmpty(assetBundleName)) AssetImporter.GetAtPath(assetPath).SetAssetBundleNameAndVariant(assetBundleName, ""); } + + /// + /// Add a component to a game object based on the component type + /// + /// + /// + private static void AddComponent(ComponentType componentType, GameObject targetGameObject) + { + switch (componentType) + { + case ComponentType.NavMeshAgent: + if (targetGameObject.GetComponent() == null) + { + NavMeshAgent n = targetGameObject.AddComponent(); + n.obstacleAvoidanceType = ObstacleAvoidanceType.NoObstacleAvoidance; + n.avoidancePriority = 0; + n.baseOffset = 0.1f; + n.radius = 1.0f; + } + + break; + case ComponentType.NotWalkable: + if (targetGameObject.GetComponent() == null) + { + NavMeshModifier navMeshModifier = targetGameObject.AddComponent(); + navMeshModifier.overrideArea = true; + navMeshModifier.area = NavMesh.GetAreaFromName("Not Walkable"); + } + + break; + case ComponentType.Camera: + // These camera settings are based on the paid assets pack + if (targetGameObject.GetComponent() == null) + { + GameObject cameraObject = new GameObject(); + + Camera camera = cameraObject.AddComponent(); + camera.clearFlags = CameraClearFlags.Color; + // Set default background color + camera.backgroundColor = new Color32(88, 85, 74, 255); + camera.orthographic = false; + + Vector3 defaultPositionForPaidAssetPack = Vector3.zero; + Quaternion defaultRotationForPaidAssetPack = Quaternion.Euler(0, 0, 0); + float defaultFieldOfViewForPaidAssetPack = 0f; + switch (targetGameObject.tag) + { + case "Plane": + cameraObject.tag = "PlaneCamera"; + + defaultPositionForPaidAssetPack = new Vector3(-0.88f, 25.1f, -4.7f); + defaultRotationForPaidAssetPack = Quaternion.Euler(70, 0, 0); + defaultFieldOfViewForPaidAssetPack = 47.1f; + break; + case "Tank": + cameraObject.tag = "TankCamera"; + + defaultPositionForPaidAssetPack = new Vector3(-1.08f, 1f, 0.23f); + defaultFieldOfViewForPaidAssetPack = 60f; + break; + } + + cameraObject.transform.position = defaultPositionForPaidAssetPack; + cameraObject.transform.rotation = defaultRotationForPaidAssetPack; + camera.fieldOfView = defaultFieldOfViewForPaidAssetPack; + cameraObject.transform.SetParent(targetGameObject.transform); + } + + break; + } + } } } \ No newline at end of file diff --git a/src/Assets/Plugins/OpenWebpage.meta b/src/Assets/Plugins/OpenWebpage.meta new file mode 100644 index 0000000..22fcb35 --- /dev/null +++ b/src/Assets/Plugins/OpenWebpage.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7d54f6ba8634e6b4ebce25f94a7fc2d2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Assets/Plugins/OpenWebpage/OpenWebpage.jslib b/src/Assets/Plugins/OpenWebpage/OpenWebpage.jslib new file mode 100644 index 0000000..a27fb7b --- /dev/null +++ b/src/Assets/Plugins/OpenWebpage/OpenWebpage.jslib @@ -0,0 +1,6 @@ +mergeInto(LibraryManager.library, { + + openPage: function (url){ + window.open(Pointer_stringify(url),'_blank'); + } +}); \ No newline at end of file diff --git a/src/Assets/Plugins/OpenWebpage/OpenWebpage.jslib.meta b/src/Assets/Plugins/OpenWebpage/OpenWebpage.jslib.meta new file mode 100644 index 0000000..c090f5a --- /dev/null +++ b/src/Assets/Plugins/OpenWebpage/OpenWebpage.jslib.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: a6bf96a0873faac478ad5f31d0c5db35 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + WebGL: WebGL + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Assets/Resources/Prefabs/UI/UI_Image_Chaos.prefab b/src/Assets/Resources/Prefabs/UI/UI_Image_Chaos.prefab new file mode 100644 index 0000000..0eb245f --- /dev/null +++ b/src/Assets/Resources/Prefabs/UI/UI_Image_Chaos.prefab @@ -0,0 +1,75 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &993539185272044432 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 993539185272044447} + - component: {fileID: 993539185272044445} + - component: {fileID: 993539185272044446} + m_Layer: 5 + m_Name: UI_Image_Chaos + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &993539185272044447 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 993539185272044432} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -662.4, y: -0.7} + m_SizeDelta: {x: 32, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &993539185272044445 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 993539185272044432} + m_CullTransparentMesh: 0 +--- !u!114 &993539185272044446 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 993539185272044432} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 12ade680e28b952408205c4d13d60c45, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 diff --git a/src/Assets/Resources/Prefabs/UI/UI_Image_Chaos.prefab.meta b/src/Assets/Resources/Prefabs/UI/UI_Image_Chaos.prefab.meta new file mode 100644 index 0000000..f9446e2 --- /dev/null +++ b/src/Assets/Resources/Prefabs/UI/UI_Image_Chaos.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ff79a0b94e4e8f647a25b63368fd081d +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Assets/Scenes/MainScene.unity b/src/Assets/Scenes/MainScene.unity index 119b0cb..2b0b621 100644 --- a/src/Assets/Scenes/MainScene.unity +++ b/src/Assets/Scenes/MainScene.unity @@ -392,6 +392,8 @@ RectTransform: - {fileID: 1527529112} - {fileID: 374698886} - {fileID: 415077533} + - {fileID: 413077761} + - {fileID: 783533408} m_Father: {fileID: 1936842677} m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -1731,6 +1733,161 @@ MonoBehaviour: m_BoolArgument: 0 m_CallState: 2 m_IsOn: 0 +--- !u!1 &391003252 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 391003253} + - component: {fileID: 391003255} + - component: {fileID: 391003254} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &391003253 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 391003252} + 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: 461464602} + 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!114 &391003254 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 391003252} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Open + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + 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: 16 + m_fontSizeBase: 16 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 514 + 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_isTextTruncated: 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_VertexBufferAutoSizeReduction: 1 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 391003254} + characterCount: 4 + spriteCount: 0 + spaceCount: 0 + wordCount: 1 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 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!222 &391003255 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 391003252} + m_CullTransparentMesh: 0 --- !u!1 &409300855 GameObject: m_ObjectHideFlags: 0 @@ -1830,6 +1987,131 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0, y: 0} +--- !u!1001 &413077760 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 169449149} + m_Modifications: + - target: {fileID: 993539185272044432, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_Name + value: UI_Image_Plane + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_RootOrder + value: 3 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchoredPosition.x + value: 294 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchoredPosition.y + value: -0.7 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_SizeDelta.x + value: 32 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_SizeDelta.y + value: 32 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchorMin.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchorMin.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchorMax.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchorMax.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_Pivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_Pivot.y + value: 0.5 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: ff79a0b94e4e8f647a25b63368fd081d, type: 3} +--- !u!224 &413077761 stripped +RectTransform: + m_CorrespondingSourceObject: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + m_PrefabInstance: {fileID: 413077760} + m_PrefabAsset: {fileID: 0} --- !u!1 &415077532 GameObject: m_ObjectHideFlags: 0 @@ -2196,7 +2478,7 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 447034565} m_CullTransparentMesh: 0 ---- !u!1 &509078248 +--- !u!1 &461464601 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -2204,36 +2486,166 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 509078249} - - component: {fileID: 509078251} - - component: {fileID: 509078250} + - component: {fileID: 461464602} + - component: {fileID: 461464605} + - component: {fileID: 461464604} + - component: {fileID: 461464603} m_Layer: 5 - m_Name: InfoPanel - m_TagString: InfoPanel + m_Name: OpenURLButton + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &509078249 + m_IsActive: 1 +--- !u!224 &461464602 RectTransform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 509078248} + m_GameObject: {fileID: 461464601} 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: 1424566906} - - {fileID: 204577907} - m_Father: {fileID: 1936842677} - m_RootOrder: 1 + - {fileID: 391003253} + m_Father: {fileID: 509078249} + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 245, y: 56.212097} + m_SizeDelta: {x: 82.92, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &461464603 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 461464601} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, 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.5471698, g: 0.5471698, b: 0.5471698, a: 1} + m_PressedColor: {r: 0.7169812, g: 0.7169812, b: 0.7169812, a: 1} + m_SelectedColor: {r: 0.7075472, g: 0.7075472, b: 0.7075472, a: 1} + m_DisabledColor: {r: 0.3207547, g: 0.3207547, b: 0.3207547, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 461464604} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 2092454561} + m_MethodName: OpenSelectedObjectUrl + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &461464604 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 461464601} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &461464605 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 461464601} + m_CullTransparentMesh: 0 +--- !u!1 &509078248 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 509078249} + - component: {fileID: 509078251} + - component: {fileID: 509078250} + m_Layer: 5 + m_Name: InfoPanel + m_TagString: InfoPanel + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &509078249 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509078248} + 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: 1424566906} + - {fileID: 204577907} + - {fileID: 461464602} + m_Father: {fileID: 1936842677} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0} - m_AnchoredPosition: {x: -305.52158, y: 111.1} - m_SizeDelta: {x: -600, y: 150} + m_AnchoredPosition: {x: -305.52158, y: 121.89} + m_SizeDelta: {x: -600, y: 171.58667} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &509078250 MonoBehaviour: @@ -2853,7 +3265,461 @@ MonoBehaviour: m_enableWordWrapping: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: -1 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_isTextTruncated: 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_VertexBufferAutoSizeReduction: 1 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 656037801} + characterCount: 7 + spriteCount: 0 + spaceCount: 0 + wordCount: 1 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 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!222 &656037802 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 656037799} + m_CullTransparentMesh: 0 +--- !u!1 &694929579 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 694929580} + - component: {fileID: 694929582} + - component: {fileID: 694929581} + m_Layer: 5 + m_Name: Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &694929580 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 694929579} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.8534653, y: 1.8534653, z: 1.8534653} + m_Children: [] + m_Father: {fileID: 297822349} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: -0.0017089844, y: -297} + m_SizeDelta: {x: -884.1006, y: 42.76155} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &694929581 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 694929579} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 0.6675987, b: 0, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &694929582 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 694929579} + m_CullTransparentMesh: 0 +--- !u!1 &710520547 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 710520548} + m_Layer: 0 + m_Name: UI + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &710520548 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 710520547} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 514.268, y: 446.5258, z: 80.5701} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1936842677} + - {fileID: 409300859} + - {fileID: 297822349} + - {fileID: 1574983361} + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &732169497 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 732169500} + - component: {fileID: 732169499} + - component: {fileID: 732169498} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &732169498 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 732169497} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &732169499 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 732169497} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &732169500 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 732169497} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &783533407 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 169449149} + m_Modifications: + - target: {fileID: 993539185272044432, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_Name + value: UI_Image_Tank + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_RootOrder + value: 4 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchoredPosition.x + value: 251 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchoredPosition.y + value: -0.7 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_SizeDelta.x + value: 32 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_SizeDelta.y + value: 32 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchorMin.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchorMin.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchorMax.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_AnchorMax.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_Pivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + propertyPath: m_Pivot.y + value: 0.5 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: ff79a0b94e4e8f647a25b63368fd081d, type: 3} +--- !u!224 &783533408 stripped +RectTransform: + m_CorrespondingSourceObject: {fileID: 993539185272044447, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + m_PrefabInstance: {fileID: 783533407} + m_PrefabAsset: {fileID: 0} +--- !u!1 &790086213 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 790086214} + - component: {fileID: 790086216} + - component: {fileID: 790086215} + - component: {fileID: 790086217} + m_Layer: 5 + m_Name: TopText + m_TagString: TopText + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &790086214 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 790086213} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.7114584, y: 0.7114584, z: 0.7114584} + m_Children: [] + m_Father: {fileID: 1936842677} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 1} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: -56.205128} + m_SizeDelta: {x: 1200, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &790086215 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 790086213} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, 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_colorMode: 3 + 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: 48 + m_fontSizeBase: 48 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 258 + 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: 0 m_linkedTextComponent: {fileID: 0} m_isLinkedTextComponent: 0 m_isTextTruncated: 0 @@ -2876,14 +3742,14 @@ MonoBehaviour: m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} m_textInfo: - textComponent: {fileID: 656037801} - characterCount: 7 + textComponent: {fileID: 790086215} + characterCount: 0 spriteCount: 0 spaceCount: 0 - wordCount: 1 + wordCount: 0 linkCount: 0 - lineCount: 1 - pageCount: 1 + lineCount: 0 + pageCount: 0 materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 @@ -2900,187 +3766,26 @@ MonoBehaviour: - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!222 &656037802 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 656037799} - m_CullTransparentMesh: 0 ---- !u!1 &694929579 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 694929580} - - component: {fileID: 694929582} - - component: {fileID: 694929581} - m_Layer: 5 - m_Name: Image - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &694929580 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 694929579} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1.8534653, y: 1.8534653, z: 1.8534653} - m_Children: [] - m_Father: {fileID: 297822349} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0.5} - m_AnchorMax: {x: 1, y: 0.5} - m_AnchoredPosition: {x: -0.0017089844, y: -297} - m_SizeDelta: {x: -884.1006, y: 42.76155} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &694929581 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 694929579} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 0.6675987, b: 0, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &694929582 +--- !u!222 &790086216 CanvasRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 694929579} + m_GameObject: {fileID: 790086213} m_CullTransparentMesh: 0 ---- !u!1 &710520547 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 710520548} - m_Layer: 0 - m_Name: UI - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &710520548 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 710520547} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 514.268, y: 446.5258, z: 80.5701} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1936842677} - - {fileID: 409300859} - - {fileID: 297822349} - - {fileID: 1574983361} - m_Father: {fileID: 0} - m_RootOrder: 4 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &732169497 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 732169500} - - component: {fileID: 732169499} - - component: {fileID: 732169498} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &732169498 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 732169497} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &732169499 +--- !u!114 &790086217 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 732169497} + m_GameObject: {fileID: 790086213} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Script: {fileID: 11500000, guid: df98bc130010c924492326f4214a4c46, type: 3} m_Name: m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &732169500 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 732169497} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1001 &810967233 PrefabInstance: m_ObjectHideFlags: 0 @@ -3629,6 +4334,52 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 971761102} m_CullTransparentMesh: 0 +--- !u!1 &977681392 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 993539185272044432, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + m_PrefabInstance: {fileID: 413077760} + m_PrefabAsset: {fileID: 0} +--- !u!114 &977681393 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 977681392} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0b148fe25e99eb48b9724523833bab1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 2092454562} + m_MethodName: GoToPlaneCamera + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &977681395 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 993539185272044446, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + m_PrefabInstance: {fileID: 413077760} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 977681392} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1 &999481249 GameObject: m_ObjectHideFlags: 0 @@ -3714,7 +4465,7 @@ GameObject: - component: {fileID: 1011823764} - component: {fileID: 1011823765} m_Layer: 0 - m_Name: CameraCenter_2 + m_Name: Main Camera Script m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -4974,7 +5725,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_text: 'Container: test-service' + m_text: 'Container: test-servicetest-servicetest-servicetest-servicetest-servicetest-servicetest-service' m_isRightToLeft: 0 m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} @@ -5043,12 +5794,12 @@ MonoBehaviour: m_margin: {x: 0, y: 0, z: 0, w: 0} m_textInfo: textComponent: {fileID: 1424566907} - characterCount: 44 + characterCount: 96 spriteCount: 0 spaceCount: 2 wordCount: 2 linkCount: 0 - lineCount: 1 + lineCount: 2 pageCount: 1 materialCount: 1 m_isUsingLegacyAnimationComponent: 0 @@ -7229,6 +7980,7 @@ RectTransform: - {fileID: 1740229892} - {fileID: 169449149} - {fileID: 321470733} + - {fileID: 790086214} m_Father: {fileID: 710520548} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -7323,6 +8075,52 @@ MonoBehaviour: m_PersistentCalls: m_Calls: [] m_IsOn: 1 +--- !u!1 &2017130684 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 993539185272044432, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + m_PrefabInstance: {fileID: 783533407} + m_PrefabAsset: {fileID: 0} +--- !u!114 &2017130685 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2017130684} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0b148fe25e99eb48b9724523833bab1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 2092454562} + m_MethodName: GoToTankCamera + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &2017130687 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 993539185272044446, guid: ff79a0b94e4e8f647a25b63368fd081d, + type: 3} + m_PrefabInstance: {fileID: 783533407} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2017130684} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1 &2050117650 GameObject: m_ObjectHideFlags: 0 @@ -7746,6 +8544,7 @@ GameObject: - component: {fileID: 2092454562} - component: {fileID: 2092454566} - component: {fileID: 2092454570} + - component: {fileID: 2092454571} m_Layer: 0 m_Name: Managers m_TagString: Untagged @@ -7801,6 +8600,7 @@ MonoBehaviour: m_EditorClassIdentifier: InfoPanel: {fileID: 509078248} DestroyButton: {fileID: 204577906} + OpenButton: {fileID: 461464601} --- !u!114 &2092454562 MonoBehaviour: m_ObjectHideFlags: 0 @@ -7814,6 +8614,8 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: ToggleAttackModeCheckbox: {fileID: 374698885} + TankUiImage: {fileID: 2017130687} + PlaneUiImage: {fileID: 977681395} --- !u!114 &2092454563 MonoBehaviour: m_ObjectHideFlags: 0 @@ -7936,6 +8738,23 @@ MonoBehaviour: AssetsLoaded: m_PersistentCalls: m_Calls: [] +--- !u!114 &2092454571 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2092454558} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a60ddf26899871f4cb84a7dfebc85f27, type: 3} + m_Name: + m_EditorClassIdentifier: + MainCamera: {fileID: 1503446977} + CameraChanged: + m_PersistentCalls: + m_Calls: [] + ActiveCamera: 0 --- !u!1 &2130652342 GameObject: m_ObjectHideFlags: 0 diff --git a/src/Assets/Scripts/Components/DestroyGridTile.cs b/src/Assets/Scripts/Components/DestroyGridTile.cs index 17d9879..746e278 100644 --- a/src/Assets/Scripts/Components/DestroyGridTile.cs +++ b/src/Assets/Scripts/Components/DestroyGridTile.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using Assets.Scripts.Managers; using Assets.Scripts.Models; using Assets.Scripts.Utils; @@ -57,14 +55,19 @@ void Update() // Check if the top of boundary is below the ground if (position <= 0) { - // Create a destroyed grass tile - GameObject destroyedGrassTile = - Instantiate( - AssetsManager.Instance.GetPredefinedPrefab(AssetsManager.PrefabType.DestroyedGridTile), _startPos, - Quaternion.identity); - GridManager.Instance.Grid[Tile] = new TileObject - {GameObject = destroyedGrassTile, ObjectType = ObjectType.DestroyedBuilding}; - destroyedGrassTile.name = gameObject.name; + // Create a destroyed grass tile if the tile has not been filled in the meantime + if (GridManager.Instance.Grid[Tile] == null || GridManager.Instance.Grid[Tile].GameObject == null) + { + GameObject destroyedGrassTile = + Instantiate( + AssetsManager.Instance.GetPredefinedPrefab(AssetsManager.PrefabType.DestroyedGridTile), + _startPos, + Quaternion.identity); + GridManager.Instance.Grid[Tile] = new TileObject + {GameObject = destroyedGrassTile, ObjectType = ObjectType.DestroyedBuilding}; + destroyedGrassTile.name = gameObject.name; + } + Destroy(gameObject); } diff --git a/src/Assets/Scripts/Components/Effects/Effect.cs b/src/Assets/Scripts/Components/Effects/Effect.cs index c44da7f..eb29db2 100644 --- a/src/Assets/Scripts/Components/Effects/Effect.cs +++ b/src/Assets/Scripts/Components/Effects/Effect.cs @@ -7,13 +7,17 @@ namespace Assets.Scripts.Components.Effects { /// - /// Component that adds fire effects on the top of a GameObject by using the collision boundaries. + /// Component that adds effects on the top of a GameObject by using the collision boundaries. + /// Call the method to set the correct Fx prefab. /// public class Effect : MonoBehaviour { private readonly List _effects = new List(); - + /// + /// This function will set the correct prefab/effect that is being used to spawn on top of gameobjects. + /// + /// public void SetFx(GameObject fxObject) { Bounds bounds = BoundariesUtil.GetMaxBounds(gameObject); @@ -32,6 +36,7 @@ public void SetFx(GameObject fxObject) void OnDestroy() { + // Destroy all the effects that we have in our memory foreach (GameObject effect in _effects) { Destroy(effect); diff --git a/src/Assets/Scripts/Components/FallingBomb.cs b/src/Assets/Scripts/Components/FallingBomb.cs index e0b00fc..09f7d7b 100644 --- a/src/Assets/Scripts/Components/FallingBomb.cs +++ b/src/Assets/Scripts/Components/FallingBomb.cs @@ -5,19 +5,24 @@ namespace Assets.Scripts.Components { + /// + /// Class used for the bomb that is falling out of the plane. + /// internal class FallingBomb : MonoBehaviour { - void Update() { + // This can only happen when the bomb dropped on something that is not above the world if (transform.position.y < 0) { Destroy(gameObject); return; } + // Make the bomb fall down transform.Translate(transform.up * -10f * Time.deltaTime); + // Check if we hit the building we are aiming at if (Physics.Raycast(transform.position, Vector3.down, out RaycastHit hit, 5f)) { // Check if hit collider is actually a building @@ -31,11 +36,14 @@ void Update() else Debug.LogWarning("Target can not be found"); + // Create an explosion GameObject explosion = Instantiate( AssetsManager.Instance.GetPrefab(SettingsManager.Instance.Settings.AssetBundle.Chaos.ExplosionPrefab), hit.collider.transform.position, Quaternion.identity); Debug.Log($"KILL! {hit.collider.gameObject.name}"); + + // Destroy the explosion and the bomb Destroy(explosion, 10f); Destroy(gameObject); } diff --git a/src/Assets/Scripts/Components/Navigators/PlaneNavigator.cs b/src/Assets/Scripts/Components/Navigators/PlaneNavigator.cs index 0d48d5b..3e9b018 100644 --- a/src/Assets/Scripts/Components/Navigators/PlaneNavigator.cs +++ b/src/Assets/Scripts/Components/Navigators/PlaneNavigator.cs @@ -8,6 +8,9 @@ namespace Assets.Scripts.Components.Navigators { + /// + /// This class is used for the plane to navigate through the map + /// internal class PlaneNavigator : MonoBehaviour { // Speed @@ -19,20 +22,24 @@ internal class PlaneNavigator : MonoBehaviour // Height of the plane public float PlaneHeight = 80f; + // Layer mask that is being used for the Raycast private int _layerMask; + // This property must be set when the airplane fired something so it will not fire again private bool _fired; private GameObject _propeller; + // Do a barrel roll private bool _barrelRoll; + // Keep the euler angles in memory so we can reset the plane after a barrel roll private Vector3 _currentEulerAngles; - private bool _randomFiringEnabled; - + // X border of the plane private int _maxX; + // Z border of the plane private int _maxZ; /// @@ -43,14 +50,20 @@ internal class PlaneNavigator : MonoBehaviour // Start is called before the first frame update void Start() { + // Get the grid boundaries (int maxX, int maxZ) = BoundariesUtil.CalculateMaxGridBoundaries(GridManager.Instance); _maxX = maxX; _maxZ = maxZ; + + // Set the correct LayerMask used in Raycasting _layerMask = LayerMask.GetMask("Default"); + + // Select a random spawn position (Vector3 randomPos, Quaternion rotation) = SelectSpawnPoint(); transform.position = randomPos; transform.rotation = rotation; + // Loop through all children and check if a Proppeler exists for (int i = 0; i < transform.childCount; i++) { if (transform.GetChild(i).name == "Proppeler002") @@ -59,6 +72,7 @@ void Start() } } + // Set the minimum Buildings required for chaos MinimumBuildings = SettingsManager.Instance.Settings.Chaos.MinimumBuildings; } @@ -77,13 +91,15 @@ public void ToggleBarrelRoll() /// Tuple SelectSpawnPoint() { - // if Z is 500, we select -500 & 500 - int[] randomZ = {_maxX * (-1), _maxX}; + // if Z is 500, we select something between the -500 & 500 + int[] randomZ = {_maxZ * (-1), _maxZ}; + // Pick a random value between the for example -500 & 500 int randValue = Random.Range(0, randomZ.Length); Quaternion rotation; - int x = Random.Range(0, 499); + int x = Random.Range(0, _maxX - 1); int z = randomZ[randValue]; + // Set the correct rotation for the plane. if (x > 10 && z < 10) rotation = Quaternion.Euler(0f, 180f, 0f); else if (x > 10 && z > 10) @@ -100,14 +116,19 @@ void LateUpdate() { // Check if the plane is flying out of the boundaries, if so reset the position of the plane if (transform.position.z > _maxZ + 100 || transform.position.x > _maxX + 100 || - transform.position.z < -_maxX - 100 || + transform.position.z < -_maxZ - 100 || transform.position.x < -_maxX - 100) { + // We are crossing the border, set new a position transform.position = SelectSpawnPoint().Item1; transform.rotation = SelectSpawnPoint().Item2; _currentEulerAngles = transform.eulerAngles; + + // Reset fired for this path _fired = false; + + ChaosManager.Instance.PlaneTargetChangedEvent.Invoke(null); } } @@ -131,30 +152,33 @@ void Update() // Calculate rotation and rotate the propeller if (_propeller != null) { - Vector3 newPropellerAngles = new Vector3(_propeller.transform.eulerAngles.x + 10f, - _propeller.transform.eulerAngles.y, - _propeller.transform.eulerAngles.z); - _propeller.transform.eulerAngles = newPropellerAngles; + _propeller.transform.Rotate(0, 0, 90 * 20 * Time.deltaTime); } + // If we already fired or attack mode isn't turned on, return if (_fired || !IsFiringEnabled) return; + // Check if we are flying over a building if (Physics.Raycast(transform.position, Vector3.down, out RaycastHit hit, 200f, _layerMask)) { // Chance of 1 in 100 every frame so still quite a big chance - _randomFiringEnabled = Random.Range(0, 100) == 1; - if (hit.collider.gameObject.CompareTag("Building") && _randomFiringEnabled && CityManager + bool randomFiringEnabled = Random.Range(0, 100) == 1; + + // Check if we hit a building with our raycast and check if the building has the correct requirements + if (hit.collider.gameObject.CompareTag("Building") && randomFiringEnabled && CityManager .Instance.GameModel .Neighbourhoods .Single(x => x.Name == hit.collider.gameObject.name.Replace("neighbourhood-", "")) - .VisualizedObjects.Count(x=>x is IVisualizedBuilding) >= MinimumBuildings) + .VisualizedObjects.Count(x => x is IVisualizedBuilding) >= MinimumBuildings) { + // We met the requirements Drop a bomb on the building _fired = true; Instantiate(AssetsManager.Instance.GetPredefinedPrefab(AssetsManager.PrefabType.Bomb), new Vector3(hit.collider.gameObject.transform.position.x, transform.position.y, hit.collider.gameObject.transform.position.z), Quaternion.identity); - Debug.Log($"HIT! {hit.collider.gameObject.name}"); + ChaosManager.Instance.PlaneTargetChangedEvent.Invoke( + hit.collider.gameObject.name.Replace("neighbourhood-", "")); } } } diff --git a/src/Assets/Scripts/Components/Navigators/TankNavigator.cs b/src/Assets/Scripts/Components/Navigators/TankNavigator.cs index 51121be..69d74fe 100644 --- a/src/Assets/Scripts/Components/Navigators/TankNavigator.cs +++ b/src/Assets/Scripts/Components/Navigators/TankNavigator.cs @@ -5,6 +5,7 @@ using Assets.Scripts.Utils; using UnityEngine; using UnityEngine.AI; +using UnityEngine.Events; namespace Assets.Scripts.Components.Navigators { @@ -12,12 +13,14 @@ namespace Assets.Scripts.Components.Navigators internal class TankNavigator : MonoBehaviour { public IVisualizedObject Target { get; private set; } + private NavMeshAgent _agent; public bool HasTarget { get; private set; } private GameObject _turret; + private bool _rotating = false; /// @@ -25,7 +28,16 @@ internal class TankNavigator : MonoBehaviour /// You can change the standby behavior in /// public bool IsStandby { get; private set; } + + + /// + /// Property to see if the tank is ready to fire (will happen after rotating). + /// public bool IsReadyToFire { get; private set; } + + /// + /// Property to enable or disable firing after the tank is at target. + /// public bool IsFiringEnabled { get; set; } = false; void Start() @@ -34,6 +46,10 @@ void Start() _turret = GameObject.FindGameObjectWithTag("TankTurret"); } + /// + /// Function to set the target of the tank + /// + /// The GameObject of the target should not be null public void SetTarget(IVisualizedObject target) { IsStandby = false; @@ -44,23 +60,31 @@ public void SetTarget(IVisualizedObject target) _agent.isStopped = false; _agent.SetDestination(target.GameObject.transform.position); HasTarget = true; + ChaosManager.Instance.TankTargetChanged.Invoke(target.GameObject.name.Replace("neighbourhood-", "")); } } + /// + /// Function to reset the target of the tank. + /// public void RemoveTarget() { Target = null; HasTarget = false; + ChaosManager.Instance.TankTargetChanged.Invoke(null); } // Update is called once per frame void Update() { + // Check if we have a target and if we are actually at the target if (HasTarget && NavigationUtil.PathComplete(_agent)) { + if (!_rotating && Target != null) { _agent.isStopped = true; + // We stopped rotating so we are ready to fire if (IsFiringEnabled) Fire(); else @@ -82,16 +106,45 @@ private void Fire() StartCoroutine(ApiManager.Instance.KillVisualizedObject(Target)); if (Target.GameObject != null) { + // Create an explosion GameObject explosion = Instantiate( AssetsManager.Instance.GetPredefinedPrefab(AssetsManager.PrefabType.ExplosionFx), Target.GameObject.transform.position, Quaternion.identity); + + // Destroy the explosion after 10 seconds since we don't want this object to stay in the world Destroy(explosion, 10f); } + // Set target back to null Target = null; HasTarget = false; - StartCoroutine(Rotate(transform.eulerAngles.y)); + + // Rotate the turret back to normal + StartCoroutine(RotateBack()); + } + } + + /// + /// Function to rotate the tank turret back to the direction of the tank + /// + /// + private IEnumerator RotateBack() + { + _rotating = true; + float startRotation = _turret.transform.eulerAngles.y; + float t = 0.0f; + while (Math.Abs(_turret.gameObject.transform.rotation.eulerAngles.y - transform.rotation.eulerAngles.y) > + 0.1f) + { + t += Time.deltaTime; + float yRotation = Mathf.Lerp(startRotation, transform.rotation.eulerAngles.y, t / 1.5f) % 360.0f; + _turret.transform.eulerAngles = new Vector3(_turret.transform.eulerAngles.x, yRotation, + _turret.transform.eulerAngles.z); + yield return null; } + + IsReadyToFire = !IsReadyToFire; + _rotating = false; } /// @@ -117,12 +170,17 @@ private IEnumerator Rotate(float targetRotationY) _rotating = false; } + /// + /// Function to set the tank in stand-by mode. Should be used when no valid target can be found. + /// + /// Set this only to true if you want the tank to be in stand-by mode public void SetStandby(bool standby) { + IsStandby = standby; Target = null; HasTarget = false; _agent.ResetPath(); - IsStandby = standby; + ChaosManager.Instance.TankTargetChanged.Invoke(null); } } } \ No newline at end of file diff --git a/src/Assets/Scripts/Components/Navigators/VehicleNavigator.cs b/src/Assets/Scripts/Components/Navigators/VehicleNavigator.cs index 2dc9117..55d3fcb 100644 --- a/src/Assets/Scripts/Components/Navigators/VehicleNavigator.cs +++ b/src/Assets/Scripts/Components/Navigators/VehicleNavigator.cs @@ -45,15 +45,18 @@ public void StartPathFinding(bool enableRenderers = true) { if (Target == null) { + // If the target does not exists anymore for any reason, destroy this vehicle Destroy(gameObject); } else { if (_agent.isActiveAndEnabled) { + // Check if we need to drive back or need to drive to the actual target _agent.SetDestination(_drivingBack ? _startPos : Target.transform.position); if (enableRenderers) { + // Enable all renders for the vehicle foreach (Renderer childRenderer in GetComponentsInChildren()) { childRenderer.enabled = true; diff --git a/src/Assets/Scripts/Components/NeighbourhoodSearch.cs b/src/Assets/Scripts/Components/NeighbourhoodSearch.cs index a8df162..549cd23 100644 --- a/src/Assets/Scripts/Components/NeighbourhoodSearch.cs +++ b/src/Assets/Scripts/Components/NeighbourhoodSearch.cs @@ -49,19 +49,23 @@ public void SearchNeighbourhood(string searchString) CityManager.Instance.GameModel.Neighbourhoods.Where(x => x.Name.Contains(searchString)) .Take(2).ToList(); + // Check how many neighbourhoods we found switch (neighbourhoodModels.Count) { case 2: + // With 2 enabled both buttons NothingFoundText.gameObject.SetActive(false); SetButton(neighbourhoodModels[0], SearchButton1); SetButton(neighbourhoodModels[1], SearchButton2); break; case 1: + // With 1 only enable one button NothingFoundText.gameObject.SetActive(false); SetButton(neighbourhoodModels[0], SearchButton1); DisableButton(SearchButton2); break; default: + // With nothing disable both buttons and set the not found text active NothingFoundText.gameObject.SetActive(true); DisableButton(SearchButton1); DisableButton(SearchButton2); @@ -82,6 +86,7 @@ private static void SetButton(NeighbourhoodModel neighbourhoodModel, Button butt button.gameObject.SetActive(true); + // Remove all onclick listeners and create a new one button.onClick.RemoveAllListeners(); button.onClick.AddListener(() => { OnButtonClick(neighbourhoodModel); }); } diff --git a/src/Assets/Scripts/Components/TopText.cs b/src/Assets/Scripts/Components/TopText.cs new file mode 100644 index 0000000..ceb9376 --- /dev/null +++ b/src/Assets/Scripts/Components/TopText.cs @@ -0,0 +1,66 @@ +using Assets.Scripts.Components.Navigators; +using Assets.Scripts.Managers; +using TMPro; +using UnityEngine; + +namespace Assets.Scripts.Components +{ + /// + /// This class will manage the text on top of the screen. + /// If the active camera is changed it will change the text depending on the type of camera. + /// + public class TopText : MonoBehaviour + { + private TMP_Text _text; + + private string _planeText; + + private string _tankText; + + private string _defaultText = "Searching for a target"; + + // Start is called before the first frame update + void Start() + { + _tankText = _defaultText; + _planeText = _defaultText; + + CameraManager.Instance.CameraChanged.AddListener(UpdateTextByActiveCamera); + ChaosManager.Instance.TankTargetChanged.AddListener(OnTankTargetChanged); + ChaosManager.Instance.PlaneTargetChangedEvent.AddListener(OnPlaneTargetChanged); + _text = GetComponent(); + FindObjectOfType(); + } + + private void OnPlaneTargetChanged(string targetName) + { + _planeText = string.IsNullOrEmpty(targetName) ? _defaultText : $"Target: {targetName}"; + UpdateTextByActiveCamera(); + } + + private void OnTankTargetChanged(string targetName) + { + _tankText = string.IsNullOrEmpty(targetName) ? _defaultText : $"Target: {targetName}"; + UpdateTextByActiveCamera(); + } + + /// + /// Function to update the top text depending on the active camera. + /// + private void UpdateTextByActiveCamera() + { + switch (CameraManager.Instance.ActiveCameraType) + { + case CameraManager.CameraType.PlaneCamera: + _text.text = _planeText; + break; + case CameraManager.CameraType.TankCamera: + _text.text = _tankText; + break; + default: + _text.text = ""; + break; + } + } + } +} \ No newline at end of file diff --git a/src/Assets/Scripts/Components/TopText.cs.meta b/src/Assets/Scripts/Components/TopText.cs.meta new file mode 100644 index 0000000..8e7db64 --- /dev/null +++ b/src/Assets/Scripts/Components/TopText.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df98bc130010c924492326f4214a4c46 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Assets/Scripts/Components/TrafficPanel.cs b/src/Assets/Scripts/Components/TrafficPanel.cs index e493015..d2c1ee3 100644 --- a/src/Assets/Scripts/Components/TrafficPanel.cs +++ b/src/Assets/Scripts/Components/TrafficPanel.cs @@ -45,6 +45,7 @@ private void AssetsLoaded() { foreach (VehiclePrefab vehicle in SettingsManager.Instance.Settings.AssetBundle.Vehicles) { + // Create an image object and add it to the bottom bar GameObject g = Instantiate(Image, BottomPanel.transform); Image img = g.GetComponent(); img.overrideSprite = AssetsManager.Instance.GetVehicleSpritesByType(vehicle.Name); diff --git a/src/Assets/Scripts/Components/TrafficPopup.cs b/src/Assets/Scripts/Components/TrafficPopup.cs index 6a2c0cf..671a329 100644 --- a/src/Assets/Scripts/Components/TrafficPopup.cs +++ b/src/Assets/Scripts/Components/TrafficPopup.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Linq; using Assets.Scripts.Managers; -using Assets.Scripts.Models; using Assets.Scripts.Models.VisualizedObjects; using TMPro; using UnityEngine; @@ -54,6 +53,7 @@ private void UpdatePopup() vehicles = vehicles.Where(x => x.NeighbourhoodModel.Team == TeamManager.Instance.SelectedTeam); } + // Loop through all vehicles and update them foreach (TrafficManager.Vehicle vehicle in vehicles) { if (vehicle.VehicleGameObject != null) @@ -89,6 +89,8 @@ private void AddRow(Sprite sprite, string service, VisualizedVehicleModel vehicl // Add an event trigger object so we can make the button clickable EventTrigger eventTrigger = trafficRow.AddComponent(); EventTrigger.Entry entry = new EventTrigger.Entry {eventID = EventTriggerType.PointerClick}; + + // Add a lambda with the onclick function entry.callback.AddListener(eventData => { OnObjectClickManager.Instance.HighlightVehicle(vehicleGameObject); diff --git a/src/Assets/Scripts/Managers/ApiManager.cs b/src/Assets/Scripts/Managers/ApiManager.cs index 70b3d36..adf4b3c 100644 --- a/src/Assets/Scripts/Managers/ApiManager.cs +++ b/src/Assets/Scripts/Managers/ApiManager.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Runtime.InteropServices; using Assets.Scripts.Interfaces; using Assets.Scripts.Models; using Assets.Scripts.Utils; @@ -160,6 +161,41 @@ private IEnumerator LoadDataFromApi() yield return null; } + /// + /// Function to open the web browser of the device to a specific url that belongs to a neighbourhood. + /// + /// + public IEnumerator OpenNeighbourhoodUrl(string neighbourhoodName) + { + using (UnityWebRequest webRequest = + UnityWebRequest.Get($"{_gameEndpoint}/url?identifier={neighbourhoodName}")) + { + // Request and wait for the desired page. + webRequest.timeout = 10; + yield return webRequest.SendWebRequest(); + if (webRequest.isNetworkError || webRequest.isHttpError) + { + Debug.LogWarning($"Cannot find url of neighbourhood. Error: {webRequest.error}"); + } + else + { + string url = JsonParser.ParseNeighbourhoodUrl(webRequest.downloadHandler.text); + if (!string.IsNullOrEmpty(url)) + { +#if UNITY_WEBGL && !UNITY_EDITOR + openPage(url); +#else + Application.OpenURL(url); +#endif + } + } + + yield return null; + } + + yield return null; + } + /// /// Kill the connection with SignalR when the API manager is being destroyed. /// @@ -169,5 +205,8 @@ void OnDestroy() Debug.Log("Disconnecting from server."); _srLib.Exit(); } + + [DllImport("__Internal")] + private static extern void openPage(string url); } } \ No newline at end of file diff --git a/src/Assets/Scripts/Managers/AssetsManager.cs b/src/Assets/Scripts/Managers/AssetsManager.cs index 004cf62..2a06737 100644 --- a/src/Assets/Scripts/Managers/AssetsManager.cs +++ b/src/Assets/Scripts/Managers/AssetsManager.cs @@ -34,6 +34,7 @@ internal class AssetsManager : Singleton void Start() { SettingsManager.Instance.SettingsLoadedEvent.AddListener(SettingsLoaded); + RuntimePreviewGenerator.BackgroundColor = new Color(0.3f,0.3f,0.3f,0.1f); } private IEnumerator LoadAssetBundle(string url) @@ -311,6 +312,19 @@ private void GenerateVehicleSprites() // Add the sprite to the caching dictionary _spriteCacheDictionary.Add(vehiclePrefab.Name, texture.GenerateSprite()); } + + Texture2D planeTexture = + RuntimePreviewGenerator.GenerateModelPreview( + GetPrefab(SettingsManager.Instance.Settings.AssetBundle.Chaos.PlanePrefab) + .transform); + _spriteCacheDictionary.Add(SettingsManager.Instance.Settings.AssetBundle.Chaos.PlanePrefab, + planeTexture.GenerateSprite()); + Texture2D tankTexture = + RuntimePreviewGenerator.GenerateModelPreview( + GetPrefab(SettingsManager.Instance.Settings.AssetBundle.Chaos.TankPrefab) + .transform); + _spriteCacheDictionary.Add(SettingsManager.Instance.Settings.AssetBundle.Chaos.TankPrefab, + tankTexture.GenerateSprite()); } /// diff --git a/src/Assets/Scripts/Managers/CameraController.cs b/src/Assets/Scripts/Managers/CameraController.cs index e0b0fb3..8e743d0 100644 --- a/src/Assets/Scripts/Managers/CameraController.cs +++ b/src/Assets/Scripts/Managers/CameraController.cs @@ -73,6 +73,7 @@ void Start() // As soon as the grid is changed we calculate the boundaries GridManager.Instance.GridInitializedEvent.AddListener(CalculateMaxCameraBoundaries); + _lockControls = false; } void LateUpdate() @@ -90,14 +91,14 @@ void LateUpdate() } - void FixedUpdate() + void Update() { // Controls are locked, do nothing // Check if user is focused on an UI-element - if (EventSystem.current.IsPointerOverGameObject()) return; + if (EventSystem.current.IsPointerOverGameObject() || !Cam.gameObject.activeInHierarchy) return; // Zoom and rotation is allowed of controls are locked Rotation(); @@ -241,8 +242,8 @@ private void Zoom() // Set the camera's position to the position of the temporary variable - - Cam.fieldOfView = size; + if(size < ZoomMax && size > ZoomMin) + Cam.fieldOfView = size; } /// @@ -293,6 +294,7 @@ public void FocusOnTarget(Vector3 targetPos) /// The following speed, default .1f public void FollowTarget(GameObject targetObj, float speed = .1f) { + if (!Cam.gameObject.activeInHierarchy) return; _followSpeed = speed; FollowTargetObject = targetObj; _lockControls = true; diff --git a/src/Assets/Scripts/Managers/CameraManager.cs b/src/Assets/Scripts/Managers/CameraManager.cs new file mode 100644 index 0000000..65d8616 --- /dev/null +++ b/src/Assets/Scripts/Managers/CameraManager.cs @@ -0,0 +1,68 @@ +using System; +using Assets.Scripts.Utils; +using UnityEngine; +using UnityEngine.Events; + +namespace Assets.Scripts.Managers +{ + internal class CameraManager : Singleton + { + public Camera MainCamera; + + public Camera PlaneCamera { get; set; } + + public Camera TankCamera { get; set; } + + public UnityEvent CameraChanged; + + public CameraType ActiveCameraType; + public Camera ActiveCamera; + + void Start() + { + ActiveCamera = MainCamera; + ActiveCameraType = CameraType.MainCamera; + } + + public void SwitchCamera(CameraType cameraType) + { + switch (cameraType) + { + case CameraType.MainCamera: + if (PlaneCamera != null) + PlaneCamera.gameObject.SetActive(false); + if (TankCamera != null) + TankCamera.gameObject.SetActive(false); + MainCamera.gameObject.SetActive(true); + ActiveCamera = MainCamera; + break; + case CameraType.PlaneCamera: + MainCamera.gameObject.SetActive(false); + if (TankCamera != null) + TankCamera.gameObject.SetActive(false); + PlaneCamera.gameObject.SetActive(true); + ActiveCamera = PlaneCamera; + break; + case CameraType.TankCamera: + MainCamera.gameObject.SetActive(false); + if (PlaneCamera != null) + PlaneCamera.gameObject.SetActive(false); + TankCamera.gameObject.SetActive(true); + ActiveCamera = TankCamera; + break; + default: + throw new ArgumentOutOfRangeException(nameof(cameraType), cameraType, null); + } + + ActiveCameraType = cameraType; + CameraChanged?.Invoke(); + } + + public enum CameraType + { + MainCamera, + PlaneCamera, + TankCamera + } + } +} \ No newline at end of file diff --git a/src/Assets/Scripts/Managers/CameraManager.cs.meta b/src/Assets/Scripts/Managers/CameraManager.cs.meta new file mode 100644 index 0000000..40f9841 --- /dev/null +++ b/src/Assets/Scripts/Managers/CameraManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a60ddf26899871f4cb84a7dfebc85f27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Assets/Scripts/Managers/ChaosManager.cs b/src/Assets/Scripts/Managers/ChaosManager.cs index 9bf49fa..890e772 100644 --- a/src/Assets/Scripts/Managers/ChaosManager.cs +++ b/src/Assets/Scripts/Managers/ChaosManager.cs @@ -1,13 +1,15 @@ -using Assets.Scripts.Components; +using System; using Assets.Scripts.Interfaces; using Assets.Scripts.Models; using Assets.Scripts.Models.VisualizedObjects; using Assets.Scripts.Utils; using UnityEngine; -using System; using System.Collections.Generic; using System.Linq; +using Assets.Scripts.Components; using Assets.Scripts.Components.Navigators; +using UnityEngine.Events; +using UnityEngine.UI; namespace Assets.Scripts.Managers { @@ -17,14 +19,28 @@ namespace Assets.Scripts.Managers /// internal class ChaosManager : Singleton { + [System.Serializable] + internal class TargetChangedEvent : UnityEvent + { + } + + // UI elements public GameObject ToggleAttackModeCheckbox; + public Image TankUiImage; + public Image PlaneUiImage; + + public TargetChangedEvent TankTargetChanged; + + public TargetChangedEvent PlaneTargetChangedEvent; + + // Objects private GameObject _tankGameObject; private GameObject _planeGameObject; private TankNavigator _tankNavigator; private PlaneNavigator _planeNavigator; + // Other private bool _foundTargets; - private int _minimumBuildings = 2; // Start is called before the first frame update @@ -32,6 +48,38 @@ void Start() { GridManager.Instance.GridInitializedEvent.AddListener(GridInitialized); TeamManager.Instance.TeamSelectionChangedEvent.AddListener(TeamSelectionChanged); + AssetsManager.Instance.AssetsLoaded.AddListener(AssetsLoaded); + CameraManager.Instance.CameraChanged.AddListener(OnCameraChanged); + } + + private void OnCameraChanged() + { + Color planeUiColor = Color.white; + Color tankUiColor = Color.white; + switch (CameraManager.Instance.ActiveCameraType) + { + case CameraManager.CameraType.PlaneCamera: + planeUiColor = Color.green; + break; + case CameraManager.CameraType.TankCamera: + tankUiColor = Color.green; + break; + } + + if (PlaneUiImage != null) + PlaneUiImage.color = planeUiColor; + if (TankUiImage != null) + TankUiImage.color = tankUiColor; + } + + private void AssetsLoaded() + { + TankUiImage.sprite = + AssetsManager.Instance.GetVehicleSpritesByType(SettingsManager.Instance.Settings.AssetBundle.Chaos + .TankPrefab); + PlaneUiImage.sprite = + AssetsManager.Instance.GetVehicleSpritesByType(SettingsManager.Instance.Settings.AssetBundle.Chaos + .PlanePrefab); } /// @@ -53,6 +101,12 @@ private void GridInitialized() spawnPoint.Key, spawnPoint.Value); _tankNavigator = _tankGameObject.AddComponent(); + CameraManager.Instance.TankCamera = _tankGameObject.GetComponentInChildren(); + CameraManager.Instance.TankCamera.gameObject.SetActive(false); + } + else + { + Destroy(TankUiImage); } if (SettingsManager.Instance.Settings.Chaos.PlaneEnabled) @@ -63,6 +117,12 @@ private void GridInitialized() AssetsManager.Instance.GetPredefinedPrefab(AssetsManager.PrefabType.Plane), new Vector3(0f, 80f, 0f), Quaternion.Euler(0f, 90f, 0f)); _planeNavigator = _planeGameObject.AddComponent(); + CameraManager.Instance.PlaneCamera = _planeGameObject.GetComponentInChildren(); + CameraManager.Instance.PlaneCamera.gameObject.SetActive(false); + } + else + { + Destroy(PlaneUiImage); } _minimumBuildings = SettingsManager.Instance.Settings.Chaos.MinimumBuildings; @@ -93,7 +153,7 @@ public void SetFiringEnabled(bool firingEnabled) /// void LateUpdate() { - // We need to pick a new target here + // We need to pick a new target for the tank here if (_tankNavigator != null && _tankNavigator.Target == null && !_tankNavigator.IsStandby) { IVisualizedObject target = SelectTarget(); @@ -142,12 +202,10 @@ private IVisualizedObject SelectTarget() return null; } + // Pick a random neighbourhood from the list NeighbourhoodModel randomNeighbourhoodModel = randomNeighbourhoodQuery.PickRandom(); - // No target found. Tank is probably going in standby mode now. - - // We found a target and it's a building. Return the target. IVisualizedObject obj = randomNeighbourhoodModel.VisualizedObjects .First(visualizedObject => @@ -155,5 +213,29 @@ private IVisualizedObject SelectTarget() _foundTargets = true; return obj; } + + public void GoToTankCamera() + { + if (CameraManager.Instance.ActiveCameraType == CameraManager.CameraType.TankCamera) + { + CameraManager.Instance.SwitchCamera(CameraManager.CameraType.MainCamera); + } + else + { + CameraManager.Instance.SwitchCamera(CameraManager.CameraType.TankCamera); + } + } + + public void GoToPlaneCamera() + { + if (CameraManager.Instance.ActiveCameraType == CameraManager.CameraType.PlaneCamera) + { + CameraManager.Instance.SwitchCamera(CameraManager.CameraType.MainCamera); + } + else + { + CameraManager.Instance.SwitchCamera(CameraManager.CameraType.PlaneCamera); + } + } } } \ No newline at end of file diff --git a/src/Assets/Scripts/Managers/CityManager.cs b/src/Assets/Scripts/Managers/CityManager.cs index af74469..5e560bb 100644 --- a/src/Assets/Scripts/Managers/CityManager.cs +++ b/src/Assets/Scripts/Managers/CityManager.cs @@ -36,7 +36,14 @@ void Update() { if (Input.GetKeyDown(KeyCode.Escape)) { - SceneManager.LoadScene("MainMenu"); + if (CameraManager.Instance.ActiveCameraType != CameraManager.CameraType.MainCamera) + { + CameraManager.Instance.SwitchCamera(CameraManager.CameraType.MainCamera); + } + else + { + SceneManager.LoadScene("MainMenu"); + } } } @@ -120,8 +127,8 @@ private void RemoveVisualizedBuildings(string neighbourhoodName, string identifi neighbourhoodModel.Name == neighbourhoodName); // Make a list of buildings we need to remove. We don't want to remove vehicles in this manager. List removedBuildings = - neighbourhood?.VisualizedObjects.Where( - x => x.Identifier == identifier && x is IVisualizedBuilding).Cast().ToList(); + neighbourhood?.VisualizedObjects.OfType().Where( + x => x.Identifier == identifier).ToList(); if (removedBuildings != null) { foreach (IVisualizedBuilding removedBuilding in removedBuildings) @@ -171,6 +178,7 @@ private void UpdateNeighbourhood(string neighbourhoodName, NeighbourhoodModel up neighbourhoodModel.Name == neighbourhoodName); if (neighbourhood != null) { + // Update the age and layer values of the neighbourhood neighbourhood.Age = updatedNeighbourhood.Age; neighbourhood.LayerValues = updatedNeighbourhood.LayerValues; } @@ -232,8 +240,10 @@ private void AddBuilding(string neighbourhoodName, IVisualizedObject newVisualiz } // Check if there are buildings with the same identifier. - List existingVisualizedObjects = neighbourhood.VisualizedObjects.Where(x => - x.Identifier == newVisualizedObject.Identifier && x is IVisualizedBuilding).Cast().ToList(); + List existingVisualizedObjects = neighbourhood.VisualizedObjects + .OfType().Where(x => + x.Identifier == newVisualizedObject.Identifier) + .ToList(); // Destroy every building that has the same identifier. foreach (IVisualizedBuilding visualizedObject in existingVisualizedObjects) diff --git a/src/Assets/Scripts/Managers/GridManager.cs b/src/Assets/Scripts/Managers/GridManager.cs index 8f672c4..4ae9953 100644 --- a/src/Assets/Scripts/Managers/GridManager.cs +++ b/src/Assets/Scripts/Managers/GridManager.cs @@ -156,6 +156,8 @@ private void SpawnRandomRoad(int startZ) /// private void SpawnMainRoads() { + // Loop through all empty tiles on the borders of the map + // X = 0 | X = 500 for example. 0,0 0,10 0,20... 490,0 490,10 490,20... foreach (KeyValuePair tile in Grid .Where(tile => tile.Key.X == 0 || (tile.Key.X == Cols * TileSize - TileSize) && tile.Value == null) .ToList()) @@ -163,6 +165,7 @@ private void SpawnMainRoads() AssetsManager.PrefabType prefabType = AssetsManager.PrefabType.RoadStraight; Quaternion rotation = Quaternion.Euler(0, 90f, 0); + // Calculate the rotation of the corner by checking the position in the map if (tile.Key.X == Cols * TileSize - TileSize && tile.Key.Z == Rows * TileSize - TileSize) { rotation = Quaternion.Euler(0, 270f, 0); @@ -183,13 +186,16 @@ private void SpawnMainRoads() rotation = Quaternion.Euler(0, 90f, 0); prefabType = AssetsManager.PrefabType.RoadCorner; } - + // Spawn the road GameObject gameObj = Instantiate(AssetsManager.Instance.GetPredefinedPrefab(prefabType), new Vector3(tile.Key.X, 0.5f, tile.Key.Z), rotation); + + // Override the tile Grid[tile.Key] = new TileObject {ObjectType = ObjectType.Road, GameObject = gameObj}; } + // Create the last road on the map foreach (KeyValuePair tile in Grid .Where(tile => (tile.Key.Z == 0 || tile.Key.Z == Rows * TileSize - TileSize) && tile.Value == null) .ToList()) @@ -212,43 +218,52 @@ private void SpawnMainRoads() /// public void SpawnNeighbourhood(NeighbourhoodModel neighbourhoodModel) { + // If there are no visualized objects, destroy the block if (neighbourhoodModel.VisualizedObjects.Count < 1) { DestroyBlock(neighbourhoodModel, false); return; } + // Make a list of buildings List visualizedObjects = neighbourhoodModel.VisualizedObjects.OfType().ToList(); // Calculate total tile count we need to spawn this building (if building is wider than the TileSize) int tileCount = GetTotalTilesRequired(visualizedObjects, neighbourhoodModel.Age) + 1; + // Find the amount of tiles we need to spawn this neighbourhood List tiles = FindTiles(tileCount); + if (tiles.Count != tileCount) { + // Can't spawn the neighbourhood. Not enough tiles per street. Debug.LogError( "Building block went wrong. Not enough tiles!\r\nIncrease the TilesPerStreet in the config.json"); return; } + // Set spawn offset and tile index to 0 float spawnOffsetX = 0; int tileIndex = 0; // Loop through all the visualized objects for (int index = 0; index < visualizedObjects.Count; index++) { + // Get the correct tile Tile tile = tiles[tileIndex]; // If the tile is already filled, destroy it. if (Grid[tile] != null && Grid[tile].GameObject != null) Destroy(Grid[tile].GameObject); + // Spawn a building at this street GameObject building = SpawnBuilding(tile, visualizedObjects[index].Size, neighbourhoodModel.Age, neighbourhoodModel, visualizedObjects[index] is VisualizedStagingBuildingModel); + // Set the correct tile information Grid[tile] = new TileObject {GameObject = building, ObjectType = ObjectType.Building}; tileIndex++; - // Check how many tiles we need to spawsn this building + // Check how many tiles we need to spawn this building int tilesRequired = GetTilesRequiredForBuilding(building); // Check if we need more than 1 tile for this building @@ -260,28 +275,35 @@ public void SpawnNeighbourhood(NeighbourhoodModel neighbourhoodModel) if (hit.transform.gameObject.CompareTag("Grass") || hit.transform.gameObject.CompareTag("Road")) spawnOffsetX += hit.distance; } - + // We might need to move the building to align perfectly like calculated in the raycast. building.transform.position = new Vector3(building.transform.position.x + spawnOffsetX, building.transform.position.y, building.transform.position.z); for (int i = 1; i < tilesRequired; i++) { + // If we need more than 1 tile fill the next tiles as well + // This will only happen if the building is wider than the TileSize Tile tile2 = tiles[tileIndex]; + // Destroy existing object if it's not the building we are trying to spawn if (Grid[tile2] != null && !Grid[tile2].GameObject.Equals(building)) Destroy(Grid[tile2].GameObject); + + // Set the correct tile information Grid[tile2] = new TileObject {GameObject = building, ObjectType = ObjectType.Building}; tileIndex++; } } - + // Set the correct game object in the visualized object of the neighbourhood so we can use it as reference neighbourhoodModel .VisualizedObjects[neighbourhoodModel.VisualizedObjects.IndexOf(visualizedObjects[index])] .GameObject = building; } + // Spawn a grass patch as a divider between buildings GameObject grassPatch = Instantiate( AssetsManager.Instance.GetPredefinedPrefab(AssetsManager.PrefabType.Grass), new Vector3(tiles.Last().X, 0.5f, tiles.Last().Z), Quaternion.Euler(0, 90f, 0)); + // Add the grass patch to the list of visualized objects neighbourhoodModel.VisualizedObjects.Add(new VisualizedGrassTileModel {GameObject = grassPatch}); Grid[tiles.Last()] = new TileObject @@ -299,6 +321,7 @@ public void SpawnNeighbourhood(NeighbourhoodModel neighbourhoodModel) /// public GameObject SpawnBuilding(Tile tile, int size, int age, NeighbourhoodModel neighbourhood, bool staging) { + // Default rotation Quaternion buildingRotation = Quaternion.Euler(0, 90f, 0); GameObject building; if (staging) @@ -307,13 +330,16 @@ public GameObject SpawnBuilding(Tile tile, int size, int age, NeighbourhoodModel } else { + // Extract the tuple with the building prefab and the rotation (GameObject buildingObject, float rotation) = AssetsManager.Instance.GetBuildingPrefab(size, age); buildingRotation = Quaternion.Euler(0, rotation, 0); building = buildingObject; } + // Spawn the prefab with the correct location and rotation building = Instantiate(building, new Vector3(tile.X, 0.5f, tile.Z), buildingRotation); + // Set the name of the object so we can use it later as a reference building.name = $"neighbourhood-{neighbourhood.Name}"; return building; } @@ -328,17 +354,19 @@ public void DestroyBuilding(IVisualizedBuilding visualizedObject, bool destroyEf { if (visualizedObject.GameObject == null) return; + // Get the correct tile from the grid List> gridObjects = Grid.Where(t => t.Value != null && t.Value.GameObject != null && t.Value.GameObject.Equals(visualizedObject.GameObject)).ToList(); foreach (KeyValuePair gridObject in gridObjects) { + // Check if we want a destroy effect or not if (visualizedObject is VisualizedStagingBuildingModel || !destroyEffect) Destroy(visualizedObject.GameObject); else visualizedObject.GameObject.AddComponent().Tile = gridObject.Key; - + // Set the tile to null Grid[gridObject.Key] = null; } } @@ -462,7 +490,7 @@ public int GetTotalTilesRequired(IEnumerable buildings, int public int GetTilesRequiredForBuilding(GameObject building) { const int threshold = 1; - int tiles = 0; + int tiles = 1; Vector3 sizeBounds = building.GetComponent().sharedMesh.bounds.size; @@ -472,7 +500,6 @@ public int GetTilesRequiredForBuilding(GameObject building) tiles++; } - tiles++; return tiles; } diff --git a/src/Assets/Scripts/Managers/LayerManager.cs b/src/Assets/Scripts/Managers/LayerManager.cs index 176f4ae..fa53596 100644 --- a/src/Assets/Scripts/Managers/LayerManager.cs +++ b/src/Assets/Scripts/Managers/LayerManager.cs @@ -49,7 +49,10 @@ public void Setup(GameModel gameModel) { if (SettingsManager.Instance.Settings.Layers.Enabled) { + // Default Y = -20 float y = -20f; + + // Loop through all layers and generate a button with the correct texture foreach (VisualLayerModel layer in gameModel.Layers) { StartCoroutine(GenerateButtonWithTexture(layer, 0f, y)); @@ -61,6 +64,7 @@ public void Setup(GameModel gameModel) float heightDeltaY = rt.sizeDelta.y; + // Set the correct height for the layers panel heightDeltaY += gameModel.Layers.Count * 50; rt.sizeDelta = new Vector2(rt.sizeDelta.x, heightDeltaY); @@ -96,29 +100,37 @@ private IEnumerator GenerateButtonWithTexture(VisualLayerModel visualLayer, floa { GameObject buttonObject = new GameObject(); + // Create a button Button button = buttonObject.AddComponent