commit 039ae76a141bf6cc7253c5489baf6c167a0ae7a2 Author: in0finite Date: Sun May 31 19:07:22 2020 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b9547729 --- /dev/null +++ b/.gitignore @@ -0,0 +1,78 @@ +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ +[Tt]est/ +[Bb]uild/ +[Ss]onarQube/ +sonarqube.cmd + +# Autogenerated VS/MD solution and project files +/*.csproj +/*.unityproj +/*.sln +/*.suo +/*.user +/*.userprefs +/*.pidb +/*.pdb +/*.booproj +/.vs + +# Built program and data +/*.exe +/*_Data +*.apk +*.unitypackage + +# ============ # +# OS generated # +# ============ # +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Unity3D generated meta files +*.pidb.meta + +#Unity3D Generated File On Crash Reports +sysinfo.txt + +# Custom + +*.xml +.sonarqube/ +SonarQube/ +Build/Build_Data/StreamingAssets/ +Assets/StreamingAssets/*.log +Assets/StreamingAssets/*.html +Assets/StreamingAssets/*.meta +Assets/FromAssetStore/LlamaSoftware/LightLod/Demo/ +Assets/FromAssetStore/SpriteLights/Scenes/ + +# Clean-up + +VS/ +Assets/StreamingAssets/SAConsole/ +Assets/Plugins/SAPI/ +Assets/Plugins/SAPI.meta + +# I have to except one html & log as example + +**UnityVS** + +#Assets/Standard Assets +#Assets/Standard Assets.meta +#Assets/Editor/ImageEffects +#Assets/Editor/ImageEffects.meta + +#Assets/Scripts/Generated/*.cs +#Assets/Scripts/Generated/*.cs.meta + +config.user.json +anim.txt +*.app +*.ppm diff --git a/Assets/Materials.meta b/Assets/Materials.meta new file mode 100644 index 00000000..dd53ad1c --- /dev/null +++ b/Assets/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8cc124e3fa362490da94c0ffec66efbd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/BarMaterial.mat b/Assets/Materials/BarMaterial.mat new file mode 100644 index 00000000..20f86988 --- /dev/null +++ b/Assets/Materials/BarMaterial.mat @@ -0,0 +1,76 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: BarMaterial + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/Materials/BarMaterial.mat.meta b/Assets/Materials/BarMaterial.mat.meta new file mode 100644 index 00000000..b52b79ca --- /dev/null +++ b/Assets/Materials/BarMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 462655ef225074e38955bd3d2c859996 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/GroundMaterial.mat b/Assets/Materials/GroundMaterial.mat new file mode 100644 index 00000000..d980c251 --- /dev/null +++ b/Assets/Materials/GroundMaterial.mat @@ -0,0 +1,76 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: GroundMaterial + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.33962262, g: 0.31173217, b: 0.056069765, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/Materials/GroundMaterial.mat.meta b/Assets/Materials/GroundMaterial.mat.meta new file mode 100644 index 00000000..7da5b08a --- /dev/null +++ b/Assets/Materials/GroundMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e35c2e98492314f7ba69db58641d55d4 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins.meta b/Assets/Plugins.meta new file mode 100644 index 00000000..87838e19 --- /dev/null +++ b/Assets/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d9cdcd5129097a4ca020d7c7108268c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/GTAAudioSharp.dll b/Assets/Plugins/GTAAudioSharp.dll new file mode 100644 index 00000000..3c1cdf32 Binary files /dev/null and b/Assets/Plugins/GTAAudioSharp.dll differ diff --git a/Assets/Plugins/GTAAudioSharp.dll.meta b/Assets/Plugins/GTAAudioSharp.dll.meta new file mode 100644 index 00000000..a60799a3 --- /dev/null +++ b/Assets/Plugins/GTAAudioSharp.dll.meta @@ -0,0 +1,30 @@ +fileFormatVersion: 2 +guid: d1d87ea3b404e405084dfa85ce5c4c0d +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NVorbis.dll b/Assets/Plugins/NVorbis.dll new file mode 100644 index 00000000..282aca69 Binary files /dev/null and b/Assets/Plugins/NVorbis.dll differ diff --git a/Assets/Plugins/NVorbis.dll.meta b/Assets/Plugins/NVorbis.dll.meta new file mode 100644 index 00000000..a9cad38f --- /dev/null +++ b/Assets/Plugins/NVorbis.dll.meta @@ -0,0 +1,30 @@ +fileFormatVersion: 2 +guid: ecffd2aec4232496fae0a66357fa4dc8 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Newtonsoft.Json.dll b/Assets/Plugins/Newtonsoft.Json.dll new file mode 100644 index 00000000..0a61735d Binary files /dev/null and b/Assets/Plugins/Newtonsoft.Json.dll differ diff --git a/Assets/Plugins/Newtonsoft.Json.dll.meta b/Assets/Plugins/Newtonsoft.Json.dll.meta new file mode 100644 index 00000000..87b8f422 --- /dev/null +++ b/Assets/Plugins/Newtonsoft.Json.dll.meta @@ -0,0 +1,24 @@ +fileFormatVersion: 2 +guid: 2456b79ad58a18f46a3234355e9ccda2 +timeCreated: 1428170678 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + platformData: + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + DefaultValueInitialized: true + WindowsStoreApps: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs.meta b/Assets/Prefabs.meta new file mode 100644 index 00000000..18b021f7 --- /dev/null +++ b/Assets/Prefabs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2bc786a0d0ca44d44a9ad3f2580d153c +folderAsset: yes +timeCreated: 1428857476 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Bar.prefab b/Assets/Prefabs/Bar.prefab new file mode 100644 index 00000000..de6235a2 --- /dev/null +++ b/Assets/Prefabs/Bar.prefab @@ -0,0 +1,273 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1593438409806284} + m_IsPrefabParent: 1 +--- !u!1 &1171840773875052 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4701839834558394} + - component: {fileID: 33657283202367978} + - component: {fileID: 23531935586254422} + m_Layer: 0 + m_Name: Border + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!1 &1411512408611134 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4726725973345636} + - component: {fileID: 33373223207792738} + - component: {fileID: 23454915502141244} + m_Layer: 0 + m_Name: Fill + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1593438409806284 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4499964060633094} + - component: {fileID: 114589864964184512} + m_Layer: 0 + m_Name: Bar + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1914116251164102 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4080981792371420} + - component: {fileID: 33307161497582294} + - component: {fileID: 23642605326664974} + m_Layer: 0 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4080981792371420 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1914116251164102} + 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: 4499964060633094} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4499964060633094 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1593438409806284} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4.16, y: 3.69, z: 3.73} + m_LocalScale: {x: 1, y: 0.2, z: 1} + m_Children: + - {fileID: 4701839834558394} + - {fileID: 4080981792371420} + - {fileID: 4726725973345636} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4701839834558394 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1171840773875052} + 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: 4499964060633094} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4726725973345636 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1411512408611134} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -0.01} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 4499964060633094} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!23 &23454915502141244 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1411512408611134} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: 462655ef225074e38955bd3d2c859996, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!23 &23531935586254422 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1171840773875052} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: 462655ef225074e38955bd3d2c859996, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!23 &23642605326664974 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1914116251164102} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: 462655ef225074e38955bd3d2c859996, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &33307161497582294 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1914116251164102} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!33 &33373223207792738 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1411512408611134} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!33 &33657283202367978 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1171840773875052} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &114589864964184512 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1593438409806284} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c7111f45c86a74947af5f6831ab01122, type: 3} + m_Name: + m_EditorClassIdentifier: + faceTowardsCamera: 1 diff --git a/Assets/Prefabs/Bar.prefab.meta b/Assets/Prefabs/Bar.prefab.meta new file mode 100644 index 00000000..7208cdce --- /dev/null +++ b/Assets/Prefabs/Bar.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 92671d073b68a421fa8cf12bd74315cb +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/GameManager.prefab b/Assets/Prefabs/GameManager.prefab new file mode 100644 index 00000000..866cbb6b --- /dev/null +++ b/Assets/Prefabs/GameManager.prefab @@ -0,0 +1,175 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1297494511425690} + m_IsPrefabParent: 1 +--- !u!1 &1297494511425690 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4476511338334242} + - component: {fileID: 114366052828304570} + - component: {fileID: 114659537100185892} + - component: {fileID: 114195546318360620} + - component: {fileID: 114805125582614736} + - component: {fileID: 114529712737653322} + - component: {fileID: 114560248511158306} + - component: {fileID: 114468774129516696} + - component: {fileID: 114463745687567314} + m_Layer: 0 + m_Name: GameManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4476511338334242 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2060.4775, y: 18.083828, z: 792.3567} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &114195546318360620 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 769ff20407cff41688e681458d8528fb, type: 3} + m_Name: + m_EditorClassIdentifier: + logoTexture: {fileID: 2800000, guid: 7ba03d38f2c9d483eb98097a1990d3ec, type: 3} + barPrefab: {fileID: 1593438409806284, guid: 92671d073b68a421fa8cf12bd74315cb, type: 2} +--- !u!114 &114366052828304570 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: baae2154fadd37540b96289b2b9e9d39, type: 3} + m_Name: + m_EditorClassIdentifier: + spawnOffset: {x: 0, y: 2, z: 5} + spawnKey: 118 +--- !u!114 &114463745687567314 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c0735457b0cfd4a77bab1c58f1d77882, type: 3} + m_Name: + m_EditorClassIdentifier: + playStartupSound: 1 + startupSoundTimeOffset: 4 +--- !u!114 &114468774129516696 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: be87ebc3b426867448164f659f750671, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114529712737653322 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2d4bc8271f92a431080da3f76af5f901, type: 3} + m_Name: + m_EditorClassIdentifier: + pedPrefab: {fileID: 1273918895060814, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + displayHealthBarAbovePeds: 1 + healthBarWorldWidth: 0.65 + healthBarWorldHeight: 0.08 + healthBarMaxScreenHeight: 8 + healthBarVerticalOffset: 0.3 + AIStoppingDistance: 3 + AIVehicleEnterDistance: 1.25 + AIOutOfRangeTimeout: 5 + AIOutOfRangeDistance: 250 +--- !u!114 &114560248511158306 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 409653cfe36614ceab3cbfbf9ed04fce, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114659537100185892 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 987093d4b0d5b09428ae0410f453a296, type: 3} + m_Name: + m_EditorClassIdentifier: + actionKey: 112 +--- !u!114 &114805125582614736 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1297494511425690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5b19ecbdc94cb426782bb12647cbe133, type: 3} + m_Name: + m_EditorClassIdentifier: + m_animConvertMultiplier: 3.25 + m_gunFlashDuration: 0.07 + m_gunFlashRotationSpeed: 3600 + AIMWITHARM_headRotationOffset: {x: 0, y: 0, z: 90} + AIMWITHARM_clavicleRotationOffset: {x: 0, y: 0, z: 0} + AIMWITHARM_upperArmRotationOffset: {x: 150, y: -90, z: 0} + AIMWITHARM_foreArmRotationOffset: {x: 150, y: -90, z: 0} + AIMWITHARM_handRotationOffset: {x: -90, y: 0, z: 0} + AIMWITHARM_controlUpperArm: 1 + AIMWITHARM_controlForeArm: 1 + AIMWITHARM_controlHand: 1 + AIMWITHARM_upperArmStartRotationEulers: {x: -1.686, y: 164.627, z: -97.904} + AIMWITHARM_upperArmEndRotationEulers: {x: 170, y: -90, z: -2.412} + AIMWITHARM_maxAimAngle: 95 + AIMWITHARM_maxHeadRotationAngle: 50 + crouchSpineRotationOffset: {x: 0, y: 35, z: 90} + crouchSpineRotationOffset2: {x: 0, y: 15, z: 90} + projectileRaycastMask: + serializedVersion: 2 + m_Bits: 4294967291 + drawLineFromGun: 0 diff --git a/Assets/Prefabs/GameManager.prefab.meta b/Assets/Prefabs/GameManager.prefab.meta new file mode 100644 index 00000000..95579377 --- /dev/null +++ b/Assets/Prefabs/GameManager.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9678826ffd3ed244997780ccbdec99b7 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Networkable.meta b/Assets/Prefabs/Networkable.meta new file mode 100644 index 00000000..9ee71edb --- /dev/null +++ b/Assets/Prefabs/Networkable.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 303f8e34e1374d14f8fc7cbc7df5aa90 +folderAsset: yes +timeCreated: 1428857483 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Networkable/Player.prefab b/Assets/Prefabs/Networkable/Player.prefab new file mode 100644 index 00000000..8639447d --- /dev/null +++ b/Assets/Prefabs/Networkable/Player.prefab @@ -0,0 +1,230 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &151936 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 411904} + - 143: {fileID: 14323918} + - 114: {fileID: 11434656} + m_Layer: 0 + m_Name: Player + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &168992 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 480888} + - 114: {fileID: 11405868} + - 111: {fileID: 11181010} + - 114: {fileID: 11456232} + m_Layer: 0 + m_Name: PlayerModel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &188192 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 438450} + - 20: {fileID: 2096612} + - 124: {fileID: 12438378} + - 92: {fileID: 9280882} + - 81: {fileID: 8126816} + m_Layer: 0 + m_Name: Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!4 &411904 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 151936} + 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: 480888} + - {fileID: 438450} + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!4 &438450 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 188192} + 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: 411904} + m_RootOrder: 1 +--- !u!4 &480888 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168992} + 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: 411904} + m_RootOrder: 0 +--- !u!20 &2096612 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 188192} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: .192156866, g: .301960796, b: .474509805, a: .0196078438} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: .300000012 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_HDR: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: .0219999999 +--- !u!81 &8126816 +AudioListener: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 188192} + m_Enabled: 1 +--- !u!92 &9280882 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 188192} + m_Enabled: 1 +--- !u!111 &11181010 +Animation: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168992} + m_Enabled: 1 + serializedVersion: 3 + m_Animation: {fileID: 0} + m_Animations: + - {fileID: 0} + m_WrapMode: 0 + m_PlayAutomatically: 1 + m_AnimatePhysics: 0 + m_CullingType: 0 +--- !u!114 &11405868 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168992} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e93599847d269df4da17655e4ac7b3d7, type: 3} + m_Name: + m_EditorClassIdentifier: + PedestrianId: 167 + AnimGroup: 1 + AnimIndex: 3 +--- !u!114 &11434656 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 151936} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ef6b4848632966a4cb177a878e7ce8e9, type: 3} + m_Name: + m_EditorClassIdentifier: + _editorIdSerialized: 256 + Camera: {fileID: 2096612} + PlayerModel: {fileID: 11405868} + TurnSpeed: 10 +--- !u!114 &11456232 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168992} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c16e4a02d730abb40a82e801954132f7, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!124 &12438378 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 188192} + m_Enabled: 1 +--- !u!143 &14323918 +CharacterController: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 151936} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Height: 1.75 + m_Radius: .25 + m_SlopeLimit: 45 + m_StepOffset: .300000012 + m_SkinWidth: .0799999982 + m_MinMoveDistance: .00100000005 + m_Center: {x: 0, y: 0, z: 0} +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 151936} + m_IsPrefabParent: 1 diff --git a/Assets/Prefabs/Networkable/Player.prefab.meta b/Assets/Prefabs/Networkable/Player.prefab.meta new file mode 100644 index 00000000..49e89cd0 --- /dev/null +++ b/Assets/Prefabs/Networkable/Player.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2efc0f7174246f84fba88b52ea93bc71 +timeCreated: 1428816635 +licenseType: Pro +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Networking.prefab b/Assets/Prefabs/Networking.prefab new file mode 100644 index 00000000..72e5d805 --- /dev/null +++ b/Assets/Prefabs/Networking.prefab @@ -0,0 +1,96 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &138422 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 495706} + m_Layer: 0 + m_Name: Client + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &173954 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 458624} + m_Layer: 0 + m_Name: Networking + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &199630 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 413050} + m_Layer: 0 + m_Name: Server + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &413050 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 199630} + 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: 458624} + m_RootOrder: 1 +--- !u!4 &458624 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 173954} + 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: 495706} + - {fileID: 413050} + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!4 &495706 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 138422} + 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: 458624} + m_RootOrder: 0 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 173954} + m_IsPrefabParent: 1 diff --git a/Assets/Prefabs/Networking.prefab.meta b/Assets/Prefabs/Networking.prefab.meta new file mode 100644 index 00000000..e176e255 --- /dev/null +++ b/Assets/Prefabs/Networking.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f1fb24ea8c25e644cb89baa25b4a8bff +timeCreated: 1428852774 +licenseType: Pro +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/PauseMenu.prefab b/Assets/Prefabs/PauseMenu.prefab new file mode 100644 index 00000000..369830a7 --- /dev/null +++ b/Assets/Prefabs/PauseMenu.prefab @@ -0,0 +1,457 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1693201817607148} + m_IsPrefabParent: 1 +--- !u!1 &1149364431340810 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4460574794146942} + - component: {fileID: 114130700506787182} + - component: {fileID: 114299782105903270} + - component: {fileID: 114176722346621994} + - component: {fileID: 114921708719520758} + - component: {fileID: 114354152432710700} + m_Layer: 0 + m_Name: Settings + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1693201817607148 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4615557407145958} + - component: {fileID: 114435663141359712} + - component: {fileID: 114592069113923140} + - component: {fileID: 114924086961640034} + - component: {fileID: 114611395026534988} + - component: {fileID: 114636911127793484} + - component: {fileID: 114911863237150764} + - component: {fileID: 114753158958291610} + - component: {fileID: 114604904801458000} + - component: {fileID: 114769417846371336} + - component: {fileID: 114366197016130562} + - component: {fileID: 114396965753478646} + - component: {fileID: 114184621571316304} + - component: {fileID: 114509004744246330} + - component: {fileID: 114096753951945486} + m_Layer: 0 + m_Name: PauseMenu + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4460574794146942 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1149364431340810} + 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: 4615557407145958} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4615557407145958 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + 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: 4460574794146942} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &114096753951945486 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 409653cfe36614ceab3cbfbf9ed04fce, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114130700506787182 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1149364431340810} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fc581ee14e49f45bd8c98693d8ad173f, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114176722346621994 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1149364431340810} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0c960baf8e8064cf5b80a1e60a5b79e6, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114184621571316304 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 47b9d4dc7492d4d5892d2931d8a960be, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Weapons + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 1 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114299782105903270 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1149364431340810} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f0b1df49a9e0a49d8947a7026c7371d0, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114354152432710700 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1149364431340810} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f92118c7df2474d4a9935fb6dec5f26e, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114366197016130562 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 09e5fb65bfb794372ad6dc715a59c96b, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Map + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 0 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114396965753478646 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 729503e0f7dfa4729ae2141d6422e9f1, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Animations + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 1 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114435663141359712 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 661aa8bc19a0e4d3dbb894f6b7b77966, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114509004744246330 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a3ba44be90f64d798a3abe7d45cab8f, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Peds + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 0 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 + numPedsPerPage: 30 +--- !u!114 &114592069113923140 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6c526ed17adca405e83c352cf842f516, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Console + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 75 + y: 173.5 + width: 150 + height: 347 + useScrollView: 0 + m_spaceBeforeContent: 15 + m_spaceAfterContent: 5 + m_registerInMainMenuOnStart: 0 + restrictLogCount: 1 + maxLogCount: 1000 +--- !u!114 &114604904801458000 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8acb19522c6ef4152bd0760482a0a166, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Options + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 1 + m_spaceBeforeContent: 15 + m_spaceAfterContent: 10 + m_registerInMainMenuOnStart: 1 +--- !u!114 &114611395026534988 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e43dd3376534c44ea99e33b8a01cadba, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Utilities + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 1 + windowRect: + serializedVersion: 2 + x: 304 + y: 10 + width: 200 + height: 100 + useScrollView: 1 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114636911127793484 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e4b0085a8c4174cb5a131d3baa1d8744, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Controls + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 1 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114753158958291610 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e6804c9298f5040f68e0c902f6739ed0, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: DayTime + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 0 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114769417846371336 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4428e76f4d28f48fdb58f39252b4e240, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Vehicle Spawner + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 1 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114911863237150764 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4187a46a1c9ad4590a8b39ab12ce6522, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Teleport + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 1 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 1 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114921708719520758 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1149364431340810} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3c3852056a1bf469ab2128fe025acd57, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114924086961640034 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1693201817607148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a86af676e111c4861b8e0f454c7cb025, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: World stats + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 10 + y: 10 + width: 250 + height: 330 + useScrollView: 0 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 0 diff --git a/Assets/Prefabs/PauseMenu.prefab.meta b/Assets/Prefabs/PauseMenu.prefab.meta new file mode 100644 index 00000000..9b991db9 --- /dev/null +++ b/Assets/Prefabs/PauseMenu.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 259a477cc43ab4eb184305bfc583d66e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Ped.prefab b/Assets/Prefabs/Ped.prefab new file mode 100644 index 00000000..71b649f6 --- /dev/null +++ b/Assets/Prefabs/Ped.prefab @@ -0,0 +1,479 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1273918895060814} + m_IsPrefabParent: 1 +--- !u!1 &1154474390377672 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4073572401439152} + - component: {fileID: 114656303205122358} + - component: {fileID: 114812630007084968} + - component: {fileID: 114351941950376482} + - component: {fileID: 114744342131181246} + - component: {fileID: 114976811281896722} + - component: {fileID: 114691651370694836} + - component: {fileID: 114042463799621090} + - component: {fileID: 114485782082765270} + - component: {fileID: 114857049298782194} + - component: {fileID: 114564354208745784} + - component: {fileID: 114607436013890848} + - component: {fileID: 114051921114482032} + - component: {fileID: 114805415584932730} + - component: {fileID: 114860926047028576} + - component: {fileID: 114541342841796004} + - component: {fileID: 114663503631305326} + - component: {fileID: 114059006300769246} + - component: {fileID: 114803762585694722} + - component: {fileID: 114244562150032294} + - component: {fileID: 114293662543306134} + m_Layer: 11 + m_Name: States + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1273918895060814 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4388436116821042} + - component: {fileID: 143191563852256374} + - component: {fileID: 114099438993920694} + - component: {fileID: 114173420020992462} + - component: {fileID: 114879899237604226} + - component: {fileID: 114220037769542022} + m_Layer: 11 + m_Name: Ped + m_TagString: Player + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1531309216951106 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4389762674885628} + - component: {fileID: 114671475596742702} + - component: {fileID: 111466364692026036} + m_Layer: 0 + m_Name: PlayerModel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4073572401439152 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + 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: 4388436116821042} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4388436116821042 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1273918895060814} + m_LocalRotation: {x: 0, y: 0.73046196, z: 0, w: 0.6829534} + m_LocalPosition: {x: 2106.089, y: 40, z: 1848.0103} + m_LocalScale: {x: 1.0000002, y: 0.99999976, z: 1.0000005} + m_Children: + - {fileID: 4389762674885628} + - {fileID: 4073572401439152} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4389762674885628 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1531309216951106} + 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: 4388436116821042} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!111 &111466364692026036 +Animation: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1531309216951106} + m_Enabled: 1 + serializedVersion: 3 + m_Animation: {fileID: 0} + m_Animations: [] + m_WrapMode: 0 + m_PlayAutomatically: 1 + m_AnimatePhysics: 0 + m_CullingType: 0 +--- !u!114 &114042463799621090 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 01e72808e9f8b455f94e3549c8f134c5, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114051921114482032 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ad7b39219621a45dea5eddf1c67486c3, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114059006300769246 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a658f459c4f543c5abdd7d9570a9b5f, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114099438993920694 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1273918895060814} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ef6b4848632966a4cb177a878e7ce8e9, type: 3} + m_Name: + m_EditorClassIdentifier: + Camera: {fileID: 0} + PlayerModel: {fileID: 114671475596742702} + shouldPlayAnims: 1 + TurnSpeed: 10 + characterController: {fileID: 0} + jumpSpeed: 8 + m_cameraDistance: 3 + m_cameraDistanceVehicle: 6 + m_cameraClampValue: {x: 60, y: 60} + m_maxHealth: 100 + m_enterVehicleRadius: 2 +--- !u!114 &114173420020992462 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1273918895060814} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 57e796a954503384dbd1282729710af5, type: 3} + m_Name: + m_EditorClassIdentifier: + CursorSensitivity: {x: 7, y: 7} + clampInDegrees: {x: 60, y: 60} + smoothing: {x: 10, y: 10} + m_doSmooth: 0 + m_smoothMovement: 0 +--- !u!114 &114220037769542022 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1273918895060814} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 62374ff6df2c74f9699075492ef7fdb9, type: 3} + m_Name: + m_EditorClassIdentifier: + m_health: 100 + m_onDamage: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 114220037769542022} + m_MethodName: HandleDamageByDefault + 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 + m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &114244562150032294 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d7968f7ed64924436af362bf4c5d54f7, type: 3} + m_Name: + m_EditorClassIdentifier: + cameraFocusPosOffsetY: 0.25 +--- !u!114 &114293662543306134 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e111211033b048ca9ca00766168ed4b, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114351941950376482 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5aa51e616c8584acd8d28097eb9f8be1, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114485782082765270 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7969460c603724e2a9bcaee09e341625, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114541342841796004 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6f43370ea311141ba88d19a40632349a, type: 3} + m_Name: + m_EditorClassIdentifier: + launchVelocityMultiplier: 1 + glideVelocity: 1.75 + landVelocityMultiplier: 0.5 +--- !u!114 &114564354208745784 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 56bc009b7edfa4901ae6929c4a201732, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114607436013890848 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b9781f849e2154fafb2fea73ccdb831c, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114656303205122358 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 84062dfd700b5436292c51d37eba57f0, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114663503631305326 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 72812118050114157b2f9d5368c7e7c7, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114671475596742702 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1531309216951106} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e93599847d269df4da17655e4ac7b3d7, type: 3} + m_Name: + m_EditorClassIdentifier: + m_startingPedId: 167 +--- !u!114 &114691651370694836 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f9ef25e0552fe44acb26b71aae5751f5, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114744342131181246 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 055ab10393eb2465f90002aaceff36a8, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114803762585694722 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 262dd793913e349f7ac18af5bcadf7cb, type: 3} + m_Name: + m_EditorClassIdentifier: + cameraFocusPosOffsetY: 0.25 +--- !u!114 &114805415584932730 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a05f5f56342e540b7a0328605b41e046, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114812630007084968 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 45b03f8d0638d443fb02c2f0242646be, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114857049298782194 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 85425b3e6cf1749d08bc08ac3a55fad8, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114860926047028576 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 209709c163d044d2fbc29d291fdbc821, type: 3} + m_Name: + m_EditorClassIdentifier: + moveMultiplier: 10 + moveFastMultiplier: 100 +--- !u!114 &114879899237604226 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1273918895060814} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 104b2f17607c64562aea9bbcedc03368, type: 3} + m_Name: + m_EditorClassIdentifier: + autoAddWeapon: 1 + m_aimWithRifleMaxAnimTime: 0.7 + cameraAimOffset: {x: 0.7, y: 0.2, z: -1} + SpineOffset: {x: 0, y: 45, z: 90} + weaponAttachType: 1 + rotatePlayerInDirectionOfAiming: 1 +--- !u!114 &114976811281896722 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1154474390377672} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d352c5defdc794c3a9df9525af79755a, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!143 &143191563852256374 +CharacterController: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1273918895060814} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Height: 1.75 + m_Radius: 0.25 + m_SlopeLimit: 45 + m_StepOffset: 0.3 + m_SkinWidth: 0.08 + m_MinMoveDistance: 0.001 + m_Center: {x: 0, y: 0, z: 0} diff --git a/Assets/Prefabs/Ped.prefab.meta b/Assets/Prefabs/Ped.prefab.meta new file mode 100644 index 00000000..d51c6d36 --- /dev/null +++ b/Assets/Prefabs/Ped.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9d45d42a7408c1e4ab325d6840364b84 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/UI.prefab b/Assets/Prefabs/UI.prefab new file mode 100644 index 00000000..77d92df1 --- /dev/null +++ b/Assets/Prefabs/UI.prefab @@ -0,0 +1,1100 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1611271869868126} + m_IsPrefabParent: 1 +--- !u!1 &1024578193815106 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224336795728798768} + - component: {fileID: 222961533395048624} + - component: {fileID: 114468575846868774} + m_Layer: 0 + m_Name: Outline-Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1048134811087868 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4623215929862266} + - component: {fileID: 114031243425832284} + m_Layer: 0 + m_Name: HUD + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1085484459653070 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224716624785451066} + - component: {fileID: 222650630699500124} + - component: {fileID: 114106417822196936} + m_Layer: 0 + m_Name: PlayerIcon + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1119829896786722 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224787473038982262} + - component: {fileID: 223682112327264460} + - component: {fileID: 114640548221265298} + - component: {fileID: 114019617034570716} + m_Layer: 5 + m_Name: Minimap-Canvas + m_TagString: UI + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1158250797250008 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224020270871840966} + - component: {fileID: 222666466498633646} + - component: {fileID: 114690809005601046} + - component: {fileID: 114487661805984862} + m_Layer: 5 + m_Name: Minimap + m_TagString: UI + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1247426396754748 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4139429664069144} + - component: {fileID: 114042572616448592} + m_Layer: 0 + m_Name: FPSDisplay + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1266252102531166 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224132835488623496} + - component: {fileID: 223003346341044794} + - component: {fileID: 114920527060738022} + - component: {fileID: 114566137607167922} + m_Layer: 0 + m_Name: MinimapIcons-Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1272879139834682 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224538364652313416} + - component: {fileID: 222272163299695602} + - component: {fileID: 114074779211426578} + m_Layer: 0 + m_Name: NorthIcon + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1377734331079614 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224081885638458158} + m_Layer: 0 + m_Name: NorthPivot + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1514841759843754 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4649684838142242} + - component: {fileID: 114727961998957292} + m_Layer: 0 + m_Name: MainMenu + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1594478129176806 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4105821110255708} + - component: {fileID: 114494588390292834} + - component: {fileID: 114791952012152782} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1611271869868126 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4450559263798022} + - component: {fileID: 114473132252556806} + m_Layer: 0 + m_Name: UI + m_TagString: UI + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1627404700688260 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224402533417526356} + m_Layer: 5 + m_Name: Minimap-Container + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1704002877622592 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224266887972739060} + - component: {fileID: 223736806774217056} + - component: {fileID: 114768103706765874} + - component: {fileID: 114302915264615784} + m_Layer: 0 + m_Name: MinimapOutline-Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1773833053091010 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224779433496236624} + - component: {fileID: 222341476611336406} + - component: {fileID: 114943004525129146} + m_Layer: 5 + m_Name: Minimap-Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1794000083898140 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4163146413860628} + - component: {fileID: 114403716082730598} + m_Layer: 0 + m_Name: MinimapSystem + m_TagString: Minimap + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1901320160272788 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4484009134148236} + - component: {fileID: 114064859265624614} + - component: {fileID: 114940213983707650} + m_Layer: 0 + m_Name: Windows + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4105821110255708 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1594478129176806} + m_LocalRotation: {x: -0, y: -0.73046196, z: 0, w: 0.6829534} + m_LocalPosition: {x: 1985.2616, y: -40, z: -1977.2429} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 4450559263798022} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4139429664069144 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1247426396754748} + 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: 4450559263798022} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4163146413860628 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1794000083898140} + 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: 224787473038982262} + - {fileID: 224266887972739060} + - {fileID: 224132835488623496} + m_Father: {fileID: 4450559263798022} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4450559263798022 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1611271869868126} + m_LocalRotation: {x: -0, y: 0.73046196, z: -0, w: 0.6829534} + m_LocalPosition: {x: 2106.089, y: 40, z: 1848.0103} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 4105821110255708} + - {fileID: 4163146413860628} + - {fileID: 4139429664069144} + - {fileID: 4623215929862266} + - {fileID: 4649684838142242} + - {fileID: 4484009134148236} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4484009134148236 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1901320160272788} + 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: 4450559263798022} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4623215929862266 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1048134811087868} + 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: 4450559263798022} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4649684838142242 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1514841759843754} + 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: 4450559263798022} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &114019617034570716 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1119829896786722} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &114031243425832284 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1048134811087868} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 32c417c622c0c4e2e8e323b02ec0ac9c, type: 3} + m_Name: + m_EditorClassIdentifier: + crosshairSize: 30.7 + crosshairScaleMode: 0 + hudScreenCorner: 1 + hudSize: {x: 100, y: 100} + hudPadding: {x: 10, y: 10} + healthColor: {r: 1, g: 0, b: 0, a: 1} + healthBackgroundColor: {r: 0.5, g: 0, b: 0, a: 1} + drawRedDotOnScreenCenter: 0 +--- !u!114 &114042572616448592 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1247426396754748} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a6f440c6b65774755ba61e110bc899d1, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114064859265624614 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1901320160272788} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bd9456433955e448eb1b6abd46c39d07, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Change path to GTA + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 0 + m_spaceBeforeContent: 0 + m_spaceAfterContent: 0 + m_registerInMainMenuOnStart: 1 +--- !u!114 &114074779211426578 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1272879139834682} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!114 &114106417822196936 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1085484459653070} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!114 &114302915264615784 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1704002877622592} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &114403716082730598 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1794000083898140} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 517af0b56117a42c9a9cd043b7d1c767, type: 3} + m_Name: + m_EditorClassIdentifier: + outlineCanvas: {fileID: 223736806774217056} + iconCanvas: {fileID: 223003346341044794} + canvas: {fileID: 223682112327264460} + northImage: {fileID: 114074779211426578} + playerImage: {fileID: 114106417822196936} + outlineImage: {fileID: 114468575846868774} + maskImage: {fileID: 114690809005601046} + mapImage: {fileID: 114943004525129146} + mapTransform: {fileID: 224779433496236624} + maskTransform: {fileID: 224020270871840966} + mapContainer: {fileID: 224402533417526356} + zoom: 1.3 + calibrator: 3.9 + zoomDuration: 1 + mapZoomScaler: 1 + mapMovement: 5 + debugActive: 1 + curZoomPercentage: 0 +--- !u!114 &114468575846868774 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1024578193815106} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 21300000, guid: 12a56c0ffd5ba344095cbd5e7b9c60a2, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!114 &114473132252556806 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1611271869868126} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 409653cfe36614ceab3cbfbf9ed04fce, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114487661805984862 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1158250797250008} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -1200242548, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 1 +--- !u!114 &114494588390292834 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1594478129176806} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!114 &114566137607167922 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1266252102531166} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &114640548221265298 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1119829896786722} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!114 &114690809005601046 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1158250797250008} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.45098042, g: 0.54509807, b: 0.6862745, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 21300000, guid: b0b9ba50b59216648a23aa61f8c656c8, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!114 &114727961998957292 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1514841759843754} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f5b556e077dc4e268ae212027bb0276, type: 3} + m_Name: + m_EditorClassIdentifier: + minButtonHeight: 30 + minButtonWidth: 80 + spaceAtBottom: 40 + spaceBetweenButtons: 30 + drawBackground: 1 + backgroundColor: {r: 0.064887136, g: 0.04111782, b: 0.11320752, a: 1} + drawLogo: 1 +--- !u!114 &114768103706765874 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1704002877622592} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!114 &114791952012152782 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1594478129176806} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, 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 &114920527060738022 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1266252102531166} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!114 &114940213983707650 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1901320160272788} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 75e2fbfb7537d48aa93fda618e34a0a0, type: 3} + m_Name: + m_EditorClassIdentifier: + windowName: Audio + m_isOpenedByDefaultInMainMenu: 0 + m_isOpenedByDefaultInPauseMenu: 0 + windowRect: + serializedVersion: 2 + x: 57.5 + y: 78.75 + width: 115 + height: 157.5 + useScrollView: 1 + m_spaceBeforeContent: 20 + m_spaceAfterContent: 10 + m_registerInMainMenuOnStart: 0 +--- !u!114 &114943004525129146 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1773833053091010} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &222272163299695602 +CanvasRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1272879139834682} +--- !u!222 &222341476611336406 +CanvasRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1773833053091010} +--- !u!222 &222650630699500124 +CanvasRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1085484459653070} +--- !u!222 &222666466498633646 +CanvasRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1158250797250008} +--- !u!222 &222961533395048624 +CanvasRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1024578193815106} +--- !u!223 &223003346341044794 +Canvas: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1266252102531166} + m_Enabled: 0 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 2 + m_TargetDisplay: 0 +--- !u!223 &223682112327264460 +Canvas: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1119829896786722} + m_Enabled: 0 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!223 &223736806774217056 +Canvas: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1704002877622592} + m_Enabled: 0 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 1 + m_TargetDisplay: 0 +--- !u!224 &224020270871840966 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1158250797250008} + 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: 224402533417526356} + m_Father: {fileID: 224787473038982262} + 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: 0, y: 0} + m_SizeDelta: {x: 256, y: 256} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!224 &224081885638458158 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1377734331079614} + 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: 224538364652313416} + m_Father: {fileID: 224132835488623496} + 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: 0, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!224 &224132835488623496 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1266252102531166} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 224081885638458158} + - {fileID: 224716624785451066} + m_Father: {fileID: 4163146413860628} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!224 &224266887972739060 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1704002877622592} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 224336795728798768} + m_Father: {fileID: 4163146413860628} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!224 &224336795728798768 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1024578193815106} + 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: 224266887972739060} + 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: 0, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!224 &224402533417526356 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1627404700688260} + 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: 224779433496236624} + m_Father: {fileID: 224020270871840966} + 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: 0, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!224 &224538364652313416 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1272879139834682} + 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: 224081885638458158} + 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: 0, y: 128} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!224 &224716624785451066 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1085484459653070} + 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: 224132835488623496} + m_RootOrder: 1 + 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: 0, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!224 &224779433496236624 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1773833053091010} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 224402533417526356} + 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: 0, y: 0} + m_SizeDelta: {x: 1536, y: 1536} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!224 &224787473038982262 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1119829896786722} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 224020270871840966} + m_Father: {fileID: 4163146413860628} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI.prefab.meta b/Assets/Prefabs/UI.prefab.meta new file mode 100644 index 00000000..f7edfe96 --- /dev/null +++ b/Assets/Prefabs/UI.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dd5c14626ef595d439de799ec08c2b16 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/VehicleManager.prefab b/Assets/Prefabs/VehicleManager.prefab new file mode 100644 index 00000000..9168035b --- /dev/null +++ b/Assets/Prefabs/VehicleManager.prefab @@ -0,0 +1,80 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1911095784419342} + m_IsPrefabParent: 1 +--- !u!1 &1911095784419342 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4141056491348262} + - component: {fileID: 114720109693249180} + - component: {fileID: 114351707393174560} + m_Layer: 0 + m_Name: VehicleManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4141056491348262 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1911095784419342} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &114351707393174560 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1911095784419342} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 409653cfe36614ceab3cbfbf9ed04fce, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114720109693249180 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1911095784419342} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 82a245a7166802b41bcb706255d566f1, type: 3} + m_Name: + m_EditorClassIdentifier: + DragScale: 0.05 + AccelerationScale: 75 + BreakingScale: 1 + SuspensionForceScale: 100000 + SuspensionDampingScale: 50000 + MassScale: 1 + ForwardFrictionExtremumSlip: 0.125 + ForwardFrictionExtremumValue: 2.5 + ForwardFrictionAsymptoteSlip: 1 + ForwardFrictionAsymptoteValue: 2 + SideFrictionExtremumSlip: 0.5 + SideFrictionExtremumValue: 2.5 + SideFrictionAsymptoteSlip: 1 + SideFrictionAsymptoteValue: 2 + AntiRollScale: 20000 diff --git a/Assets/Prefabs/VehicleManager.prefab.meta b/Assets/Prefabs/VehicleManager.prefab.meta new file mode 100644 index 00000000..27dc762b --- /dev/null +++ b/Assets/Prefabs/VehicleManager.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4fdeb0b43fda44cd48a2a49fa62c0245 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/World.prefab b/Assets/Prefabs/World.prefab new file mode 100644 index 00000000..147873a0 --- /dev/null +++ b/Assets/Prefabs/World.prefab @@ -0,0 +1,791 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &111262 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 418232} + m_Layer: 0 + m_Name: Player Spawns + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &121014 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 492816} + m_Layer: 0 + m_Name: Focus + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &133962 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 421924} + m_Layer: 0 + m_Name: Los Santos - Car Park Downtown + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &139442 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 440826} + - component: {fileID: 2068374} + - component: {fileID: 12458128} + - component: {fileID: 9210286} + - component: {fileID: 8101816} + m_Layer: 0 + m_Name: Preview Camera + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!1 &143544 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 499186} + - component: {fileID: 114077829182571006} + m_Layer: 0 + m_Name: World + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &149528 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 472884} + - component: {fileID: 11436500} + - component: {fileID: 11450014} + m_Layer: 0 + m_Name: Cell + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &153756 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 406580} + - component: {fileID: 10808534} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &156920 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 475742} + m_Layer: 0 + m_Name: Grove Street + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &162096 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 461086} + m_Layer: 0 + m_Name: Desert Airport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &169526 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 462626} + - component: {fileID: 11455068} + m_Layer: 0 + m_Name: Water + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &406580 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 153756} + m_LocalRotation: {x: -0.17860633, y: 0.82139367, z: -0.3830222, w: -0.38302246} + m_LocalPosition: {x: 0, y: 10, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 499186} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &418232 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 111262} + 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: 4493953062982132} + - {fileID: 475742} + - {fileID: 4393180410188950} + - {fileID: 461086} + - {fileID: 4694664445516102} + - {fileID: 4404069868695510} + - {fileID: 4410618639338142} + - {fileID: 4832859264981614} + - {fileID: 4077053835485560} + - {fileID: 4153270575826190} + - {fileID: 4281002318532498} + - {fileID: 4916251233388722} + - {fileID: 421924} + m_Father: {fileID: 499186} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &421924 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 133962} + m_LocalRotation: {x: 0, y: 0.9929142, z: 0, w: 0.11883355} + m_LocalPosition: {x: 1647.612, y: 40, z: -1104.8595} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 12 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &440826 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 139442} + m_LocalRotation: {x: -0.1380647, y: 0.11767495, z: -0.016523361, w: -0.983269} + m_LocalPosition: {x: 2123.1091, y: 38.322205, z: -1147.449} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 499186} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &461086 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 162096} + m_LocalRotation: {x: 0, y: -0.731205, z: 0, w: 0.6821578} + m_LocalPosition: {x: 429.3022, y: 40, z: 2520.922} + m_LocalScale: {x: 1.0000005, y: 1, z: 1.0000005} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: -93.97501, z: 0} +--- !u!4 &462626 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 169526} + 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: 499186} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &472884 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 149528} + 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: 499186} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &475742 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 156920} + m_LocalRotation: {x: 0, y: -0.36325127, z: 0, w: 0.9316912} + m_LocalPosition: {x: 2499.062, y: 40, z: -1673.578} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: -42.6, z: 0} +--- !u!4 &492816 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 121014} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2119, y: 32.80384, z: -1133} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 499186} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &499186 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 143544} + 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: 472884} + - {fileID: 406580} + - {fileID: 462626} + - {fileID: 440826} + - {fileID: 418232} + - {fileID: 492816} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!20 &2068374 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 139442} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!81 &8101816 +AudioListener: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 139442} + m_Enabled: 1 +--- !u!92 &9210286 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 139442} + m_Enabled: 1 +--- !u!108 &10808534 +Light: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 153756} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 1 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!114 &11436500 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 149528} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: df6efcfa667fce549bcc3deb68a7e8d5, type: 3} + m_Name: + m_EditorClassIdentifier: + CellIds: 000000000d000000 + PreviewCamera: {fileID: 0} + Focus: {fileID: 0} + Water: {fileID: 11455068} + divisionLoadOrderDistanceFactor: 16 + divisionRefreshDistanceDelta: 1 + maxDrawDistance: 500 + loadParkedVehicles: 0 +--- !u!114 &11450014 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 149528} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 29ff195586224b54ebfe1e606d27a4b3, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &11455068 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 169526} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 57ea334de36794f45af24c665b00e893, type: 3} + m_Name: + m_EditorClassIdentifier: + WaterPrefab: {fileID: 0} +--- !u!124 &12458128 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 139442} + m_Enabled: 1 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 143544} + m_IsPrefabParent: 1 +--- !u!1 &1000405462072482 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4916251233388722} + m_Layer: 0 + m_Name: Red County - Catalinas Cabin + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1061115742419774 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4493953062982132} + m_Layer: 0 + m_Name: Las Venturas - The Visage Casino + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1207184902467428 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4404069868695510} + m_Layer: 0 + m_Name: Area 69 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1446699222852744 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4410618639338142} + m_Layer: 0 + m_Name: Mike Toreno's Ranch + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1550219727895838 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4393180410188950} + m_Layer: 0 + m_Name: San Fierro Garage + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1551681599764314 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4153270575826190} + m_Layer: 0 + m_Name: Santa Maria Beach + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1635632847464120 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4694664445516102} + m_Layer: 0 + m_Name: Gant Bridge + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1675865652371734 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4832859264981614} + m_Layer: 0 + m_Name: Angel Pine + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1678886838302222 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4281002318532498} + m_Layer: 0 + m_Name: Los Santos Airport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1743648181207958 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4077053835485560} + m_Layer: 0 + m_Name: Los Santos - Car Park + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4077053835485560 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1743648181207958} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2119, y: 40, z: -1133} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 8 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4153270575826190 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1551681599764314} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 347, y: 6, z: -1783} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 9 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4281002318532498 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1678886838302222} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1829, y: 14, z: -2600} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 10 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4393180410188950 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1550219727895838} + m_LocalRotation: {x: 0, y: 0.6859772, z: 0, w: 0.7276231} + m_LocalPosition: {x: -2020, y: 40, z: 157.8858} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 86.62501, z: 0} +--- !u!4 &4404069868695510 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1207184902467428} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 146, y: 27, z: 1903} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4410618639338142 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1446699222852744} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -708, y: 13, z: 958} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4493953062982132 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1061115742419774} + m_LocalRotation: {x: 0, y: 0.73046196, z: 0, w: 0.6829534} + m_LocalPosition: {x: 2106.089, y: 40, z: 1848.0103} + m_LocalScale: {x: 1.0000002, y: 0.99999976, z: 1.0000005} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4694664445516102 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1635632847464120} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -2574, y: 8, z: 1380} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4832859264981614 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1675865652371734} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -2195, y: 32, z: -2272} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 7 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4916251233388722 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000405462072482} + m_LocalRotation: {x: 0, y: -0.98017275, z: 0, w: 0.19814493} + m_LocalPosition: {x: 870.7422, y: 100, z: -33.3372} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 418232} + m_RootOrder: 11 + m_LocalEulerAnglesHint: {x: 0, y: -157.143, z: 0} +--- !u!114 &114077829182571006 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 143544} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f448a6ce85e59e943974de56271f3ce5, type: 3} + m_Name: + m_EditorClassIdentifier: + lightCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0.000001270324 + value: 1.0000031 + inSlope: -2.9000547 + outSlope: -2.9000547 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.24999273 + - serializedVersion: 3 + time: 0.5000107 + value: 0.009750675 + inSlope: -0.0068289125 + outSlope: -0.0068289125 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 0.8998677 + value: 0.50498855 + inSlope: 4.620677 + outSlope: 4.620677 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.70871896 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: 2.85 + outSlope: 2.85 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33334053 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + dirLight: {fileID: 406580} + startTimeState: 1 diff --git a/Assets/Prefabs/World.prefab.meta b/Assets/Prefabs/World.prefab.meta new file mode 100644 index 00000000..a93d61a1 --- /dev/null +++ b/Assets/Prefabs/World.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b6900baf9f552ba46ad27d4ada4d5489 +timeCreated: 1428852486 +licenseType: Pro +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources.meta b/Assets/Resources.meta new file mode 100644 index 00000000..33396c76 --- /dev/null +++ b/Assets/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 603de303daa395b418b547f6bc1c32c2 +folderAsset: yes +timeCreated: 1428857472 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/ALSF1.txt b/Assets/Resources/ALSF1.txt new file mode 100644 index 00000000..3491b830 --- /dev/null +++ b/Assets/Resources/ALSF1.txt @@ -0,0 +1,1311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Resources/ALSF1.txt.meta b/Assets/Resources/ALSF1.txt.meta new file mode 100644 index 00000000..b575a2ea --- /dev/null +++ b/Assets/Resources/ALSF1.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4d7b4020a6aae464382a163f4ac359d1 +timeCreated: 1434709476 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/ALSF2.txt b/Assets/Resources/ALSF2.txt new file mode 100644 index 00000000..01ed072d --- /dev/null +++ b/Assets/Resources/ALSF2.txt @@ -0,0 +1,1677 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Resources/ALSF2.txt.meta b/Assets/Resources/ALSF2.txt.meta new file mode 100644 index 00000000..9a2a313a --- /dev/null +++ b/Assets/Resources/ALSF2.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0b542310d6f1e6c4e9307e2d5ca69140 +timeCreated: 1434709600 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/CALVERT1.txt b/Assets/Resources/CALVERT1.txt new file mode 100644 index 00000000..d607cb72 --- /dev/null +++ b/Assets/Resources/CALVERT1.txt @@ -0,0 +1,1001 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Resources/CALVERT1.txt.meta b/Assets/Resources/CALVERT1.txt.meta new file mode 100644 index 00000000..a31f8645 --- /dev/null +++ b/Assets/Resources/CALVERT1.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dee3ccf72a3d19946b58687caf3a109b +timeCreated: 1434709600 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/CALVERT2.txt b/Assets/Resources/CALVERT2.txt new file mode 100644 index 00000000..97f95479 --- /dev/null +++ b/Assets/Resources/CALVERT2.txt @@ -0,0 +1,1601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Resources/CALVERT2.txt.meta b/Assets/Resources/CALVERT2.txt.meta new file mode 100644 index 00000000..dbeb8a66 --- /dev/null +++ b/Assets/Resources/CALVERT2.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: db6b1f285d9bbe748ba6cc38faf7088d +timeCreated: 1434709600 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Icons.meta b/Assets/Resources/Icons.meta new file mode 100644 index 00000000..01f45088 --- /dev/null +++ b/Assets/Resources/Icons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 44cc862ca611e6d44b81b4afaad7fe98 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Icons/file.png b/Assets/Resources/Icons/file.png new file mode 100644 index 00000000..d4327568 Binary files /dev/null and b/Assets/Resources/Icons/file.png differ diff --git a/Assets/Resources/Icons/file.png.meta b/Assets/Resources/Icons/file.png.meta new file mode 100644 index 00000000..8e6aa7a8 --- /dev/null +++ b/Assets/Resources/Icons/file.png.meta @@ -0,0 +1,84 @@ +fileFormatVersion: 2 +guid: f6fea87c98026ac44872166b035b0c55 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Icons/folder.png b/Assets/Resources/Icons/folder.png new file mode 100644 index 00000000..e468a17b Binary files /dev/null and b/Assets/Resources/Icons/folder.png differ diff --git a/Assets/Resources/Icons/folder.png.meta b/Assets/Resources/Icons/folder.png.meta new file mode 100644 index 00000000..2892277a --- /dev/null +++ b/Assets/Resources/Icons/folder.png.meta @@ -0,0 +1,84 @@ +fileFormatVersion: 2 +guid: f1027ba3b2ff2ed4d8868026e40b2190 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Materials.meta b/Assets/Resources/Materials.meta new file mode 100644 index 00000000..817447bf --- /dev/null +++ b/Assets/Resources/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e250861528054e648a70c52aac5f514b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Materials/Blinker.mat b/Assets/Resources/Materials/Blinker.mat new file mode 100644 index 00000000..f8210956 --- /dev/null +++ b/Assets/Resources/Materials/Blinker.mat @@ -0,0 +1,38 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: Blinker + m_Shader: {fileID: 4800000, guid: dadfcbf3fd9ab9e4ba80fe75af45f5a0, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _MKGlowTex: + m_Texture: {fileID: 2800000, guid: 724b0adf5b6b69c43863fc67ece43293, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: c5ada9378fe83174ba05bb42d33281f8, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _MKGlowOffSet: 0 + - _MKGlowPower: 5 + - _MKGlowTexStrength: 10 + - _Shininess: 0.053888544 + m_Colors: + - _Color: {r: 1, g: 0.5019608, b: 0, a: 1} + - _MKGlowColor: {r: 1, g: 0.5019608, b: 0, a: 1} + - _MKGlowTexColor: {r: 1, g: 1, b: 1, a: 1} + - _SpecColor: {r: 1, g: 0.125, b: 0.125, a: 1} diff --git a/Assets/Resources/Materials/Blinker.mat.meta b/Assets/Resources/Materials/Blinker.mat.meta new file mode 100644 index 00000000..62c2d197 --- /dev/null +++ b/Assets/Resources/Materials/Blinker.mat.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 5eced709d62b52e4d909eb9913a6696f +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/SALS.txt b/Assets/Resources/SALS.txt new file mode 100644 index 00000000..33a0bf81 --- /dev/null +++ b/Assets/Resources/SALS.txt @@ -0,0 +1,705 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Resources/SALS.txt.meta b/Assets/Resources/SALS.txt.meta new file mode 100644 index 00000000..d32efd81 --- /dev/null +++ b/Assets/Resources/SALS.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d7e30a4501ef274418bf0ff19801d825 +timeCreated: 1434709600 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Shaders.meta b/Assets/Resources/Shaders.meta new file mode 100644 index 00000000..adef692a --- /dev/null +++ b/Assets/Resources/Shaders.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 17a34a441bc965941878ecfc33f2ba47 +folderAsset: yes +timeCreated: 1427221093 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Shaders/Default.shader b/Assets/Resources/Shaders/Default.shader new file mode 100644 index 00000000..ba14f6ab --- /dev/null +++ b/Assets/Resources/Shaders/Default.shader @@ -0,0 +1,39 @@ +Shader "SanAndreasUnity/Default" +{ + Properties + { + _MainTex ("Albedo (RGB)", 2D) = "white" {} + _MaskTex ("Mask (A)", 2D) = "white" {} + _NoiseTex ("Noise (A)", 2D) = "white" {} + + _Color ("Color", Color) = (1, 1, 1, 1) + + _Fade ("Fade", Range(-1.0, 1.0)) = 1 + + _AlphaCutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 + } + + SubShader + { + Tags { + "RenderType" = "Opaque" + "Queue" = "Geometry" + } + + LOD 200 + Cull Front + + CGPROGRAM + + #pragma surface surf Standard addshadow alphatest:_AlphaCutoff + #pragma target 3.0 + + #define FADE + + #include "Shared.cginc" + + ENDCG + } + + FallBack "Diffuse" +} diff --git a/Assets/Resources/Shaders/Default.shader.meta b/Assets/Resources/Shaders/Default.shader.meta new file mode 100644 index 00000000..48bf6e26 --- /dev/null +++ b/Assets/Resources/Shaders/Default.shader.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 49fd1db3df113024cbd126e6512e1a72 +timeCreated: 1428237667 +licenseType: Pro +ShaderImporter: + defaultTextures: + - _MainTex: {fileID: 2800000, guid: 26141a431cce8b6499c3bf7518547f18, type: 3} + - _MaskTex: {instanceID: 0} + - _NoiseTex: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Shaders/NoBackCull.shader b/Assets/Resources/Shaders/NoBackCull.shader new file mode 100644 index 00000000..e8a936a3 --- /dev/null +++ b/Assets/Resources/Shaders/NoBackCull.shader @@ -0,0 +1,39 @@ +Shader "SanAndreasUnity/NoBackCull" +{ + Properties + { + _MainTex ("Albedo (RGB)", 2D) = "white" {} + _MaskTex ("Mask (A)", 2D) = "white" {} + _NoiseTex ("Noise (A)", 2D) = "white" {} + + _Color ("Color", Color) = (1, 1, 1, 1) + + _Fade ("Fade", Range(-1.0, 1.0)) = 1 + + _AlphaCutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 + } + + SubShader + { + Tags { + "RenderType" = "Opaque" + "Queue" = "Geometry" + } + + LOD 200 + Cull Off + + CGPROGRAM + + #pragma surface surf Standard addshadow alphatest:_AlphaCutoff + #pragma target 3.0 + + #define FADE + + #include "Shared.cginc" + + ENDCG + } + + FallBack "Diffuse" +} diff --git a/Assets/Resources/Shaders/NoBackCull.shader.meta b/Assets/Resources/Shaders/NoBackCull.shader.meta new file mode 100644 index 00000000..562b36b0 --- /dev/null +++ b/Assets/Resources/Shaders/NoBackCull.shader.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4b35cae85d16f8944bece3d3f097382f +timeCreated: 1428237670 +licenseType: Pro +ShaderImporter: + defaultTextures: + - _MainTex: {fileID: 2800000, guid: 26141a431cce8b6499c3bf7518547f18, type: 3} + - _MaskTex: {instanceID: 0} + - _NoiseTex: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Shaders/Shared.cginc b/Assets/Resources/Shaders/Shared.cginc new file mode 100644 index 00000000..c6791b26 --- /dev/null +++ b/Assets/Resources/Shaders/Shared.cginc @@ -0,0 +1,90 @@ +sampler2D _MainTex; +sampler2D _MaskTex; + +fixed4 _Color; + +#ifdef VEHICLE +int _CarColorIndex; + +fixed3 _CarColor1; +fixed3 _CarColor2; +fixed3 _CarColor3; +fixed3 _CarColor4; + +fixed3 _HeadLightColor; +fixed3 _TailLightColor; + +fixed4 _Lights; + +float _Metallic; +float _Smoothness; +#endif + +#ifdef FADE +sampler2D _NoiseTex; + +fixed _Fade; +#endif + +struct Input +{ + float2 uv_MainTex; + float4 screenPos; + float4 color : COLOR; +}; + +void surf(Input IN, inout SurfaceOutputStandard o) +{ +#ifdef FADE + fixed noise = tex2D(_NoiseTex, IN.screenPos.xy / (IN.screenPos.w == 0 ? 1 : IN.screenPos.w)).a * .99; + fixed fade = fixed(_Fade < 0 ? noise > 1 + _Fade : noise < _Fade); +#else + fixed fade = 1; +#endif + + fixed3 clr = tex2D(_MainTex, IN.uv_MainTex).rgb; + fixed mask = tex2D(_MaskTex, IN.uv_MainTex).a; + +#ifdef VEHICLE + fixed3 carColors[9] = { + fixed3(1, 1, 1), + _CarColor1, + _CarColor2, + _CarColor3, + _CarColor4, + _HeadLightColor, + _HeadLightColor, + _TailLightColor, + _TailLightColor + }; + + fixed carEmission[9] = { + 0, + 0, + 0, + 0, + 0, + exp(_Lights.x * 2) - 1, + exp(_Lights.y * 2) - 1, + exp(_Lights.z * 2) - 1, + exp(_Lights.w * 2) - 1 + }; +#endif + + o.Albedo = clr +#ifdef VEHICLE + * carColors[_CarColorIndex] +#endif + * IN.color.rgb * _Color.rgb; + + o.Alpha = fade * mask * IN.color.a * _Color.a; + +#ifdef VEHICLE + o.Metallic = _Metallic * o.Alpha; + o.Smoothness = _Smoothness; + o.Emission = carEmission[_CarColorIndex] * o.Albedo; +#else + o.Metallic = 0; + o.Smoothness = 0; +#endif +} diff --git a/Assets/Resources/Shaders/Shared.cginc.meta b/Assets/Resources/Shaders/Shared.cginc.meta new file mode 100644 index 00000000..c08dd4e3 --- /dev/null +++ b/Assets/Resources/Shaders/Shared.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fbaa8a726bf97e245971285e58770e3d +timeCreated: 1427318127 +licenseType: Pro +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Shaders/Transparent.shader b/Assets/Resources/Shaders/Transparent.shader new file mode 100644 index 00000000..6eb60147 --- /dev/null +++ b/Assets/Resources/Shaders/Transparent.shader @@ -0,0 +1,39 @@ +Shader "SanAndreasUnity/Transparent" +{ + Properties + { + _MainTex ("Albedo (RGB)", 2D) = "white" {} + _MaskTex ("Mask (A)", 2D) = "white" {} + _NoiseTex ("Noise (A)", 2D) = "white" {} + + _Color ("Color", Color) = (1, 1, 1, 1) + + _Fade ("Fade", Range(-1.0, 1.0)) = 1 + } + + SubShader + { + Tags { + "RenderType" = "Transparent" + "Queue" = "Transparent" + "ForceNoShadowCasting" = "True" + } + + LOD 200 + Cull Front + ZWrite Off + + CGPROGRAM + + #pragma surface surf Standard alpha:fade noshadow + #pragma target 3.0 + + #define FADE + + #include "Shared.cginc" + + ENDCG + } + + FallBack "Diffuse" +} diff --git a/Assets/Resources/Shaders/Transparent.shader.meta b/Assets/Resources/Shaders/Transparent.shader.meta new file mode 100644 index 00000000..c4fb8dfe --- /dev/null +++ b/Assets/Resources/Shaders/Transparent.shader.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bb103097da716f9429c3e6f1bd163ec1 +timeCreated: 1428237675 +licenseType: Pro +ShaderImporter: + defaultTextures: + - _MainTex: {fileID: 2800000, guid: 26141a431cce8b6499c3bf7518547f18, type: 3} + - _MaskTex: {instanceID: 0} + - _NoiseTex: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Shaders/TransparentNoBackCull.shader b/Assets/Resources/Shaders/TransparentNoBackCull.shader new file mode 100644 index 00000000..9dc0339a --- /dev/null +++ b/Assets/Resources/Shaders/TransparentNoBackCull.shader @@ -0,0 +1,39 @@ +Shader "SanAndreasUnity/TransparentNoBackCull" +{ + Properties + { + _MainTex ("Albedo (RGB)", 2D) = "white" {} + _MaskTex ("Mask (A)", 2D) = "white" {} + _NoiseTex ("Noise (A)", 2D) = "white" {} + + _Color ("Color", Color) = (1, 1, 1, 1) + + _Fade ("Fade", Range(-1.0, 1.0)) = 1 + } + + SubShader + { + Tags { + "RenderType" = "Transparent" + "Queue" = "Transparent" + "ForceNoShadowCasting" = "True" + } + + LOD 200 + Cull Off + ZWrite Off + + CGPROGRAM + + #pragma surface surf Standard alpha:fade noshadow + #pragma target 3.0 + + #define FADE + + #include "Shared.cginc" + + ENDCG + } + + FallBack "Diffuse" +} diff --git a/Assets/Resources/Shaders/TransparentNoBackCull.shader.meta b/Assets/Resources/Shaders/TransparentNoBackCull.shader.meta new file mode 100644 index 00000000..37226755 --- /dev/null +++ b/Assets/Resources/Shaders/TransparentNoBackCull.shader.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d0ef1746d4f9edb4ea29696a672cdbd8 +timeCreated: 1428237679 +licenseType: Pro +ShaderImporter: + defaultTextures: + - _MainTex: {fileID: 2800000, guid: 26141a431cce8b6499c3bf7518547f18, type: 3} + - _MaskTex: {instanceID: 0} + - _NoiseTex: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Shaders/Vehicle.shader b/Assets/Resources/Shaders/Vehicle.shader new file mode 100644 index 00000000..5c69be14 --- /dev/null +++ b/Assets/Resources/Shaders/Vehicle.shader @@ -0,0 +1,51 @@ +Shader "SanAndreasUnity/Vehicle" +{ + Properties + { + _MainTex ("Albedo (RGB)", 2D) = "white" {} + _MaskTex ("Mask (A)", 2D) = "white" {} + _NoiseTex ("Noise (A)", 2D) = "white" {} + + _Metallic ("Metallic", Range(0.0, 1.0)) = 0 + _Smoothness ("Smoothness", Range(0.0, 1.0)) = 0 + _Color ("Color", Color) = (1, 1, 1, 1) + + _CarColorIndex ("Car Color Index", Range(0, 8)) = 0 + + _CarColor1 ("Car Color 1", Color) = (1, 1, 1, 1) + _CarColor2 ("Car Color 2", Color) = (1, 1, 1, 1) + _CarColor3 ("Car Color 3", Color) = (1, 1, 1, 1) + _CarColor4 ("Car Color 4", Color) = (1, 1, 1, 1) + + _HeadLightColor ("Head Light Color", Color) = (1, 1, 1, 1) + _TailLightColor ("Tail Light Color", Color) = (1, 1, 1, 1) + + _Lights ("Light Brightnesses", Vector) = (1, 1, 1, 1) + + _AlphaCutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 + } + + SubShader + { + Tags { + "RenderType" = "Opaque" + "Queue" = "Geometry" + } + + LOD 200 + Cull Off + + CGPROGRAM + + #pragma surface surf Standard addshadow alphatest:_AlphaCutoff + #pragma target 3.0 + + #define VEHICLE + + #include "Shared.cginc" + + ENDCG + } + + FallBack "Diffuse" +} diff --git a/Assets/Resources/Shaders/Vehicle.shader.meta b/Assets/Resources/Shaders/Vehicle.shader.meta new file mode 100644 index 00000000..f71e1f57 --- /dev/null +++ b/Assets/Resources/Shaders/Vehicle.shader.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1dfc503a7a71189419ce3bd16bd7fe8c +timeCreated: 1428246393 +licenseType: Pro +ShaderImporter: + defaultTextures: + - _MainTex: {fileID: 2800000, guid: 26141a431cce8b6499c3bf7518547f18, type: 3} + - _MaskTex: {instanceID: 0} + - _NoiseTex: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Shaders/VehicleTransparent.shader b/Assets/Resources/Shaders/VehicleTransparent.shader new file mode 100644 index 00000000..49f8e6ff --- /dev/null +++ b/Assets/Resources/Shaders/VehicleTransparent.shader @@ -0,0 +1,50 @@ +Shader "SanAndreasUnity/VehicleTransparent" +{ + Properties + { + _MainTex ("Albedo (RGB)", 2D) = "white" {} + _MaskTex ("Mask (A)", 2D) = "white" {} + _NoiseTex ("Noise (A)", 2D) = "white" {} + + _Metallic ("Metallic", Range(0.0, 1.0)) = 0 + _Smoothness ("Smoothness", Range(0.0, 1.0)) = 0 + _Color ("Color", Color) = (1, 1, 1, 1) + + _CarColorIndex ("Car Color Index", Range(0, 8)) = 0 + + _CarColor1 ("Car Color 1", Color) = (1, 1, 1, 1) + _CarColor2 ("Car Color 2", Color) = (1, 1, 1, 1) + _CarColor3 ("Car Color 3", Color) = (1, 1, 1, 1) + _CarColor4 ("Car Color 4", Color) = (1, 1, 1, 1) + + _HeadLightColor ("Head Light Color", Color) = (1, 1, 1, 1) + _TailLightColor ("Tail Light Color", Color) = (1, 1, 1, 1) + + _Lights ("Light Brightnesses", Vector) = (1, 1, 1, 1) + } + + SubShader + { + Tags { + "RenderType" = "Transparent" + "Queue" = "Transparent" + } + + LOD 200 + Cull Off + ZWrite Off + + CGPROGRAM + + #pragma surface surf Standard addshadow alpha + #pragma target 3.0 + + #define VEHICLE + + #include "Shared.cginc" + + ENDCG + } + + FallBack "Diffuse" +} diff --git a/Assets/Resources/Shaders/VehicleTransparent.shader.meta b/Assets/Resources/Shaders/VehicleTransparent.shader.meta new file mode 100644 index 00000000..912bffcc --- /dev/null +++ b/Assets/Resources/Shaders/VehicleTransparent.shader.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a30271b9e70d2e1449126ba4eace3155 +timeCreated: 1428246398 +licenseType: Pro +ShaderImporter: + defaultTextures: + - _MainTex: {fileID: 2800000, guid: 26141a431cce8b6499c3bf7518547f18, type: 3} + - _MaskTex: {instanceID: 0} + - _NoiseTex: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Skins.meta b/Assets/Resources/Skins.meta new file mode 100644 index 00000000..60290a55 --- /dev/null +++ b/Assets/Resources/Skins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7c7422b8c1749a54d8b10e18339ad0ce +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Skins/File Browser.guiskin b/Assets/Resources/Skins/File Browser.guiskin new file mode 100644 index 00000000..57fa1777 --- /dev/null +++ b/Assets/Resources/Skins/File Browser.guiskin @@ -0,0 +1,1430 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12001, guid: 0000000000000000e000000000000000, type: 0} + m_Name: File Browser + m_EditorClassIdentifier: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_box: + m_Name: box + m_Normal: + m_Background: {fileID: 11001, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.79999995, g: 0.79999995, b: 0.79999995, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 6 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 1 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_button: + m_Name: button + m_Normal: + m_Background: {fileID: 11006, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_Hover: + m_Background: {fileID: 11003, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 11002, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 11005, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9019608, g: 0.9019608, b: 0.9019608, a: 1} + m_OnHover: + m_Background: {fileID: 11004, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 11002, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_toggle: + m_Name: toggle + m_Normal: + m_Background: {fileID: 11018, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.89112896, g: 0.89112896, b: 0.89112896, a: 1} + m_Hover: + m_Background: {fileID: 11014, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 11013, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 11016, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.8901961, g: 0.8901961, b: 0.8901961, a: 1} + m_OnHover: + m_Background: {fileID: 11015, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 11017, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 14 + m_Right: 0 + m_Top: 14 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 15 + m_Right: 0 + m_Top: 3 + m_Bottom: 0 + m_Overflow: + m_Left: -1 + m_Right: 0 + m_Top: -4 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_label: + m_Name: label + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 1 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_textField: + m_Name: textfield + m_Normal: + m_Background: {fileID: 11024, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.79999995, g: 0.79999995, b: 0.79999995, a: 1} + m_Hover: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 11025, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 3 + m_Right: 3 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 3 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_textArea: + m_Name: textarea + m_Normal: + m_Background: {fileID: 11024, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9019608, g: 0.9019608, b: 0.9019608, a: 1} + m_Hover: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.79999995, g: 0.79999995, b: 0.79999995, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 11025, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 3 + m_Right: 3 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 1 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_window: + m_Name: window + m_Normal: + m_Background: {fileID: 11023, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 11022, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 8 + m_Right: 8 + m_Top: 18 + m_Bottom: 8 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 10 + m_Right: 10 + m_Top: 20 + m_Bottom: 10 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 1 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: -18} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalSlider: + m_Name: horizontalslider + m_Normal: + m_Background: {fileID: 11009, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 3 + m_Right: 3 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: -1 + m_Right: -1 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: -2 + m_Bottom: -3 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 12 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalSliderThumb: + m_Name: horizontalsliderthumb + m_Normal: + m_Background: {fileID: 11011, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 11012, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 11010, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 7 + m_Right: 7 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: -1 + m_Right: -1 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 12 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalSlider: + m_Name: verticalslider + m_Normal: + m_Background: {fileID: 11021, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 3 + m_Bottom: 3 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: -1 + m_Bottom: -1 + m_Overflow: + m_Left: -2 + m_Right: -3 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 0 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 12 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_verticalSliderThumb: + m_Name: verticalsliderthumb + m_Normal: + m_Background: {fileID: 11011, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 11012, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 11010, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 7 + m_Bottom: 7 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: -1 + m_Bottom: -1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 12 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_horizontalScrollbar: + m_Name: horizontalscrollbar + m_Normal: + m_Background: {fileID: 11008, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 9 + m_Right: 9 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 1 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 15 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarThumb: + m_Name: horizontalscrollbarthumb + m_Normal: + m_Background: {fileID: 11007, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 6 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: -1 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 13 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarLeftButton: + m_Name: horizontalscrollbarleftbutton + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarRightButton: + m_Name: horizontalscrollbarrightbutton + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbar: + m_Name: verticalscrollbar + m_Normal: + m_Background: {fileID: 11020, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 9 + m_Bottom: 9 + m_Margin: + m_Left: 1 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 1 + m_Bottom: 1 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 15 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbarThumb: + m_Name: verticalscrollbarthumb + m_Normal: + m_Background: {fileID: 11019, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 6 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 6 + m_Bottom: 6 + m_Overflow: + m_Left: -1 + m_Right: -1 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 15 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_verticalScrollbarUpButton: + m_Name: verticalscrollbarupbutton + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbarDownButton: + m_Name: verticalscrollbardownbutton + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_ScrollView: + m_Name: scrollview + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_CustomStyles: + - m_Name: List Item + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.99989897, g: 1, b: 0.99984187, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 2800000, guid: c7323a4d2b48b430dbce49efeb6010be, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.99989897, g: 1, b: 0.99984187, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 1 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_Settings: + m_DoubleClickSelectsWord: 1 + m_TripleClickSelectsLine: 1 + m_CursorColor: {r: 1, g: 1, b: 1, a: 1} + m_CursorFlashSpeed: -1 + m_SelectionColor: {r: 1, g: 0.38403907, b: 0, a: 0.7} +--- !u!1002 &11400001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Resources/Skins/File Browser.guiskin.meta b/Assets/Resources/Skins/File Browser.guiskin.meta new file mode 100644 index 00000000..480f1a8c --- /dev/null +++ b/Assets/Resources/Skins/File Browser.guiskin.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 036cd929e6cccbb4dabf58eb6714e86a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Sprites.meta b/Assets/Resources/Sprites.meta new file mode 100644 index 00000000..bd116a48 --- /dev/null +++ b/Assets/Resources/Sprites.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a2695a5fe73945647a067ed04c956548 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Sprites/Diamond.png b/Assets/Resources/Sprites/Diamond.png new file mode 100644 index 00000000..8eb1b1ec Binary files /dev/null and b/Assets/Resources/Sprites/Diamond.png differ diff --git a/Assets/Resources/Sprites/Diamond.png.meta b/Assets/Resources/Sprites/Diamond.png.meta new file mode 100644 index 00000000..b766dce3 --- /dev/null +++ b/Assets/Resources/Sprites/Diamond.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 724b0adf5b6b69c43863fc67ece43293 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 0 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 3 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 4 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 4 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: + - - {x: 0, y: 2} + - {x: -2, y: -0.00000008742278} + - {x: 0.00000017484555, y: -2} + - {x: 2, y: 0.000000023849761} + physicsShape: + - - {x: 0, y: 2} + - {x: -2, y: -0.00000008742278} + - {x: 0.00000017484555, y: -2} + - {x: 2, y: 0.000000023849761} + bones: [] + spriteID: ef44cace1e26a88448e6dcbf1df94ac5 + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Sprites/MapCircle.psd b/Assets/Resources/Sprites/MapCircle.psd new file mode 100644 index 00000000..bd8b0b40 Binary files /dev/null and b/Assets/Resources/Sprites/MapCircle.psd differ diff --git a/Assets/Resources/Sprites/MapCircle.psd.meta b/Assets/Resources/Sprites/MapCircle.psd.meta new file mode 100644 index 00000000..b2579196 --- /dev/null +++ b/Assets/Resources/Sprites/MapCircle.psd.meta @@ -0,0 +1,117 @@ +fileFormatVersion: 2 +guid: b0b9ba50b59216648a23aa61f8c656c8 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 040115a0b3938954d8233d2443a2d692 + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Sprites/MapCircleOutline.psd b/Assets/Resources/Sprites/MapCircleOutline.psd new file mode 100644 index 00000000..026ec505 Binary files /dev/null and b/Assets/Resources/Sprites/MapCircleOutline.psd differ diff --git a/Assets/Resources/Sprites/MapCircleOutline.psd.meta b/Assets/Resources/Sprites/MapCircleOutline.psd.meta new file mode 100644 index 00000000..112e159e --- /dev/null +++ b/Assets/Resources/Sprites/MapCircleOutline.psd.meta @@ -0,0 +1,117 @@ +fileFormatVersion: 2 +guid: 12a56c0ffd5ba344095cbd5e7b9c60a2 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/TDZ.txt b/Assets/Resources/TDZ.txt new file mode 100644 index 00000000..e72d0bdf --- /dev/null +++ b/Assets/Resources/TDZ.txt @@ -0,0 +1,1263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Resources/TDZ.txt.meta b/Assets/Resources/TDZ.txt.meta new file mode 100644 index 00000000..53ee5d67 --- /dev/null +++ b/Assets/Resources/TDZ.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dec1154bc9a1b154aa86e0a634772fdd +timeCreated: 1434709600 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Textures.meta b/Assets/Resources/Textures.meta new file mode 100644 index 00000000..d9999228 --- /dev/null +++ b/Assets/Resources/Textures.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 67f9cd0cf88ef1643ad6cecf017a576f +folderAsset: yes +timeCreated: 1427225533 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Textures/Blank.png b/Assets/Resources/Textures/Blank.png new file mode 100644 index 00000000..818c71d0 Binary files /dev/null and b/Assets/Resources/Textures/Blank.png differ diff --git a/Assets/Resources/Textures/Blank.png.meta b/Assets/Resources/Textures/Blank.png.meta new file mode 100644 index 00000000..6c279017 --- /dev/null +++ b/Assets/Resources/Textures/Blank.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 370fc8c5db96f0a4883aaad635493401 +timeCreated: 1427225533 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Textures/chipfont.png b/Assets/Resources/Textures/chipfont.png new file mode 100644 index 00000000..962fe60b Binary files /dev/null and b/Assets/Resources/Textures/chipfont.png differ diff --git a/Assets/Resources/Textures/chipfont.png.meta b/Assets/Resources/Textures/chipfont.png.meta new file mode 100644 index 00000000..68481527 --- /dev/null +++ b/Assets/Resources/Textures/chipfont.png.meta @@ -0,0 +1,117 @@ +fileFormatVersion: 2 +guid: 65ea267515b30584db1c0175f4b9380e +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Textures/missing.png b/Assets/Resources/Textures/missing.png new file mode 100644 index 00000000..d5fdf397 Binary files /dev/null and b/Assets/Resources/Textures/missing.png differ diff --git a/Assets/Resources/Textures/missing.png.meta b/Assets/Resources/Textures/missing.png.meta new file mode 100644 index 00000000..94958f42 --- /dev/null +++ b/Assets/Resources/Textures/missing.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 26141a431cce8b6499c3bf7518547f18 +timeCreated: 1428237620 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Textures/transparent.png b/Assets/Resources/Textures/transparent.png new file mode 100644 index 00000000..a8511b35 Binary files /dev/null and b/Assets/Resources/Textures/transparent.png differ diff --git a/Assets/Resources/Textures/transparent.png.meta b/Assets/Resources/Textures/transparent.png.meta new file mode 100644 index 00000000..c351e079 --- /dev/null +++ b/Assets/Resources/Textures/transparent.png.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: c5ada9378fe83174ba05bb42d33281f8 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes.meta b/Assets/Scenes.meta new file mode 100644 index 00000000..2c973f94 --- /dev/null +++ b/Assets/Scenes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a95a585a5fdbb7d4bbc66e0b484b55aa +folderAsset: yes +timeCreated: 1427063906 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Main.unity b/Assets/Scenes/Main.unity new file mode 100644 index 00000000..eba519f7 --- /dev/null +++ b/Assets/Scenes/Main.unity @@ -0,0 +1,455 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.7490196, g: 0.7490196, b: 0.7490196, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 1430544495} + m_IndirectSpecularColor: {r: 0.44657868, g: 0.496413, b: 0.5748156, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 0 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1001 &31119094 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 458624, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 458624, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 458624, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 458624, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 458624, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 458624, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 458624, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 458624, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + propertyPath: m_RootOrder + value: 2 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: f1fb24ea8c25e644cb89baa25b4a8bff, type: 2} + m_IsPrefabParent: 0 +--- !u!1001 &592530377 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalPosition.x + value: 2106.089 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalPosition.y + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalPosition.z + value: 1848.0103 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalRotation.y + value: 0.73046196 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalRotation.w + value: 0.6829534 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_RootOrder + value: 3 + objectReference: {fileID: 0} + - target: {fileID: 114173420020992462, guid: 9d45d42a7408c1e4ab325d6840364b84, + type: 2} + propertyPath: m_doSmooth + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 20067565082138416, guid: 9d45d42a7408c1e4ab325d6840364b84, + type: 2} + propertyPath: near clip plane + value: 0.1 + objectReference: {fileID: 0} + - target: {fileID: 20067565082138416, guid: 9d45d42a7408c1e4ab325d6840364b84, + type: 2} + propertyPath: field of view + value: 60 + objectReference: {fileID: 0} + - target: {fileID: 1273918895060814, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_Layer + value: 11 + objectReference: {fileID: 0} + - target: {fileID: 114099438993920694, guid: 9d45d42a7408c1e4ab325d6840364b84, + type: 2} + propertyPath: Camera + value: + objectReference: {fileID: 1117230323} + m_RemovedComponents: + - {fileID: 114401842841139250, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + - {fileID: 114828623362714814, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + - {fileID: 114912848126749456, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + - {fileID: 114741845841415948, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + m_ParentPrefab: {fileID: 100100000, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + m_IsPrefabParent: 0 +--- !u!4 &592530378 stripped +Transform: + m_PrefabParentObject: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, + type: 2} + m_PrefabInternal: {fileID: 592530377} +--- !u!1 &1117230320 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1117230324} + - component: {fileID: 1117230323} + - component: {fileID: 1117230322} + - component: {fileID: 1117230321} + - component: {fileID: 1117230325} + m_Layer: 0 + m_Name: Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1117230321 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1117230320} + m_Enabled: 1 +--- !u!124 &1117230322 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1117230320} + m_Enabled: 1 +--- !u!20 &1117230323 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1117230320} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1117230324 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1117230320} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 10.879656, y: -3.3310251, z: 54.095062} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1117230325 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1117230320} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 27b72409b037b08459c5c96c104ca2fe, type: 3} + m_Name: + m_EditorClassIdentifier: + toggleKey: 0 + displayLines: 1 + displayGizmos: 0 + zOnShader: {fileID: 4800000, guid: 6602491fb85d04f7facf2932f1831720, type: 3} + zOffShader: {fileID: 4800000, guid: 12cb60961770c4d7e8cc1662ca101fec, type: 3} +--- !u!108 &1430544495 stripped +Light: + m_PrefabParentObject: {fileID: 10808534, guid: b6900baf9f552ba46ad27d4ada4d5489, + type: 2} + m_PrefabInternal: {fileID: 2088939132} +--- !u!1001 &1631170488 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_RootOrder + value: 4 + objectReference: {fileID: 0} + - target: {fileID: 11400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: textureSize + value: 16 + objectReference: {fileID: 0} + - target: {fileID: 11400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: waterMode + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + m_IsPrefabParent: 0 +--- !u!1 &1631170489 stripped +GameObject: + m_PrefabParentObject: {fileID: 100000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 2} + m_PrefabInternal: {fileID: 1631170488} +--- !u!1001 &2088939132 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 11436500, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: focusPoints.Array.size + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 499186, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 499186, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 499186, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 499186, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 499186, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 499186, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 499186, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 499186, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: m_RootOrder + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11455068, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: WaterPrefab + value: + objectReference: {fileID: 1631170489} + - target: {fileID: 11436500, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: Focus + value: + objectReference: {fileID: 1117230324} + - target: {fileID: 11436500, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + propertyPath: focusPoints.Array.data[0] + value: + objectReference: {fileID: 592530378} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: b6900baf9f552ba46ad27d4ada4d5489, type: 2} + m_IsPrefabParent: 0 diff --git a/Assets/Scenes/Main.unity.meta b/Assets/Scenes/Main.unity.meta new file mode 100644 index 00000000..28979282 --- /dev/null +++ b/Assets/Scenes/Main.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d0dd0b2b82e7ac84c92f1fffb0a83854 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/ModelViewer.unity b/Assets/Scenes/ModelViewer.unity new file mode 100644 index 00000000..0224c9fa --- /dev/null +++ b/Assets/Scenes/ModelViewer.unity @@ -0,0 +1,928 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.7490196, g: 0.7490196, b: 0.7490196, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44658786, g: 0.4964227, b: 0.5748251, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &4 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 0 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 1024 + m_ReflectionCompression: 2 + m_MixedBakeMode: 1 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 0 +--- !u!196 &5 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &36890519 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 36890521} + - component: {fileID: 36890520} + m_Layer: 0 + m_Name: Loader + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &36890520 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 36890519} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 29ff195586224b54ebfe1e606d27a4b3, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &36890521 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 36890519} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1672.9816, y: 14.781347, z: -1052.278} + 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!1 &54778219 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 54778220} + - component: {fileID: 54778223} + - component: {fileID: 54778222} + - component: {fileID: 54778221} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &54778220 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 54778219} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -1.27, y: 0.908, z: -6.71} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1084569001} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &54778221 +BoxCollider: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 54778219} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &54778222 +MeshRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 54778219} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &54778223 +MeshFilter: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 54778219} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &87615028 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 87615030} + - component: {fileID: 87615029} + m_Layer: 0 + m_Name: ModelViewer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &87615029 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 87615028} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9358e53be455ff144a4d0bab73b0c020, type: 3} + m_Name: + m_EditorClassIdentifier: + modelId: 355 + textureDictionaryName: + modelLoadType: 2 + targetParent: {fileID: 0} + load: 0 +--- !u!4 &87615030 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 87615028} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1.5, y: 1.235832, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &362290641 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalPosition.y + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalRotation.y + value: 0.730462 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_LocalRotation.w + value: 0.68295336 + objectReference: {fileID: 0} + - target: {fileID: 4388436116821042, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + propertyPath: m_RootOrder + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 114671475596742702, guid: 9d45d42a7408c1e4ab325d6840364b84, + type: 2} + propertyPath: PedestrianId + value: 163 + objectReference: {fileID: 0} + - target: {fileID: 114099438993920694, guid: 9d45d42a7408c1e4ab325d6840364b84, + type: 2} + propertyPath: Camera + value: + objectReference: {fileID: 1024790309} + - target: {fileID: 114671475596742702, guid: 9d45d42a7408c1e4ab325d6840364b84, + type: 2} + propertyPath: m_startingPedId + value: 163 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 9d45d42a7408c1e4ab325d6840364b84, type: 2} + m_IsPrefabParent: 0 +--- !u!1 &740136313 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 740136314} + - component: {fileID: 740136317} + - component: {fileID: 740136316} + - component: {fileID: 740136315} + m_Layer: 0 + m_Name: Cube (2) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &740136314 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 740136313} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -7.41, y: 0.908, z: 4.69} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1084569001} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &740136315 +BoxCollider: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 740136313} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &740136316 +MeshRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 740136313} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &740136317 +MeshFilter: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 740136313} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &862277649 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 862277653} + - component: {fileID: 862277652} + - component: {fileID: 862277651} + - component: {fileID: 862277650} + m_Layer: 0 + m_Name: Ground + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!23 &862277650 +MeshRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 862277649} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: e35c2e98492314f7ba69db58641d55d4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!64 &862277651 +MeshCollider: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 862277649} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Convex: 0 + m_CookingOptions: 14 + m_SkinWidth: 0.01 + m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} +--- !u!33 &862277652 +MeshFilter: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 862277649} + m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &862277653 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 862277649} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 32, y: 1, z: 32} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1007300631 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1007300633} + - component: {fileID: 1007300632} + m_Layer: 0 + m_Name: PedestrianModelViewer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1007300632 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1007300631} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1bce8e9c5332db34ab54033e1d462ffd, type: 3} + m_Name: + m_EditorClassIdentifier: + pedestrian: {fileID: 0} +--- !u!4 &1007300633 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1007300631} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.08672047, y: 1.8087432, z: -0.023024797} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1024790305 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1024790310} + - component: {fileID: 1024790309} + - component: {fileID: 1024790308} + - component: {fileID: 1024790307} + - component: {fileID: 1024790306} + - component: {fileID: 1024790311} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1024790306 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1024790305} + m_Enabled: 1 +--- !u!124 &1024790307 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1024790305} + m_Enabled: 1 +--- !u!92 &1024790308 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1024790305} + m_Enabled: 1 +--- !u!20 &1024790309 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1024790305} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0.019607844} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1024790310 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1024790305} + m_LocalRotation: {x: -0.0532625, y: 0.9103561, z: -0.12393946, w: -0.39122108} + m_LocalPosition: {x: 2.7437458, y: 2.38386, z: 2.626285} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1024790311 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1024790305} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 27b72409b037b08459c5c96c104ca2fe, type: 3} + m_Name: + m_EditorClassIdentifier: + toggleKey: 0 + displayLines: 1 + displayGizmos: 0 + zOnShader: {fileID: 4800000, guid: 6602491fb85d04f7facf2932f1831720, type: 3} + zOffShader: {fileID: 4800000, guid: 12cb60961770c4d7e8cc1662ca101fec, type: 3} +--- !u!1 &1084569000 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1084569001} + m_Layer: 0 + m_Name: Obstacles + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1084569001 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1084569000} + 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: 1789048031} + - {fileID: 54778220} + - {fileID: 740136314} + - {fileID: 1443196081} + m_Father: {fileID: 0} + m_RootOrder: 7 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1250333810 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1250333812} + - component: {fileID: 1250333811} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &1250333811 +Light: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1250333810} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &1250333812 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1250333810} + m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.109381676, w: 0.87542605} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1443196080 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1443196081} + - component: {fileID: 1443196084} + - component: {fileID: 1443196083} + - component: {fileID: 1443196082} + m_Layer: 0 + m_Name: Cube (3) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1443196081 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1443196080} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 16.04, y: 0.908, z: -2.78} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1084569001} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &1443196082 +BoxCollider: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1443196080} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1443196083 +MeshRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1443196080} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &1443196084 +MeshFilter: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1443196080} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1789048030 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1789048031} + - component: {fileID: 1789048034} + - component: {fileID: 1789048033} + - component: {fileID: 1789048032} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1789048031 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1789048030} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5.2, y: 0.908, z: 8.64} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1084569001} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &1789048032 +BoxCollider: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1789048030} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1789048033 +MeshRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1789048030} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &1789048034 +MeshFilter: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1789048030} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} diff --git a/Assets/Scenes/ModelViewer.unity.meta b/Assets/Scenes/ModelViewer.unity.meta new file mode 100644 index 00000000..32736a47 --- /dev/null +++ b/Assets/Scenes/ModelViewer.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4d342ee4081345b4fa59c038c306616d +timeCreated: 1428353896 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Startup.unity b/Assets/Scenes/Startup.unity new file mode 100644 index 00000000..12ddad49 --- /dev/null +++ b/Assets/Scenes/Startup.unity @@ -0,0 +1,429 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44658786, g: 0.4964227, b: 0.5748251, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1001 &129416363 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 4141056491348262, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4141056491348262, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4141056491348262, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4141056491348262, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 4141056491348262, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + propertyPath: m_LocalRotation.y + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 4141056491348262, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + propertyPath: m_LocalRotation.z + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 4141056491348262, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 4141056491348262, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + propertyPath: m_RootOrder + value: 5 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 4fdeb0b43fda44cd48a2a49fa62c0245, type: 2} + m_IsPrefabParent: 0 +--- !u!1001 &508769729 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 4476511338334242, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + propertyPath: m_LocalPosition.x + value: 2060.4775 + objectReference: {fileID: 0} + - target: {fileID: 4476511338334242, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + propertyPath: m_LocalPosition.y + value: 18.083828 + objectReference: {fileID: 0} + - target: {fileID: 4476511338334242, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + propertyPath: m_LocalPosition.z + value: 792.3567 + objectReference: {fileID: 0} + - target: {fileID: 4476511338334242, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4476511338334242, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4476511338334242, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4476511338334242, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 4476511338334242, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + propertyPath: m_RootOrder + value: 2 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 9678826ffd3ed244997780ccbdec99b7, type: 2} + m_IsPrefabParent: 0 +--- !u!1001 &589245766 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 4450559263798022, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + propertyPath: m_LocalPosition.x + value: 2106.089 + objectReference: {fileID: 0} + - target: {fileID: 4450559263798022, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + propertyPath: m_LocalPosition.y + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 4450559263798022, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + propertyPath: m_LocalPosition.z + value: 1848.0103 + objectReference: {fileID: 0} + - target: {fileID: 4450559263798022, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 4450559263798022, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + propertyPath: m_LocalRotation.y + value: 0.73046196 + objectReference: {fileID: 0} + - target: {fileID: 4450559263798022, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + propertyPath: m_LocalRotation.z + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 4450559263798022, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + propertyPath: m_LocalRotation.w + value: 0.6829534 + objectReference: {fileID: 0} + - target: {fileID: 4450559263798022, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + propertyPath: m_RootOrder + value: 3 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: dd5c14626ef595d439de799ec08c2b16, type: 2} + m_IsPrefabParent: 0 +--- !u!1 &732841203 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 732841207} + - component: {fileID: 732841206} + - component: {fileID: 732841205} + - component: {fileID: 732841204} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &732841204 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 732841203} + m_Enabled: 1 +--- !u!124 &732841205 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 732841203} + m_Enabled: 1 +--- !u!20 &732841206 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 732841203} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &732841207 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 732841203} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &1324114424 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 4615557407145958, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4615557407145958, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4615557407145958, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4615557407145958, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4615557407145958, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4615557407145958, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4615557407145958, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 4615557407145958, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + propertyPath: m_RootOrder + value: 4 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 259a477cc43ab4eb184305bfc583d66e, type: 2} + m_IsPrefabParent: 0 +--- !u!1 &1849129671 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1849129673} + - component: {fileID: 1849129672} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &1849129672 +Light: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1849129671} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &1849129673 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1849129671} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} diff --git a/Assets/Scenes/Startup.unity.meta b/Assets/Scenes/Startup.unity.meta new file mode 100644 index 00000000..faedd0c7 --- /dev/null +++ b/Assets/Scenes/Startup.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 025dece97687f439e94a9fe8c3b1b3fe +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts.meta b/Assets/Scripts.meta new file mode 100644 index 00000000..720b3c04 --- /dev/null +++ b/Assets/Scripts.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1a128e49b41401e4c9f25f9da9dcc196 +folderAsset: yes +timeCreated: 1427044922 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio.meta b/Assets/Scripts/Audio.meta new file mode 100644 index 00000000..0bb3d198 --- /dev/null +++ b/Assets/Scripts/Audio.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7f4e2111aaee445a8a75a6736a893d10 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/AudioStream.cs b/Assets/Scripts/Audio/AudioStream.cs new file mode 100644 index 00000000..18fde874 --- /dev/null +++ b/Assets/Scripts/Audio/AudioStream.cs @@ -0,0 +1,72 @@ +using NVorbis; +using System; +using System.IO; +using UnityEngine; + +namespace SanAndreasUnity.Audio +{ + + /// + /// Audio stream class + /// + public class AudioStream : IDisposable + { + /// + /// Reader + /// + private VorbisReader reader; + + /// + /// Audio clip + /// + private AudioClip audioClip; + + /// + /// Audio clip + /// + public AudioClip AudioClip + { + get + { + return audioClip; + } + } + + /// + /// Constructor + /// + /// Stream + /// Audio clip name + /// Close stream on dispose + public AudioStream(Stream stream, string audioClipName, bool closeStreamOnDispose) + { + reader = new VorbisReader(stream, closeStreamOnDispose); + audioClip = AudioClip.Create(audioClipName, (int)(reader.TotalSamples), reader.Channels, reader.SampleRate, true, (data) => + { + if (data != null) + { + if (data.Length > 0) + { + reader.ReadSamples(data, 0, Mathf.Min(data.Length, Mathf.Max(0, (int)(reader.TotalSamples - reader.DecodedPosition)))); + } + } + }, (newPosition) => + { + reader.DecodedPosition = newPosition; + }); + } + + /// + /// Dispose + /// + public void Dispose() + { + if (reader != null) + { + reader.Dispose(); + reader = null; + } + } + } + +} diff --git a/Assets/Scripts/Audio/AudioStream.cs.meta b/Assets/Scripts/Audio/AudioStream.cs.meta new file mode 100644 index 00000000..dda84778 --- /dev/null +++ b/Assets/Scripts/Audio/AudioStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9079bf3e9bf24e82b44206d1892f94a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours.meta b/Assets/Scripts/Behaviours.meta new file mode 100644 index 00000000..6ff5a261 --- /dev/null +++ b/Assets/Scripts/Behaviours.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 09278210c6463954e86d76cfb230d0e7 +folderAsset: yes +timeCreated: 1427465928 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Audio.meta b/Assets/Scripts/Behaviours/Audio.meta new file mode 100644 index 00000000..427f0ee1 --- /dev/null +++ b/Assets/Scripts/Behaviours/Audio.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bf47d9f291dc9484a9371bc9fac3a550 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Audio/AudioManager.cs b/Assets/Scripts/Behaviours/Audio/AudioManager.cs new file mode 100644 index 00000000..890b2d14 --- /dev/null +++ b/Assets/Scripts/Behaviours/Audio/AudioManager.cs @@ -0,0 +1,265 @@ +using System.Collections.Generic; +using UnityEngine; +using GTAAudioSharp; +using System.IO; +using SanAndreasUnity.Audio; + +namespace SanAndreasUnity.Behaviours.Audio +{ + + public class AudioManager : MonoBehaviour + { + + public static AudioManager Instance { get; private set; } + + private static GTAAudioFiles s_gtaAudioFiles; + public static GTAAudioFiles AudioFiles { get { return s_gtaAudioFiles; } } + + // private Dictionary sfxAudioClips = new Dictionary(); + + // private Dictionary streamsAudioClips = new Dictionary(); + + // private Dictionary streamsAudioStreams = new Dictionary(); + + public bool playStartupSound = true; + public float startupSoundTimeOffset = 0f; + static AudioSource s_startupAudioSource; + + public const int kSfxSampleSize = 2; + + // static AudioClip s_sfxGENRLClip; + // public static AudioClip SfxGENRLClip { get { return s_sfxGENRLClip; } } + + // describes single sound inside sfx bank + public struct SfxBankAudioData + { + public int startTimeMs; + // public int lengthMs; + // public float lengthSeconds { get { return this.lengthMs / 1000f; } } + public int bitrateKbs; // kb/s + public int offsetInBytes; + public int bitsPerSecond { get { return this.bitrateKbs * 1000; } } + public float bytesPerSecond { get { return this.bitsPerSecond / 8f; } } + // public int sizeInBytes { get { return Mathf.RoundToInt( this.lengthSeconds * this.bytesPerSecond ); } } + public int sizeInBytes; + } + + static SfxBankAudioData[] s_sfxGENRL137Timings; + public static SfxBankAudioData[] SfxGENRL137Timings { get { return s_sfxGENRL137Timings; } } + + + + void Awake () + { + Instance = this; + } + + void OnDisable () + { + if (s_gtaAudioFiles != null) + { + s_gtaAudioFiles.Dispose (); + s_gtaAudioFiles = null; + } + } + + void Start () { + + } + + void OnLoaderFinished () + { + if (s_startupAudioSource != null) + { + Destroy (s_startupAudioSource.gameObject); + } + } + + void Update () { + + } + + + public static void InitFromLoader () + { + + s_gtaAudioFiles = GTAAudio.OpenRead (Path.Combine (Utilities.Config.GamePath, "audio")); + + s_sfxGENRL137Timings = LoadSfxBankTimings (Path.Combine (Utilities.Config.DataPath, "SFX_GENRL_137.txt")); + + if (Instance.playStartupSound) + { + s_startupAudioSource = PlayStream ("Beats", 1); + if (s_startupAudioSource != null) + s_startupAudioSource.time = Instance.startupSoundTimeOffset; + } + + // s_sfxGENRLClip = CreateAudioClipFromSfx ("GENRL", 136, 0); + + } + + public static SfxBankAudioData[] LoadSfxBankTimings (string filePath) + { + // int sampleSize = 2; + System.IFormatProvider formatProvider = System.Globalization.CultureInfo.InvariantCulture; + var lines = File.ReadAllLines (filePath); + SfxBankAudioData[] datas = new SfxBankAudioData[(lines.Length - 1)]; // skip last line + // int currentTime = 0; + float currentOffset = 0; + for (int i = 0, lineIndex = 0; i < datas.Length; i++) + { + string[] splits = lines [lineIndex++].Split (' '); + + // datas [i].startTimeMs = currentTime; + // datas [i].offsetInBytes = Mathf.RoundToInt (currentOffset); + + // int clipLengthMs = int.Parse (lines [lineIndex++], formatProvider); + // datas [i].lengthMs = clipLengthMs; + + // int bitrate = 288;//int.Parse (lines [lineIndex++], formatProvider); + // lineIndex ++; + // datas [i].bitrateKbs = bitrate; + + // currentTime += clipLengthMs; + // currentOffset += (clipLengthMs / 1000f) * (bitrate * 1000f / 8f); + + datas [i].offsetInBytes = int.Parse (splits [0]); + datas [i].sizeInBytes = int.Parse (splits [1]); + datas [i].bitrateKbs = Mathf.RoundToInt( FreqToKbs( int.Parse (splits [2]) ) ); + + } + // Debug.LogFormat ("sfx timings loaded - current offset {0}", currentOffset); + return datas; + } + + + public static AudioClip CreateAudioClipFromStream (string streamFileName, int bankIndex) + { + AudioStream audio_stream = null; + System.DateTime startTime = System.DateTime.Now; + + int streams_bank_index = bankIndex; + string streams_file_name = streamFileName; + string key = streams_file_name + "." + streams_bank_index; + + + if ((s_gtaAudioFiles != null) && (streams_bank_index >= 0)) + { + try + { + Stream stream = s_gtaAudioFiles.OpenStreamsAudioStreamByName(streams_file_name, (uint)streams_bank_index); + if (stream != null) + { + audio_stream = new AudioStream(stream, key, true); + } + } + catch (System.Exception e) + { + Debug.LogError(e); + } + } + + + if (audio_stream != null) + { + System.TimeSpan time_span = System.DateTime.Now - startTime; + Debug.Log("\"" + key + "\" took " + time_span.TotalSeconds + " seconds."); + + return audio_stream.AudioClip; + } + + return null; + } + + public static AudioSource PlayStream (string streamFileName, int bankIndex) + { + var clip = CreateAudioClipFromStream (streamFileName, bankIndex); + if (clip != null) + { + AudioSource audioSource = new GameObject (streamFileName + "." + bankIndex).AddComponent (); + audioSource.time = 0.0f; + audioSource.clip = clip; + audioSource.Play(); + + // destroy game object when sound is finished playing + Destroy( audioSource.gameObject, clip.length ); + + return audioSource; + } + + return null; + } + + public static AudioClip CreateAudioClipFromSfx (string sfxFileName, int bankIndex, int audioIndex, SfxBankAudioData? sfxBankAudioData) + { + + if (null == s_gtaAudioFiles || bankIndex < 0 || audioIndex < 0) + return null; + + AudioClip ret = null; + string clipName = sfxFileName + "." + bankIndex + "." + audioIndex; + + try + { + using (GTAAudioStream audio_stream = s_gtaAudioFiles.OpenSFXAudioStreamByName(sfxFileName, (uint)bankIndex, (uint)audioIndex)) + { + if (audio_stream != null) + { + // this audio stream holds all sounds from this bank + + int freq = sfxBankAudioData.HasValue ? Mathf.RoundToInt( KbsToFreq( sfxBankAudioData.Value.bitrateKbs ) ) : audio_stream.SampleRate ; + int offsetInBytes = sfxBankAudioData.HasValue ? sfxBankAudioData.Value.offsetInBytes : 0 ; + int sizeInBytes = sfxBankAudioData.HasValue ? sfxBankAudioData.Value.sizeInBytes : (int) audio_stream.Length ; + + ret = CreateAudioClipFromSfx (clipName, audio_stream, offsetInBytes, sizeInBytes, freq); + + } + } + } + catch (System.Exception e) + { + Debug.LogError(e); + } + + return ret; + } + + public static AudioClip CreateAudioClipFromSfx (string clipName, GTAAudioStream audio_stream, int offsetInBytes, int sizeInBytes, int frequency) + { + AudioClip ret = null; + + audio_stream.Position = offsetInBytes; + + byte[] int_pcm = new byte[sizeInBytes]; + + if (audio_stream.Read(int_pcm, 0, int_pcm.Length) == int_pcm.Length) + { + float[] float_pcm = new float[int_pcm.Length / sizeof(short)]; + for (int i = 0; i < float_pcm.Length; i++) + { + float_pcm[i] = Mathf.Clamp(((short)(int_pcm[i * sizeof(short)] | (int_pcm[(i * sizeof(short)) + 1] << 8)) / 32767.5f), -1.0f, 1.0f); + } + ret = AudioClip.Create(clipName, float_pcm.Length, 1, frequency, false); + ret.SetData(float_pcm, 0); + + Debug.LogFormat("loaded sfx: name {0}, offset {1}, size {2}, length {3}, bitrate Kb/s {4}, stream size {5}, freq {6}", + clipName, offsetInBytes, sizeInBytes, ret.length, + FreqToKbs (frequency), audio_stream.Length, frequency); + } + + return ret; + } + + static float FreqToKbs(int freq) + { + return freq * kSfxSampleSize * 8f / 1000f; + } + + static float KbsToFreq(float kbs) + { + return kbs / 8f * 1000f / kSfxSampleSize; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Audio/AudioManager.cs.meta b/Assets/Scripts/Behaviours/Audio/AudioManager.cs.meta new file mode 100644 index 00000000..95ea16d2 --- /dev/null +++ b/Assets/Scripts/Behaviours/Audio/AudioManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0735457b0cfd4a77bab1c58f1d77882 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/CharacterModelChanger.cs b/Assets/Scripts/Behaviours/CharacterModelChanger.cs new file mode 100644 index 00000000..b20bb1d9 --- /dev/null +++ b/Assets/Scripts/Behaviours/CharacterModelChanger.cs @@ -0,0 +1,47 @@ +using SanAndreasUnity.Behaviours; +using UnityEngine; + +public class CharacterModelChanger : MonoBehaviour +{ + public KeyCode actionKey = KeyCode.P; + + // Use this for initialization + private void Start() + { + } + + // Update is called once per frame + private void Update() + { + if (Input.GetKeyDown(actionKey)) + { + ChangePedestrianModel(); + } + } + + public static void ChangePedestrianModel() + { + if (Ped.Instance != null) + { + ChangePedestrianModel(Ped.Instance.PlayerModel, -1); + } + } + + public static void ChangePedestrianModel(PedModel ped, int newModelId) + { + + if (-1 == newModelId) + newModelId = Ped.RandomPedId; + + // Retry with another random model if this one doesn't work + try + { + ped.Load(newModelId); + } + catch (System.NullReferenceException ex) + { + Debug.LogException (ex); + ChangePedestrianModel(ped, -1); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/CharacterModelChanger.cs.meta b/Assets/Scripts/Behaviours/CharacterModelChanger.cs.meta new file mode 100644 index 00000000..959112b3 --- /dev/null +++ b/Assets/Scripts/Behaviours/CharacterModelChanger.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 987093d4b0d5b09428ae0410f453a296 +timeCreated: 1474209975 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Damageable.cs b/Assets/Scripts/Behaviours/Damageable.cs new file mode 100644 index 00000000..4571081c --- /dev/null +++ b/Assets/Scripts/Behaviours/Damageable.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Events; + +namespace SanAndreasUnity.Behaviours +{ + + public class DamageInfo + { + public float amount = 0f; + public object data = null; + } + + public class Damageable : MonoBehaviour + { + + [SerializeField] private float m_health = 0f; + public float Health { get { return m_health; } set { m_health = value; } } + + [SerializeField] private UnityEvent m_onDamage = new UnityEvent (); + + public DamageInfo LastDamageInfo { get; private set; } + + + + public void Damage (DamageInfo info) + { + this.LastDamageInfo = info; + m_onDamage.Invoke (); + } + + public void HandleDamageByDefault () + { + DamageInfo info = this.LastDamageInfo; + + this.Health -= info.amount; + + if (this.Health <= 0f) { + Destroy (this.gameObject); + } + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Damageable.cs.meta b/Assets/Scripts/Behaviours/Damageable.cs.meta new file mode 100644 index 00000000..41fc3ebc --- /dev/null +++ b/Assets/Scripts/Behaviours/Damageable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62374ff6df2c74f9699075492ef7fdb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Frame.cs b/Assets/Scripts/Behaviours/Frame.cs new file mode 100644 index 00000000..297aa972 --- /dev/null +++ b/Assets/Scripts/Behaviours/Frame.cs @@ -0,0 +1,42 @@ +using SanAndreasUnity.Importing.RenderWareStream; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours +{ + public class Frame : MonoBehaviour + { + private string _path; + + public int Index { get; private set; } + public int BoneId { get; private set; } + public string Name { get; internal set; } + + public Frame Parent { get; internal set; } + public int ParentIndex { get; internal set; } + + public Vector3 LocalVelocity; + + public HierarchyAnimationFlags Flags; + + public string Path + { + get { return _path ?? (_path = FindPath()); } + } + + internal void Initialize(Importing.Conversion.Geometry.GeometryFrame frame) + { + Index = frame.Source.Index; + BoneId = frame.Source.HAnim != null ? (int)frame.Source.HAnim.NodeId : -1; + Name = frame.Name; + + if (frame.Source.HAnim == null) return; + + Flags = frame.Source.HAnim.Flags; + } + + private string FindPath() + { + return Parent == null ? Name : string.Format("{0}/{1}", Parent.Path, Name); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Frame.cs.meta b/Assets/Scripts/Behaviours/Frame.cs.meta new file mode 100644 index 00000000..fea284d7 --- /dev/null +++ b/Assets/Scripts/Behaviours/Frame.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6fd6fcce207fab44fa9365ea21bc25e6 +timeCreated: 1428792472 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/FrameContainer.cs b/Assets/Scripts/Behaviours/FrameContainer.cs new file mode 100644 index 00000000..124ce0f9 --- /dev/null +++ b/Assets/Scripts/Behaviours/FrameContainer.cs @@ -0,0 +1,85 @@ +using SanAndreasUnity.Importing.Conversion; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours +{ + public class FrameContainer : MonoBehaviour, IEnumerable + { + private Frame[] _frames; + private Dictionary _boneIdDict; + + public Frame Root { get { return _frames.FirstOrDefault(x => x.Parent == null); } } + + internal void Initialize(Geometry.GeometryFrame[] frames, + Dictionary transforms) + { + _frames = frames.Select(x => + { + var frame = transforms[x].gameObject.AddComponent(); + frame.Initialize(x); + return frame; + }).ToArray(); + + for (var i = 0; i < frames.Length; ++i) + { + var frame = frames[i]; + if (frame.ParentIndex == -1) continue; + _frames[i].Parent = _frames[frame.ParentIndex]; + _frames[i].ParentIndex = frame.ParentIndex; + } + + _boneIdDict = _frames.Where(x => x.BoneId > -1).ToDictionary(x => x.BoneId, x => x); + } + + public Frame GetByName(string name, bool ignoreWhiteSpaces = false) + { + if (ignoreWhiteSpaces) + name = name.Replace (" ", ""); + + if (ignoreWhiteSpaces) + return _frames.FirstOrDefault (x => x.Name.Replace (" ", "") == name); + else + return _frames.FirstOrDefault (x => x.Name == name); + } + + public Frame GetByIndex(int index) + { + return _frames[index]; + } + + public Frame GetByBoneId(int boneId) + { + return _boneIdDict[boneId]; + } + + public IEnumerator GetEnumerator() + { + return _frames.AsEnumerable().GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return _frames.GetEnumerator(); + } + + private void OnDrawGizmosSelected() + { + if (_frames == null) return; + + foreach (var frame in _frames) + { + if (frame == null) return; + + Gizmos.color = Color.white; + Gizmos.DrawWireSphere(frame.transform.position, 0.02f); + + if (frame.Parent != null) + { + Gizmos.DrawLine(frame.transform.position, frame.Parent.transform.position); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/FrameContainer.cs.meta b/Assets/Scripts/Behaviours/FrameContainer.cs.meta new file mode 100644 index 00000000..a7279d1f --- /dev/null +++ b/Assets/Scripts/Behaviours/FrameContainer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c16e4a02d730abb40a82e801954132f7 +timeCreated: 1428788125 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/GameManager.cs b/Assets/Scripts/Behaviours/GameManager.cs new file mode 100644 index 00000000..d91e6355 --- /dev/null +++ b/Assets/Scripts/Behaviours/GameManager.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace SanAndreasUnity.Behaviours { + + public class SceneChangedMessage { + public Scene s1; + public Scene s2; + } + + public class GameManager : MonoBehaviour { + + public static GameManager Instance { get ; private set ; } + + public static bool CursorLocked { get ; private set ; } + + public Texture2D logoTexture = null; + + public GameObject barPrefab; + + + /// Are we in a startup scene ? + public static bool IsInStartupScene { get { return UnityEngine.SceneManagement.SceneManager.GetActiveScene ().buildIndex == 0; } } + + + + private void Awake() { + + if (null == Instance) + Instance = this; + + } + + void OnEnable () + { + SceneManager.activeSceneChanged += this.OnSceneChangedInternal; + } + + void OnDisable () + { + SceneManager.activeSceneChanged -= this.OnSceneChangedInternal; + } + + void OnSceneChangedInternal (Scene s1, Scene s2) + { + Utilities.F.SendMessageToObjectsOfType("OnSceneChanged", new SceneChangedMessage() {s1 = s1, s2 = s2}); + } + + void Start () { + + } + + void Update () { + + + // Fix cursor state if it has been 'broken', happens eg. with zoom gestures in the editor in macOS + if (CursorLocked && ((Cursor.lockState != CursorLockMode.Locked) || (Cursor.visible))) + { + Cursor.lockState = CursorLockMode.Locked; + Cursor.visible = false; + } + + + } + + public static bool CanPlayerReadInput() { + + return Loader.HasLoaded && !UI.PauseMenu.IsOpened; + + } + + public static void ChangeCursorState(bool locked) + { + CursorLocked = locked; + Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None; + Cursor.visible = !locked; + } + + public static void ExitApplication() { + + #if UNITY_EDITOR + UnityEditor.EditorApplication.isPlaying = false; + #else + Application.Quit (); + #endif + + } + + public static void SetMaxFps (int maxFps) + { + QualitySettings.vSyncCount = 0; + Application.targetFrameRate = maxFps; + } + + public static int GetMaxFps () + { + if (!IsFpsLimited ()) + return 0; + return Application.targetFrameRate; + } + + public static bool IsFpsLimited () + { + return QualitySettings.vSyncCount == 0; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/GameManager.cs.meta b/Assets/Scripts/Behaviours/GameManager.cs.meta new file mode 100644 index 00000000..a7389b42 --- /dev/null +++ b/Assets/Scripts/Behaviours/GameManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 769ff20407cff41688e681458d8528fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Loader.cs b/Assets/Scripts/Behaviours/Loader.cs new file mode 100644 index 00000000..4e8afa51 --- /dev/null +++ b/Assets/Scripts/Behaviours/Loader.cs @@ -0,0 +1,517 @@ +using System.IO; +using SanAndreasUnity.Importing.Animation; +using SanAndreasUnity.Importing.Archive; +using SanAndreasUnity.Importing.Collision; +using SanAndreasUnity.Importing.Conversion; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Vehicles; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours.World; +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace SanAndreasUnity.Behaviours +{ + + public class Loader : MonoBehaviour + { + + public static bool HasLoaded { get; private set; } + public static bool IsLoading { get; private set; } + + public static string LoadingStatus { get; private set; } + + private static int m_currentStepIndex = 0; + + private static float m_totalEstimatedLoadingTime = 0; + + private static bool m_hasErrors = false; + private static System.Exception m_loadException; + + private static IArchive[] s_archives; + + public class LoadingStep + { + public IEnumerator Coroutine { get; private set; } + public System.Action LoadFunction { get; private set; } + public string Description { get; set; } + public bool StopLoadingOnException { get; private set; } + public float TimeElapsed { get; internal set; } + public float EstimatedTime { get; private set; } + + public LoadingStep (System.Action loadFunction, string description, float estimatedTime = 0f, bool stopLoadingOnException = true) + { + this.LoadFunction = loadFunction; + this.Description = description; + this.EstimatedTime = estimatedTime; + this.StopLoadingOnException = stopLoadingOnException; + } + + public LoadingStep (IEnumerator coroutine, string description, float estimatedTime = 0f, bool stopLoadingOnException = true) + { + this.Coroutine = coroutine; + this.Description = description; + this.EstimatedTime = estimatedTime; + this.StopLoadingOnException = stopLoadingOnException; + } + + } + + private static List m_loadingSteps = new List (); + + public static Texture2D CurrentSplashTex { get; set; } + public static Texture2D SplashTex1 { get; set; } + public static Texture2D SplashTex2 { get; set; } + + private static bool m_showFileBrowser = false; + private static FileBrowser m_fileBrowser = null; + + + + void Start () + { + + AddLoadingSteps (); + + StartCoroutine (LoadCoroutine ()); + + } + + private static void AddLoadingSteps () + { + + LoadingStep[] steps = new LoadingStep[] { + new LoadingStep ( StepLoadConfig, "Loading config", 0.02f ), + new LoadingStep ( StepSelectGTAPath(), "Select path to GTA", 0.0f ), + new LoadingStep ( StepLoadArchives, "Loading archives", 1.7f ), + new LoadingStep ( StepLoadSplashScreen, "Loading splash screen", 0.06f ), + new LoadingStep ( StepSetSplash1, "Set splash 1" ), + new LoadingStep ( StepLoadAudio, "Loading audio" ), + new LoadingStep ( StepLoadCollision, "Loading collision files", 0.9f ), + new LoadingStep ( StepLoadItemInfo, "Loading item info", 2.4f ), + new LoadingStep ( StepLoadHandling, "Loading handling", 0.01f ), + //new LoadingStep ( () => { throw new System.Exception ("testing error handling"); }, "testing error handling", 0.01f ), + new LoadingStep ( StepLoadAnimGroups, "Loading animation groups", 0.02f ), + new LoadingStep ( StepLoadCarColors, "Loading car colors", 0.04f ), + new LoadingStep ( StepLoadWeaponsData, "Loading weapons data", 0.05f ), + new LoadingStep ( StepSetSplash2, "Set splash 2" ), + new LoadingStep ( StepLoadMap, "Loading map", 2.1f ), + new LoadingStep ( StepLoadSpecialTextures, "Loading special textures", 0.01f ), + }; + + + for (int i = 0; i < steps.Length; i++) { + AddLoadingStep (steps [i]); + } + + + if (Cell.Instance != null) { + // add steps for cell + AddLoadingStep( new LoadingStep( () => Cell.Instance.CreateStaticGeometry (), "Creating static geometry", 5.8f ) ); + AddLoadingStep( new LoadingStep( () => Cell.Instance.InitStaticGeometry (), "Init static geometry", 0.35f ) ); + AddLoadingStep( new LoadingStep( () => Cell.Instance.LoadParkedVehicles (), "Loading parked vehicles", 0.2f ) ); + AddLoadingStep( new LoadingStep( () => Cell.Instance.AddMapObjectsToDivisions (), "Adding map objects to divisions", 0.85f ) ); + AddLoadingStep( new LoadingStep( () => Cell.Instance.LoadWater (), "Loading water", 0.08f ) ); + AddLoadingStep( new LoadingStep( () => Cell.Instance.FinalizeLoad (), "Finalize world loading", 0.01f ) ); + + } + + } + + private static void AddLoadingStep (LoadingStep step) + { + m_loadingSteps.AddIfNotPresent (step); + } + + + private static IEnumerator LoadCoroutine () + { + + var stopwatch = System.Diagnostics.Stopwatch.StartNew (); + + IsLoading = true; + + Debug.Log("Started loading GTA"); + + // wait a few frames - to "unblock" the program, and to let other scripts initialize before + // registering their loading steps + yield return null; + yield return null; + + // calculate total loading time + m_totalEstimatedLoadingTime = m_loadingSteps.Sum( step => step.EstimatedTime ); + + var stopwatchForSteps = new System.Diagnostics.Stopwatch (); + + foreach (var step in m_loadingSteps) { + + // update description + LoadingStatus = step.Description; + yield return null; + + stopwatchForSteps.Restart (); + + var en = step.Coroutine; + + if (en != null) { + // this step uses coroutine + + bool hasNext = true; + + while (hasNext) { + + hasNext = false; + try { + hasNext = en.MoveNext (); + } catch (System.Exception ex) { + HandleExceptionDuringLoad (ex); + if (step.StopLoadingOnException) { + yield break; + } + } + + // update description + LoadingStatus = step.Description; + yield return null; + + } + } else { + // this step uses a function + + try { + step.LoadFunction (); + } catch(System.Exception ex) { + HandleExceptionDuringLoad (ex); + if (step.StopLoadingOnException) { + yield break; + } + } + } + + // step finished it's work + + step.TimeElapsed = stopwatchForSteps.ElapsedMilliseconds; + + m_currentStepIndex++; + + Debug.LogFormat ("{0} - finished in {1} ms", step.Description, step.TimeElapsed); + } + + // all steps finished loading + + HasLoaded = true; + IsLoading = false; + + Debug.Log("GTA loading finished in " + stopwatch.Elapsed.TotalSeconds + " seconds"); + + // notify all scripts + F.SendMessageToObjectsOfType( "OnLoaderFinished" ); + + } + + private static void HandleExceptionDuringLoad (System.Exception ex) + { + m_hasErrors = true; + m_loadException = ex; + + Debug.LogException (ex); + } + + + private static void StepLoadConfig () + { + Config.Load (); + } + + private static IEnumerator StepSelectGTAPath () + { + yield return null; + + string path = Config.GetPath(Config.const_game_dir); + + if (string.IsNullOrEmpty (path)) { + // path is not set + // show file browser to user to select path + m_showFileBrowser = true; + } else { + yield break; + } + + // wait until user selects a path + while (m_showFileBrowser) { + yield return null; + } + + // refresh path + path = Config.GetPath(Config.const_game_dir); + + if (string.IsNullOrEmpty (path)) { + // path was not set + throw new System.Exception ("Path to GTA was not set"); + } + + } + + private static void StepLoadArchives () + { + + string[] archivePaths = Config.GetPaths("archive_paths"); + + List listArchives = new List(); + + foreach (var path in archivePaths) + { + if (File.Exists(path)) + { + listArchives.Add(ArchiveManager.LoadImageArchive(path)); + } + else if (Directory.Exists(path)) + { + listArchives.Add(ArchiveManager.LoadLooseArchive(path)); + } + else + { + throw new System.Exception("Archive not found: " + path); + } + } + + s_archives = listArchives.FindAll(a => a != null).ToArray(); + + } + + private static void StepLoadSplashScreen () + { + var txd = TextureDictionary.Load ("LOADSCS"); + + int index1 = Random.Range (1, 15); + int index2 = Random.Range (1, 15); + + SplashTex1 = txd.GetDiffuse ("loadsc" + index1).Texture; + SplashTex2 = txd.GetDiffuse ("loadsc" + index2).Texture; + + } + + private static void StepSetSplash1 () + { + CurrentSplashTex = SplashTex1; + } + + private static void StepSetSplash2 () + { + CurrentSplashTex = SplashTex2; + } + + private static void StepLoadAudio () + { + Audio.AudioManager.InitFromLoader (); + } + + private static void StepLoadCollision () + { + + int numCollisionFiles = 0; + + foreach (var archive in s_archives) + { + foreach (var colFile in archive.GetFileNamesWithExtension(".col")) + { + CollisionFile.Load(colFile); + numCollisionFiles++; + } + } + + Debug.Log("Number of collision files " + numCollisionFiles); + + } + + private static void StepLoadItemInfo () + { + + foreach (var path in Config.GetPaths("item_paths")) + { + var ext = Path.GetExtension(path).ToLower(); + switch (ext) + { + case ".dat": + Item.ReadLoadList(path); + break; + + case ".ide": + Item.ReadIde(path); + break; + + case ".ipl": + Item.ReadIpl(path); + break; + } + } + + } + + private static void StepLoadHandling () + { + Handling.Load(Config.GetPath("handling_path")); + } + + private static void StepLoadAnimGroups () + { + foreach (var path in Config.GetPaths("anim_groups_paths")) + { + AnimationGroup.Load(path); + } + } + + private static void StepLoadCarColors () + { + CarColors.Load(Config.GetPath("car_colors_path")); + } + + private static void StepLoadWeaponsData () + { + Importing.Weapons.WeaponData.Load(Config.GetPath("weapons_path")); + } + + private static void StepLoadMap () + { + //MiniMap.loadTextures(); + MiniMap.AssingMinimap (); + } + + private static void StepLoadSpecialTextures () + { + + // Load mouse cursor texture + Texture2D mouse = TextureDictionary.Load("fronten_pc").GetDiffuse("mouse").Texture; + Texture2D mouseFix = new Texture2D(mouse.width, mouse.height); + + for (int x = 0; x < mouse.width; x++) + for (int y = 0; y < mouse.height; y++) + mouseFix.SetPixel(x, mouse.height - y - 1, mouse.GetPixel(x, y)); + + mouseFix.Apply(); + Cursor.SetCursor(mouseFix, Vector2.zero, CursorMode.Auto); + + // load crosshair texture + Weapon.CrosshairTexture = TextureDictionary.Load("hud").GetDiffuse("siteM16").Texture; + + // fist texture + Weapon.FistTexture = TextureDictionary.Load("hud").GetDiffuse("fist").Texture; + + } + + + + public static float GetProgressPerc () + { + if (m_currentStepIndex <= 0) + return 0f; + + if (m_currentStepIndex >= m_loadingSteps.Count) + return 1f; + + float estimatedTimePassed = 0f; + for (int i = 0; i < m_currentStepIndex; i++) { + estimatedTimePassed += m_loadingSteps [i].EstimatedTime; + } + + return Mathf.Clamp01 (estimatedTimePassed / m_totalEstimatedLoadingTime); + } + + + private void Update() + { + + } + + private void OnGUI() + { + if (HasLoaded) + return; + + // background + + if (CurrentSplashTex != null) { + GUIUtils.DrawTextureWithYFlipped (new Rect (0, 0, Screen.width, Screen.height), CurrentSplashTex); + } else { + GUIUtils.DrawRect (new Rect (0, 0, Screen.width, Screen.height), Color.black); + } + + // display loading progress + + GUILayout.BeginArea(new Rect(10, 5, 400, Screen.height)); + + // current status + GUILayout.Label("" + LoadingStatus + ""); + + // progress bar + GUILayout.Space (10); + DisplayProgressBar (); + + // display error + if (m_hasErrors) { + GUILayout.Space (20); + GUILayout.Label("" + "The following exception occured during the current step:\n" + "" + m_loadException.ToString ()); + } + + // display all steps +// GUILayout.Space (10); +// DisplayAllSteps (); + + GUILayout.EndArea(); + + DisplayFileBrowser (); + + } + + private static void DisplayAllSteps () + { + + int i=0; + foreach (var step in m_loadingSteps) { + GUILayout.Label( step.Description + (m_currentStepIndex > i ? (" - " + step.TimeElapsed + " ms") : "") ); + i++; + } + + } + + private static void DisplayProgressBar () + { + float width = 200; + float height = 12; + +// Rect rect = GUILayoutUtility.GetLastRect (); +// rect.position += new Vector2 (0, rect.height); +// rect.size = new Vector2 (width, height); + + Rect rect = GUILayoutUtility.GetRect( width, height ); + rect.width = width; + + float progressPerc = GetProgressPerc (); + GUIUtils.DrawBar( rect, progressPerc, new Vector4(149, 185, 244, 255) / 256.0f, new Vector4(92, 147, 237, 255) / 256.0f, 2f ); + + } + + private static void DisplayFileBrowser () + { + if (!m_showFileBrowser) + return; + + if (null == m_fileBrowser) { + Rect rect = GUIUtils.GetCenteredRect (new Vector2 (550, 350)); + + m_fileBrowser = new FileBrowser(rect, "Select path to GTA", (string path) => { + m_showFileBrowser = false; + Config.SetString (Config.const_game_dir, path); + Config.SaveUserConfigSafe (); + } ); + m_fileBrowser.BrowserType = FileBrowserType.Directory; + } + + m_fileBrowser.OnGUI (); + + } + + } +} diff --git a/Assets/Scripts/Behaviours/Loader.cs.meta b/Assets/Scripts/Behaviours/Loader.cs.meta new file mode 100644 index 00000000..a34bd84f --- /dev/null +++ b/Assets/Scripts/Behaviours/Loader.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 29ff195586224b54ebfe1e606d27a4b3 +timeCreated: 1428343645 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/LoadingThread.cs b/Assets/Scripts/Behaviours/LoadingThread.cs new file mode 100644 index 00000000..23dd41bf --- /dev/null +++ b/Assets/Scripts/Behaviours/LoadingThread.cs @@ -0,0 +1,137 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using System.Threading; +using System.Runtime.CompilerServices; + +namespace SanAndreasUnity.Behaviours +{ + + public class LoadingThread : MonoBehaviour { + + public struct Job + { + public System.Func action ; + public System.Action callbackSuccess ; + public System.Action callbackError ; + public System.Action callbackFinish; + internal object result ; + internal System.Exception exception ; + } + + static System.Collections.Concurrent.BlockingCollection> s_jobs = new System.Collections.Concurrent.BlockingCollection> (); + static Thread s_thread; + static System.Collections.Concurrent.BlockingCollection> s_processedJobs = new System.Collections.Concurrent.BlockingCollection> (); + + static bool s_shouldThreadExit = false; + + + + void Start () { + + s_thread = new Thread (ThreadFunction); + s_thread.Start (); + + } + + void OnDisable () + { + if (s_thread != null) + { + var sw = System.Diagnostics.Stopwatch.StartNew (); + // s_thread.Interrupt (); + TellThreadToExit (); + if (s_thread.Join (7000)) + Debug.LogFormat ("Stopped loading thread in {0} ms", sw.Elapsed.TotalMilliseconds); + else + Debug.LogError ("Failed to stop loading thread"); + } + } + + void Update () { + + // get all processed jobs + + Job job; + while (s_processedJobs.TryTake (out job, 0)) + { + if (job.exception != null) + { + // error happened + + if (job.callbackError != null) + Utilities.F.RunExceptionSafe( () => job.callbackError (job.exception) ); + + Debug.LogException (job.exception); + } + else + { + // success + if (job.callbackSuccess != null) + Utilities.F.RunExceptionSafe( () => job.callbackSuccess (job.result) ); + } + + // invoke finish callback + if (job.callbackFinish != null) + F.RunExceptionSafe (() => job.callbackFinish (job.result)); + } + + } + + + public static void RegisterJob (Job job) + { + if (null == job.action) + return; + + job.exception = null; + + var j = new Job () { + action = () => job.action(), + callbackError = job.callbackError, + }; + if(job.callbackSuccess != null) + j.callbackSuccess = (arg) => job.callbackSuccess( (T) arg ); + if(job.callbackFinish != null) + j.callbackFinish = (arg) => job.callbackFinish( (T) arg ); + + s_jobs.Add (j); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + static bool ShouldThreadExit() + { + return s_shouldThreadExit; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + static void TellThreadToExit() + { + s_shouldThreadExit = true; + } + + static void ThreadFunction () + { + + while (!ShouldThreadExit ()) + { + Job job; + if (!s_jobs.TryTake (out job, 200)) + continue; + + try + { + job.result = job.action(); + } + catch(System.Exception ex) + { + job.exception = ex; + } + + s_processedJobs.Add (job); + } + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/LoadingThread.cs.meta b/Assets/Scripts/Behaviours/LoadingThread.cs.meta new file mode 100644 index 00000000..bc5d7a30 --- /dev/null +++ b/Assets/Scripts/Behaviours/LoadingThread.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be87ebc3b426867448164f659f750671 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/MapObject.cs b/Assets/Scripts/Behaviours/MapObject.cs new file mode 100644 index 00000000..0f3715d7 --- /dev/null +++ b/Assets/Scripts/Behaviours/MapObject.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using UnityEngine; +using Debug = UnityEngine.Debug; +using UnityEngine.Profiling; + +namespace SanAndreasUnity.Behaviours +{ + public abstract class MapObject : MonoBehaviour, IComparable + { + private static Texture2D _sNoiseTex; + + private static bool ShouldGenerateNoiseTex + { + get { return _sNoiseTex == null || _sNoiseTex.width != Screen.width || _sNoiseTex.height != Screen.height; } + } + + private static int _sBreakableLayer = -1; + + public static int BreakableLayer + { + get { return _sBreakableLayer == -1 ? _sBreakableLayer = LayerMask.NameToLayer("Breakable") : _sBreakableLayer; } + } + + private static int _sNoiseTexId = -1; + + protected static int NoiseTexId + { + get { return _sNoiseTexId == -1 ? _sNoiseTexId = Shader.PropertyToID("_NoiseTex") : _sNoiseTexId; } + } + + private static int _sFadeId = -1; + + protected static int FadeId + { + get { return _sFadeId == -1 ? _sFadeId = Shader.PropertyToID("_Fade") : _sFadeId; } + } + + private static void GenerateNoiseTex() + { + var width = Screen.width; + var height = Screen.height; + + var timer = new Stopwatch(); + timer.Start(); + + if (_sNoiseTex == null) + { + _sNoiseTex = new Texture2D(width, height, TextureFormat.Alpha8, false); + _sNoiseTex.filterMode = FilterMode.Bilinear; + } + else + { + _sNoiseTex.Resize(width, height); + } + + var rand = new System.Random(0x54e03b19); + var buffer = new byte[width * height]; + rand.NextBytes(buffer); + + _sNoiseTex.LoadRawTextureData(buffer); + _sNoiseTex.Apply(false, false); + + UnityEngine.Debug.LogFormat("Noise gen time: {0:F2} ms", timer.Elapsed.TotalMilliseconds); + } + + protected static Texture2D NoiseTex + { + get + { + if (ShouldGenerateNoiseTex) GenerateNoiseTex(); + return _sNoiseTex; + } + } + + private static readonly System.Random _sRandom = new System.Random(0x54e03b19); + + private bool _loaded; + + public bool HasLoaded { get { return _loaded; } } + + public List Flags; + + public Vector2 CellPos { get; private set; } + + public int RandomInt { get; private set; } + + internal float LoadOrder { get; private set; } + + protected void Initialize(Vector3 pos, Quaternion rot) + { + transform.position = pos; + transform.localRotation = rot; + + CellPos = new Vector2(pos.x, pos.z); + + RandomInt = _sRandom.Next(); + + _loaded = false; + } + + public bool RefreshLoadOrder(Vector3 from) + { + Profiler.BeginSample ("MapObject.RefreshLoadOrder", this); + LoadOrder = OnRefreshLoadOrder(from); + Profiler.EndSample (); + return !float.IsPositiveInfinity(LoadOrder); + } + + protected abstract float OnRefreshLoadOrder(Vector3 from); + + public void Show() + { + if (!_loaded) + { + _loaded = true; + + Profiler.BeginSample ("OnLoad", this); + OnLoad(); + Profiler.EndSample (); + } + + Profiler.BeginSample ("OnShow", this); + OnShow(); + Profiler.EndSample (); + + LoadOrder = float.PositiveInfinity; + } + + protected virtual void OnLoad() + { + } + + protected virtual void OnShow() + { + } + + public int CompareTo(MapObject other) + { + return LoadOrder > other.LoadOrder ? 1 : LoadOrder == other.LoadOrder ? 0 : -1; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/MapObject.cs.meta b/Assets/Scripts/Behaviours/MapObject.cs.meta new file mode 100644 index 00000000..871d6849 --- /dev/null +++ b/Assets/Scripts/Behaviours/MapObject.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 17dac92ae48895e489d83b029f4e77ab +timeCreated: 1427465928 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/MiniMap.cs b/Assets/Scripts/Behaviours/MiniMap.cs new file mode 100644 index 00000000..11ff7bfa --- /dev/null +++ b/Assets/Scripts/Behaviours/MiniMap.cs @@ -0,0 +1,677 @@ +using SanAndreasUnity.Behaviours.Vehicles; +using SanAndreasUnity.Importing.Conversion; +using SanAndreasUnity.Utilities; +using System; +using System.Collections; +using System.IO; +using UnityEngine; +using UnityEngine.UI; +using Object = UnityEngine.Object; + +namespace SanAndreasUnity.Behaviours +{ + public class MiniMap : MonoBehaviour + { + public const int tileEdge = 12; // width/height of map in tiles + public const int tileCount = tileEdge * tileEdge; // number of tiles + public const int mapEdge = 6000; // width/height of map in world coordinates + public const int texSize = 128; // width/height of single tile in px + public const int mapSize = tileEdge * texSize; // width/height of whole map in px + public const int uiSize = 256, uiOffset = 10; + private const bool outputChunks = false, outputImage = false; + + public static bool toggleMap; + + public Canvas outlineCanvas, + iconCanvas, + canvas; + + public Image northImage, + playerImage, + outlineImage, + maskImage, + mapImage; + + public RectTransform mapTransform, + maskTransform, + mapContainer; + + public float zoom = 1.3f; + private const float scaleConst = 1f; + + public const float maxVelocity = 300f; + public static float[] zooms = new float[10] { .5f, .75f, 1f, 1.2f, 1.4f, 1.6f, 2f, 2.5f, 3f, 5f }; + + // Why? + [HideInInspector] [Obsolete] public float calibrator = 2.34f; + + public float zoomDuration = 1, + mapZoomScaler = 1, + mapMovement = 5; + + public bool debugActive = true; + + #region "Properties" + + public static MiniMap Instance { get; private set; } + + private float realZoom + { + get + { + return zoom * scaleConst; + } + set + { + zoom = value / scaleConst; + } + } + + private Vector3 pPos + { + get + { + if (m_ped == null) return Vector3.zero; + return m_ped.transform.position; + } + } + + private float _gTimer; + + private string _zName; + + private string ZoneName + { + get + { + if (_gTimer == 0) + { + Vector3 playerPos = Vector3.zero; + try + { + playerPos = pPos; + } + catch { } + + _zName = SZone.GetZoneName(ZoneHelpers.zoneInfoList, playerPos); + } + + return _zName; + } + } + + public Texture2D NorthBlip { get { return this.northBlip; } } + + public Texture2D PlayerBlip { get { return this.playerBlip; } } + + public Texture2D WaypointTexture { get { return this.waypointTexture; } } + + public Texture2D MapTexture { get { return this.mapTexture; } } + + public Texture2D BlackPixel { get { return this.blackPixel; } } + + public Texture2D SeaPixel { get { return this.seaPixel; } } + + #endregion "Properties" + + public static void AssingMinimap() + { + GameObject UI = GameObject.FindGameObjectWithTag("UI"); + Transform root = UI != null ? UI.transform : null; + + GameObject minimap = GameObject.FindGameObjectWithTag("Minimap"); + if (minimap == null) + { + minimap = new GameObject(); + + minimap.name = "Minimap"; + minimap.tag = "Minimap"; + + minimap.transform.parent = root; + } + + MiniMap map = minimap.GetComponent(); + + if (map == null) + map = minimap.AddComponent(); + + if (!map.isSetup) map.Setup(); + } + + private void loadTextures() + { + mapTexture = new Texture2D(mapSize, mapSize, TextureFormat.ARGB32, false, true); + + string folder = Path.Combine(Application.streamingAssetsPath, "map-chunks"); + + if (outputChunks) + { + if (!Directory.Exists(folder)) + Directory.CreateDirectory(folder); + } + + Debug.Log("Merging all map sprites into one sprite."); + for (int i = 0; i < tileCount; i++) + { + // Offset + int y = ((i / tileEdge) + 1) * texSize, + x = (i % tileEdge) * texSize; + + string name = "radar" + ((i < 10) ? "0" : "") + i; + var texDict = TextureDictionary.Load(name); + + Texture2D tex = texDict.GetDiffuse(name).Texture; + + if (outputChunks) + { + string id = name.Substring(5); + Texture2D image = new Texture2D(texSize, texSize, TextureFormat.ARGB32, false); + + for (int xx = 0; xx < texSize; ++xx) + for (int yy = 0; yy < texSize; ++yy) + image.SetPixel(xx, texSize - yy - 1, tex.GetPixel(xx, yy)); + + image.Apply(); + + File.WriteAllBytes(Path.Combine(folder, string.Format("{0}.jpg", id)), ImageConversion.EncodeToPNG(image)); + } + + for (int ii = 0; ii < texSize; ++ii) + for (int jj = 0; jj < texSize; ++jj) + mapTexture.SetPixel(x + ii, texSize - (y + jj) - 1, tex.GetPixel(ii, jj)); + } + + Debug.Log("Finished merging minimap!"); + mapTexture.Apply(); + mapSprite = Sprite.Create(mapTexture, new Rect(0, 0, mapTexture.width, mapTexture.height), new Vector2(mapTexture.width, mapTexture.height) / 2); + + if (outputImage) + File.WriteAllBytes(Path.Combine(Application.streamingAssetsPath, "gta-map.png"), mapTexture.EncodeToPNG()); + + circleMask = Resources.Load("Sprites/MapCircle"); + + huds = TextureDictionary.Load("hud"); + northBlip = huds.GetDiffuse("radar_north").Texture; + playerBlip = huds.GetDiffuse("radar_centre").Texture; + waypointTexture = huds.GetDiffuse("radar_waypoint").Texture; + + Debug.Log("Finished loading minimap textures!"); + } + + // -------------------------------- + + #region Private fields + + // Texture & control flags + private Ped m_ped; + + private PlayerController playerController; + + private TextureDictionary huds; + + private Texture2D northBlip, playerBlip, waypointTexture, mapTexture; + private Sprite mapSprite, circleMask; + + private Transform northPivot; + + // Flags + private bool enableMinimap, isReady, isSetup; + + // Zoom vars + public float curZoomPercentage; + + private float lastZoom, lastLerpedZoom, lerpedZoomCounter; + + private int zoomSelector = 2; + + private Coroutine zoomCoroutine; + + // Toggle flags + private bool toggleInfo = true; + + // GUI Elements + private Texture2D blackPixel, seaPixel; + + private float fAlpha = 1; + private bool showZoomPanel; + + private Vector2 mapScroll, + screenCenter, + screenDims, + //baseMapRect, + windowSize, + //constantMapRect, + mapUpperLeftCorner, + mapRect, + mapMousePosition, + mapZoomPos; //, baseMapSize; + + private const float mapMaxScale = 1f, + mapMinScale = .25f, + constZoom = 1.25f; + + private float curZoom = 1; + + //private float mapScale = mapMaxScale / 1.5f, + // baseScale; + + #endregion Private fields + + private void Setup() + { + loadTextures(); + + GameObject playerObj = GameObject.FindGameObjectWithTag("Player"); + if (playerObj != null) + { + m_ped = playerObj.GetComponent(); + playerController = playerObj.GetComponent(); + } + + if (canvas != null && canvas.enabled) + canvas.enabled = false; + + if (iconCanvas != null && iconCanvas.enabled) + iconCanvas.enabled = false; + + if (outlineCanvas != null && outlineCanvas.enabled) + outlineCanvas.enabled = false; + + blackPixel = new Texture2D(1, 1); + blackPixel.SetPixel(0, 0, new Color(0, 0, 0, .5f)); + blackPixel.Apply(); + + seaPixel = new Texture2D(1, 1); + seaPixel.SetPixel(0, 0, new Color(.45f, .54f, .678f)); + seaPixel.Apply(); + + isSetup = true; + isReady = true; + Debug.Log("Finished minimap setup!"); + } + + private void Awake() + { + Instance = this; + + if (!isReady) + return; + + if (!isSetup) + Setup(); + } + + private void Update() + { + if (!isReady) return; + + if (!enableMinimap) + { + Debug.Log("Starting to enable minimap!"); + + string error = "{0} is null or disabled! (Please, keep it active!)"; + + if (canvas != null && !canvas.enabled) + canvas.enabled = true; + else + Debug.LogErrorFormat(error, "Canvas"); + + if (iconCanvas != null && !iconCanvas.enabled) + iconCanvas.enabled = true; + else + Debug.LogErrorFormat(error, "IconCanvas"); + + if (outlineCanvas != null && !outlineCanvas.enabled) + outlineCanvas.enabled = true; + else + Debug.LogErrorFormat(error, "OutlineCanvas"); + + if (northBlip != null && northImage != null) + northImage.sprite = Sprite.Create(northBlip, new Rect(0, 0, northBlip.width, northBlip.height), new Vector2(northBlip.width, northBlip.height) / 2); + else + Debug.LogErrorFormat(error, "NorthImage"); + + if (playerBlip != null && playerImage != null) + playerImage.sprite = Sprite.Create(playerBlip, new Rect(0, 0, playerBlip.width, playerBlip.height), new Vector2(playerBlip.width, playerBlip.height) / 2); + else + Debug.LogErrorFormat(error, "PlayerImage"); + + if (mapImage != null) + mapImage.sprite = mapSprite; + + if (maskImage != null && maskImage.sprite == null) + maskImage.sprite = circleMask; + + if (mapContainer != null) + mapContainer.sizeDelta = new Vector2(uiSize, uiSize); + else + Debug.LogErrorFormat(error, "MapContainer"); + + if (maskTransform == null) + Debug.LogErrorFormat(error, "MaskTransform"); + + curZoomPercentage = zooms[zoomSelector]; + + enableMinimap = true; + + // Must review: For some reason values are Y-axis inverted + + float left = Screen.width - uiSize - uiOffset, + top = Screen.height - uiSize - uiOffset * 2; + + Vector3 globalPos = new Vector3(left, top, 0) / 2; + + if (maskTransform != null) + maskTransform.localPosition = globalPos; + + if (playerImage != null) + { + playerImage.rectTransform.localPosition = globalPos; + playerImage.rectTransform.localScale = Vector3.one * .2f; + playerImage.rectTransform.localRotation = Quaternion.Euler(0, 0, 180); + } + + if (northImage != null) + { + northPivot = northImage.rectTransform.parent; + + northImage.rectTransform.localPosition = new Vector3(0, uiSize / 2, 0) / .2f; + northImage.rectTransform.localRotation = Quaternion.Euler(0, 180, 0); + } + + if (northPivot != null) + { + northPivot.localPosition = globalPos; + northPivot.localScale = Vector3.one * .2f; + } + + if (outlineImage != null) + { + outlineImage.rectTransform.localPosition = globalPos; + outlineImage.rectTransform.sizeDelta = Vector2.one * uiSize; + outlineImage.rectTransform.localScale = Vector3.one * 1.05f; + } + + //baseScale = Screen.width / (float)mapTexture.width; + screenCenter = new Vector2(Screen.width, Screen.height) / 2; + screenDims = screenCenter * 2; + windowSize = new Vector2(Screen.width - 120, Screen.height - 120); + //baseMapRect = new Vector2(mapTexture.width, mapTexture.height) * (baseScale * (mapScale / mapMaxScale) * 2); + // This value is constant + //constantMapRect = new Vector2(mapTexture.width, mapTexture.height) * (baseScale * 2); + mapUpperLeftCorner = Vector2.one * 60; + + Debug.Log("Minimap started!"); + } + + if (Input.GetKeyDown(KeyCode.N)) + ++zoomSelector; + else if (Input.GetKeyDown(KeyCode.B)) + --zoomSelector; + + if (Input.GetKeyDown(KeyCode.N) || Input.GetKeyDown(KeyCode.B)) + { + if (zoomCoroutine != null) StopCoroutine(zoomCoroutine); + zoomCoroutine = StartCoroutine(ChangeZoom(Input.GetKeyDown(KeyCode.N))); + } + + if (Input.GetKeyDown(KeyCode.F8)) + toggleInfo = !toggleInfo; + + //if (Input.GetKeyDown(KeyCode.M)) + // toggleMap = !toggleMap; + + float mousePosY = screenDims.y - Input.mousePosition.y; + Vector2 movement = Vector2.zero, // WIP : + offset + centerOffset = new Vector2(Mathf.Lerp(0, 1, Mathf.Clamp01((Input.mousePosition.x - mapUpperLeftCorner.x) / windowSize.x)), Mathf.Lerp(0, 1, Mathf.Clamp01((mousePosY - mapUpperLeftCorner.y) / windowSize.y))); + + /*if (Input.mousePosition.x < mapUpperLeftCorner.x) + centerOffset.x = 0; + else if (Input.mousePosition.x > windowSize.x) + centerOffset.x = 1; + + if (mousePosY < mapUpperLeftCorner.y) + centerOffset.y = 0; + else if (mousePosY > windowSize.y) + centerOffset.y = 1;*/ + + bool isScrolling = false; + + Vector2 realMousePos = new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y); + mapMousePosition = TransformPosition(new Vector2(Input.mousePosition.x, mousePosY) - mapUpperLeftCorner); + + if (Input.mouseScrollDelta != Vector2.zero) + { + //mapScale += Input.mouseScrollDelta.y * Time.fixedDeltaTime * mapZoomScaler; + + // WIP: I want to scroll to mouse position + + if (Input.mouseScrollDelta.y > 0) + { + // WIP: I have to get the current map texture position (like a Raycast) and set the the center with this + //mapScroll.x += centerOffset.x * mapMovement * 5; + //mapScroll.y += centerOffset.y * mapMovement * 5; + + //mapZoomPos = mapMousePosition - windowSize / 2; //Vector2.Lerp(windowSize / 2 - baseMapRect / 2, mapMousePosition - windowSize / 2, curZoomPercentage); + curZoom *= constZoom; + mapZoomPos = realMousePos - constZoom * (realMousePos - mapZoomPos); + } + + curZoom = Mathf.Clamp(curZoom, mapMinScale, mapMaxScale); + + isScrolling = true; + } + + //Debug.LogFormat("Zoom Center: {0}, Mouse Pos: {1}; Map Scroll: {2}", centerOffset * mapRect, new Vector2(Input.mousePosition.x, mousePosY), mapScroll); + + if (!isScrolling) + { + if (Input.GetMouseButton(2)) + { + movement.x = centerOffset.x * mapMovement; + movement.y = centerOffset.y * mapMovement; + } + else + { + movement.x = Input.GetAxis("Horizontal") * mapMovement; + movement.y = Input.GetAxis("Vertical") * mapMovement; + } + + mapScroll.x -= movement.x; + mapScroll.y += movement.y; + } + } + + private Vector2 TransformPosition(Vector2 mousePos) + { + //Vector2 realMapScroll = new Vector2(-mapScroll.x, mapScroll.y); + return mousePos - mapScroll; + } + + public static Vector2 WorldPosToMapPos(Vector3 worldPos) + { + // map center is at (0,0) world coordinates + // this, for example, means that the left edge of the world is at: -mapEdge / 2.0f + + // adjust world position, so that (0,0) world coordinates are mapped to (0,0) map coordinates + worldPos += new Vector3(mapEdge / 2.0f, 0, mapEdge / 2.0f); + + float mul = mapSize / (float)mapEdge; + return new Vector2(worldPos.x * mul, worldPos.z * mul); + } + + public static Vector3 MapPosToWorldPos(Vector2 mapPos) + { + // adjust map position, so that (0,0) map coordinated are mapped to (0,0) world coordinates + mapPos -= Vector2.one * (mapSize * 0.5f); + + float mul = mapEdge / (float)mapSize; + + return new Vector3(mapPos.x * mul, 0.0f, mapPos.y * mul); + } + + private void FixedUpdate() + { + if (playerController != null && !GameManager.CanPlayerReadInput() && debugActive) return; + + if (playerController != null) + realZoom = Mathf.Lerp(.9f * scaleConst, 1.3f * scaleConst, 1 - Mathf.Clamp(playerController.CurVelocity, 0, maxVelocity) / maxVelocity) * curZoomPercentage; + + _gTimer += Time.fixedDeltaTime; + if (_gTimer > 1) + _gTimer = 0; + } + + private void LateUpdate() + { + if (!isReady) return; + if (playerController != null && !GameManager.CanPlayerReadInput() && debugActive) return; + + if (mapTransform != null) + { + float deltaZoom = realZoom - lastZoom; + + mapTransform.localScale = new Vector3(realZoom, realZoom, 1); + + lastZoom = realZoom; + } + + Vector3 defPos = (new Vector3(pPos.x, pPos.z, 0) * (uiSize / -1000f)) / scaleConst; // Why? + // calibrator + + if (mapContainer != null) + { + // WIP: Make this static to avoid shakering + float lerpedZoom = realZoom; //Mathf.Lerp(lastLerpedZoom, realZoom, lerpedZoomCounter); + + mapContainer.localPosition = new Vector3(defPos.x * lerpedZoom, defPos.y * lerpedZoom, 1); + + lerpedZoomCounter += Time.deltaTime; + + if (lerpedZoomCounter > 1) + lerpedZoomCounter = 0; + } + + float relAngle = Camera.main.transform.eulerAngles.y; + + if (maskTransform != null) + maskTransform.localRotation = Quaternion.Euler(0, 0, relAngle); + + if (northPivot != null) + northPivot.localRotation = Quaternion.Euler(0, 0, relAngle); + + if (playerImage != null && m_ped != null) + playerImage.rectTransform.localRotation = Quaternion.Euler(0, 0, relAngle - (m_ped.transform.eulerAngles.y + 180)); + } + + private IEnumerator ChangeZoom(bool isIncreasing) + { + showZoomPanel = true; + fAlpha = 1; + + zoomSelector = GetClampedZoomSelector(zoomSelector); + float curZoom = zooms[zoomSelector % zooms.Length], + lastZoom = zooms[GetClampedZoomSelector(zoomSelector - 1 * (isIncreasing ? 1 : -1)) % zooms.Length]; + + float t = 0; + while (t < zoomDuration) + { + curZoomPercentage = Mathf.Lerp(lastZoom, curZoom, t / zoomDuration); + yield return new WaitForFixedUpdate(); + t += Time.fixedDeltaTime; + fAlpha -= Time.fixedDeltaTime / zoomDuration; + } + + showZoomPanel = false; + zoomCoroutine = null; + } + + private int GetClampedZoomSelector(int? val = null) + { + int zoomVal = val == null ? zoomSelector : val.Value; + + if (zoomVal < 0) + zoomVal = zooms.Length - 1; + + return zoomVal; + } + + private void OnGUI() + { + if (!Loader.HasLoaded) + return; + + if (!isReady || !toggleInfo) return; + + if (!toggleMap) + { + GUILayout.BeginArea(new Rect(Screen.width - uiSize - 10, uiSize + 20, uiSize, 80)); + + GUIStyle style = new GUIStyle("label") { alignment = TextAnchor.MiddleCenter }; + + Vector2 labelSize = new Vector2(uiSize, 25); + Rect labelRect = new Rect(Vector2.zero, labelSize); + + // display player pos + +// GUI.DrawTexture(labelRect, blackPixel); +// GUI.Label(labelRect, +// string.Format("x: {0}, y: {1}, z: {2}", pPos.x.ToString("F2"), pPos.y.ToString("F2"), pPos.z.ToString("F2")), +// style); + + // display current zone name + + Rect zoneRect = labelRect; //new Rect(uiSize / 2 - uiSize / (2 * 3), 25, uiSize / 3, 25); + + GUI.DrawTexture(zoneRect, blackPixel); + GUI.Label(zoneRect, ZoneName, style); + + if (showZoomPanel) + { + Color previousColor = GUI.color; + + Rect zoomPanel = new Rect(uiSize / 2 - uiSize / (2 * 4), 55, uiSize / 4, 25); + + GUI.color = new Color(0, 0, 0, fAlpha); + + GUI.DrawTexture(zoomPanel, blackPixel); + + GUI.color = new Color(255, 255, 255, fAlpha); + + GUI.Label(zoomPanel, string.Format("x{0}", curZoomPercentage.ToString("F2")), style); + + GUI.color = previousColor; + } + + GUILayout.EndArea(); + } + else + { + mapRect = new Vector2(mapTexture.width, mapTexture.height); //* (baseScale * (mapScale / mapMaxScale) * 2); + + GUI.DrawTexture(new Rect(50, 50, Screen.width - 100, Screen.height - 100), blackPixel); + + GUI.DrawTexture(new Rect(mapUpperLeftCorner, windowSize), seaPixel); + + GUILayout.BeginArea(new Rect(mapUpperLeftCorner, windowSize)); + + GUILayout.BeginArea(new Rect(mapScroll, mapRect * curZoom)); + + GUI.DrawTexture(new Rect(mapZoomPos, mapRect * curZoom), mapTexture); + //if (Event.current.type.Equals(EventType.Repaint)) + //GUI.DrawTexture(new Rect(10, 10, 100, 100), mapTexture); + + GUI.DrawTexture(new Rect(Vector2.zero, Vector2.one * 16), blackPixel); + + // WIP: I have to load move cursor + // WIP: I have to load map bars + // WIP: I have to load marker + // WIP: Draw player pointer & undescovered zones + // + drag & drop + + GUILayout.EndArea(); + GUILayout.EndArea(); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/MiniMap.cs.meta b/Assets/Scripts/Behaviours/MiniMap.cs.meta new file mode 100644 index 00000000..fdef4b9c --- /dev/null +++ b/Assets/Scripts/Behaviours/MiniMap.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 517af0b56117a42c9a9cd043b7d1c767 +timeCreated: 1490822349 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/ModelViewer.cs b/Assets/Scripts/Behaviours/ModelViewer.cs new file mode 100644 index 00000000..45820d05 --- /dev/null +++ b/Assets/Scripts/Behaviours/ModelViewer.cs @@ -0,0 +1,125 @@ +using SanAndreasUnity.Importing.Conversion; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours +{ + [ExecuteInEditMode] + public class ModelViewer : MonoBehaviour + { + public enum ModelLoadType + { + Custom = 0, + Ped = 1, + Weapon = 2, + Vehicle = 3 + } + + public int modelId = 355; // ak47 + public string textureDictionaryName = ""; + public ModelLoadType modelLoadType = ModelLoadType.Weapon; + public Transform targetParent = null; + + public bool load = false; + + private int m_currentModelId = 355; + private string m_currentTextureDictionaryName = ""; + private ModelLoadType m_modelLoadType = ModelLoadType.Weapon; + + private FrameContainer m_frameContainer = null; + + // Use this for initialization + private void Start() + { + } + + // Update is called once per frame + private void Update() + { + CheckForChanges(); + } + + private void OnValidate() + { + CheckForChanges(); + } + + private void CheckForChanges() + { + if (!load) + return; + + if (m_modelLoadType != modelLoadType) + { + Load(); + return; + } + + if (m_currentModelId != modelId) + { + Load(); + return; + } + + if (modelLoadType == ModelLoadType.Custom) + { + if (m_currentTextureDictionaryName != textureDictionaryName) + { + Load(); + } + } + } + + public void Load() + { + string modelName = ""; + string textDict = ""; + if (modelLoadType == ModelLoadType.Weapon) + { + WeaponDef def = Item.GetDefinition(modelId); + if (null == def) + return; + modelName = def.ModelName; + textDict = def.TextureDictionaryName; + } + else if (modelLoadType == ModelLoadType.Ped) + { + PedestrianDef def = Item.GetDefinition(modelId); + if (null == def) + return; + modelName = def.ModelName; + textDict = def.TextureDictionaryName; + } + else if (modelLoadType == ModelLoadType.Vehicle) + { + VehicleDef def = Item.GetDefinition(modelId); + if (null == def) + return; + modelName = def.ModelName; + textDict = def.TextureDictionaryName; + } + else + { + return; + } + + var geoms = Geometry.Load(modelName, textDict); + if (null == geoms) + return; + + if (m_frameContainer != null) + { + Destroy(m_frameContainer.Root.gameObject); + Destroy(m_frameContainer); + } + + Transform tr = null == targetParent ? transform : targetParent; + m_frameContainer = geoms.AttachFrames(tr, MaterialFlags.Default); + + m_currentModelId = modelId; + m_currentTextureDictionaryName = textureDictionaryName; + m_modelLoadType = modelLoadType; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/ModelViewer.cs.meta b/Assets/Scripts/Behaviours/ModelViewer.cs.meta new file mode 100644 index 00000000..04d35f7e --- /dev/null +++ b/Assets/Scripts/Behaviours/ModelViewer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9358e53be455ff144a4d0bab73b0c020 +timeCreated: 1474296439 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/OutOfRangeDestroyer.cs b/Assets/Scripts/Behaviours/OutOfRangeDestroyer.cs new file mode 100644 index 00000000..f99cbaba --- /dev/null +++ b/Assets/Scripts/Behaviours/OutOfRangeDestroyer.cs @@ -0,0 +1,46 @@ +using UnityEngine; + +public class OutOfRangeDestroyer : MonoBehaviour +{ + public float timeUntilDestroyed = 5; + public float range = 250; + public Transform targetObject = null; + + private float timeSinceOutOfRange = 0; + + // Use this for initialization + private void Start() + { + if (null == targetObject) + { + if (Camera.current != null) + targetObject = Camera.current.transform; + } + } + + // Update is called once per frame + private void Update() + { + timeSinceOutOfRange += Time.deltaTime; + + if (null == targetObject) + { + if (Camera.current != null) + targetObject = Camera.current.transform; + } + + if (null != targetObject) + { + float distanceSq = (transform.position - targetObject.position).sqrMagnitude; + if (distanceSq <= range * range) + { + timeSinceOutOfRange = 0; + } + } + + if (timeSinceOutOfRange >= timeUntilDestroyed) + { + Destroy(gameObject); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/OutOfRangeDestroyer.cs.meta b/Assets/Scripts/Behaviours/OutOfRangeDestroyer.cs.meta new file mode 100644 index 00000000..d7d5dc6a --- /dev/null +++ b/Assets/Scripts/Behaviours/OutOfRangeDestroyer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5c2a0f67299380147baa2dc88c37f772 +timeCreated: 1474123993 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped.meta b/Assets/Scripts/Behaviours/Ped.meta new file mode 100644 index 00000000..4eba6a1b --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 16bdad8e8fedf2b4f8a5f9a5874d0559 +folderAsset: yes +timeCreated: 1428252231 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/Ped.cs b/Assets/Scripts/Behaviours/Ped/Ped.cs new file mode 100644 index 00000000..0cd165e6 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/Ped.cs @@ -0,0 +1,667 @@ +using SanAndreasUnity.Behaviours.Vehicles; +using SanAndreasUnity.Behaviours.World; +using SanAndreasUnity.Importing.Animation; +using System.Collections; +using System.Diagnostics; +using UnityEngine; +using Debug = UnityEngine.Debug; +using SanAndreasUnity.Utilities; +using System.Collections.Generic; +using System.Linq; + +namespace SanAndreasUnity.Behaviours +{ + [DefaultExecutionOrder(-100)] + [RequireComponent(typeof(CharacterController))] +#if CLIENT + public partial class Ped : Networking.Networkable +#else + public partial class Ped : MonoBehaviour +#endif + { + #region Private Fields + + private static List s_allPeds = new List (); + public static Ped[] AllPeds { get { return s_allPeds.ToArray (); } } + + private WeaponHolder m_weaponHolder; + public WeaponHolder WeaponHolder { get { return m_weaponHolder; } } + + private StateMachine m_stateMachine = new StateMachine (); + + #endregion Private Fields + + #region Inspector Fields + + public Camera Camera; + public PedModel PlayerModel; + + public bool shouldPlayAnims = true; + + public float TurnSpeed = 10f; + + public CharacterController characterController; + + public float jumpSpeed = 8.0f; + + [SerializeField] private float m_cameraDistance = 3f; + public float CameraDistance { get { return m_cameraDistance; } set { m_cameraDistance = value; } } + + [SerializeField] private float m_cameraDistanceVehicle = 6f; + public float CameraDistanceVehicle { get { return m_cameraDistanceVehicle; } set { m_cameraDistanceVehicle = value; } } + + [SerializeField] private Vector2 m_cameraClampValue = new Vector2(60, 60); + public Vector2 CameraClampValue { get { return m_cameraClampValue; } set { m_cameraClampValue = value; } } + + #endregion Inspector Fields + + #region Properties + + public Peds.States.BaseScriptState[] States { get; private set; } + public Peds.States.BaseScriptState CurrentState { get { return (Peds.States.BaseScriptState) m_stateMachine.CurrentState; } } + + public Cell Cell { get { return Cell.Instance; } } + + public UnityEngine.Animation AnimComponent { get { return PlayerModel.AnimComponent; } } + + public SanAndreasUnity.Importing.Items.Definitions.PedestrianDef PedDef { get { return this.PlayerModel.Definition; } } + + public static int RandomPedId { + get { + int count = Ped.SpawnablePedDefs.Count (); + if (count < 1) + throw new System.Exception ("No ped definitions found"); + + int index = Random.Range (0, count); + return Ped.SpawnablePedDefs.ElementAt (index).Id; + } + } + + public Vector3 Position + { + get { return transform.localPosition; } + set { transform.localPosition = value; } + } + + public bool IsGrounded + { + get + { + return characterController.isGrounded; + } + } + + public Vector2 MouseMoveInput { get; set; } + public Vector2 MouseScrollInput { get; set; } + + public bool IsWalkOn { get; set; } + public bool IsRunOn { get; set; } + public bool IsSprintOn { get; set; } + public bool IsJumpOn { get; set; } + + public Vector3 Velocity { get; private set; } + /// Current movement input. + public Vector3 Movement { get; set; } + /// Direction towards which the player turns. + public Vector3 Heading { get; set; } + + public bool IsAiming { get { return m_weaponHolder.IsAiming; } } + public Weapon CurrentWeapon { get { return m_weaponHolder.CurrentWeapon; } } + public bool IsFiring { get { return m_weaponHolder.IsFiring; } } + public Vector3 AimDirection { get { return m_weaponHolder.AimDirection; } } + public bool IsAimOn { get ; set ; } + public bool IsFireOn { get ; set ; } + public bool IsHoldingWeapon { get { return m_weaponHolder.IsHoldingWeapon; } } + + private static bool makeGPUAdjustments; + + private Coroutine m_findGroundCoroutine; + + #endregion Properties + + + public static Ped Instance { get ; private set ; } + + /// Position of player instance. + public static Vector3 InstancePos { get { return Instance.transform.position; } } + + public bool IsLocalPlayer { get; private set; } + + + + + void Awake() + { + + if (null == Instance) { + Instance = this; + IsLocalPlayer = true; + } + + characterController = GetComponent(); + m_weaponHolder = GetComponent (); + + this.States = this.GetComponentsInChildren (); + + this.AwakeForDamage (); + + } + + void Start() + { + //MySetupLocalPlayer (); + + this.StartForDamage (); + + if (null == this.CurrentState) + this.SwitchState (); + + } + + void OnEnable () + { + s_allPeds.Add (this); + } + + void OnDisable () + { + s_allPeds.Remove (this); + } + + private IEnumerator GPUAdjust() + { + // Wait to everything to load + yield return new WaitForSeconds(1); + + if (SystemInfo.graphicsShaderLevel <= 40) { + try { + Debug.Log("Adjusting settings for older GPUs"); + + Camera.main.allowMSAA = false; + Camera.main.allowHDR = false; + + foreach (var mat in transform.root.GetComponentsInChildren()) { + mat.EnableKeyword ("_SPECULARHIGHLIGHTS_OFF"); + mat.SetFloat ("_SpecularHighlights", 0f); + } + } catch { + } + } + + } + + + public T GetState() where T : Peds.States.BaseScriptState + { + var type = typeof(T); + return (T) this.States.FirstOrDefault (s => s.GetType ().Equals (type)); + } + + public T GetStateOrLogError() where T : Peds.States.BaseScriptState + { + var state = this.GetState (); + if(null == state) + Debug.LogErrorFormat ("Failed to find state: {0}", typeof(T)); + return state; + } + + public void SwitchState() where T : Peds.States.BaseScriptState { + + var state = this.GetStateOrLogError (); + if (null == state) + return; + + // IState oldState = this.CurrentState; + + m_stateMachine.SwitchState (state); + +// if (oldState != state) +// { +// Debug.LogFormat ("Switched to state: {0}", state.GetType ().Name); +// } + + } + + + public void OnSpawn() + { + // Note: Spawn is performed here. + + if (!IsGrounded) { + // Find the ground (instead of falling) + FindGround (); + } + + } + + public void Teleport(Vector3 position, Quaternion rotation) { + + if (this.IsInVehicle) + return; + + this.transform.position = position; + this.transform.rotation = rotation; + + this.FindGround (); + + } + + public void Teleport(Vector3 position) { + + this.Teleport (position, this.transform.rotation); + + } + + public void FindGround () + { + if (m_findGroundCoroutine != null) { + StopCoroutine (m_findGroundCoroutine); + m_findGroundCoroutine = null; + } + + m_findGroundCoroutine = StartCoroutine (FindGroundCoroutine ()); + } + + private IEnumerator FindGroundCoroutine() + { + + yield return null; + + // set y pos to high value, so that higher grounds can be loaded + this.transform.SetY (150); + + Vector3 startingPos = this.transform.position; + + // wait for loader to finish, in case he didn't + while (!Loader.HasLoaded) + yield return null; + + // yield until you find ground beneath or above the player, or until timeout expires + + float timeStarted = Time.time; + int numAttempts = 1; + + while (true) { + + if (Time.time - timeStarted > 4.0f) { + // timeout expired + Debug.LogWarning("Failed to find ground - timeout expired"); + yield break; + } + + // maintain starting position + this.transform.position = startingPos; + this.Velocity = Vector3.zero; + + RaycastHit hit; + float raycastDistance = 1000f; + // raycast against all layers, except player + int raycastLayerMask = ~ LayerMask.GetMask ("Player"); + + Vector3[] raycastPositions = new Vector3[]{ this.transform.position, this.transform.position + Vector3.up * raycastDistance }; //transform.position - Vector3.up * characterController.height; + Vector3[] raycastDirections = new Vector3[]{ Vector3.down, Vector3.down }; + string[] customMessages = new string[]{ "from center", "from above" }; + + for (int i = 0; i < raycastPositions.Length; i++) { + + if (Physics.Raycast (raycastPositions[i], raycastDirections[i], out hit, raycastDistance, raycastLayerMask)) { + // ray hit the ground + // we can move there + + this.OnFoundGround (hit, numAttempts, customMessages [i]); + + yield break; + } + + } + + + numAttempts++; + yield return null; + } + + } + + private void OnFoundGround(RaycastHit hit, int numAttempts, string customMessage) { + + this.transform.position = hit.point + Vector3.up * characterController.height * 1.5f; + this.Velocity = Vector3.zero; + + Debug.LogFormat ("Found ground at {0}, distance {1}, object name {2}, num attempts {3}, {4}", hit.point, hit.distance, + hit.transform.name, numAttempts, customMessage); + + } + +#if CLIENT + + private void SetupLocalPlayer() + { + Camera.gameObject.SetActive(true); + Camera.transform.SetParent(null, true); + + Cell.Focus = transform; + Cell.PreviewCamera.gameObject.SetActive(false); + + gameObject.AddComponent(); + } + +#endif + + + private void Update() + { + if (!Loader.HasLoaded) + return; + + if (this.CurrentState != null) + { + this.CurrentState.UpdateState (); + } + + // Reset to a valid (and solid!) start position when falling below the world + if (transform.position.y < -300) + { + Velocity = new Vector3(0, 0, 0); + Transform spawn = GameObject.Find("Player Spawns").GetComponentsInChildren()[1]; + transform.position = spawn.position; + transform.rotation = spawn.rotation; + } + + // ConstrainPosition (); + + // ConstrainRotation (); + + // UpdateAnims (); + + //if (IsDrivingVehicle) + // UpdateWheelTurning(); + + //If player falls from the map + if (IsGrounded && transform.position.y < -50) + { + Vector3 t = transform.position; + transform.position = new Vector3(t.x, 150, t.z); + FindGround(); + } + + this.UpdateDamageStuff (); + + // IsWalking = IsRunning = false; + + if (this.CurrentState != null) + this.CurrentState.PostUpdateState(); + + } + + void LateUpdate () + { + + if (this.CurrentState != null) + { + this.CurrentState.LateUpdateState (); + } + + } + + public void ConstrainPosition() { + + // Constrain to stay inside map + + if (transform.position.x < -3000) + { + var t = transform.position; + t.x = -3000; + transform.position = t; + } + if (transform.position.x > 3000) + { + var t = transform.position; + t.x = 3000; + transform.position = t; + } + if (transform.position.z < -3000) + { + var t = transform.position; + t.z = -3000; + transform.position = t; + } + if (transform.position.z > 3000) + { + var t = transform.position; + t.z = 3000; + transform.position = t; + } + + } + + public void ConstrainRotation () + { + if (IsInVehicle) + return; + + // ped can only rotate around Y axis + + Vector3 eulers = this.transform.eulerAngles; + if (eulers.x != 0f || eulers.z != 0f) { + eulers.x = 0f; + eulers.z = 0f; + this.transform.eulerAngles = eulers; + } + + } + + private void UpdateAnims() { + + if (!this.shouldPlayAnims) + return; + + if (IsInVehicle || m_weaponHolder.IsHoldingWeapon) + return; + + if (IsRunOn) { + + PlayerModel.PlayAnim (AnimGroup.WalkCycle, AnimIndex.Run, PlayMode.StopAll); + + } else if (IsWalkOn) { + + PlayerModel.PlayAnim (AnimGroup.WalkCycle, AnimIndex.Walk, PlayMode.StopAll); + + } else if (IsSprintOn) { + + PlayerModel.PlayAnim (AnimGroup.MyWalkCycle, AnimIndex.sprint_civi); + + } else { + // player is standing + PlayerModel.PlayAnim(AnimGroup.WalkCycle, AnimIndex.Idle, PlayMode.StopAll); + + } + + } + + private void FixedUpdate() + { + if (!Loader.HasLoaded) + return; + + if (this.CurrentState != null) + { + this.CurrentState.FixedUpdateState (); + } + + } + + public void UpdateHeading() + { + + if (this.IsAiming && this.CurrentWeapon != null && !this.CurrentWeapon.CanTurnInDirectionOtherThanAiming) { + // ped heading can only be the same as ped direction + this.Heading = this.WeaponHolder.AimDirection; + } + + // player can look only along X and Z axis + this.Heading = this.Heading.WithXAndZ ().normalized; + + } + + public void UpdateRotation() + { + + // rotate player towards his heading + Vector3 forward = Vector3.RotateTowards (this.transform.forward, Heading, TurnSpeed * Time.deltaTime, 0.0f); + this.transform.rotation = Quaternion.LookRotation(forward); + + } + + public void UpdateMovement() + { + + + // movement can only be done on X and Z axis + this.Movement = this.Movement.WithXAndZ (); + + // change heading to match movement input + //if (Movement.sqrMagnitude > float.Epsilon) + //{ + // Heading = Vector3.Scale(Movement, new Vector3(1f, 0f, 1f)).normalized; + //} + + // change velocity based on movement input and current speed extracted from anim + + float modelVel = Mathf.Abs( PlayerModel.Velocity [PlayerModel.VelocityAxis] ); + //Vector3 localMovement = this.transform.InverseTransformDirection (this.Movement); + //Vector3 globalMovement = this.transform.TransformDirection( Vector3.Scale( localMovement, modelVel ) ); + + Vector3 vDiff = this.Movement * modelVel - new Vector3(Velocity.x, 0f, Velocity.z); + Velocity += vDiff; + + // apply gravity + Velocity = new Vector3(Velocity.x, characterController.isGrounded + ? 0f : Velocity.y - (-Physics.gravity.y) * 2f * Time.fixedDeltaTime, Velocity.z); + + + // finally, move the character + characterController.Move(Velocity * Time.fixedDeltaTime); + + +// if(!IsLocalPlayer) +// { +// Velocity = characterController.velocity; +// } + + } + + + public void StartFiring () + { + if (!this.IsAiming) + return; + + ((Peds.States.IAimState)this.CurrentState).StartFiring(); + } + + public void StopFiring () + { + if (!this.IsFiring) + return; + + ((Peds.States.IFireState)this.CurrentState).StopFiring(); + } + + + public void ResetInput () + { + this.ResetMovementInput (); + this.MouseMoveInput = Vector2.zero; + this.MouseScrollInput = Vector2.zero; + this.IsAimOn = this.IsFireOn = false; + } + + public void ResetMovementInput () + { + this.IsWalkOn = this.IsRunOn = this.IsSprintOn = false; + this.Movement = Vector3.zero; + this.IsJumpOn = false; + } + + public void OnFireButtonPressed () + { + if (this.CurrentState != null) + this.CurrentState.OnFireButtonPressed (); + } + + public void OnAimButtonPressed () + { + if (this.CurrentState != null) + this.CurrentState.OnAimButtonPressed (); + } + + public void OnSubmitPressed () + { + if (this.CurrentState != null) + { + this.CurrentState.OnSubmitPressed (); + } + } + + public void OnJumpButtonPressed () + { + if (this.CurrentState != null) + this.CurrentState.OnJumpPressed (); + } + + public void OnCrouchButtonPressed () + { + if (this.CurrentState != null) + this.CurrentState.OnCrouchButtonPressed (); + } + + public void OnNextWeaponButtonPressed () + { + if (this.CurrentState != null) + this.CurrentState.OnNextWeaponButtonPressed (); + } + + public void OnPreviousWeaponButtonPressed () + { + if (this.CurrentState != null) + this.CurrentState.OnPreviousWeaponButtonPressed (); + } + + public void OnFlyButtonPressed () + { + if (this.CurrentState != null) + this.CurrentState.OnFlyButtonPressed (); + } + + public void OnFlyThroughButtonPressed () + { + if (this.CurrentState != null) + this.CurrentState.OnFlyThroughButtonPressed (); + } + + + void OnGUI () + { + if (!Loader.HasLoaded) + return; + + + } + + void OnDrawGizmosSelected () + { + + // draw heading ray + + Gizmos.color = Color.blue; + Gizmos.DrawLine (this.transform.position, this.transform.position + this.Heading); + + // draw movement ray + + Gizmos.color = Color.green; + Gizmos.DrawLine (this.transform.position, this.transform.position + this.Movement); + + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Ped/Ped.cs.meta b/Assets/Scripts/Behaviours/Ped/Ped.cs.meta new file mode 100644 index 00000000..a706e89a --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/Ped.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ef6b4848632966a4cb177a878e7ce8e9 +timeCreated: 1428856936 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/PedStalker.cs b/Assets/Scripts/Behaviours/Ped/PedStalker.cs new file mode 100644 index 00000000..a399e54b --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/PedStalker.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Utilities; +using System.Linq; + +namespace SanAndreasUnity.Behaviours +{ + + public class PedStalker : MonoBehaviour + { + + public Ped MyPed { get; private set; } + + public float stoppingDistance = 3; + + + + void Awake () + { + this.MyPed = this.GetComponentOrLogError (); + } + + void Update () + { + + // reset input + this.MyPed.ResetInput (); + + // follow player instance + + if (Ped.Instance != null) { + + Vector3 targetPos = Ped.InstancePos; + float currentStoppingDistance = this.stoppingDistance; + + if (Ped.Instance.IsInVehicleSeat && !this.MyPed.IsInVehicle) { + // find a free vehicle seat to enter vehicle + + var vehicle = Ped.Instance.CurrentVehicle; + // var seat = Player.Instance.CurrentVehicleSeatAlignment; + + var closestfreeSeat = Ped.GetFreeSeats (vehicle).Select (sa => new { sa = sa, tr = vehicle.GetSeatTransform (sa) }) + .OrderBy (s => s.tr.Distance (this.transform.position)) + .FirstOrDefault (); + + if (closestfreeSeat != null) { + // check if it is in range + if (closestfreeSeat.tr.Distance (this.transform.position) < this.MyPed.EnterVehicleRadius) { + // the seat is in range + this.MyPed.EnterVehicle (vehicle, closestfreeSeat.sa); + } else { + // the seat is not in range + // move towards this seat + targetPos = closestfreeSeat.tr.position; + currentStoppingDistance = 0.1f; + } + } + + } else if (!Ped.Instance.IsInVehicle && this.MyPed.IsInVehicleSeat) { + // target player is not in vehicle, and ours is + // exit the vehicle + + this.MyPed.ExitVehicle (); + } + + + if (this.MyPed.IsInVehicle) + return; + + Vector3 diff = targetPos - this.transform.position; + float distance = diff.magnitude; + + if (distance > currentStoppingDistance) + { + Vector3 diffDir = diff.normalized; + + this.MyPed.IsRunOn = true; + this.MyPed.Movement = diffDir; + this.MyPed.Heading = diffDir; + } + + } + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/PedStalker.cs.meta b/Assets/Scripts/Behaviours/Ped/PedStalker.cs.meta new file mode 100644 index 00000000..8b82f939 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/PedStalker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5559f06beef7d4d41b2b13efddfc36fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/Ped_Damage.cs b/Assets/Scripts/Behaviours/Ped/Ped_Damage.cs new file mode 100644 index 00000000..44f7bc4f --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/Ped_Damage.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.Behaviours +{ + + public partial class Ped : MonoBehaviour { + + public Damageable Damageable { get; private set; } + + public float Health { get { return this.Damageable.Health; } set { this.Damageable.Health = value; } } + [SerializeField] private float m_maxHealth = 100f; + public float MaxHealth { get { return m_maxHealth; } set { m_maxHealth = value; } } + + public Bar HealthBar { get; private set; } + + + + void AwakeForDamage () + { + this.Damageable = this.GetComponentOrThrow (); + + } + + void StartForDamage () + { + this.CreateHealthBar (); + + } + + void CreateHealthBar () + { + this.HealthBar = Object.Instantiate (GameManager.Instance.barPrefab, this.transform).GetComponentOrThrow (); + // this.HealthBar.SetBorderWidth (0.1f); + this.HealthBar.BackgroundColor = UI.HUD.Instance.healthBackgroundColor; + this.HealthBar.FillColor = UI.HUD.Instance.healthColor; + this.HealthBar.BorderColor = Color.black; + + this.UpdateHealthBar (); + } + + void UpdateDamageStuff () + { + this.UpdateHealthBar (); + } + + void UpdateHealthBar () + { + bool shouldBeVisible = PedManager.Instance.displayHealthBarAbovePeds && this != Ped.Instance; + this.HealthBar.gameObject.SetActive (shouldBeVisible); + + if (shouldBeVisible) + { + this.HealthBar.BarSize = new Vector3 (PedManager.Instance.healthBarWorldWidth, PedManager.Instance.healthBarWorldHeight, 1.0f); + this.HealthBar.SetFillPerc (this.Health / this.MaxHealth); + this.HealthBar.transform.position = this.GetPosForHealthBar (); + this.HealthBar.MaxHeightOnScreen = PedManager.Instance.healthBarMaxScreenHeight; + } + + } + + public void DrawHealthBar () + { + + Vector3 pos = this.GetPosForHealthBar (); + + Rect rect = GUIUtils.GetRectForBarAsBillboard (pos, PedManager.Instance.healthBarWorldWidth, + PedManager.Instance.healthBarWorldHeight, Camera.main); + + // limit height + rect.height = Mathf.Min (rect.height, PedManager.Instance.healthBarMaxScreenHeight); + + float borderWidth = Mathf.Min( 2f, rect.height / 4f ); + GUIUtils.DrawBar( rect, this.Health / this.MaxHealth, UI.HUD.Instance.healthColor, UI.HUD.Instance.healthBackgroundColor, borderWidth ); + + } + + private Vector3 GetPosForHealthBar () + { + if (null == this.PlayerModel.Head) + return this.transform.position; + + Vector3 pos = this.PlayerModel.Head.position; + pos += this.transform.up * PedManager.Instance.healthBarVerticalOffset; + + return pos; + } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/Ped_Damage.cs.meta b/Assets/Scripts/Behaviours/Ped/Ped_Damage.cs.meta new file mode 100644 index 00000000..8b228508 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/Ped_Damage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6f0a3f06a5484e9cb09b80eb5283284 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/Ped_Spawning.cs b/Assets/Scripts/Behaviours/Ped/Ped_Spawning.cs new file mode 100644 index 00000000..a7be13ad --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/Ped_Spawning.cs @@ -0,0 +1,107 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; +using System.Linq; + +namespace SanAndreasUnity.Behaviours +{ + + public partial class Ped : MonoBehaviour + { + + public static IEnumerable SpawnablePedDefs { + get { + return Item.GetDefinitions ().Where (def => def.Id != 0 && def.ModelName != "WMYST" + && def.TextureDictionaryName != "generic"); + } + } + + + public static Ped SpawnPed (PedestrianDef def, Vector3 pos, Quaternion rot) + { + CheckPedPrefab (); + + var go = Instantiate (PedManager.Instance.pedPrefab, pos, rot); + go.name = "Ped " + def.ModelName + " " + def.Id; + + var ped = go.GetComponentOrThrow (); + ped.PlayerModel.StartingPedId = def.Id; + ped.EnterVehicleRadius = PedManager.Instance.AIVehicleEnterDistance; + + var destroyer = ped.gameObject.GetOrAddComponent (); + destroyer.timeUntilDestroyed = PedManager.Instance.AIOutOfRangeTimeout; + destroyer.range = PedManager.Instance.AIOutOfRangeDistance; + + return ped; + } + + public static Ped SpawnPed (int pedId, Vector3 pos, Quaternion rot) + { + var def = Item.GetDefinition (pedId); + if (null == def) + throw new System.ArgumentException ("Failed to spawn ped: definition not found by id: " + pedId); + return SpawnPed (def, pos, rot); + } + + public static Ped SpawnPed (int pedId) + { + Vector3 pos; + Quaternion rot; + if (GetPositionForPedSpawn (out pos, out rot)) + return SpawnPed (pedId, pos, rot); + return null; + } + + public static PedStalker SpawnPedStalker (int pedId, Vector3 pos, Quaternion rot) + { + var ped = SpawnPed (pedId, pos, rot); + + var stalker = ped.gameObject.GetOrAddComponent (); + stalker.stoppingDistance = PedManager.Instance.AIStoppingDistance; + + return stalker; + } + + public static PedStalker SpawnPedStalker (int pedId) + { + Vector3 pos; + Quaternion rot; + if (GetPositionForPedSpawn (out pos, out rot)) + return SpawnPedStalker (pedId, pos, rot); + return null; + } + + public static bool GetPositionForPedSpawn (out Vector3 pos, out Quaternion rot) + { + pos = Vector3.zero; + rot = Quaternion.identity; + + if (Ped.Instance != null) { + + Vector3 offset = Random.onUnitSphere; + offset.y = 0f; + offset.Normalize (); + offset *= Random.Range (5f, 15f); + + pos = Ped.Instance.transform.TransformPoint (offset); + rot = Random.rotation; + + return true; + } + + return false; + } + + private static void CheckPedPrefab () + { + + if(null == PedManager.Instance.pedPrefab) + throw new System.Exception ("Ped prefab is null"); + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/Ped_Spawning.cs.meta b/Assets/Scripts/Behaviours/Ped/Ped_Spawning.cs.meta new file mode 100644 index 00000000..9bfde7ed --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/Ped_Spawning.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 111681befda174f039986ef58ec2b1eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/Ped_Vehicle.cs b/Assets/Scripts/Behaviours/Ped/Ped_Vehicle.cs new file mode 100644 index 00000000..9779e36a --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/Ped_Vehicle.cs @@ -0,0 +1,109 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours.Vehicles; +using SanAndreasUnity.Behaviours.World; +using SanAndreasUnity.Importing.Animation; +using System.Linq; +using SanAndreasUnity.Behaviours.Peds.States; + +namespace SanAndreasUnity.Behaviours +{ + + public partial class Ped : MonoBehaviour { + + [SerializeField] private float m_enterVehicleRadius = 2.0f; + public float EnterVehicleRadius { get { return m_enterVehicleRadius; } set { m_enterVehicleRadius = value; } } + + public Vehicle CurrentVehicle { + get { + if (this.CurrentState != null && this.CurrentState is IVehicleState) + { + return ((IVehicleState)this.CurrentState).CurrentVehicle; + } + return null; + } + } + + public Vehicle.Seat CurrentVehicleSeat { + get { + if (this.CurrentState != null && this.CurrentState is IVehicleState) + { + return ((IVehicleState)this.CurrentState).CurrentVehicleSeat; + } + return null; + } + } + + public bool IsInVehicle { get { return CurrentVehicle != null; } } + + public bool IsInVehicleSeat { get { return this.CurrentState != null && this.CurrentState.RepresentsState (typeof(VehicleSittingState)); } } + + public bool IsDrivingVehicle { get { return this.IsInVehicleSeat && this.CurrentVehicleSeat.IsDriver && this.IsInVehicle; } } + + public Vehicle.SeatAlignment CurrentVehicleSeatAlignment { get { return CurrentVehicleSeat.Alignment; } } + + + + public void EnterVehicle(Vehicle vehicle, Vehicle.SeatAlignment seatAlignment, bool immediate = false) + { + // find state script, and call it's method + this.GetStateOrLogError().TryEnterVehicle( vehicle, seatAlignment, immediate ); + } + + public void ExitVehicle(bool immediate = false) + { + this.GetStateOrLogError ().ExitVehicle (immediate); + } + + + public static List GetFreeSeats( Vehicle vehicle ) + { + return vehicle.Seats.Where (s => !s.IsTaken).Select (s => s.Alignment).ToList (); + +// var freeSeats = new List (vehicle.Seats.Select (s => s.Alignment)); +// +// var players = FindObjectsOfType (); +// +// foreach (var p in players) { +// if (p.IsInVehicle && p.CurrentVehicle == vehicle) { +// freeSeats.Remove (p.CurrentVehicleSeatAlignment); +// } +// } +// +// return freeSeats; + } + + private void UpdateWheelTurning() + { + + } + + + public Vehicle FindVehicleInRange () + { + + // find any vehicles that have a seat inside the checking radius and sort by closest seat + return FindObjectsOfType() + .Where(x => Vector3.Distance(transform.position, x.FindClosestSeatTransform(transform.position).position) < EnterVehicleRadius) + .OrderBy(x => Vector3.Distance(transform.position, x.FindClosestSeatTransform(transform.position).position)) + .FirstOrDefault(); + + } + + public Vehicle TryEnterVehicleInRange () + { + var vehicle = this.FindVehicleInRange (); + if (null == vehicle) + return null; + + var seat = vehicle.FindClosestSeat(this.transform.position); + + this.EnterVehicle(vehicle, seat); + + return vehicle; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/Ped_Vehicle.cs.meta b/Assets/Scripts/Behaviours/Ped/Ped_Vehicle.cs.meta new file mode 100644 index 00000000..4d0edd69 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/Ped_Vehicle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e242f15feb88443096128aae44ef576 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/PlayerController.cs b/Assets/Scripts/Behaviours/Ped/PlayerController.cs new file mode 100644 index 00000000..aac9a53d --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/PlayerController.cs @@ -0,0 +1,283 @@ +using SanAndreasUnity.Behaviours.Vehicles; +using SanAndreasUnity.Importing.Animation; +using SanAndreasUnity.Utilities; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours +{ + [DefaultExecutionOrder(-50)] + [RequireComponent(typeof(Ped))] + public class PlayerController : MonoBehaviour + { + + public static PlayerController Instance { get { return Ped.Instance != null ? Ped.Instance.GetComponent() : null; } } + + private Ped m_ped; + + public static bool _showVel = true; + + // Alpha speedometer + private const float velTimer = 1 / 4f; + + private float m_velCounter = velTimer; + + private Vector3 m_lastPos = Vector3.zero, + m_deltaPos = Vector3.zero; + + private Vector2 _mouseAbsolute; + private Vector2 _smoothMouse = Vector2.zero; + + + public Vector2 CursorSensitivity = new Vector2(2f, 2f); + + public Vector2 clampInDegrees = new Vector2(90, 60); + + public float EnterVehicleRadius { get { return m_ped.EnterVehicleRadius; } } + + public Vector2 smoothing = new Vector2(10, 10); + [SerializeField] private bool m_doSmooth = true; + + [SerializeField] private bool m_smoothMovement = false; + + public float CurVelocity { get { return m_deltaPos.magnitude * 3.6f / velTimer; } } + + + + private void Awake() + { + m_ped = GetComponent(); + + } + + + private void OnGUI() + { + if (!m_ped.IsLocalPlayer) + return; + + if (!Loader.HasLoaded) + return; + + + // show that we are in flying state + if (m_ped.CurrentState is Peds.States.FlyState) + { + int height = 25; + GUILayout.BeginArea(new Rect(Screen.width - 140, Screen.height - height, 140, height)); + GUILayout.Label("Flying-mode enabled!"); + GUILayout.EndArea(); + } + + if (_showVel) + GUI.Label(GUIUtils.GetCornerRect(ScreenCorner.TopLeft, 100, 25, new Vector2(5, 5)), string.Format("{0:0.0} km/h", m_deltaPos.magnitude * 3.6f / velTimer), new GUIStyle("label") { alignment = TextAnchor.MiddleCenter }); + + // show current ped state + // GUI.Label (GUIUtils.GetCornerRect(ScreenCorner.BottomLeft, 250, 50), string.Format("Current ped state: {0}", m_ped.CurrentState != null ? m_ped.CurrentState.GetType().Name : "none") ); + + } + + private void FixedUpdate() + { + m_velCounter -= Time.deltaTime; + if (m_velCounter <= 0) + { + Vector3 t = new Vector3(transform.position.x, 0, transform.position.z); + + m_deltaPos = t - m_lastPos; + m_lastPos = t; + + m_velCounter = velTimer; + } + } + + private void Update() + { + if (!m_ped.IsLocalPlayer) + return; + + if (Input.GetKeyDown(KeyCode.F9)) + _showVel = !_showVel; + + if (!Loader.HasLoaded) + return; + + + // reset ped input + m_ped.ResetMovementInput (); + m_ped.MouseMoveInput = Vector2.zero; + m_ped.MouseScrollInput = Vector2.zero; + + + if (!GameManager.CanPlayerReadInput()) return; + + + // states must be read before events, otherwise callback functions for events will not have access + // to states (they will always be unpressed/reset, because we did a reset above) + this.ReadStates (); + this.ReadEvents (); + + + } + + void ReadStates() + { + + this.ReadCameraInput (); + + m_ped.MouseScrollInput = Input.mouseScrollDelta; + + + m_ped.IsAimOn = Input.GetButton ("RightClick"); + m_ped.IsFireOn = Input.GetButton ("LeftClick"); + + m_ped.IsJumpOn = Input.GetButton ("Jump"); + + + Vector3 inputMove = Vector3.zero; + if (m_smoothMovement) + inputMove = new Vector3 (Input.GetAxis ("Horizontal"), 0f, Input.GetAxis ("Vertical")); + else + inputMove = new Vector3 (Input.GetAxisRaw ("Horizontal"), 0f, Input.GetAxisRaw ("Vertical")); + + if (inputMove.sqrMagnitude > 0f) + { + inputMove.Normalize(); + + if (Input.GetButton ("Walk")) + m_ped.IsWalkOn = true; + else if (Input.GetButton ("Sprint")) + m_ped.IsSprintOn = true; + else + m_ped.IsRunOn = true; + + } + + if (m_ped.Camera != null) + m_ped.Movement = m_ped.Camera.transform.TransformVector (inputMove).normalized; + else + m_ped.Movement = inputMove.normalized; + + if (m_ped.Movement.sqrMagnitude > float.Epsilon) { + // only assign heading if there is any movement - we don't want the heading to be zero vector + m_ped.Heading = m_ped.Movement; + } + + } + + void ReadEvents() + { + + if (Input.GetButtonDown ("LeftClick")) + m_ped.OnFireButtonPressed (); + + if (Input.GetButtonDown ("RightClick")) + m_ped.OnAimButtonPressed (); + + if (Input.GetKeyDown (KeyCode.Q)) + m_ped.OnPreviousWeaponButtonPressed(); + else if (Input.GetKeyDown (KeyCode.E)) + m_ped.OnNextWeaponButtonPressed(); + + if (Input.GetButtonDown("Use")) + m_ped.OnSubmitPressed (); + + if (Input.GetButtonDown("Jump")) + m_ped.OnJumpButtonPressed (); + + if (Input.GetKeyDown(KeyCode.C)) + m_ped.OnCrouchButtonPressed (); + + if (Input.GetKeyDown (KeyCode.T)) + m_ped.OnFlyButtonPressed(); + + if (Input.GetKeyDown (KeyCode.R)) + m_ped.OnFlyThroughButtonPressed(); + + } + + private void ReadCameraInput () + { + + if (GameManager.CanPlayerReadInput()) + { + // rotate camera + + var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")); + var rightAnalogDelta = new Vector2(Input.GetAxisRaw("Joystick X"), Input.GetAxisRaw("Joystick Y")); + + Vector2 totalMouseDelta = mouseDelta + rightAnalogDelta; + + totalMouseDelta = Vector2.Scale (totalMouseDelta, this.CursorSensitivity); + + m_ped.MouseMoveInput = totalMouseDelta; + + + if (m_doSmooth) + { + + _smoothMouse.x = Mathf.Lerp (_smoothMouse.x, totalMouseDelta.x, 1f / smoothing.x); + _smoothMouse.y = Mathf.Lerp (_smoothMouse.y, totalMouseDelta.y, 1f / smoothing.y); + + _mouseAbsolute += _smoothMouse; + } + else + { + _mouseAbsolute += totalMouseDelta; + } + + + if (clampInDegrees.y > 0) + _mouseAbsolute.y = Mathf.Clamp(_mouseAbsolute.y, -clampInDegrees.y, clampInDegrees.y); + + } + + + } + + + private void OnDrawGizmosSelected() + { + if (null == m_ped) + return; + + Gizmos.color = Color.white; + + // draw enter vehicle radius + Gizmos.DrawWireSphere(transform.position, EnterVehicleRadius); + + // find closest vehicle in entering range + + var vehicles = FindObjectsOfType() + .Where(x => Vector3.Distance(transform.position, x.FindClosestSeatTransform(transform.position).position) < EnterVehicleRadius) + .OrderBy(x => Vector3.Distance(transform.position, x.FindClosestSeatTransform(transform.position).position)).ToArray(); + + foreach (var vehicle in vehicles) + { + // draw all seats + foreach (var seat in vehicle.Seats) + { + Gizmos.color = Color.red; + Gizmos.DrawWireSphere(seat.Parent.position, 0.1f); + } + + // draw closest seat + + var closestSeat = vehicle.FindClosestSeat(transform.position); + + if (closestSeat != Vehicle.SeatAlignment.None) + { + var closestSeatTransform = vehicle.GetSeatTransform(closestSeat); + + Gizmos.color = Color.green; + Gizmos.DrawWireSphere(closestSeatTransform.position, 0.1f); + Gizmos.DrawLine(transform.position, closestSeatTransform.position); + } + + break; + } + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Ped/PlayerController.cs.meta b/Assets/Scripts/Behaviours/Ped/PlayerController.cs.meta new file mode 100644 index 00000000..551472e1 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/PlayerController.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 57e796a954503384dbd1282729710af5 +timeCreated: 1428252232 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States.meta b/Assets/Scripts/Behaviours/Ped/States.meta new file mode 100644 index 00000000..26b09c86 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ea1fab4829689456698568f0e8f6428f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseAimMovementState.cs b/Assets/Scripts/Behaviours/Ped/States/BaseAimMovementState.cs new file mode 100644 index 00000000..3024355c --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseAimMovementState.cs @@ -0,0 +1,505 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Weapons; +using SanAndreasUnity.Importing.Animation; +using SanAndreasUnity.Behaviours.Weapons; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + /// + /// Base class for all aim-movement states. + /// + public abstract class BaseAimMovementState : BaseScriptState, IAimState + { + protected Weapon m_weapon { get { return m_ped.CurrentWeapon; } } + + public abstract AnimId aimWithArm_LowerAnim { get; } + + public virtual float AimAnimMaxTime { get { return m_weapon.AimAnimMaxTime; } } + public virtual float AimAnimFireMaxTime { get { return m_weapon.AimAnimFireMaxTime; } } + + + + public override void UpdateState() + { + + base.UpdateState (); + + if (!this.IsActiveState) + return; + + + if (this.SwitchToNonAimMovementState ()) + return; + if (this.SwitchToFiringState ()) + return; + if (this.SwitchToOtherAimMovementState ()) + return; + if (this.SwitchToFallingState ()) + return; + + } + + public override void LateUpdateState () + { + base.LateUpdateState (); + + if (!this.IsActiveState) + return; + + m_ped.WeaponHolder.UpdateWeaponTransform (); + + } + + + protected virtual bool SwitchToNonAimMovementState () + { + // check if we should exit aiming state + if (!m_ped.IsHoldingWeapon || !m_ped.IsAimOn) + { + // Debug.LogFormat ("Exiting aim state, IsHoldingWeapon {0}, IsAimOn {1}", m_ped.IsHoldingWeapon, m_ped.IsAimOn); + BaseMovementState.SwitchToMovementStateBasedOnInput (m_ped); + return true; + } + return false; + } + + protected virtual bool SwitchToFiringState () + { + return false; + } + + protected virtual bool SwitchToOtherAimMovementState () + { + BaseAimMovementState.SwitchToAimMovementStateBasedOnInput (m_ped); + return ! this.IsActiveState; + } + + protected virtual bool SwitchToFallingState () + { + return false; + } + + + public static void SwitchToAimMovementStateBasedOnInput (Ped ped) + { + + if (ped.IsWalkOn) + { + ped.SwitchState (); + } + else if (ped.IsRunOn) + { + if (ped.CurrentWeapon != null && ped.CurrentWeapon.HasFlag (GunFlag.AIMWITHARM)) + ped.SwitchState (); + else + ped.SwitchState (); + } + else if (ped.IsSprintOn) + { + ped.SwitchState (); + } + else + { + ped.SwitchState (); + } + + } + + + protected virtual void RotateSpine() + { + BaseAimMovementState.RotateSpineToMatchAimDirection (m_ped); + } + + public static void RotateSpineToMatchAimDirection (Ped ped) + { + if (null == ped.CurrentWeapon) + return; + + if (ped.CurrentWeapon.HasFlag (GunFlag.AIMWITHARM)) + return; + + // TODO: spine's forward vector should be the same as aim direction + // this will not work for peds without camera + ped.PlayerModel.Spine.LookAt(ped.Camera.transform.position + ped.Camera.transform.forward * 500); + + // now apply offset to spine rotation + // this has to be done because spine is not rotated properly - is it intentionally done, or is it error in model importing ? + + Vector3 eulers = ped.WeaponHolder.SpineOffset; + if (ped.CurrentWeapon.HasFlag (GunFlag.AIMWITHARM)) + eulers.y = 0; + ped.PlayerModel.Spine.Rotate (eulers); + // PlayerModel.ChangeSpineRotation (this.CurrentWeaponTransform.forward, Camera.transform.position + Camera.transform.forward * Camera.farClipPlane - this.CurrentWeaponTransform.position, SpineRotationSpeed, ref tempSpineLocalEulerAngles, ref targetRot, ref spineRotationLastFrame); + + } + + protected virtual void RotatePedInDirectionOfAiming() + { + if (m_ped.CurrentWeapon.HasFlag (GunFlag.AIMWITHARM)) + return; + + BaseAimMovementState.RotatePedInDirectionOfAiming( m_ped ); + } + + public static void RotatePedInDirectionOfAiming(Ped ped) + { + +// Vector3 lookAtPos = Camera.transform.position + Camera.transform.forward * 500; +// lookAtPos.y = m_player.transform.position.y; +// +// m_player.transform.LookAt (lookAtPos, Vector3.up); + + // TODO: this will not work if ped doesn't have camera + + Vector3 forward = ped.Camera.transform.forward; + forward.y = 0; + forward.Normalize (); + // m_player.transform.forward = forward; + ped.Heading = forward; + + + } + + + public virtual void StartFiring() + { + BaseFireMovementState.SwitchToFireMovementStateBasedOnInput(m_ped); + } + + + protected override void UpdateAnims () + { + if (m_weapon != null) + { + AnimationState state; + + if (m_weapon.HasFlag (GunFlag.AIMWITHARM)) + state = this.UpdateAnimsAWA (); + else + state = this.UpdateAnimsNonAWA (); + + if (m_weapon) + { + m_weapon.AimAnimState = state; + if (state) + this.UpdateAimAnim (state); + } + + if (m_weapon && m_weapon.HasFlag(GunFlag.AIMWITHARM)) + { + // update arm transforms + // this has to be done after updating aim anim + this.UpdateArmTransformsForAWA(); + } + + // spine should be rotated no matter if state was changed or not during anim updating + // this should be done AFTER updating anims + this.RotateSpine (); + } + } + + /// + /// Update anims for non AWA (AIMWITHARM) weapons. + /// + protected virtual AnimationState UpdateAnimsNonAWA() + { + return null; + } + + /// + /// Update anims for AWA (AIMWITHARM) weapons. + /// + protected virtual AnimationState UpdateAnimsAWA() + { + return BaseAimMovementState.UpdateAnimsAWA (m_ped, this.aimWithArm_LowerAnim); + } + + public static AnimationState UpdateAnimsAWA(Ped ped, AnimId aimWithArm_LowerAnim) + { + + // aim with arm + // eg: pistol, tec9, sawnoff + + var model = ped.PlayerModel; + + model.Play2Anims (new AnimId (AnimGroup.Colt45, AnimIndex.colt45_fire), aimWithArm_LowerAnim); + + var state = model.LastAnimState; + model.LastAnimState.wrapMode = WrapMode.ClampForever; + + model.RemoveAllMixingTransforms (model.LastAnimState); + model.AddMixingTransform (model.LastAnimState, model.RightClavicle, true); + + model.AddMixingTransform (model.LastSecondaryAnimState, model.LeftClavicle, true); + model.AddMixingTransforms (model.LastSecondaryAnimState, model.Pelvis, model.Belly, model.Spine, model.UpperSpine, model.RBreast, model.LBreast, model.Neck); + + if (model.AnimsChanged) { + // reset model state + model.ResetModelState (); + // sample the animation, because otherwise, model will remain in original state for 1 frame + model.AnimComponent.Sample (); + } + + return state; + } + + protected virtual void UpdateAimAnim(AnimationState state) + { + BaseAimMovementState.UpdateAimAnim (m_ped, state, this.AimAnimMaxTime, this.AimAnimFireMaxTime, () => this.TryFire()); + } + + public static void UpdateAimAnim(Ped ped, AnimationState state, float aimAnimMaxTime, float aimAnimFireMaxTime, + System.Func tryFireFunc) + { + + if (state.time > aimAnimMaxTime) { + + if (ped.IsFiring) { + state.enabled = true; + + // check if anim reached end + if(state.time >= aimAnimFireMaxTime) { + // anim reached end, revert it to start + + state.time = aimAnimMaxTime; + ped.AnimComponent.Sample (); + + // if (!ped.IsFireOn || !ped.IsAimOn) + { + // no longer firing + ped.StopFiring (); + } + } + } else { + // check if we should start firing + + if (ped.IsFireOn && tryFireFunc()) { + // we started firing + + } else { + // we should remain in aim state + state.time = aimAnimMaxTime; + ped.AnimComponent.Sample (); + state.enabled = false; + } + } + + } + + + } + + protected virtual void UpdateArmTransformsForAWA() + { + BaseAimMovementState.UpdateArmTransformsForAWA (m_ped); + } + + public static void UpdateArmTransformsForAWA(Ped ped) + { + var player = ped; + var model = ped.PlayerModel; + var weapon = ped.CurrentWeapon; + + + float timePerc = Mathf.Clamp01 (model.LastAnimState.time / weapon.AimAnimMaxTime); + + // rotate arm to match direction of player + + // we'll need a few adjustments, because arm's right vector is player's forward vector, + // and arm's forward vector is player's down vector => arm's up is player's left + // Vector3 forward = - player.transform.right ; // -player.transform.up; + // Vector3 up = player.transform.up; // -player.transform.right; + // Vector3 lookAtPos = player.transform.position + forward * 500; + + model.ResetFrameState (model.RightUpperArm); + model.ResetFrameState (model.RightForeArm); + model.ResetFrameState (model.RightHand); + + Vector3 aimDir = player.Camera.transform.forward; + Vector3 aimDirLocal = player.transform.InverseTransformDirection (aimDir); + + bool isAimingOnOppositeSide = aimDirLocal.x < 0f; + float oppositeSideAngle = Vector3.Angle( Vector3.forward, aimDirLocal.WithXAndZ () ); + bool isAimingBack = oppositeSideAngle > WeaponsManager.Instance.AIMWITHARM_maxAimAngle; + + Quaternion startRot = Quaternion.LookRotation( -player.transform.up, player.transform.forward ); // Quaternion.Euler (WeaponsManager.Instance.AIMWITHARM_upperArmStartRotationEulers); + Quaternion endRot = Quaternion.LookRotation (aimDir); //Quaternion.LookRotation( forward, up ); + // Vector3 endForwardLocal = new Vector3(0.9222f, -0.3429f, 0.179f); + // Vector3 endUpLocal = new Vector3(-0.3522f, -0.9357f, 0.02171f); + Quaternion endRotForeArm = endRot; + + if (isAimingBack) { + // aim in the air + + endRot = Quaternion.LookRotation ( Vector3.Lerp(-player.transform.up, player.transform.forward, 0.7f).normalized ); + + // we need to apply rotation that is opposite of given offset for x axis - to assure that forehand's up matches ped's back + Quaternion q = Quaternion.AngleAxis( 90f - WeaponsManager.Instance.AIMWITHARM_foreArmRotationOffset.x, player.transform.up ); + endRotForeArm = Quaternion.LookRotation (q * player.transform.up, q * (-player.transform.forward)); + + } else if (isAimingOnOppositeSide) { + // upper arm will slightly follow direction of aiming, but only along y and z axes + // forearm will have direction of aiming + + Vector3 dir = aimDirLocal; + dir.x = 0; // no looking left or right + if (oppositeSideAngle != 0) { + // dir.y = Mathf.Sign (dir.y) * ( Mathf.Abs (dir.y) - 1.0f * oppositeSideAngle / 90f ); + dir.y -= 1.0f * oppositeSideAngle / 90f; + dir.z += 1.0f * oppositeSideAngle / 90f; + if (dir.y > 0) + dir.y /= (1.0f + oppositeSideAngle / 90f); + // if (Mathf.Abs(dir.y) > dir.z) + // dir.z = Mathf.Abs(dir.y); + } + dir.Normalize (); + dir = player.transform.TransformDirection (dir); + endRot = Quaternion.LookRotation (dir); + } + + // lerp + Quaternion rot = Quaternion.Lerp( startRot, endRot, timePerc ); + Quaternion rotForeArm = Quaternion.Lerp (startRot, endRotForeArm, timePerc); + + if (timePerc == 1.0f) { + // Vector3 localForward = player.transform.InverseTransformDirection (model.RightUpperArm.forward); + // Vector3 localUp = player.transform.InverseTransformDirection (model.RightUpperArm.up); + // Debug.LogFormat ("local forward {0}, local up {1}", localForward.ToString("G4"), localUp.ToString("G4")); + } + + // Quaternion deltaRot = Quaternion.FromToRotation (Vector3.forward, aimDirLocal); + + // Quaternion worldRot = player.transform.TransformRotation( rot ); + + // worldRot *= deltaRot; + + // assign new rotation + // 'rot' is in player space + // model.RightUpperArm.rotation = worldRot; + + // Quaternion convertRot = Quaternion.Euler (WeaponsManager.Instance.AIMWITHARM_upperArmEndRotationEulers); + + // head rotation + Vector3 clampedAimDir = F.ClampDirection (aimDir, player.transform.forward, WeaponsManager.Instance.AIMWITHARM_maxHeadRotationAngle); + Quaternion headRot = isAimingBack ? player.transform.rotation : Quaternion.LookRotation (clampedAimDir); + // headRot = Quaternion.Lerp( model.Head.rotation, headRot, 0.3f); + + + // set new rotations and apply aim rotation offsets + + model.Head.rotation = headRot; + model.Head.Rotate (WeaponsManager.Instance.AIMWITHARM_headRotationOffset); + + model.RightClavicle.Rotate (WeaponsManager.Instance.AIMWITHARM_clavicleRotationOffset); + + model.RightUpperArm.rotation = rot; + model.RightUpperArm.Rotate (WeaponsManager.Instance.AIMWITHARM_upperArmRotationOffset); + + model.RightForeArm.rotation = rotForeArm; + model.RightForeArm.Rotate (WeaponsManager.Instance.AIMWITHARM_foreArmRotationOffset); + + model.RightHand.localRotation = Quaternion.identity; + model.RightHand.Rotate (WeaponsManager.Instance.AIMWITHARM_handRotationOffset); + + + } + + + protected virtual bool TryFire () + { + Ped ped = m_ped; + var weapon = ped.CurrentWeapon; + + + if (ped.IsFiring) + return false; + + // check if there is ammo in clip + if (weapon.AmmoInClip < 1) + return false; + + ped.StartFiring (); + + if (!ped.IsFiring) // failed to start firing + return false; + + // reduce ammo + weapon.AmmoInClip --; + + // update gun flash + // this.EnableOrDisableGunFlash (ped); + if (weapon.GunFlash != null) + weapon.GunFlash.gameObject.SetActive (true); + weapon.UpdateGunFlashRotation (); + + // fire projectile + F.RunExceptionSafe( () => weapon.FireProjectile () ); + + // play firing sound + F.RunExceptionSafe (() => weapon.PlayFireSound() ); + + + return true; + } + + + public override void RotateCamera () + { + base.RotateCamera (); + + // this must be called from here (right after the camera transform is changed), otherwise camera will shake + this.RotatePedInDirectionOfAiming (); + } + + public override void UpdateCameraZoom() + { + // ignore + } + + public override void CheckCameraCollision () + { + Vector3 cameraFocusPos = this.GetCameraFocusPos (); + Vector3 castFrom = cameraFocusPos; + float distance; + Vector3 castDir = -m_ped.Camera.transform.forward; + + // use distance from gun aiming offset ? + if (m_ped.CurrentWeapon.GunAimingOffset != null) + { + // Vector3 desiredCameraPos = this.transform.TransformPoint (- _player.CurrentWeapon.GunAimingOffset.Aim) + Vector3.up * .5f; + // Vector3 desiredCameraPos = this.transform.TransformPoint( new Vector3(0.8f, 1.0f, -1) ); + Vector3 desiredCameraPos = cameraFocusPos + m_ped.Camera.transform.TransformVector (m_ped.WeaponHolder.cameraAimOffset); + Vector3 diff = desiredCameraPos - castFrom; + distance = diff.magnitude; + castDir = diff.normalized; + } + else + { + distance = m_ped.CameraDistance; + } + + BaseScriptState.CheckCameraCollision(m_ped, castFrom, castDir, distance); + + } + + + public override void OnSubmitPressed() + { + + // try to enter vehicle + m_ped.TryEnterVehicleInRange (); + + } + + public override void OnJumpPressed() + { + // ignore + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseAimMovementState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/BaseAimMovementState.cs.meta new file mode 100644 index 00000000..a22e5713 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseAimMovementState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62d5fe5c2f4ba4c5fb1a1ff2e342f1b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseFireMovementState.cs b/Assets/Scripts/Behaviours/Ped/States/BaseFireMovementState.cs new file mode 100644 index 00000000..60e03d67 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseFireMovementState.cs @@ -0,0 +1,114 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Weapons; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + /// + /// Base class for all movement-fire states. + /// + public abstract class BaseFireMovementState : BaseAimMovementState, IFireState + { + + + public override void UpdateState() + { + + base.UpdateState (); + + if (!this.IsActiveState) + return; + + if (!m_ped.IsFireOn) + { + // stop firing ? + // - no, because fire anim may still be running + // when anim gets finished, we'll stop firing + + } + + } + + + protected override bool SwitchToNonAimMovementState () + { + // we should not switch to non-aim state, but instead, when fire anim finishes, we will switch back to + // aim state + + // TODO: but, watch out, weapon may become null - if someone else destroys a weapon or changes current weapon + // to Hand, then weapon will be null - we may never exit fire state, because aim anim will not be updated + + // simply checking if weapon is null and exiting the state should solve the problem + + return false; + } + + protected override bool SwitchToFiringState () + { + // switch to other fire movement state + SwitchToFireMovementStateBasedOnInput (m_ped); + return ! this.IsActiveState; + } + + protected override bool SwitchToOtherAimMovementState () + { + // don't switch to aim states, because fire anim may still be running + + return ! this.IsActiveState; + } + + + public static void SwitchToFireMovementStateBasedOnInput (Ped ped) + { + + if (ped.IsWalkOn) + { + ped.SwitchState (); + } + else if (ped.IsRunOn) + { + if(ped.CurrentWeapon != null && ped.CurrentWeapon.HasFlag(GunFlag.AIMWITHARM)) + ped.SwitchState (); + else + ped.SwitchState (); + } + else if (ped.IsSprintOn) + { + ped.SwitchState (); + } + else + { + ped.SwitchState (); + } + + } + + + public override void StartFiring () + { + // ignore + + } + + public virtual void StopFiring () + { + BaseAimMovementState.SwitchToAimMovementStateBasedOnInput (m_ped); + } + + + public override void OnSubmitPressed() + { + // ignore + + } + + public override void OnJumpPressed() + { + // ignore + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseFireMovementState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/BaseFireMovementState.cs.meta new file mode 100644 index 00000000..181d9f18 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseFireMovementState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d7be7838de3446da9e392255437d05c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseMovementState.cs b/Assets/Scripts/Behaviours/Ped/States/BaseMovementState.cs new file mode 100644 index 00000000..ed27d34b --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseMovementState.cs @@ -0,0 +1,113 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + /// + /// Base class for all movement states. + /// + public abstract class BaseMovementState : BaseScriptState + { + public abstract AnimId movementAnim { get; } + public abstract AnimId movementWeaponAnim { get; } + + + + public override void UpdateState() { + + base.UpdateState (); + + if (!this.IsActiveState) + return; + + + this.SwitchToMovementState (); + + if (!this.IsActiveState) + return; + + this.SwitchToAimState (); + + } + + protected virtual void SwitchToMovementState() + { + BaseMovementState.SwitchToMovementStateBasedOnInput (m_ped); + } + + public static void SwitchToMovementStateBasedOnInput (Ped ped) + { + + if (ped.IsJumpOn && ped.GetStateOrLogError().CanJump()) + { + ped.GetState().Jump(); + } + else if (ped.IsWalkOn) + { + ped.SwitchState (); + } + else if (ped.IsRunOn) + { + ped.SwitchState (); + } + else if (ped.IsSprintOn) + { + if (ped.CurrentWeapon != null && !ped.CurrentWeapon.CanSprintWithIt) + ped.SwitchState (); + else + ped.SwitchState (); + } + else + { + ped.SwitchState (); + } + + } + + protected virtual void SwitchToAimState() + { + if (m_ped.IsAimOn && m_ped.IsHoldingWeapon) + { + BaseAimMovementState.SwitchToAimMovementStateBasedOnInput (m_ped); + } + } + + protected override void UpdateAnims () + { + if (m_ped.CurrentWeapon != null) + { + m_ped.PlayerModel.PlayAnim (this.movementWeaponAnim); + } + else + { + m_ped.PlayerModel.PlayAnim (this.movementAnim); + } + } + + public override void OnSubmitPressed() { + + // try to enter vehicle + m_ped.TryEnterVehicleInRange (); + + } + + public override void OnCrouchButtonPressed () + { + m_ped.SwitchState(); + } + + public override void OnFlyButtonPressed () + { + m_ped.GetStateOrLogError ().EnterState (false); + } + + public override void OnFlyThroughButtonPressed () + { + m_ped.GetStateOrLogError ().EnterState (true); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseMovementState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/BaseMovementState.cs.meta new file mode 100644 index 00000000..5a9247cb --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseMovementState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a47880db99c254926b99ef0728d252cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseScriptState.cs b/Assets/Scripts/Behaviours/Ped/States/BaseScriptState.cs new file mode 100644 index 00000000..b1f8d7e1 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseScriptState.cs @@ -0,0 +1,259 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + /// + /// Base class for all states that are scripts. + /// + public abstract class BaseScriptState : MonoBehaviour, IPedState + { + + protected Ped m_ped; + protected PedModel m_model { get { return m_ped.PlayerModel; } } + // protected StateMachine m_stateMachine; + protected new Transform transform { get { return m_ped.transform; } } + public bool IsActiveState { get { return m_ped.CurrentState == this; } } + + + + protected virtual void Awake () + { + m_ped = this.GetComponentInParent (); + } + + protected virtual void OnEnable () + { + + } + + protected virtual void OnDisable () + { + + } + + protected virtual void Start () + { + + } + + public virtual void OnBecameActive () + { + + } + + public virtual void OnBecameInactive () + { + + } + + public virtual bool RepresentsState (System.Type type) + { + var myType = this.GetType (); + return myType.Equals (type) || myType.IsSubclassOf (type); + } + + public bool RepresentsState () where T : IState + { + return this.RepresentsState (typeof(T)); + } + + public virtual void UpdateState() { + + // read input + + // call appropriate function for every input action + + + this.ConstrainPosition(); + this.ConstrainRotation(); + + } + + public virtual void PostUpdateState() + { + if (m_ped.Camera) + this.UpdateCamera (); + } + + public virtual void LateUpdateState() + { + + if (m_ped.shouldPlayAnims) + this.UpdateAnims (); + + } + + public virtual void FixedUpdateState() + { + + this.UpdateHeading(); + this.UpdateRotation(); + this.UpdateMovement(); + + } + + protected virtual void ConstrainPosition() + { + m_ped.ConstrainPosition(); + } + + protected virtual void ConstrainRotation () + { + m_ped.ConstrainRotation(); + } + + protected virtual void UpdateHeading() + { + m_ped.UpdateHeading (); + } + + protected virtual void UpdateRotation() + { + m_ped.UpdateRotation (); + } + + protected virtual void UpdateMovement() + { + m_ped.UpdateMovement (); + } + + public virtual void UpdateCamera() + { + this.RotateCamera(); + this.UpdateCameraZoom(); + this.CheckCameraCollision (); + } + + public virtual void RotateCamera() + { + BaseScriptState.RotateCamera(m_ped, m_ped.MouseMoveInput, m_ped.CameraClampValue.y); + } + + public static void RotateCamera(Ped ped, Vector2 mouseDelta, float xAxisClampValue) + { + Camera cam = ped.Camera; + + if (mouseDelta.sqrMagnitude < float.Epsilon) + return; + + // cam.transform.Rotate( new Vector3(-mouseDelta.y, mouseDelta.x, 0f), Space.World ); + var eulers = cam.transform.eulerAngles; + // eulers.z = 0f; + eulers.x += - mouseDelta.y; + eulers.y += mouseDelta.x; + // adjust x + if (eulers.x > 180f) + eulers.x -= 360f; + // clamp + if (xAxisClampValue > 0) + eulers.x = Mathf.Clamp(eulers.x, -xAxisClampValue, xAxisClampValue); + + cam.transform.rotation = Quaternion.AngleAxis(eulers.y, Vector3.up) + * Quaternion.AngleAxis(eulers.x, Vector3.right); + + } + + public virtual Vector3 GetCameraFocusPos() + { + return m_ped.transform.position + Vector3.up * 0.5f; + } + + public virtual float GetCameraDistance() + { + return m_ped.CameraDistance; + } + + public virtual void UpdateCameraZoom() + { + m_ped.CameraDistance = Mathf.Clamp(m_ped.CameraDistance - m_ped.MouseScrollInput.y, 2.0f, 32.0f); + } + + public virtual void CheckCameraCollision() + { + BaseScriptState.CheckCameraCollision (m_ped, this.GetCameraFocusPos (), -m_ped.Camera.transform.forward, + this.GetCameraDistance ()); + } + + public static void CheckCameraCollision(Ped ped, Vector3 castFrom, Vector3 castDir, float cameraDistance) + { + + // cast a ray from ped to camera to see if it hits anything + // if so, then move the camera to hit point + + Camera cam = ped.Camera; + + float distance = cameraDistance; + var castRay = new Ray(castFrom, castDir); + RaycastHit hitInfo; + + if (Physics.SphereCast(castRay, 0.25f, out hitInfo, distance, + -1 ^ (1 << MapObject.BreakableLayer) ^ (1 << Vehicles.Vehicle.Layer))) + { + distance = hitInfo.distance; + } + + cam.transform.position = castRay.GetPoint(distance); + + } + + protected virtual void UpdateAnims() + { + + } + + + public virtual void OnFireButtonPressed() + { + + } + + public virtual void OnAimButtonPressed() + { + + } + + public virtual void OnSubmitPressed() + { + + } + + public virtual void OnJumpPressed() + { + + } + + public virtual void OnCrouchButtonPressed() + { + + } + + public virtual void OnNextWeaponButtonPressed() + { + m_ped.WeaponHolder.SwitchWeapon (true); + } + + public virtual void OnPreviousWeaponButtonPressed() + { + m_ped.WeaponHolder.SwitchWeapon (false); + } + + public virtual void OnFlyButtonPressed() + { + + } + + public virtual void OnFlyThroughButtonPressed() + { + + } + + public virtual void OnDamaged(DamageInfo info) + { + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseScriptState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/BaseScriptState.cs.meta new file mode 100644 index 00000000..c7162def --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseScriptState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b2b4e6edbba042dc8036798b339281c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseVehicleState.cs b/Assets/Scripts/Behaviours/Ped/States/BaseVehicleState.cs new file mode 100644 index 00000000..9e99d246 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseVehicleState.cs @@ -0,0 +1,60 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours.Vehicles; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class BaseVehicleState : BaseScriptState, IVehicleState + { + private Vehicle m_currentVehicle; + public Vehicle CurrentVehicle { get { return m_currentVehicle; } protected set { m_currentVehicle = value; } } + + public Vehicle.Seat CurrentVehicleSeat { get; protected set; } + public Vehicle.SeatAlignment CurrentVehicleSeatAlignment { get { return this.CurrentVehicleSeat.Alignment; } } + + + protected override void UpdateHeading() + { + + } + + protected override void UpdateRotation() + { + + } + + protected override void UpdateMovement() + { + + } + + protected override void ConstrainRotation () + { + + } + + public bool CanEnterVehicle (Vehicle vehicle, Vehicle.SeatAlignment seatAlignment) + { + if (m_ped.IsInVehicle) + return false; + + if (m_ped.IsAiming || m_ped.WeaponHolder.IsFiring) + return false; + + var seat = vehicle.GetSeat (seatAlignment); + if (null == seat) + return false; + + // check if specified seat is taken + if (seat.IsTaken) + return false; + + // everything is ok, we can enter vehicle + + return true; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/BaseVehicleState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/BaseVehicleState.cs.meta new file mode 100644 index 00000000..38950d47 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/BaseVehicleState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e2b698e351774c10b9898f9e0e7037b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/CrouchAimState.cs b/Assets/Scripts/Behaviours/Ped/States/CrouchAimState.cs new file mode 100644 index 00000000..0af7abdd --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/CrouchAimState.cs @@ -0,0 +1,164 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class CrouchAimState : BaseAimMovementState + { + // not used + public override AnimId aimWithArm_LowerAnim { get { throw new System.InvalidOperationException(); } } + + // override aim anim timings + public override float AimAnimMaxTime { get { return m_weapon.CrouchAimAnimMaxTime; } } + public override float AimAnimFireMaxTime { get { return m_weapon.CrouchAimAnimFireMaxTime; } } + + public float cameraFocusPosOffsetY = 0.25f; + + + + protected override bool SwitchToNonAimMovementState () + { + // switch to Crouch state + if( !m_ped.IsAimOn || !m_ped.IsHoldingWeapon ) + { + m_ped.SwitchState(); + return true; + } + + // switch to Roll state + if(m_ped.Movement.sqrMagnitude > float.Epsilon && m_ped.GetStateOrLogError().CanRoll()) + { + float angle = Vector3.Angle(m_ped.Movement, m_ped.transform.forward); + if( angle > 50 && angle < 130 ) + { + float rightAngle = Vector3.Angle( m_ped.Movement, m_ped.transform.right ); + bool left = rightAngle > 90; + m_ped.GetState().Roll( left ); + return true; + } + } + + return false; + } + + protected override bool SwitchToFiringState () + { + return false; + } + + protected override bool SwitchToOtherAimMovementState () + { + // there are no other states to switch to + return false; + } + + protected override void RotateSpine () + { + + if( null == m_model.Spine || null == m_weapon ) + return; + + Vector3 forward = m_ped.transform.forward.WithXAndZ(); + float xzLength = m_ped.AimDirection.WithXAndZ().magnitude; + forward = forward.normalized * xzLength; + forward.y = m_ped.AimDirection.y; + forward.Normalize(); + + m_model.Spine.forward = forward; + + // apply rotation offset + + m_model.Spine.Rotate( m_weapon.CrouchSpineRotationOffset ); + + } + + public override void StartFiring () + { + // switch to CrouchFire state + m_ped.SwitchState(); + } + + protected override void UpdateAnims () + { + base.UpdateAnims(); + + // if( !this.IsActiveState ) + // return; + + // anim does not set correct velocity + // set it to zero to make the ped stand in place + // this should be done even if parent method changed active state + m_model.RootFrame.LocalVelocity = Vector3.zero; + + // if( !this.IsActiveState ) + // return; + + // we need to adjust local position of some bones - root frame needs to be 0.5 units below the ped + + // for some reason, y position always remains 0.25 + // m_model.UnnamedFrame.transform.localPosition = m_model.UnnamedFrame.transform.localPosition.WithXAndZ(); + + Vector3 pos = m_model.RootFrame.transform.localPosition; + pos.y = -0.5f - m_model.UnnamedFrame.transform.localPosition.y; + m_model.RootFrame.transform.localPosition = pos; + + } + + protected override AnimationState UpdateAnimsNonAWA () + { + return this.UpdateAnimsAll(); + } + + protected override AnimationState UpdateAnimsAWA () + { + return this.UpdateAnimsAll(); + } + + protected virtual AnimationState UpdateAnimsAll() + { + var state = m_model.PlayAnim(m_weapon.CrouchAimAnim); + state.wrapMode = WrapMode.ClampForever; + return state; + } + + protected override void UpdateArmTransformsForAWA () + { + // ignore + } + + protected override void RotatePedInDirectionOfAiming () + { + BaseAimMovementState.RotatePedInDirectionOfAiming( m_ped ); + } + + protected override void UpdateHeading () + { + // we need to override default behaviour, because otherwise ped will be turning around while aiming + // with AWA weapons + + m_ped.Heading = m_ped.AimDirection.WithXAndZ ().normalized; + } + + public override Vector3 GetCameraFocusPos () + { + return m_ped.transform.position + Vector3.up * this.cameraFocusPosOffsetY; + } + + + + + public override void OnJumpPressed () + { + // ignore + } + + public override void OnCrouchButtonPressed () + { + // ignore + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/CrouchAimState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/CrouchAimState.cs.meta new file mode 100644 index 00000000..9a4628a5 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/CrouchAimState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 262dd793913e349f7ac18af5bcadf7cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/CrouchFireState.cs b/Assets/Scripts/Behaviours/Ped/States/CrouchFireState.cs new file mode 100644 index 00000000..54299621 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/CrouchFireState.cs @@ -0,0 +1,38 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class CrouchFireState : CrouchAimState, IFireState + { + + + protected override bool SwitchToFiringState () + { + // there are no other fire movement states to switch to + return false; + } + + protected override bool SwitchToOtherAimMovementState () + { + // we'll switch to aim state when fire anim finishes + return false; + } + + public override void StartFiring () + { + // ignore + } + + public virtual void StopFiring () + { + // switch to crouch-aim state + m_ped.SwitchState(); + } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/CrouchFireState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/CrouchFireState.cs.meta new file mode 100644 index 00000000..d54888f5 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/CrouchFireState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7968f7ed64924436af362bf4c5d54f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/CrouchMoveState.cs b/Assets/Scripts/Behaviours/Ped/States/CrouchMoveState.cs new file mode 100644 index 00000000..d713ff68 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/CrouchMoveState.cs @@ -0,0 +1,42 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class CrouchMoveState : BaseMovementState + { + public override AnimId movementAnim { get { return new AnimId ("ped", "GunCrouchFwd"); } } + public override AnimId movementWeaponAnim { get { return this.movementAnim; } } + + + + protected override void SwitchToMovementState () + { + // can only switch to Crouch state + if( m_ped.Movement.sqrMagnitude < float.Epsilon ) + { + m_ped.SwitchState(); + } + } + + protected override void SwitchToAimState () + { + // can only switch to CrouchAim state + CrouchState.SwitchToAimState(m_ped); + } + + public override void OnJumpPressed () + { + // ignore + } + + public override void OnCrouchButtonPressed () + { + m_ped.SwitchState(); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/CrouchMoveState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/CrouchMoveState.cs.meta new file mode 100644 index 00000000..8dd23657 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/CrouchMoveState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a658f459c4f543c5abdd7d9570a9b5f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/CrouchState.cs b/Assets/Scripts/Behaviours/Ped/States/CrouchState.cs new file mode 100644 index 00000000..118b7257 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/CrouchState.cs @@ -0,0 +1,58 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class CrouchState : BaseMovementState + { + public override AnimId movementAnim { get { return new AnimId ("ped", "WEAPON_crouch"); } } + public override AnimId movementWeaponAnim { get { return this.movementAnim; } } + + + + protected override void SwitchToMovementState () + { + // can only switch to CrouchMove state + if( m_ped.Movement.sqrMagnitude > float.Epsilon ) + { + m_ped.SwitchState(); + } + } + + protected override void SwitchToAimState () + { + CrouchState.SwitchToAimState(m_ped); + } + + public static void SwitchToAimState(Ped ped) + { + // can only switch to CrouchAim state + if( ped.IsAimOn && ped.IsHoldingWeapon ) + { + ped.SwitchState(); + } + } + + public override void OnJumpPressed () + { + // switch to stand state + // it's better to do this event-based, because after switching to stand state, we may enter + // jump state right after it + + // we can't switch to stand state, because that will cause ped to jump (jump button will be on) + + // m_ped.SwitchState(); + } + + public override void OnCrouchButtonPressed () + { + // switch to stand state + + m_ped.SwitchState(); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/CrouchState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/CrouchState.cs.meta new file mode 100644 index 00000000..27657715 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/CrouchState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 72812118050114157b2f9d5368c7e7c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/FlyState.cs b/Assets/Scripts/Behaviours/Ped/States/FlyState.cs new file mode 100644 index 00000000..c4944056 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/FlyState.cs @@ -0,0 +1,75 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class FlyState : BaseScriptState + { + public float moveMultiplier = 10f; + public float moveFastMultiplier = 100f; + private bool m_flyThrough = false; + + + + public override void OnBecameActive () + { + base.OnBecameActive (); + + m_model.PlayAnim(AnimGroup.WalkCycle, AnimIndex.RoadCross, PlayMode.StopAll); // play 'flying' animation + } + + public override void OnBecameInactive () + { + m_ped.characterController.detectCollisions = true; + base.OnBecameInactive (); + } + + public void EnterState (bool flyThrough) + { + m_ped.SwitchState (); + m_flyThrough = flyThrough; + m_ped.characterController.detectCollisions = !flyThrough; + } + + public override void OnSubmitPressed () + { + m_ped.TryEnterVehicleInRange (); + } + + public override void OnJumpPressed () + { + // ignore + } + + public override void OnFlyButtonPressed () + { + m_ped.SwitchState (); + } + + public override void OnFlyThroughButtonPressed () + { + // toggle collision detection + m_flyThrough = !m_flyThrough; + m_ped.characterController.detectCollisions = !m_flyThrough; + } + + protected override void UpdateHeading () + { + m_ped.Heading = Vector3.Scale(m_ped.Movement, new Vector3(1f, 0f, 1f)).normalized; + } + + protected override void UpdateMovement () + { + Vector3 delta = m_ped.Movement * Time.fixedDeltaTime; + delta *= m_ped.IsSprintOn ? this.moveFastMultiplier : this.moveMultiplier; + if (m_flyThrough) + m_ped.transform.position += delta; + else + m_ped.characterController.Move (delta); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/FlyState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/FlyState.cs.meta new file mode 100644 index 00000000..2e105810 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/FlyState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 209709c163d044d2fbc29d291fdbc821 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/IAimState.cs b/Assets/Scripts/Behaviours/Ped/States/IAimState.cs new file mode 100644 index 00000000..de5bc01c --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/IAimState.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public interface IAimState : IPedState + { + + void StartFiring (); + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/IAimState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/IAimState.cs.meta new file mode 100644 index 00000000..891a0c3e --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/IAimState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e52b6f1f63af34b35a1fdee577cd1bcf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/IFireState.cs b/Assets/Scripts/Behaviours/Ped/States/IFireState.cs new file mode 100644 index 00000000..cccb5d99 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/IFireState.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public interface IFireState : IPedState + { + + void StopFiring(); + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/IFireState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/IFireState.cs.meta new file mode 100644 index 00000000..fbaf6463 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/IFireState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c4e55170d0c3e4fd1a45072873520999 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/IPedState.cs b/Assets/Scripts/Behaviours/Ped/States/IPedState.cs new file mode 100644 index 00000000..4bd43d07 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/IPedState.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public interface IPedState : Utilities.IState { + + /// Called at the end of Update(). + void PostUpdateState (); + + //void OnCollision(Collision info); + void OnDamaged(DamageInfo info); + + void OnFireButtonPressed(); + void OnAimButtonPressed(); + void OnSubmitPressed (); + void OnJumpPressed (); + void OnCrouchButtonPressed (); + void OnNextWeaponButtonPressed(); + void OnPreviousWeaponButtonPressed(); + void OnFlyButtonPressed(); + void OnFlyThroughButtonPressed(); + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/IPedState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/IPedState.cs.meta new file mode 100644 index 00000000..9fed8bae --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/IPedState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e605340475c104b089bc7c4022180ef6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/IVehicleState.cs b/Assets/Scripts/Behaviours/Ped/States/IVehicleState.cs new file mode 100644 index 00000000..97838705 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/IVehicleState.cs @@ -0,0 +1,15 @@ +using UnityEngine; +using SanAndreasUnity.Behaviours.Vehicles; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public interface IVehicleState : IPedState + { + + Vehicle CurrentVehicle { get; } + Vehicle.Seat CurrentVehicleSeat { get; } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/IVehicleState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/IVehicleState.cs.meta new file mode 100644 index 00000000..82b66186 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/IVehicleState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa4aad57e46be49f29ea976352ca6e8d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/JumpState.cs b/Assets/Scripts/Behaviours/Ped/States/JumpState.cs new file mode 100644 index 00000000..e3b13f48 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/JumpState.cs @@ -0,0 +1,184 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; +using System.Collections; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class JumpState : BaseMovementState + { + public override AnimId movementAnim { get { return new AnimId (AnimGroup.WalkCycle, AnimIndex.Idle); } } + public override AnimId movementWeaponAnim { get { return this.movementAnim; } } + + private Coroutine m_coroutine; + private int m_currentAnimIndex = 0; + + [Range(0, 10)] public float launchVelocityMultiplier = 1f; + [Range(0, 10)] public float glideVelocity = 2f; + [Range(0, 10)] public float landVelocityMultiplier = 1f; + + + + public override void OnBecameActive () + { + base.OnBecameActive (); + + m_currentAnimIndex = 0; + m_coroutine = this.StartCoroutine (this.Coroutine()); + } + + public override void OnBecameInactive () + { + if (m_coroutine != null) + this.StopCoroutine (m_coroutine); + + m_coroutine = null; + + base.OnBecameInactive (); + } + + IEnumerator Coroutine() + { + // play 3 anims one after another + + m_currentAnimIndex = 0; + + var state = m_model.PlayAnim ("ped", "JUMP_launch"); + state.wrapMode = WrapMode.Once; + while( state.enabled ) + { + yield return null; + } + + m_currentAnimIndex++; + + state = m_model.PlayAnim ("ped", "JUMP_glide"); + state.wrapMode = WrapMode.Once; + while (state.enabled) + yield return null; + + m_currentAnimIndex++; + + state = m_model.PlayAnim ("ped", "JUMP_land"); + state.wrapMode = WrapMode.Once; + while (state.enabled) + yield return null; + + // all anims finished + // switch to other state + // Debug.LogFormat("All 3 anims finished, switching state"); + m_ped.SwitchState(); + + } + + public bool CanJump() + { + if (m_ped.CurrentWeapon != null && m_ped.CurrentWeapon.IsHeavy) + return false; + if( !m_ped.IsGrounded ) + return false; + return true; + } + + public bool Jump() + { + if (!this.CanJump ()) + return false; + + m_ped.SwitchState (); + return true; + } + + + public override void UpdateState () + { + base.UpdateState (); + + if (!this.IsActiveState) + return; + + // if character is grounded, then we are no longer in jump state + if (m_currentAnimIndex == 1 && m_ped.IsGrounded) + { + // Debug.LogFormat ("Character is grounded, exiting jump state"); + m_ped.SwitchState (); + } + + } + + protected override void SwitchToMovementState () + { + // ignore + } + + protected override void SwitchToAimState () + { + // ignore + } + + protected override void UpdateAnims () + { + // ignore + } + + public override void OnSubmitPressed () + { + // ignore + } + + public override void OnJumpPressed () + { + // ignore + } + + public override void OnCrouchButtonPressed () + { + // ignore + } + + public override void OnFlyButtonPressed () + { + // ignore + } + + public override void OnFlyThroughButtonPressed () + { + // ignore + } + + protected override void UpdateHeading () + { + // not required, since we don't use heading + m_ped.Heading = m_ped.transform.forward; + } + + protected override void UpdateRotation () + { + // ignore + // rotation can not be changed while jumping + } + + protected override void UpdateMovement () + { + Vector3 modelVelocity = m_model.Velocity; + if( m_currentAnimIndex == 0 ) + modelVelocity.z *= this.launchVelocityMultiplier; + else if( m_currentAnimIndex == 1 ) + modelVelocity.z = this.glideVelocity; + else if( m_currentAnimIndex == 2 ) + { + modelVelocity.y = Mathf.Min(modelVelocity.y, 0f); // don't allow to move upwards + modelVelocity.z *= this.landVelocityMultiplier; + } + + Vector3 velocity = m_ped.transform.forward.WithXAndZ().normalized * modelVelocity.z + Vector3.up * modelVelocity.y; + // we won't apply gravity + + m_ped.characterController.Move (velocity * Time.deltaTime); + } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/JumpState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/JumpState.cs.meta new file mode 100644 index 00000000..cee37fc8 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/JumpState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f43370ea311141ba88d19a40632349a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/RollState.cs b/Assets/Scripts/Behaviours/Ped/States/RollState.cs new file mode 100644 index 00000000..5a236586 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/RollState.cs @@ -0,0 +1,133 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class RollState : BaseMovementState + { + public override AnimId movementAnim { get { return m_rollLeft ? new AnimId ("ped", "Crouch_Roll_L") : new AnimId ("ped", "Crouch_Roll_R"); } } + public override AnimId movementWeaponAnim { get { return this.movementAnim; } } + + private bool m_rollLeft = false; + private AnimationState m_animState; + + + + public bool CanRoll() + { + if( this.IsActiveState ) + return false; + return true; + } + + public bool Roll(bool left) + { + if( !this.CanRoll() ) + return false; + + m_rollLeft = left; + m_ped.SwitchState(); + + return true; + } + + public override void OnBecameActive () + { + base.OnBecameActive(); + m_animState = m_model.PlayAnim( this.movementAnim ); + m_animState.wrapMode = WrapMode.Once; + m_model.VelocityAxis = 0; // movement will be done along x axis + } + + + protected override void SwitchToMovementState () + { + // don't switch to any state from here - we'll switch when anim finishes + } + + protected override void SwitchToAimState () + { + // don't switch to any state from here - we'll switch when anim finishes + } + + + protected override void UpdateHeading () + { + m_ped.Heading = m_ped.transform.forward; + } + + protected override void UpdateRotation () + { + // don't change rotation + } + + protected override void UpdateMovement () + { + m_ped.Movement = m_rollLeft ? -m_ped.transform.right : m_ped.transform.right; + base.UpdateMovement(); + } + + protected override void UpdateAnims () + { + // correct local x position of root frame + Vector3 pos = m_model.RootFrame.transform.localPosition; + pos.x = 0f; + m_model.RootFrame.transform.localPosition = pos; + } + + public override void LateUpdateState () + { + base.LateUpdateState(); + + if( !this.IsActiveState ) + return; + + // check if anim is finished + + if( null == m_animState || !m_animState.enabled ) + { + // anim finished + // switch to other state + + // try to switch to crouch aim state + CrouchState.SwitchToAimState(m_ped); + if( !this.IsActiveState ) + return; + + // switch to crouch state + m_ped.SwitchState(); + } + + } + + + public override void OnSubmitPressed () + { + // ignore + } + + public override void OnJumpPressed () + { + // ignore + } + + public override void OnCrouchButtonPressed () + { + // ignore + } + + public override void OnFlyButtonPressed () + { + // ignore + } + + public override void OnFlyThroughButtonPressed () + { + // ignore + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/RollState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/RollState.cs.meta new file mode 100644 index 00000000..172c4a1f --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/RollState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e111211033b048ca9ca00766168ed4b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/RunAimState.cs b/Assets/Scripts/Behaviours/Ped/States/RunAimState.cs new file mode 100644 index 00000000..e3f010fc --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/RunAimState.cs @@ -0,0 +1,21 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class RunAimState : BaseAimMovementState + { + public override AnimId aimWithArm_LowerAnim { get { return m_ped.CurrentWeapon.RunAnim; } } + + + public override void OnBecameActive () + { + base.OnBecameActive (); + // m_ped.PlayerModel.PlayAnim (AnimGroup.Gun, AnimIndex.run_armed); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/RunAimState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/RunAimState.cs.meta new file mode 100644 index 00000000..67062cdc --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/RunAimState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56bc009b7edfa4901ae6929c4a201732 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/RunFireState.cs b/Assets/Scripts/Behaviours/Ped/States/RunFireState.cs new file mode 100644 index 00000000..96b84224 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/RunFireState.cs @@ -0,0 +1,20 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class RunFireState : BaseFireMovementState + { + public override AnimId aimWithArm_LowerAnim { get { return m_ped.CurrentWeapon.RunAnim; } } + + + public override void OnBecameActive () + { + base.OnBecameActive (); + // m_ped.PlayerModel.Play2Anims (m_ped.CurrentWeapon.AimAnim, m_ped.CurrentWeapon.RunAnim); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/RunFireState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/RunFireState.cs.meta new file mode 100644 index 00000000..27f7d64a --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/RunFireState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a05f5f56342e540b7a0328605b41e046 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/RunState.cs b/Assets/Scripts/Behaviours/Ped/States/RunState.cs new file mode 100644 index 00000000..acc1f790 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/RunState.cs @@ -0,0 +1,16 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class RunState : BaseMovementState + { + public override AnimId movementAnim { get { return new AnimId (AnimGroup.WalkCycle, AnimIndex.Run); } } + public override AnimId movementWeaponAnim { get { return m_ped.CurrentWeapon.RunAnim; } } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/RunState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/RunState.cs.meta new file mode 100644 index 00000000..201e6e10 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/RunState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5aa51e616c8584acd8d28097eb9f8be1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/SprintState.cs b/Assets/Scripts/Behaviours/Ped/States/SprintState.cs new file mode 100644 index 00000000..fdf70cb4 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/SprintState.cs @@ -0,0 +1,16 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class SprintState : BaseMovementState + { + public override AnimId movementAnim { get { return new AnimId (AnimGroup.MyWalkCycle, AnimIndex.sprint_civi); } } + public override AnimId movementWeaponAnim { get { return new AnimId (AnimGroup.MyWalkCycle, AnimIndex.sprint_civi); } } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/SprintState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/SprintState.cs.meta new file mode 100644 index 00000000..fa427a91 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/SprintState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 055ab10393eb2465f90002aaceff36a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/StandAimState.cs b/Assets/Scripts/Behaviours/Ped/States/StandAimState.cs new file mode 100644 index 00000000..282d6c49 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/StandAimState.cs @@ -0,0 +1,41 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class StandAimState : BaseAimMovementState + { + public override AnimId aimWithArm_LowerAnim { get { return m_ped.CurrentWeapon.IdleAnim; } } + + + public override void OnBecameActive () + { + base.OnBecameActive (); + // m_ped.PlayerModel.PlayAnim (AnimGroup.MyWalkCycle, AnimIndex.GUN_STAND); + } + + protected override AnimationState UpdateAnimsNonAWA () + { + return StandAimState.UpdateAnimsNonAWA (m_ped); + } + + public static AnimationState UpdateAnimsNonAWA(Ped ped) + { + + ped.PlayerModel.Play2Anims( ped.CurrentWeapon.AimAnim, ped.CurrentWeapon.AimAnimLowerPart ); + + // some anims don't set root frame velocity, so we have to set it + ped.PlayerModel.RootFrame.LocalVelocity = Vector3.zero; + + var state = ped.PlayerModel.LastAnimState; + state.wrapMode = WrapMode.ClampForever; + + + return state; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/StandAimState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/StandAimState.cs.meta new file mode 100644 index 00000000..17d44c6c --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/StandAimState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7969460c603724e2a9bcaee09e341625 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/StandFireState.cs b/Assets/Scripts/Behaviours/Ped/States/StandFireState.cs new file mode 100644 index 00000000..dab0479e --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/StandFireState.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class StandFireState : BaseFireMovementState + { + public override AnimId aimWithArm_LowerAnim { get { return m_ped.CurrentWeapon.IdleAnim; } } + + + public override void OnBecameActive () + { + base.OnBecameActive (); + // m_ped.PlayerModel.Play2Anims (m_ped.CurrentWeapon.AimAnim, m_ped.CurrentWeapon.AimAnimLowerPart); + } + + protected override AnimationState UpdateAnimsNonAWA () + { + return StandAimState.UpdateAnimsNonAWA (m_ped); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/StandFireState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/StandFireState.cs.meta new file mode 100644 index 00000000..2b56e522 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/StandFireState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b9781f849e2154fafb2fea73ccdb831c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/StandState.cs b/Assets/Scripts/Behaviours/Ped/States/StandState.cs new file mode 100644 index 00000000..ff1f5258 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/StandState.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class StandState : BaseMovementState + { + public override AnimId movementAnim { get { return new AnimId (AnimGroup.WalkCycle, AnimIndex.Idle); } } + public override AnimId movementWeaponAnim { get { return m_ped.CurrentWeapon.IdleAnim; } } + + + public override void UpdateState() { + + base.UpdateState(); + + if (!this.IsActiveState) + return; + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/StandState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/StandState.cs.meta new file mode 100644 index 00000000..0af8906a --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/StandState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84062dfd700b5436292c51d37eba57f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/VehicleEnteringState.cs b/Assets/Scripts/Behaviours/Ped/States/VehicleEnteringState.cs new file mode 100644 index 00000000..ad6ef486 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/VehicleEnteringState.cs @@ -0,0 +1,112 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours.Vehicles; +using SanAndreasUnity.Behaviours.World; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class VehicleEnteringState : BaseVehicleState + { + PedModel PlayerModel { get { return m_ped.PlayerModel; } } + + + + public override void OnBecameActive() { + + } + + public bool TryEnterVehicle(Vehicle vehicle, Vehicle.SeatAlignment seatAlignment, bool immediate = false) + { + if (!this.CanEnterVehicle (vehicle, seatAlignment)) + return false; + + + Vehicle.Seat seat = vehicle.GetSeat (seatAlignment); + + // switch state here + m_ped.SwitchState(); + + this.CurrentVehicle = vehicle; + this.CurrentVehicleSeat = seat; + seat.OccupyingPed = m_ped; + + m_ped.characterController.enabled = false; + + + if (m_ped.IsLocalPlayer) + { + if (m_ped.Camera != null) { + // m_ped.Camera.transform.SetParent (seat.Parent, true); + } + + /* + SendToServer(_lastPassengerState = new PlayerPassengerState { + Vechicle = vehicle, + SeatAlignment = (int) seatAlignment + }, DeliveryMethod.ReliableOrdered, 1); + */ + } + + m_ped.transform.SetParent(seat.Parent); + m_ped.transform.localPosition = Vector3.zero; + m_ped.transform.localRotation = Quaternion.identity; + + if (m_ped.IsLocalPlayer && seat.IsDriver) + { + vehicle.StartControlling(); + } + + m_ped.PlayerModel.IsInVehicle = true; + + + if (!vehicle.IsNightToggled && WorldController.IsNight) + vehicle.IsNightToggled = true; + else if (vehicle.IsNightToggled && !WorldController.IsNight) + vehicle.IsNightToggled = false; + + Debug.Log ("IsNightToggled? " + vehicle.IsNightToggled); + + + StartCoroutine (EnterVehicleAnimation (seat, immediate)); + + + return true; + } + + private System.Collections.IEnumerator EnterVehicleAnimation(Vehicle.Seat seat, bool immediate) + { + var animIndex = seat.IsLeftHand ? AnimIndex.GetInLeft : AnimIndex.GetInRight; + + PlayerModel.VehicleParentOffset = Vector3.Scale(PlayerModel.GetAnim(AnimGroup.Car, animIndex).RootEnd, new Vector3(-1, -1, -1)); + + if (!immediate) + { + var animState = PlayerModel.PlayAnim(AnimGroup.Car, animIndex, PlayMode.StopAll); + animState.wrapMode = WrapMode.Once; + + // TODO: also check if this state is still active state + while (animState.enabled) + { + yield return new WaitForEndOfFrame(); + } + } + + // TODO: check if this state is still active, and if vehicle is alive + + + // player now completely entered the vehicle + + // call method from CarSittingState - he will switch state + m_ped.GetStateOrLogError ().EnterVehicle(this.CurrentVehicle, seat); + + // this variable is not needed - it can be obtained based on current state + // IsInVehicleSeat = true; + + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/VehicleEnteringState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/VehicleEnteringState.cs.meta new file mode 100644 index 00000000..85fdae91 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/VehicleEnteringState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d352c5defdc794c3a9df9525af79755a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/VehicleExitingState.cs b/Assets/Scripts/Behaviours/Ped/States/VehicleExitingState.cs new file mode 100644 index 00000000..7f6d1cf0 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/VehicleExitingState.cs @@ -0,0 +1,103 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours.Vehicles; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class VehicleExitingState : BaseVehicleState + { + PedModel PlayerModel { get { return m_ped.PlayerModel; } } + + + public override void OnBecameActive() { + + + } + + public void ExitVehicle(bool immediate = false) + { + if (!m_ped.IsInVehicle || !m_ped.IsInVehicleSeat) + return; + + // obtain current vehicle from Ped + this.CurrentVehicle = m_ped.CurrentVehicle; + this.CurrentVehicleSeat = m_ped.CurrentVehicleSeat; + + // after obtaining parameters, switch to this state + m_ped.SwitchState (); + + // this should be done only if player was a driver ? + this.CurrentVehicle.StopControlling(); + + if (m_ped.IsLocalPlayer) + { + /* + SendToServer(_lastPassengerState = new PlayerPassengerState { + Vechicle = null + }, DeliveryMethod.ReliableOrdered, 1); + */ + } + else + { + // _snapshots.Reset(); + } + + StartCoroutine (ExitVehicleAnimation (immediate)); + + } + + private System.Collections.IEnumerator ExitVehicleAnimation(bool immediate) + { + + // IsInVehicleSeat = false; + + var seat = this.CurrentVehicleSeat; + + var animIndex = seat.IsLeftHand ? AnimIndex.GetOutLeft : AnimIndex.GetOutRight; + + PlayerModel.VehicleParentOffset = Vector3.Scale(PlayerModel.GetAnim(AnimGroup.Car, animIndex).RootStart, new Vector3(-1, -1, -1)); + + if (!immediate) + { + var animState = PlayerModel.PlayAnim(AnimGroup.Car, animIndex, PlayMode.StopAll); + animState.wrapMode = WrapMode.Once; + + // wait until anim finishes or stops + while (animState.enabled) + yield return new WaitForEndOfFrame(); + } + + // player now completely exited the vehicle + + PlayerModel.IsInVehicle = false; + + this.CurrentVehicle = null; + this.CurrentVehicleSeat = null; + seat.OccupyingPed = null; + + m_ped.transform.localPosition = PlayerModel.VehicleParentOffset; + m_ped.transform.localRotation = Quaternion.identity; + + m_ped.transform.SetParent(null); + + m_ped.characterController.enabled = true; + + PlayerModel.VehicleParentOffset = Vector3.zero; + + // change camera parent + if (m_ped.IsLocalPlayer) { + if (m_ped.Camera != null) { + m_ped.Camera.transform.SetParent (null, true); + } + } + + // switch to stand state + m_ped.SwitchState (); + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/VehicleExitingState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/VehicleExitingState.cs.meta new file mode 100644 index 00000000..1718a5dd --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/VehicleExitingState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01e72808e9f8b455f94e3549c8f134c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs b/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs new file mode 100644 index 00000000..e6289ef9 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs @@ -0,0 +1,90 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours.Vehicles; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class VehicleSittingState : BaseVehicleState + { + PedModel PlayerModel { get { return m_ped.PlayerModel; } } + + + + public override void OnBecameActive() { + + + } + + public void EnterVehicle(Vehicle vehicle, Vehicle.Seat seat) + { + + this.CurrentVehicle = vehicle; + this.CurrentVehicleSeat = seat; + + m_ped.SwitchState (); + + if (seat.IsDriver) + { + m_ped.PlayerModel.PlayAnim(AnimGroup.Car, AnimIndex.Sit, PlayMode.StopAll); + } + else + { + m_ped.PlayerModel.PlayAnim(AnimGroup.Car, AnimIndex.SitPassenger, PlayMode.StopAll); + } + + } + + + public override void OnSubmitPressed() { + + // exit the vehicle + m_ped.ExitVehicle(); + + } + + public override void UpdateState() { + + base.UpdateState(); + + if (m_ped.IsDrivingVehicle) + this.UpdateWheelTurning (); + + } + + protected virtual void UpdateWheelTurning() + { + + PlayerModel.VehicleParentOffset = Vector3.zero; + + var driveState = CurrentVehicle.Steering > 0 ? AnimIndex.DriveRight : AnimIndex.DriveLeft; + + var state = PlayerModel.PlayAnim(AnimGroup.Car, driveState, PlayMode.StopAll); + + state.speed = 0.0f; + state.wrapMode = WrapMode.ClampForever; + state.time = Mathf.Lerp(0.0f, state.length, Mathf.Abs(CurrentVehicle.Steering)); + + } + + + public override void UpdateCameraZoom() + { + m_ped.CameraDistanceVehicle = Mathf.Clamp(m_ped.CameraDistanceVehicle - m_ped.MouseScrollInput.y, 2.0f, 32.0f); + } + + public override void CheckCameraCollision () + { + BaseScriptState.CheckCameraCollision(m_ped, this.GetCameraFocusPos(), -m_ped.Camera.transform.forward, + m_ped.CameraDistanceVehicle); + } + + public new Vector3 GetCameraFocusPos() + { + return m_ped.CurrentVehicle.transform.position; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs.meta new file mode 100644 index 00000000..53fdce1d --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9ef25e0552fe44acb26b71aae5751f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/WalkAimState.cs b/Assets/Scripts/Behaviours/Ped/States/WalkAimState.cs new file mode 100644 index 00000000..fe15bd34 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/WalkAimState.cs @@ -0,0 +1,65 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class WalkAimState : BaseAimMovementState + { + public override AnimId aimWithArm_LowerAnim { get { return m_ped.CurrentWeapon.WalkAnim; } } + + + public override void OnBecameActive () + { + base.OnBecameActive (); + // m_ped.PlayerModel.PlayAnim (AnimGroup.Gun, AnimIndex.WALK_armed); + } + + protected override AnimationState UpdateAnimsNonAWA () + { + return WalkAimState.UpdateAnimsNonAWA (m_ped); + } + + public static AnimationState UpdateAnimsNonAWA (Ped ped) + { + var player = ped; + var PlayerModel = ped.PlayerModel; + var weapon = ped.CurrentWeapon; + + + float angle = Vector3.Angle (player.Movement, player.transform.forward); + + if (angle > 110) { + // move backward + PlayerModel.Play2Anims( weapon.AimAnim, new AnimId(AnimGroup.Gun, AnimIndex.GunMove_BWD) ); + } else if (angle > 70) { + // strafe - move left/right + float rightAngle = Vector3.Angle( player.Movement, player.transform.right ); + if (rightAngle > 90) { + // left + PlayerModel.Play2Anims( weapon.AimAnim, new AnimId(AnimGroup.Gun, AnimIndex.GunMove_L) ); + } else { + // right + PlayerModel.Play2Anims( weapon.AimAnim, new AnimId(AnimGroup.Gun, AnimIndex.GunMove_R) ); + } + + // we have to reset local position of root frame - for some reason, anim is changing position + // PlayerModel.RootFrame.transform.localPosition = Vector3.zero; + Importing.Conversion.Animation.RemovePositionCurves( PlayerModel.LastSecondaryAnimState.clip, PlayerModel.Frames ); + + PlayerModel.VelocityAxis = 0; + } else { + // move forward + PlayerModel.Play2Anims( weapon.AimAnim, new AnimId(AnimGroup.Gun, AnimIndex.GunMove_FWD) ); + } + + PlayerModel.LastAnimState.wrapMode = WrapMode.ClampForever; + var state = PlayerModel.LastAnimState; + + return state; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/WalkAimState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/WalkAimState.cs.meta new file mode 100644 index 00000000..fb4441c8 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/WalkAimState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85425b3e6cf1749d08bc08ac3a55fad8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/WalkFireState.cs b/Assets/Scripts/Behaviours/Ped/States/WalkFireState.cs new file mode 100644 index 00000000..1be4ddaa --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/WalkFireState.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class WalkFireState : BaseFireMovementState + { + public override AnimId aimWithArm_LowerAnim { get { return m_ped.CurrentWeapon.WalkAnim; } } + + + public override void OnBecameActive () + { + base.OnBecameActive (); + // m_ped.PlayerModel.Play2Anims (m_ped.CurrentWeapon.AimAnim, new AnimId(AnimGroup.Gun, )); + } + + protected override AnimationState UpdateAnimsNonAWA () + { + return WalkAimState.UpdateAnimsNonAWA (m_ped); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/WalkFireState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/WalkFireState.cs.meta new file mode 100644 index 00000000..91101470 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/WalkFireState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad7b39219621a45dea5eddf1c67486c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Ped/States/WalkState.cs b/Assets/Scripts/Behaviours/Ped/States/WalkState.cs new file mode 100644 index 00000000..f00c757a --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/WalkState.cs @@ -0,0 +1,16 @@ +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Peds.States +{ + + public class WalkState : BaseMovementState + { + public override AnimId movementAnim { get { return new AnimId (AnimGroup.WalkCycle, AnimIndex.Walk); } } + public override AnimId movementWeaponAnim { get { return m_ped.CurrentWeapon.WalkAnim; } } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Ped/States/WalkState.cs.meta b/Assets/Scripts/Behaviours/Ped/States/WalkState.cs.meta new file mode 100644 index 00000000..f6a91875 --- /dev/null +++ b/Assets/Scripts/Behaviours/Ped/States/WalkState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45b03f8d0638d443fb02c2f0242646be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/PedManager.cs b/Assets/Scripts/Behaviours/PedManager.cs new file mode 100644 index 00000000..c38805b1 --- /dev/null +++ b/Assets/Scripts/Behaviours/PedManager.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours +{ + + public class PedManager : MonoBehaviour + { + public static PedManager Instance { get; private set; } + + public GameObject pedPrefab; + + [Header("Health bar")] + + public bool displayHealthBarAbovePeds = false; + public float healthBarWorldWidth = 0.5f; + public float healthBarWorldHeight = 0.1f; + public float healthBarMaxScreenHeight = 20f; + public float healthBarVerticalOffset = 0.3f; + + [Header("Ped AI")] + + public float AIStoppingDistance = 3f; + public float AIVehicleEnterDistance = 1.25f; + public float AIOutOfRangeTimeout = 5f; + public float AIOutOfRangeDistance = 250f; + + + void Awake () + { + Instance = this; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/PedManager.cs.meta b/Assets/Scripts/Behaviours/PedManager.cs.meta new file mode 100644 index 00000000..e4639f6a --- /dev/null +++ b/Assets/Scripts/Behaviours/PedManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d4bc8271f92a431080da3f76af5f901 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/PedModel.cs b/Assets/Scripts/Behaviours/PedModel.cs new file mode 100644 index 00000000..a3105e8b --- /dev/null +++ b/Assets/Scripts/Behaviours/PedModel.cs @@ -0,0 +1,602 @@ +using System.Collections.Generic; +using SanAndreasUnity.Importing.Conversion; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; +using SanAndreasUnity.Importing.Animation; +using UnityEngine; +using System.Linq; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.Behaviours +{ + using Anim = SanAndreasUnity.Importing.Conversion.Animation; + + public class PedModel : MonoBehaviour + { + + /// State of last played anim. + public AnimationState LastAnimState { get; private set; } + + public AnimationState LastSecondaryAnimState { get; private set; } + + /// Last played anim. + public AnimId LastAnimId { get; private set; } + + public AnimId LastSecondaryAnimId { get; private set; } + + /// Did anims changed when played them last time ? + public bool AnimsChanged { get { return this.FirstAnimChanged || this.SecondAnimChanged; } } + public bool FirstAnimChanged { get; private set; } + public bool SecondAnimChanged { get; private set; } + + private readonly AnimId m_invalidAnimId = new AnimId (); + + private UnityEngine.Animation _anim { get; set; } + public UnityEngine.Animation AnimComponent { get { return _anim; } } + + private FrameContainer _frames; + public FrameContainer Frames { get { return _frames; } } + private Frame _root; + public Frame RootFrame { get { return _root; } } + public Frame UnnamedFrame { get; private set; } + + private readonly Dictionary _loadedAnims + = new Dictionary(); + + public PedestrianDef Definition { get; private set; } + + [SerializeField] private int m_startingPedId = 167; + public int StartingPedId { get { return m_startingPedId; } set { m_startingPedId = value; } } + + public int PedestrianId { get; private set; } + + // have we loaded model since the Loader has finished loading + private bool loadedModelOnStartup = false; + + public bool IsInVehicle { get; set; } + + public Vector3 VehicleParentOffset { get; set; } + + private Transform m_leftFinger = null; + public Transform LeftFinger { get { return m_leftFinger; } } + + private Transform m_rightFinger = null; + public Transform RightFinger { get { return m_rightFinger; } } + + private Transform m_leftHand; + public Transform LeftHand { get { return m_leftHand; } } + + private Transform m_rightHand; + public Transform RightHand { get { return m_rightHand; } } + + public Transform LeftUpperArm { get; private set; } + public Transform RightUpperArm { get; private set; } + + public Transform LeftForeArm { get; private set; } + public Transform RightForeArm { get; private set; } + + public Transform LeftClavicle { get; private set; } + public Transform RightClavicle { get; private set; } + + public Transform Head { get; private set; } + + public Transform Neck { get; private set; } + public Transform LBreast { get; private set; } + public Transform RBreast { get; private set; } + + public Transform UpperSpine { get; private set; } + public Transform Belly { get; private set; } + + public Transform Spine { get; private set; } + public Transform R_Thigh { get; private set; } + public Transform L_Thigh { get; private set; } + + public Transform Pelvis { get; private set; } + + public class FrameAnimData + { + public Vector3 pos; + public Quaternion rot; + public Vector3 velocity; + public Frame frame; + + public FrameAnimData (Vector3 pos, Quaternion rot, Vector3 velocity, Frame frame) + { + this.pos = pos; + this.rot = rot; + this.velocity = velocity; + this.frame = frame; + } + } + + private List m_originalFrameDatas = new List (); + public List OriginalFrameDatas { get { return m_originalFrameDatas; } } + + private Ped m_ped; + + /// Velocity of the model extracted from animation. + public Vector3 Velocity { get; private set; } + + /// Velocity axis to use. + public int VelocityAxis { get; set; } + + private Dictionary> m_mixedTransforms = new Dictionary>(); + + public event System.Action onLateUpdate = delegate {}; + + + + private void Awake() + { + m_ped = this.GetComponentInParent (); + } + + private void LateUpdate() + { + if (_root == null) return; + + var trans = _root.transform; + + if (IsInVehicle) + { + // 'Anchor' pedestrian model into the vehicle + this.Velocity = Vector3.zero; + trans.parent.localPosition = VehicleParentOffset; + } + else + { + // Store movement defined by animation for pedestrian model + this.Velocity = _root.LocalVelocity; + trans.parent.localPosition = new Vector3(0f, -trans.localPosition.y * .5f, -trans.localPosition.z); + } + + this.onLateUpdate (); + } + + private void Update() + { + + if (Loader.HasLoaded) + { + if (!loadedModelOnStartup) + { + loadedModelOnStartup = true; + + m_ped.OnSpawn(); + + // load model on startup + //Debug.Log("Loading pedestrian model after startup."); + Load (m_startingPedId); + + // and play animation + PlayAnim(AnimGroup.WalkCycle, AnimIndex.Idle); + + } + } + + } + + + private void OnDrawGizmosSelected() + { + float size = 0.1f; + Gizmos.color = Color.red; + + SkinnedMeshRenderer[] renderers = GetComponentsInChildren(); + foreach (SkinnedMeshRenderer smr in renderers) + { + foreach (Transform tr in smr.bones) + { + Gizmos.DrawWireCube(tr.position, new Vector3(size, size, size)); + } + } + } + + + public void Load(int id) + { + + var newDefinition = Item.GetDefinition(id); + if (null == newDefinition) + return; + + PedestrianId = id; + Definition = newDefinition; + + LastAnimId = m_invalidAnimId; + LastSecondaryAnimId = m_invalidAnimId; + LastAnimState = null; + LastSecondaryAnimState = null; + + m_originalFrameDatas.Clear (); + + _anim = this.gameObject.GetOrAddComponent (); + + LoadModel(Definition.ModelName, Definition.TextureDictionaryName); + + // save original model state + // TODO: we should first reset all anim parameters (eg mixing transforms) ? + + var state = PlayAnim(AnimGroup.WalkCycle, AnimIndex.Idle); + + if (state != null) { + state.time = 0f; + this.AnimComponent.Sample (); + } + + this.SaveModelState (); + + // load some anims + + LoadAnim(AnimGroup.WalkCycle, AnimIndex.Walk); + LoadAnim(AnimGroup.WalkCycle, AnimIndex.Run); + LoadAnim(AnimGroup.WalkCycle, AnimIndex.Panicked); + LoadAnim(AnimGroup.WalkCycle, AnimIndex.Idle); + LoadAnim(AnimGroup.WalkCycle, AnimIndex.RoadCross); + LoadAnim(AnimGroup.WalkCycle, AnimIndex.WalkStart); + + LoadAnim(AnimGroup.Car, AnimIndex.Sit); + LoadAnim(AnimGroup.Car, AnimIndex.DriveLeft); + LoadAnim(AnimGroup.Car, AnimIndex.DriveRight); + LoadAnim(AnimGroup.Car, AnimIndex.GetInLeft); + LoadAnim(AnimGroup.Car, AnimIndex.GetInRight); + LoadAnim(AnimGroup.Car, AnimIndex.GetOutLeft); + LoadAnim(AnimGroup.Car, AnimIndex.GetOutRight); + + LoadAnim(AnimGroup.MyWalkCycle, AnimIndex.IdleArmed); + LoadAnim(AnimGroup.MyWalkCycle, AnimIndex.GUN_STAND); + + // LoadAllAnimations (); + } + + + private void LoadModel(string modelName, params string[] txds) + { + if (_frames != null) + { + Destroy(_frames.Root.gameObject); + Destroy(_frames); + _frames = null; + _loadedAnims.Clear(); + } + + var geoms = Geometry.Load(modelName, txds); + _frames = geoms.AttachFrames(transform, MaterialFlags.Default); + + // we have to remove white spaces from frame names and their game objects, because some models + // have white spaces, and some don't - and we need to have the same frame names for all models, + // otherwise animations will not work on all of them + foreach (var frame in _frames) + { + frame.Name = frame.Name.Replace (" ", ""); + frame.gameObject.name = frame.Name; + } + + + _root = _frames.GetByName("Root"); + UnnamedFrame = _frames.GetByName("unnamed"); + + System.Func getFrame = (string frameName) => { + Frame frame = _frames.GetByName (frameName, true); + if(null == frame) { + Debug.LogErrorFormat("Failed to find frame by name '{0}' on model '{1}'", frameName, modelName); + return null; + } + return frame.transform; + }; + + m_rightFinger = getFrame(" R Finger"); + m_leftFinger = getFrame(" L Finger"); + m_rightHand = getFrame (" R Hand"); + m_leftHand = getFrame (" L Hand"); + RightUpperArm = getFrame (" R UpperArm"); + LeftUpperArm = getFrame (" L UpperArm"); + RightForeArm = getFrame (" R ForeArm"); + LeftForeArm = getFrame (" L ForeArm"); + RightClavicle = getFrame ("Bip01 R Clavicle"); + LeftClavicle = getFrame ("Bip01 L Clavicle"); + Head = getFrame (" Head"); + Neck = getFrame (" Neck"); + LBreast = getFrame ("L breast"); + RBreast = getFrame ("R breast"); + UpperSpine = getFrame (" Spine1"); + Belly = getFrame ("Belly"); + Spine = getFrame(" Spine"); + R_Thigh = getFrame(" R Thigh"); + L_Thigh = getFrame(" L Thigh"); + Pelvis = getFrame(" Pelvis"); + + } + + /// + /// Resets the state of the model. This includes position, rotation, and velocity of every frame (bone). + /// It does it by playing idle anim, setting it's time to 0, and sampling from it. + /// + public void ResetModelState () + { + + //var state = PlayAnim (AnimGroup.WalkCycle, AnimIndex.Idle); + //state.normalizedTime = 0; + //AnimComponent.Sample (); + + foreach (var frameData in m_originalFrameDatas) { + if (null == frameData.frame) + continue; + ResetFrameState (frameData); + } + + } + + private void SaveModelState () + { + m_originalFrameDatas.Clear (); + + foreach (var frame in this.Frames) { + m_originalFrameDatas.Add (new FrameAnimData (frame.transform.localPosition, frame.transform.localRotation, + frame.LocalVelocity, frame)); + } + } + + private void ResetFrameState (FrameAnimData frameData) + { + frameData.frame.transform.localPosition = frameData.pos; + frameData.frame.transform.localRotation = frameData.rot; + frameData.frame.LocalVelocity = frameData.velocity; + } + + public void ResetFrameState (Transform frameTransform) + { + Frame frame = frameTransform.GetComponent (); + if (null == frame) + return; + + var frameData = m_originalFrameDatas.FirstOrDefault( f => f.frame == frame ); + if (frameData != null) { + ResetFrameState (frameData); + } + + } + + + public AnimationState PlayAnim (AnimId animId, PlayMode playMode = PlayMode.StopAll) + { + this.FirstAnimChanged = this.SecondAnimChanged = false; + + var animState = LoadAnim (animId); + if (null == animState) + return null; + + this.FirstAnimChanged = !animId.Equals (LastAnimId); + this.SecondAnimChanged = !m_invalidAnimId.Equals (LastSecondaryAnimId); + + LastAnimId = animId; + LastSecondaryAnimId = m_invalidAnimId; + LastAnimState = animState; + LastSecondaryAnimState = null; + + // reset velocity axis + this.VelocityAxis = 2; + + //animState.layer = 0; + RemoveAllMixingTransforms (animState); + + _anim.Play (animState.name, playMode); + + return animState; + } + + public AnimationState PlayAnim (AnimGroup animGroup, AnimIndex animIndex, PlayMode playMode = PlayMode.StopAll) + { + return PlayAnim (new AnimId (animGroup, animIndex), playMode); + } + + public AnimationState PlayAnim (string fileName, string animName, PlayMode playMode = PlayMode.StopAll) + { + return PlayAnim (new AnimId (fileName, animName), playMode); + } + + public bool Play2Anims (AnimId animIdA, AnimId animIdB) + { + + this.FirstAnimChanged = this.SecondAnimChanged = false; + + // load anims + + var stateA = LoadAnim (animIdA); + var stateB = LoadAnim (animIdB); + + if (null == stateA || null == stateB) + return false; + + this.FirstAnimChanged = !animIdA.Equals (LastAnimId); + this.SecondAnimChanged = !animIdB.Equals (LastSecondaryAnimId); + + // reset velocity axis + this.VelocityAxis = 2; + + // play anims + + // are mixing transforms and layers preserved ? - probably + + RemoveAllMixingTransforms (stateA); + RemoveAllMixingTransforms (stateB); + + AddMixingTransform (stateA, this.Spine, true); + + AddMixingTransform (stateB, _root.transform, false); + AddMixingTransform (stateB, this.L_Thigh, true); + AddMixingTransform (stateB, this.R_Thigh, true); + + stateA.layer = 0; + stateB.layer = 1; + + this.AnimComponent.Play( stateA.clip.name, PlayMode.StopSameLayer); + this.AnimComponent.Play( stateB.clip.name, PlayMode.StopSameLayer); + + // assign last anims + + LastAnimId = animIdA; + LastSecondaryAnimId = animIdB; + LastAnimState = stateA; + LastSecondaryAnimState = stateB; + + + return true; + } + + public bool AddMixingTransform (AnimationState state, Transform tr, bool recursive) + { + List list; + if (m_mixedTransforms.TryGetValue (state, out list)) { + if (list.Contains (tr)) + return false; + state.AddMixingTransform (tr, recursive); + list.Add (tr); + return true; + } else { + state.AddMixingTransform (tr, recursive); + list = new List (){ tr }; + m_mixedTransforms.Add (state, list); + return true; + } + } + + public void AddMixingTransforms (AnimationState state, params Transform[] transforms) + { + foreach (var tr in transforms) + AddMixingTransform (state, tr, false); + } + + public bool RemoveMixingTransform (AnimationState state, Transform tr) + { + List list; + if (m_mixedTransforms.TryGetValue (state, out list)) { + if (!list.Contains (tr)) + return false; + state.RemoveMixingTransform (tr); + list.Remove (tr); + return true; + } else { + return false; + } + } + + public int RemoveAllMixingTransforms (AnimationState state) + { + List list; + if (m_mixedTransforms.TryGetValue (state, out list)) { + int count = list.Count; + foreach (var mix in list) { + state.RemoveMixingTransform (mix); + } + list.Clear (); + return count; + } else { + return 0; + } + } + + + public Anim GetAnim (AnimGroup group, AnimIndex anim) + { + string animName = GetAnimName (group, anim); + if (string.IsNullOrEmpty (animName)) + return null; + + Anim result; + return _loadedAnims.TryGetValue (animName, out result) ? result : null; + } + + public string GetAnimName (AnimGroup group, AnimIndex anim) + { + string animName = null, fileName = null; + if (GetAnimNameAndFile (group, anim, ref animName, ref fileName)) + return animName; + + return null; + } + + public bool GetAnimNameAndFile (AnimGroup group, AnimIndex anim, ref string animName, ref string fileName) + { + if (anim == AnimIndex.None) + return false; + + if (group == AnimGroup.None) + return false; + + if (null == this.Definition || string.IsNullOrEmpty (this.Definition.AnimGroupName)) + return false; + + var animGroup = AnimationGroup.Get (this.Definition.AnimGroupName, group); + if (null == animGroup) + return false; + + animName = animGroup [anim]; + fileName = animGroup.FileName; + + return true; + } + + + private AnimationState LoadAnim (AnimGroup group, AnimIndex anim) + { + string animName = null, fileName = null; + if (GetAnimNameAndFile (group, anim, ref animName, ref fileName)) + return LoadAnim (animName, fileName); + + return null; + } + + private AnimationState LoadAnim (string animName, string fileName) + { + AnimationState state = null; + + if (!_loadedAnims.ContainsKey(animName)) + { + var importedAnim = Anim.Load(fileName, animName, _frames); + if (importedAnim != null && importedAnim.Clip != null) + { + _loadedAnims.Add(animName, importedAnim); + _anim.AddClip(importedAnim.Clip, animName); + state = _anim[animName]; + } + else + { + Debug.LogErrorFormat ("Failed to load anim - file: {0}, anim name: {1}", fileName, animName); + } + } + else + { + state = _anim[animName]; + } + + return state; + } + + private AnimationState LoadAnim (AnimId animId) + { + return animId.UsesAnimGroup ? LoadAnim (animId.AnimGroup, animId.AnimIndex) : LoadAnim (animId.AnimName, animId.FileName); + } + + private void LoadAllAnimations() + { + foreach (var dict in AnimationGroup._sGroups.Values) + { + foreach (AnimationGroup animGroup in dict.Values) + { + foreach (var animName in animGroup.Animations) + { + if (!_loadedAnims.ContainsKey(animName)) + { + var clip = Importing.Conversion.Animation.Load(animGroup.FileName, animName, _frames); + _loadedAnims.Add(animName, clip); + _anim.AddClip(clip.Clip, animName); + // state = _anim [animName]; + } + } + } + } + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/PedModel.cs.meta b/Assets/Scripts/Behaviours/PedModel.cs.meta new file mode 100644 index 00000000..b3bf61a9 --- /dev/null +++ b/Assets/Scripts/Behaviours/PedModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e93599847d269df4da17655e4ac7b3d7 +timeCreated: 1428338571 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/PedestrianModelViewerUI.cs b/Assets/Scripts/Behaviours/PedestrianModelViewerUI.cs new file mode 100644 index 00000000..3a4f79b9 --- /dev/null +++ b/Assets/Scripts/Behaviours/PedestrianModelViewerUI.cs @@ -0,0 +1,20 @@ +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Importing.Animation; +using UnityEngine; + +public class PedestrianModelViewerUI : MonoBehaviour +{ + public PedModel pedestrian = null; + + + private void OnGUI() + { + if (null == pedestrian) + return; + + + GUILayout.Label("Current model ID: " + pedestrian.PedestrianId); + GUILayout.Label("Current model name: " + ((pedestrian.Definition != null) ? pedestrian.Definition.ModelName : "(null!)")); + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/PedestrianModelViewerUI.cs.meta b/Assets/Scripts/Behaviours/PedestrianModelViewerUI.cs.meta new file mode 100644 index 00000000..692457ba --- /dev/null +++ b/Assets/Scripts/Behaviours/PedestrianModelViewerUI.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1bce8e9c5332db34ab54033e1d462ffd +timeCreated: 1474063602 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/UIVehicleSpawner.cs b/Assets/Scripts/Behaviours/UIVehicleSpawner.cs new file mode 100644 index 00000000..b6ccc6af --- /dev/null +++ b/Assets/Scripts/Behaviours/UIVehicleSpawner.cs @@ -0,0 +1,42 @@ +using SanAndreasUnity.Behaviours; +using UnityEngine; + +public class UIVehicleSpawner : MonoBehaviour +{ + public Vector3 spawnOffset = new Vector3(0, 2, 5); + public KeyCode spawnKey = KeyCode.V; + + + private void Start() + { + + } + + // Update is called once per frame + private void Update() + { + if (Input.GetKeyDown(spawnKey)) + { + SpawnVehicle(); + } + } + + + public void SpawnVehicle() + { + var cont = PlayerController.Instance; + + if (null == cont) + return; + + + Vector3 pos = cont.transform.position + cont.transform.forward * spawnOffset.z + cont.transform.up * spawnOffset.y + + cont.transform.right * spawnOffset.x; + Quaternion rotation = Quaternion.LookRotation(-cont.transform.right, Vector3.up); + + // SanAndreasUnity.Behaviours.Vehicles.VehicleSpawner.Create (); + var v = SanAndreasUnity.Behaviours.Vehicles.Vehicle.Create(-1, null, pos, rotation); + Debug.Log("Spawned vehicle with id " + v.Definition.Id); + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/UIVehicleSpawner.cs.meta b/Assets/Scripts/Behaviours/UIVehicleSpawner.cs.meta new file mode 100644 index 00000000..0e1a9bbd --- /dev/null +++ b/Assets/Scripts/Behaviours/UIVehicleSpawner.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: baae2154fadd37540b96289b2b9e9d39 +timeCreated: 1474148675 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles.meta b/Assets/Scripts/Behaviours/Vehicles.meta new file mode 100644 index 00000000..b9322901 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4472d13ea88589b468b3684eb3e55beb +folderAsset: yes +timeCreated: 1428252231 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/Damage.meta b/Assets/Scripts/Behaviours/Vehicles/Damage.meta new file mode 100644 index 00000000..44a1a851 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Damage.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5014d013aec067e4eb22c9d055267361 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/Damage/DetachablePart.cs b/Assets/Scripts/Behaviours/Vehicles/Damage/DetachablePart.cs new file mode 100644 index 00000000..940afd69 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Damage/DetachablePart.cs @@ -0,0 +1,182 @@ +using SanAndreasUnity.Utilities; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + [DisallowMultipleComponent] + [AddComponentMenu("RVP/Damage/Detachable Part", 1)] + + //Class for parts that can detach + public class DetachablePart : MonoBehaviour + { + private Transform tr; + private Rigidbody rb; + private Rigidbody parentBody; + private Transform initialParent; + private Vector3 initialLocalPos; + private Quaternion initialLocalRot; + + [System.NonSerialized] + public HingeJoint hinge; + + [System.NonSerialized] + public bool detached; + + [System.NonSerialized] + public Vector3 initialPos; + + public float mass = 0.1f; + public float drag; + public float angularDrag = 0.05f; + public float looseForce = -1; + public float breakForce = 25; + + [Tooltip("A hinge joint is randomly chosen from the list to use")] + public PartJoint[] joints; + + private Vector3 initialAnchor; + + [System.NonSerialized] + public Vector3 displacedAnchor; + + private void Start() + { + tr = transform; + + if (tr.parent) + { + initialParent = tr.parent; + initialLocalPos = tr.localPosition; + initialLocalRot = tr.localRotation; + } + + parentBody = (Rigidbody)F.GetTopmostParentComponent(tr); + initialPos = tr.localPosition; + } + + private void Update() + { + if (hinge) + { + //Destory hinge if displaced too far from original position + if ((initialAnchor - displacedAnchor).sqrMagnitude > 0.1f) + { + Destroy(hinge); + } + } + } + + public void Detach(bool makeJoint) + { + if (!detached) + { + detached = true; + tr.parent = null; + rb = gameObject.AddComponent(); + rb.mass = mass; + rb.drag = drag; + rb.angularDrag = angularDrag; + + if (parentBody) + { + parentBody.mass -= mass; + rb.velocity = parentBody.GetPointVelocity(tr.position); + rb.angularVelocity = parentBody.angularVelocity; + + //Pick a random hinge joint to use + if (makeJoint && joints.Length > 0) + { + PartJoint chosenJoint = joints[Random.Range(0, joints.Length)]; + initialAnchor = chosenJoint.hingeAnchor; + displacedAnchor = initialAnchor; + + hinge = gameObject.AddComponent(); + hinge.autoConfigureConnectedAnchor = false; + hinge.connectedBody = parentBody; + hinge.anchor = chosenJoint.hingeAnchor; + hinge.axis = chosenJoint.hingeAxis; + hinge.connectedAnchor = initialPos + chosenJoint.hingeAnchor; + hinge.enableCollision = false; + hinge.useLimits = chosenJoint.useLimits; + + JointLimits limits = new JointLimits(); + limits.min = chosenJoint.minLimit; + limits.max = chosenJoint.maxLimit; + limits.bounciness = chosenJoint.bounciness; + hinge.limits = limits; + hinge.useSpring = chosenJoint.useSpring; + + JointSpring spring = new JointSpring(); + spring.targetPosition = chosenJoint.springTargetPosition; + spring.spring = chosenJoint.springForce; + spring.damper = chosenJoint.springDamper; + hinge.spring = spring; + hinge.breakForce = breakForce; + hinge.breakTorque = breakForce; + } + } + } + } + + public void Reattach() + { + if (detached) + { + detached = false; + tr.parent = initialParent; + tr.localPosition = initialLocalPos; + tr.localRotation = initialLocalRot; + + if (parentBody) + { + parentBody.mass += mass; + } + + if (hinge) + { + Destroy(hinge); + } + + if (rb) + { + Destroy(rb); + } + } + } + + //Draw joint gizmos + private void OnDrawGizmosSelected() + { + if (!tr) + { + tr = transform; + } + + if (looseForce >= 0 && joints.Length > 0) + { + Gizmos.color = Color.red; + foreach (PartJoint curJoint in joints) + { + Gizmos.DrawRay(tr.TransformPoint(curJoint.hingeAnchor), tr.TransformDirection(curJoint.hingeAxis).normalized * 0.2f); + Gizmos.DrawWireSphere(tr.TransformPoint(curJoint.hingeAnchor), 0.02f); + } + } + } + } + + //Class for storing hinge joint information in the joints list + [System.Serializable] + public class PartJoint + { + public Vector3 hingeAnchor; + public Vector3 hingeAxis = Vector3.right; + public bool useLimits; + public float minLimit; + public float maxLimit; + public float bounciness; + public bool useSpring; + public float springTargetPosition; + public float springForce; + public float springDamper; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/Damage/DetachablePart.cs.meta b/Assets/Scripts/Behaviours/Vehicles/Damage/DetachablePart.cs.meta new file mode 100644 index 00000000..07ef241f --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Damage/DetachablePart.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0b31114ac897ee4181c1dbd08e7e14b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/Damage/ShatterPart.cs b/Assets/Scripts/Behaviours/Vehicles/Damage/ShatterPart.cs new file mode 100644 index 00000000..9ae62ac3 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Damage/ShatterPart.cs @@ -0,0 +1,66 @@ +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + [RequireComponent(typeof(Renderer))] + [DisallowMultipleComponent] + [AddComponentMenu("RVP/Damage/Shatter Part", 2)] + + //Class for parts that shatter + public class ShatterPart : MonoBehaviour + { + [System.NonSerialized] + public Renderer rend; + + [System.NonSerialized] + public bool shattered; + + public float breakForce = 5; + + [Tooltip("Transform used for maintaining seams when deformed after shattering")] + public Transform seamKeeper; + + [System.NonSerialized] + public Material initialMat; + + public Material brokenMaterial; + public ParticleSystem shatterParticles; + public AudioSource shatterSnd; + + private void Start() + { + rend = GetComponent(); + if (rend) + { + initialMat = rend.sharedMaterial; + } + } + + public void Shatter() + { + if (!shattered) + { + shattered = true; + + if (shatterParticles) + { + shatterParticles.Play(); + } + + if (brokenMaterial) + { + rend.sharedMaterial = brokenMaterial; + } + else + { + rend.enabled = false; + } + + if (shatterSnd) + { + shatterSnd.Play(); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/Damage/ShatterPart.cs.meta b/Assets/Scripts/Behaviours/Vehicles/Damage/ShatterPart.cs.meta new file mode 100644 index 00000000..a697da84 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Damage/ShatterPart.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a89aa0395175ce747a619405956b45af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/Damage/VehicleDamage.cs b/Assets/Scripts/Behaviours/Vehicles/Damage/VehicleDamage.cs new file mode 100644 index 00000000..834f2089 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Damage/VehicleDamage.cs @@ -0,0 +1,779 @@ +using SanAndreasUnity.Utilities; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + [RequireComponent(typeof(Vehicle))] + [DisallowMultipleComponent] + [AddComponentMenu("RVP/Damage/Vehicle Damage", 0)] + + //Class for damaging vehicles + public class VehicleDamage : MonoBehaviour + { + private Transform tr; + private Rigidbody rb; + private Vehicle vp; + + [Range(0, 1)] + public float strength; + + public float damageFactor = 1; + + public float maxCollisionMagnitude = 100; + + [Tooltip("Maximum collision points to use when deforming, has large effect on performance")] + public int maxCollisionPoints = 2; + + [Tooltip("Collisions underneath this local y-position will be ignored")] + public float collisionIgnoreHeight; + + [Tooltip("If true, grounded wheels will not be damaged, but can still be displaced")] + public bool ignoreGroundedWheels; + + [Tooltip("Minimum time in seconds between collisions")] + public float collisionTimeGap = 0.1f; + + private float hitTime; + + [Tooltip("Whether the edges of adjacent deforming parts should match")] + public bool seamlessDeform; + + [Tooltip("Add some perlin noise to deformation")] + public bool usePerlinNoise = true; + + [Tooltip("Recalculate normals of deformed meshes")] + public bool calculateNormals = true; + + [Tooltip("Parts that are damaged")] + public Transform[] damageParts; + + [Tooltip("Meshes that are deformed")] + public MeshFilter[] deformMeshes; + + private bool[] damagedMeshes; + private DamageLogger[] damageLogger; + private Mesh[] tempMeshes; + private meshVerts[] meshVertices; + + [Tooltip("Mesh colliders that are deformed (Poor performance, must be convex)")] + public MeshCollider[] deformColliders; + + // WIP: Collider + + private bool[] damagedCols; + private Mesh[] tempCols; + private meshVerts[] colVertices; + + [Tooltip("Parts that are displaced")] + public Transform[] displaceParts; + + private Vector3[] initialPartPositions; + + private ContactPoint nullContact = new ContactPoint(); + + private const float lightContactDistance = 5; + + //Only for debug + public Vector3 lastContact = Vector3.zero; + + private void Awake() + { + TextGizmo.Init(); + } + + private void Start() + { + tr = transform; + rb = GetComponent(); + vp = GetComponent(); + + //Tell VehicleParent not to play crashing sounds because this script takes care of it +#if RVP + vp.playCrashSounds = false; + vp.playCrashSparks = false; +#endif + + if (deformMeshes != null && deformMeshes.Length > 0) + { + //Set up mesh data + tempMeshes = new Mesh[deformMeshes.Length]; + damagedMeshes = new bool[deformMeshes.Length]; + damageLogger = new DamageLogger[deformMeshes.Length]; + meshVertices = new meshVerts[deformMeshes.Length]; + for (int i = 0; i < deformMeshes.Length; i++) + { + tempMeshes[i] = deformMeshes[i].mesh; + meshVertices[i] = new meshVerts(); + meshVertices[i].verts = deformMeshes[i].mesh.vertices; + meshVertices[i].initialVerts = deformMeshes[i].mesh.vertices; + damagedMeshes[i] = false; + } + } + + if (deformColliders != null && deformColliders.Length > 0) + { + //Set up mesh collider data + tempCols = new Mesh[deformColliders.Length]; + damagedCols = new bool[deformColliders.Length]; + colVertices = new meshVerts[deformColliders.Length]; + for (int i = 0; i < deformColliders.Length; i++) + { + tempCols[i] = (Mesh)Instantiate(deformColliders[i].GetSharedMesh()); + colVertices[i] = new meshVerts(); + colVertices[i].verts = deformColliders[i].GetSharedMesh().vertices; + colVertices[i].initialVerts = deformColliders[i].GetSharedMesh().vertices; + damagedCols[i] = false; + } + } + + if (displaceParts != null && displaceParts.Length > 0) + { + //Set initial positions for displaced parts + initialPartPositions = new Vector3[displaceParts.Length]; + for (int i = 0; i < displaceParts.Length; i++) + { + initialPartPositions[i] = displaceParts[i].localPosition; + } + } + } + + private void FixedUpdate() + { + //Decrease timer for collisionTimeGap + hitTime = Mathf.Max(0, hitTime - Time.fixedDeltaTime); + //Make sure damageFactor is not negative + damageFactor = Mathf.Max(0, damageFactor); + } + + //Apply damage on collision + private void OnCollisionEnter(Collision col) + { + if (hitTime == 0 && col.relativeVelocity.sqrMagnitude * damageFactor > 1 && strength < 1) + { + Vector3 normalizedVel = col.relativeVelocity.normalized; + int colsChecked = 0; + bool soundPlayed = false; + bool sparkPlayed = false; + hitTime = collisionTimeGap; + + foreach (ContactPoint curCol in col.contacts) + { // WIP: Look deeper into GlobalControl + if (tr.InverseTransformPoint(curCol.point).y > collisionIgnoreHeight) //&& GlobalControl.damageMaskStatic == (GlobalControl.damageMaskStatic | (1 << curCol.otherCollider.gameObject.layer))) + { + colsChecked++; + +#if RVP + //Play crash sound + if (vp.crashSnd && vp.crashClips.Length > 0 && !soundPlayed) + { + vp.crashSnd.PlayOneShot(vp.crashClips[Random.Range(0, vp.crashClips.Length)], Mathf.Clamp01(col.relativeVelocity.magnitude * 0.1f)); + soundPlayed = true; + } + + //Play crash sparks + if (vp.sparks && !sparkPlayed) + { + vp.sparks.transform.position = curCol.point; + vp.sparks.transform.rotation = Quaternion.LookRotation(normalizedVel, curCol.normal); + vp.sparks.Play(); + sparkPlayed = true; + } +#endif + + DamageApplication(curCol.point, col.relativeVelocity, maxCollisionMagnitude, curCol.normal, curCol, true); + } + + //Stop checking collision points when limit reached + if (colsChecked >= maxCollisionPoints) + { + break; + } + } + + FinalizeDamage(); + } + } + + //Damage application from collision contact point + public void ApplyDamage(ContactPoint colPoint, Vector3 colVel) + { + DamageApplication(colPoint.point, colVel, Mathf.Infinity, colPoint.normal, colPoint, true); + FinalizeDamage(); + } + + //Same as above, but with extra float for clamping collision force + public void ApplyDamage(ContactPoint colPoint, Vector3 colVel, float damageForceLimit) + { + DamageApplication(colPoint.point, colVel, damageForceLimit, colPoint.normal, colPoint, true); + FinalizeDamage(); + } + + //Damage application from source other than collisions, e.g., an explosion + public void ApplyDamage(Vector3 damagePoint, Vector3 damageForce) + { + DamageApplication(damagePoint, damageForce, Mathf.Infinity, damageForce.normalized, nullContact, false); + FinalizeDamage(); + } + + //Same as above, but with extra float for clamping damage force + public void ApplyDamage(Vector3 damagePoint, Vector3 damageForce, float damageForceLimit) + { + DamageApplication(damagePoint, damageForce, damageForceLimit, damageForce.normalized, nullContact, false); + FinalizeDamage(); + } + + //Damage application from array of points + public void ApplyDamage(Vector3[] damagePoints, Vector3 damageForce) + { + foreach (Vector3 curDamagePoint in damagePoints) + { + DamageApplication(curDamagePoint, damageForce, Mathf.Infinity, damageForce.normalized, nullContact, false); + } + + FinalizeDamage(); + } + + //Damage application from array of points, but with extra float for clamping damage force + public void ApplyDamage(Vector3[] damagePoints, Vector3 damageForce, float damageForceLimit) + { + foreach (Vector3 curDamagePoint in damagePoints) + { + DamageApplication(curDamagePoint, damageForce, damageForceLimit, damageForce.normalized, nullContact, false); + } + + FinalizeDamage(); + } + + //Where the damage is actually applied + private void DamageApplication(Vector3 damagePoint, Vector3 damageForce, float damageForceLimit, Vector3 surfaceNormal, ContactPoint colPoint, bool useContactPoint) + { + float colMag = Mathf.Min(damageForce.magnitude, maxCollisionMagnitude) * (1 - strength) * damageFactor; //Magnitude of collision + float clampedColMag = Mathf.Pow(Mathf.Sqrt(colMag) * 0.5f, 1.5f); //Clamped magnitude of collision + Vector3 clampedVel = Vector3.ClampMagnitude(damageForce, damageForceLimit); //Clamped velocity of collision + Vector3 normalizedVel = damageForce.normalized; + float surfaceDot; //Dot production of collision velocity and surface normal + float massFactor = 1; //Multiplier for damage based on mass of other rigidbody + Transform curDamagePart; + float damagePartFactor; + MeshFilter curDamageMesh; + Transform curDisplacePart; + Transform seamKeeper = null; //Transform for maintaining seams on shattered parts + Vector3 seamLocalPoint; + Vector3 vertProjection; + Vector3 translation; + Vector3 clampedTranslation; + Vector3 localPos; + float vertDist; + float distClamp; + DetachablePart detachedPart; +#if RVP + Suspension damagedSus; +#endif + + //Get mass factor for multiplying damage + if (useContactPoint) + { + damagePoint = colPoint.point; + surfaceNormal = colPoint.normal; + + if (colPoint.otherCollider.attachedRigidbody) + { + massFactor = Mathf.Clamp01(colPoint.otherCollider.attachedRigidbody.mass / rb.mass); + } + } + + surfaceDot = Mathf.Clamp01(Vector3.Dot(surfaceNormal, normalizedVel)) * (Vector3.Dot((tr.position - damagePoint).normalized, normalizedVel) + 1) * 0.5f; + +#if RVP + //Damage damageable parts + for (int i = 0; i < damageParts.Length; i++) + { + curDamagePart = damageParts[i]; + damagePartFactor = colMag * surfaceDot * massFactor * Mathf.Min(clampedColMag * 0.01f, (clampedColMag * 0.001f) / Mathf.Pow(Vector3.Distance(curDamagePart.position, damagePoint), clampedColMag)); + + //Damage motors + Motor damagedMotor = curDamagePart.GetComponent(); + if (damagedMotor) + { + damagedMotor.health -= damagePartFactor * (1 - damagedMotor.strength); + } + + //Damage transmissions + Transmission damagedTransmission = curDamagePart.GetComponent(); + if (damagedTransmission) + { + damagedTransmission.health -= damagePartFactor * (1 - damagedTransmission.strength); + } + } +#endif + + if (deformMeshes != null && deformMeshes.Length > 0) + //Deform meshes + for (int i = 0; i < deformMeshes.Length; i++) + { + curDamageMesh = deformMeshes[i]; + localPos = curDamageMesh.transform.InverseTransformPoint(damagePoint); + translation = curDamageMesh.transform.InverseTransformDirection(clampedVel); + clampedTranslation = Vector3.ClampMagnitude(translation, clampedColMag); + + //Shatter parts that can shatter + ShatterPart shattered = curDamageMesh.GetComponent(); + if (shattered != null) + { + seamKeeper = shattered.seamKeeper; + if (Vector3.Distance(curDamageMesh.transform.position, damagePoint) < colMag * surfaceDot * 0.1f * massFactor && colMag * surfaceDot * massFactor > shattered.breakForce) + { + shattered.Shatter(); + } + } + + //Actual deformation + if (translation.sqrMagnitude > 0 && strength < 1) + { + for (int j = 0; j < meshVertices[i].verts.Length; j++) + { + vertDist = Vector3.Distance(meshVertices[i].verts[j], localPos); + distClamp = (clampedColMag * 0.001f) / Mathf.Pow(vertDist, clampedColMag); + + if (distClamp > 0.001f) + { + damagedMeshes[i] = true; + if (seamKeeper == null || seamlessDeform) + { + vertProjection = seamlessDeform ? Vector3.zero : Vector3.Project(normalizedVel, meshVertices[i].verts[j]); + meshVertices[i].verts[j] += (clampedTranslation - vertProjection * (usePerlinNoise ? 1 + Mathf.PerlinNoise(meshVertices[i].verts[j].x * 100, meshVertices[i].verts[j].y * 100) : 1)) * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor; + } + else + { + seamLocalPoint = seamKeeper.InverseTransformPoint(curDamageMesh.transform.TransformPoint(meshVertices[i].verts[j])); + meshVertices[i].verts[j] += (clampedTranslation - Vector3.Project(normalizedVel, seamLocalPoint) * (usePerlinNoise ? 1 + Mathf.PerlinNoise(seamLocalPoint.x * 100, seamLocalPoint.y * 100) : 1)) * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor; + } + + if (damageLogger[i] == null) + damageLogger[i] = new DamageLogger(meshVertices[i].verts); + else + damageLogger[i].UpdateVertice(j, meshVertices[i].verts[j]); + + // Implemented: Broke light on impact + + if (lastContact != damagePoint) + { + //Debug.Log("Impact from left side: " + (damagePoint - vp.m_frontLeftLight.transform.position).sqrMagnitude); + lastContact = damagePoint; + } + + if (vp != null) + { + if (vp.m_frontLeftLight != null && vp.m_frontLeftLightOk && (damagePoint - vp.m_frontLeftLight.transform.position).sqrMagnitude < lightContactDistance) + vp.m_frontLeftLightOk = false; + + if (vp.m_frontRightLight != null && vp.m_frontRightLightOk && (damagePoint - vp.m_frontRightLight.transform.position).sqrMagnitude < lightContactDistance) + vp.m_frontRightLightOk = false; + + if (vp.m_rearLeftLight != null && vp.m_rearLeftLightOk && (damagePoint - vp.m_rearLeftLight.transform.position).sqrMagnitude < lightContactDistance) + vp.m_rearLeftLightOk = false; + + if (vp.m_rearRightLight != null && vp.m_rearRightLightOk && (damagePoint - vp.m_rearRightLight.transform.position).sqrMagnitude < lightContactDistance) + vp.m_rearRightLightOk = false; + } + } + } + + //Affect handling + float avg = damageLogger[i] != null ? damageLogger[i].DamageAverage() : 0; + + // WIP: Name could be the same + // WIP: I will not use "me" more + //if (Mathf.Abs(avg) > 0 && curDamageMesh.name.Contains("wheel")) + // Debug.LogFormat("Damage Avg: {0} (Name: {1} from {2})", avg, curDamageMesh.transform.parent.name, vp.name)); + + if (false) + if (Mathf.Abs(avg) > .01f && curDamageMesh.transform.parent != null && curDamageMesh.transform.parent.name.Contains("wheel") && curDamageMesh.GetComponent() == null) + { + curDamageMesh.transform.parent.GetComponent().enabled = false; + var col = curDamageMesh.gameObject.AddComponent(); + col.convex = true; + + // WIP: Explode wheel + } + } + } + + seamKeeper = null; + + if (deformColliders != null && deformColliders.Length > 0) + //Deform mesh colliders + for (int i = 0; i < deformColliders.Length; i++) + { + localPos = deformColliders[i].transform.InverseTransformPoint(damagePoint); + translation = deformColliders[i].transform.InverseTransformDirection(clampedVel); + clampedTranslation = Vector3.ClampMagnitude(translation, clampedColMag); + + if (translation.sqrMagnitude > 0 && strength < 1) + { + for (int j = 0; j < colVertices[i].verts.Length; j++) + { + vertDist = Vector3.Distance(colVertices[i].verts[j], localPos); + distClamp = (clampedColMag * 0.001f) / Mathf.Pow(vertDist, clampedColMag); + + if (distClamp > 0.001f) + { + damagedCols[i] = true; + colVertices[i].verts[j] += clampedTranslation * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor; + } + } + } + } + + if (displaceParts != null && displaceParts.Length > 0) + //Displace parts + for (int i = 0; i < displaceParts.Length; i++) + { + curDisplacePart = displaceParts[i]; + translation = clampedVel; + clampedTranslation = Vector3.ClampMagnitude(translation, clampedColMag); + + if (translation.sqrMagnitude > 0 && strength < 1) + { + vertDist = Vector3.Distance(curDisplacePart.position, damagePoint); + distClamp = (clampedColMag * 0.001f) / Mathf.Pow(vertDist, clampedColMag); + + if (distClamp > 0.001f) + { + curDisplacePart.position += clampedTranslation * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor; + + //Detach detachable parts + if (curDisplacePart.GetComponent()) + { + detachedPart = curDisplacePart.GetComponent(); + + if (colMag * surfaceDot * massFactor > detachedPart.looseForce && detachedPart.looseForce >= 0) + { + detachedPart.initialPos = curDisplacePart.localPosition; + detachedPart.Detach(true); + } + else if (colMag * surfaceDot * massFactor > detachedPart.breakForce) + { + detachedPart.Detach(false); + } + } + //Maybe the parent of this part is what actually detaches, useful for displacing compound colliders that represent single detachable objects + else if (curDisplacePart.parent != null && curDisplacePart.parent.GetComponent()) + { + detachedPart = curDisplacePart.parent.GetComponent(); + + if (!detachedPart.detached) + { + if (colMag * surfaceDot * massFactor > detachedPart.looseForce && detachedPart.looseForce >= 0) + { + detachedPart.initialPos = curDisplacePart.parent.localPosition; + detachedPart.Detach(true); + } + else if (colMag * surfaceDot * massFactor > detachedPart.breakForce) + { + detachedPart.Detach(false); + } + } + else if (detachedPart.hinge) + { + detachedPart.displacedAnchor += curDisplacePart.parent.InverseTransformDirection(clampedTranslation * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor); + } + } + +#if RVP + //Damage suspensions and wheels + damagedSus = curDisplacePart.GetComponent(); + if (damagedSus) + { + if ((!damagedSus.wheel.grounded && ignoreGroundedWheels) || !ignoreGroundedWheels) + { + curDisplacePart.RotateAround(damagedSus.tr.TransformPoint(damagedSus.damagePivot), Vector3.ProjectOnPlane(damagePoint - curDisplacePart.position, -translation.normalized), clampedColMag * surfaceDot * distClamp * 20 * massFactor); + + damagedSus.wheel.damage += clampedColMag * surfaceDot * distClamp * 10 * massFactor; + + if (clampedColMag * surfaceDot * distClamp * 10 * massFactor > damagedSus.jamForce) + { + damagedSus.jammed = true; + } + + if (clampedColMag * surfaceDot * distClamp * 10 * massFactor > damagedSus.wheel.detachForce) + { + damagedSus.wheel.Detach(); + } + + foreach (SuspensionPart curPart in damagedSus.movingParts) + { + if (curPart.connectObj && !curPart.isHub && !curPart.solidAxle) + { + if (!curPart.connectObj.GetComponent()) + { + curPart.connectPoint += curPart.connectObj.InverseTransformDirection(clampedTranslation * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor); + } + } + } + } + } + + //Damage hover wheels + HoverWheel damagedHoverWheel = curDisplacePart.GetComponent(); + if (damagedHoverWheel) + { + if ((!damagedHoverWheel.grounded && ignoreGroundedWheels) || !ignoreGroundedWheels) + { + if (clampedColMag * surfaceDot * distClamp * 10 * massFactor > damagedHoverWheel.detachForce) + { + damagedHoverWheel.Detach(); + } + } + } +#endif + } + } + } + } + + //Apply damage to meshes + private void FinalizeDamage() + { + if (deformMeshes != null && deformMeshes.Length > 0) + { + //Apply vertices to actual meshes + for (int i = 0; i < deformMeshes.Length; i++) + { + if (damagedMeshes[i]) + { + tempMeshes[i].vertices = meshVertices[i].verts; + + if (calculateNormals) + { + tempMeshes[i].RecalculateNormals(); + } + + tempMeshes[i].RecalculateBounds(); + } + + damagedMeshes[i] = false; + } + } + + if (deformColliders != null && deformColliders.Length > 0) + { + //Apply vertices to actual mesh colliders + for (int i = 0; i < deformColliders.Length; i++) + { + if (damagedCols[i]) + { + tempCols[i].vertices = colVertices[i].verts; + deformColliders[i].sharedMesh = null; + deformColliders[i].sharedMesh = tempCols[i]; + } + + damagedCols[i] = false; + } + } + } + + public void Repair() + { +#if RVP + //Fix damaged parts + for (int i = 0; i < damageParts.Length; i++) + { + if (damageParts[i].GetComponent()) + { + damageParts[i].GetComponent().health = 1; + } + + if (damageParts[i].GetComponent()) + { + damageParts[i].GetComponent().health = 1; + } + } +#endif + + if (deformMeshes != null && deformMeshes.Length > 0) + //Restore deformed meshes + for (int i = 0; i < deformMeshes.Length; i++) + { + for (int j = 0; j < meshVertices[i].verts.Length; j++) + { + meshVertices[i].verts[j] = meshVertices[i].initialVerts[j]; + } + + tempMeshes[i].vertices = meshVertices[i].verts; + tempMeshes[i].RecalculateNormals(); + tempMeshes[i].RecalculateBounds(); + + //Fix shattered parts + ShatterPart fixedShatter = deformMeshes[i].GetComponent(); + if (fixedShatter) + { + fixedShatter.shattered = false; + + if (fixedShatter.brokenMaterial) + { + fixedShatter.rend.sharedMaterial = fixedShatter.initialMat; + } + else + { + fixedShatter.rend.enabled = true; + } + } + } + + if (deformColliders != null && deformColliders.Length > 0) + //Restore deformed mesh colliders + for (int i = 0; i < deformColliders.Length; i++) + { + for (int j = 0; j < colVertices[i].verts.Length; j++) + { + colVertices[i].verts[j] = colVertices[i].initialVerts[j]; + } + + tempCols[i].vertices = colVertices[i].verts; + deformColliders[i].sharedMesh = null; + deformColliders[i].sharedMesh = tempCols[i]; + } + +#if RVP + //Fix displaced parts + Suspension fixedSus; + Transform curDisplacePart; + for (int i = 0; i < displaceParts.Length; i++) + { + curDisplacePart = displaceParts[i]; + curDisplacePart.localPosition = initialPartPositions[i]; + + if (curDisplacePart.GetComponent()) + { + curDisplacePart.GetComponent().Reattach(); + } + else if (curDisplacePart.parent.GetComponent()) + { + curDisplacePart.parent.GetComponent().Reattach(); + } + + fixedSus = curDisplacePart.GetComponent(); + if (fixedSus) + { + curDisplacePart.localRotation = fixedSus.initialRotation; + fixedSus.jammed = false; + + foreach (SuspensionPart curPart in fixedSus.movingParts) + { + if (curPart.connectObj && !curPart.isHub && !curPart.solidAxle) + { + if (!curPart.connectObj.GetComponent()) + { + curPart.connectPoint = curPart.initialConnectPoint; + } + } + } + } + } + + //Fix wheels + foreach (Wheel curWheel in vp.wheels) + { + curWheel.Reattach(); + curWheel.FixTire(); + curWheel.damage = 0; + } + + //Fix hover wheels + foreach (HoverWheel curHoverWheel in vp.hoverWheels) + { + curHoverWheel.Reattach(); + } +#endif + } + + //Draw collisionIgnoreHeight gizmos + private void OnDrawGizmosSelected() + { + Vector3 startPoint = transform.TransformPoint(Vector3.up * collisionIgnoreHeight); + Gizmos.color = Color.red; + Gizmos.DrawRay(startPoint, transform.forward); + Gizmos.DrawRay(startPoint, -transform.forward); + Gizmos.DrawRay(startPoint, transform.right); + Gizmos.DrawRay(startPoint, -transform.right); + + foreach (var t in gameObject.GetComponentsInChildren().Where(x => x.name.Contains("wheel"))) + try + { + TextGizmo.Draw(t.position, damageLogger[System.Array.IndexOf(deformMeshes.Select(x => x.name).ToArray(), t.name)].ToString()); + } + catch + { + } + } + + //Destroy loose parts + private void OnDestroy() + { + if (displaceParts != null) + foreach (Transform curPart in displaceParts) + { + if (curPart != null && curPart.GetComponent() != null && curPart.parent == null) + { + if (curPart.GetComponent() && curPart.parent == null) + { + Destroy(curPart.gameObject); + } + else if (curPart.parent.GetComponent() && curPart.parent.parent == null) + { + Destroy(curPart.parent.gameObject); + } + } + } + } + } + + //Class for easier mesh data manipulation + internal class meshVerts + { + public Vector3[] verts; //Current mesh vertices + public Vector3[] initialVerts; //Original mesh vertices + } + + internal class DamageLogger + { + private Vector3[] verticePosition; + private Vector3[] lastVerticePosition; + + public DamageLogger(Vector3[] firstRead) + { + int len = firstRead.Length; + + verticePosition = new Vector3[len]; + lastVerticePosition = new Vector3[len]; + + // Set first read + for (int i = 0; i < len; ++i) + verticePosition[i] = new Vector3(firstRead[i].x, firstRead[i].y, firstRead[i].z); + } + + public void UpdateVertice(int index, Vector3 value) + { + lastVerticePosition[index] = value; + } + + public float DamageAverage() + { + return GetDistances().Average(); + } + + private IEnumerable GetDistances() + { + for (int i = 0; i < verticePosition.Length; ++i) + yield return Vector3.Distance(verticePosition[i], lastVerticePosition[i]); + } + + public string ToString() + { + return string.Format("Damage Avg: {0}", DamageAverage()); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/Damage/VehicleDamage.cs.meta b/Assets/Scripts/Behaviours/Vehicles/Damage/VehicleDamage.cs.meta new file mode 100644 index 00000000..3a13ed99 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Damage/VehicleDamage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 03d613698b37edb47ae5ee9b8376e810 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/Vehicle.cs b/Assets/Scripts/Behaviours/Vehicles/Vehicle.cs new file mode 100644 index 00000000..eeadfcbb --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Vehicle.cs @@ -0,0 +1,457 @@ +using SanAndreasUnity.Behaviours.World; +using SanAndreasUnity.Importing.Vehicles; +using SanAndreasUnity.Utilities; +using System.Collections; +using System.Linq; +using UnityEngine; +using VehicleDef = SanAndreasUnity.Importing.Items.Definitions.VehicleDef; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + public enum VehicleLight + { + FrontLeft = 1, + FrontRight = 2, + + RearLeft = 4, + RearRight = 8, + + Front = FrontLeft | FrontRight, + Rear = RearLeft | RearRight, + + All = Front | Rear + } + + public enum VehicleBlinkerMode + { + None, Left, Right, Emergency + } + +#if CLIENT + public partial class Vehicle : Networking.Networkable +#else + + public partial class Vehicle : MonoBehaviour +#endif + { + private static int _sLayer = -1; + + [HideInInspector] + public Light m_frontLeftLight, m_frontRightLight, m_rearLeftLight, m_rearRightLight; + + private bool frontLeftLightOk = true, frontRightLightOk = true, rearLeftLightOk = true, rearRightLightOk = true, + m_frontLeftLightPowered = true, m_frontRightLightPowered = true, m_rearLeftLightPowered = true, m_rearRightLightPowered = true; + + private const float blinkerSum = 1.5f; + + private Material directionalLightsMat; + + internal VehicleBlinkerMode blinkerMode; + + public bool m_frontLeftLightOk + { + get + { + return frontLeftLightOk; + } + set + { + frontLeftLightOk = value; + SetLight(VehicleLight.FrontLeft, value ? 1 : 0); + } + } + + public bool m_frontRightLightOk + { + get + { + return frontRightLightOk; + } + set + { + frontRightLightOk = value; + SetLight(VehicleLight.FrontRight, value ? 1 : 0); + } + } + + public bool m_rearLeftLightOk + { + get + { + return rearLeftLightOk; + } + set + { + rearLeftLightOk = value; + SetLight(VehicleLight.RearLeft, value ? 1 : 0); + } + } + + public bool m_rearRightLightOk + { + get + { + return rearRightLightOk; + } + set + { + rearRightLightOk = value; + SetLight(VehicleLight.RearRight, value ? 1 : 0); + } + } + + public static int Layer + { + get { return _sLayer == -1 ? _sLayer = UnityEngine.LayerMask.NameToLayer("Vehicle") : _sLayer; } + } + + public static int LayerMask { get { return 1 << Layer; } } + + private static int _sLightsId = -1; + + protected static int LightsId + { + get + { + return _sLightsId == -1 ? _sLightsId = Shader.PropertyToID("_Lights") : _sLightsId; + } + } + + private static int[] _sCarColorIds; + + protected static int[] CarColorIds + { + get + { + return _sCarColorIds ?? (_sCarColorIds = Enumerable.Range(1, 4) + .Select(x => Shader.PropertyToID(string.Format("_CarColor{0}", x))) + .ToArray()); + } + } + + private readonly int[] _colors = { 0, 0, 0, 0 }; + private readonly float[] _lights = { 1f, 1f, 1f, 1f }; + private MaterialPropertyBlock _props; + private bool _colorsChanged, _isNightToggled; + + private const float constRearNightIntensity = .7f; + + public bool IsNightToggled + { + get + { + return _isNightToggled; + } + set + { + _isNightToggled = value; + + SetLight(VehicleLight.FrontLeft, _isNightToggled ? VehicleAPI.frontLightIntensity : 0); + SetLight(VehicleLight.FrontRight, _isNightToggled ? VehicleAPI.frontLightIntensity : 0); + SetLight(VehicleLight.RearLeft, _isNightToggled ? constRearNightIntensity : 0); + SetLight(VehicleLight.RearRight, _isNightToggled ? constRearNightIntensity : 0); + } + } + + private VehicleController _controller; + +#if CLIENT + protected override void OnAwake() + { + _props = new MaterialPropertyBlock(); + + base.OnAwake(); + } +#else + + // Must review + private void Awake() + { + _props = new MaterialPropertyBlock(); + } + +#endif + + public void SetColors(params int[] clrIndices) + { + for (var i = 0; i < 4 && i < clrIndices.Length; ++i) + { + if (_colors[i].Equals(clrIndices[i])) continue; + _colors[i] = clrIndices[i]; + _colorsChanged = true; + } + } + + private Light GetLight(VehicleLight light) + { + //if (light == VehicleLight.All || light == VehicleLight.Front || light == VehicleLight.Rear) throw new System.Exception("Light must be right or left, can't be general!"); + switch (light) + { + case VehicleLight.FrontLeft: + return m_frontLeftLight; + + case VehicleLight.FrontRight: + return m_frontRightLight; + + case VehicleLight.RearLeft: + return m_rearLeftLight; + + case VehicleLight.RearRight: + return m_rearRightLight; + } + + return null; + } + + private bool IsLightOk(VehicleLight light) + { + switch (light) + { + case VehicleLight.FrontLeft: + return m_frontLeftLightOk; + + case VehicleLight.FrontRight: + return m_frontRightLightOk; + + case VehicleLight.RearLeft: + return m_rearLeftLightOk; + + case VehicleLight.RearRight: + return m_rearRightLightOk; + } + + return true; + } + + private bool IsAnyLightPowered() + { + if (_lights != null) + return _lights.Any(x => x > 0); + return false; + } + + public void SetLight(VehicleLight light, float brightness) + { + brightness = Mathf.Clamp01(brightness); + + for (var i = 0; i < 4; ++i) + { + var bit = 1 << i; + if (((int)light & bit) == bit) + { + VehicleLight parsedLight = (VehicleLight)bit; //VehicleAPI.ParseFromBit(i); + + if (IsLightOk(parsedLight)) + { + Light lightObj = GetLight(parsedLight); + bool mustRearPower = _isNightToggled && !VehicleAPI.IsFrontLight(light); + + if (brightness > 0 || mustRearPower) + { + if (lightObj != null && !lightObj.enabled) + { + lightObj.enabled = true; + lightObj.intensity = mustRearPower ? constRearNightIntensity : brightness; + } + } + else + { + if (lightObj != null) lightObj.enabled = false; + } + + SetLight(i, mustRearPower ? constRearNightIntensity : brightness); + } + } + } + } + + private void SetLight(int index, float brightness) + { + if (_lights[index] == brightness) return; + _lights[index] = brightness; + _colorsChanged = true; + } + + public VehicleDef Definition { get; private set; } + + public Transform DriverTransform { get; private set; } + + public bool HasDriver { get { return DriverTransform != null && DriverTransform.childCount > 0; } } + + public bool IsControlling { get { return _controller != null; } } + + public VehicleController StartControlling() + { + //SetAllCarLights(); + return _controller ?? (_controller = gameObject.AddComponent()); + } + + public void SetAllCarLights() + { + // Implemented: Add lights + + Transform headlights = this.GetComponentWithName("headlights"), + taillights = this.GetComponentWithName("taillights"); + + Vehicle vh = gameObject.GetComponent(); + + if (headlights != null) + { + m_frontLeftLight = VehicleAPI.SetCarLight(vh, headlights, VehicleLight.FrontLeft); + m_frontRightLight = VehicleAPI.SetCarLight(vh, headlights, VehicleLight.FrontRight); + } + + if (taillights != null) + { + m_rearLeftLight = VehicleAPI.SetCarLight(vh, taillights, VehicleLight.RearLeft); + m_rearRightLight = VehicleAPI.SetCarLight(vh, taillights, VehicleLight.RearRight); + } + + m_frontLeftLightOk = m_frontLeftLight != null; + m_frontRightLightOk = m_frontRightLight != null; + m_rearLeftLightOk = m_rearLeftLight != null; + m_rearRightLightOk = m_rearRightLight != null; + } + + public SeatAlignment FindClosestSeat(Vector3 position) + { + var seat = _seats.Select((s, i) => new { s, i }) + .OrderBy(x => Vector3.Distance(position, x.s.Parent.position)) + .FirstOrDefault(); + + return (seat == null ? SeatAlignment.None : seat.s.Alignment); + } + + public Transform FindClosestSeatTransform(Vector3 position) + { + return GetSeatTransform(FindClosestSeat(position)); + } + + public Seat GetSeat(SeatAlignment alignment) + { + return _seats.FirstOrDefault(x => x.Alignment == alignment); + } + + public Transform GetSeatTransform(SeatAlignment alignment) + { + return GetSeat(alignment).Parent; + } + + public void StopControlling() + { + Destroy(_controller); + _controller = null; + } + + private void UpdateColors() + { + _colorsChanged = false; + + var indices = CarColors.FromIndices(_colors); + for (var i = 0; i < 4; ++i) + _props.SetColor(CarColorIds[i], indices[i]); + + _props.SetVector(LightsId, new Vector4(_lights[0], _lights[1], _lights[2], _lights[3])); + + foreach (var frame in _frames) + { + var mr = frame.GetComponent(); + if (mr == null) continue; + mr.SetPropertyBlock(_props); + } + } + + private void Update() + { + float horAxis = Input.GetAxis("Horizontal"); + + // Set car lights + if (HasDriver) + { + if (horAxis != 0) + blinkerMode = horAxis < 0 ? VehicleBlinkerMode.Left : VehicleBlinkerMode.Right; + else if (horAxis == 0 && Steering == 0 && blinkerMode != VehicleBlinkerMode.None) + StartCoroutine(DelayedBlinkersTurnOff()); + } + + foreach (var wheel in _wheels) + { + Vector3 position = Vector3.zero; + + WheelHit wheelHit; + + if (wheel.Collider.GetGroundHit(out wheelHit)) + { + position.y = (wheelHit.point.y - wheel.Collider.transform.position.y) + wheel.Collider.radius; + } + else + { + position.y -= wheel.Collider.suspensionDistance; + } + + wheel.Child.transform.localPosition = position; + + // reset the yaw + wheel.Child.localRotation = wheel.Roll; + + // calculate new roll + wheel.Child.Rotate(wheel.IsLeftHand ? Vector3.left : Vector3.right, wheel.Collider.rpm / 60.0f * 360.0f * Time.deltaTime); + wheel.Roll = wheel.Child.localRotation; + + // apply yaw + wheel.Child.localRotation = Quaternion.AngleAxis(wheel.Collider.steerAngle, Vector3.up) * wheel.Roll; + } + + if (HasDriver) + { + if(Input.GetKeyDown(KeyCode.F)) + { + if(Vector3.Dot(transform.up, Vector3.down) > 0) + { + transform.position += Vector3.up * 1.5f; + transform.rotation = Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, 0); + } + } + + if (Input.GetKeyDown(KeyCode.L)) + { + m_frontLeftLightPowered = !m_frontLeftLight; + m_frontRightLightPowered = !m_frontRightLightPowered; + + SetLight(VehicleLight.FrontLeft, m_frontLeftLightPowered ? VehicleAPI.frontLightIntensity : 0); + SetLight(VehicleLight.FrontRight, m_frontRightLightPowered ? VehicleAPI.frontLightIntensity : 0); + } + + if (Braking > 0.125f) + SetLight(VehicleLight.Rear, 1f); + else + SetLight(VehicleLight.Rear, 0f); + } + else + { + if (IsAnyLightPowered()) + SetLight(VehicleLight.All, 0f); + Braking = 1f; + } + + if (_colorsChanged) + { + UpdateColors(); + } + } + + private void FixedUpdate() + { + // NetworkingFixedUpdate(); + PhysicsFixedUpdate(); + } + + private IEnumerator DelayedBlinkersTurnOff() + { + yield return new WaitForSeconds(blinkerSum); + + if (blinkerMode != VehicleBlinkerMode.None) + blinkerMode = VehicleBlinkerMode.None; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/Vehicle.cs.meta b/Assets/Scripts/Behaviours/Vehicles/Vehicle.cs.meta new file mode 100644 index 00000000..23c7bbbf --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Vehicle.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 462c097c3609d564eb7f4fc7ae606ec9 +timeCreated: 1428252231 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleAPI.cs b/Assets/Scripts/Behaviours/Vehicles/VehicleAPI.cs new file mode 100644 index 00000000..06e9b7e4 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleAPI.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + public static class VehicleAPI + { + #region "Lights" + + public const float constDamageFactor = 2, frontLightIntensity = 1.5f; + + public static Dictionary blinkerPos = new Dictionary(); + + internal static Light SetCarLight(Vehicle vehicle, Transform parent, VehicleLight light, Vector3? pos = null) + { + GameObject gameObject = null; + Light lightRet = SetCarLight(vehicle, parent, light, pos == null ? (IsLeftLight(light) ? new Vector3(-parent.localPosition.x * 2, 0, 0) : Vector3.zero) : pos.Value, out gameObject); + + // Now set its blinker + Transform blinker = vehicle.transform.FindChildRecursive(parent.name + "2"); + + // Note: If pixelLightCount is equal to 2 the blinker will never show + + //There is a bug, if the blinker is set the vehicle can't steer + //if (blinker != null) // || testing ... QualitySettings.pixelLightCount > 2 // Not needed + VehicleBlinker.Init(gameObject.transform, light, vehicle); //testing ? lightObj.transform : + + //Debug.Log("Is Blinker Null?: "+(blinker == null)); + + return lightRet; + + } + + internal static Light SetCarLight(Vehicle vehicle, Transform parent, VehicleLight light, Vector3 pos, out GameObject go) + { + if (light == VehicleLight.All || light == VehicleLight.Front || light == VehicleLight.Rear) throw new System.Exception("Light must be right or left, can't be general!"); + + Transform lightObj = new GameObject(GetLightName(light)).transform; + lightObj.parent = parent; + + Quaternion rot = IsFrontLight(light) ? Quaternion.identity : Quaternion.Euler(Vector3.right * 180); + + lightObj.localPosition = pos; + lightObj.localRotation = rot; + + Light ret = lightObj.gameObject.AddComponent(); + SetLightProps(GetVehicleLightParent(light).Value, ref ret); + + go = lightObj.gameObject; + return ret; + } + + internal static void LoopBlinker(VehicleBlinkerMode light, Action act) + { + try + { + switch (light) + { + case VehicleBlinkerMode.Left: + act(blinkerPos[VehicleLight.FrontLeft]); + act(blinkerPos[VehicleLight.RearLeft]); + break; + + case VehicleBlinkerMode.Right: + act(blinkerPos[VehicleLight.FrontRight]); + act(blinkerPos[VehicleLight.RearRight]); + break; + } + } catch { } + } + + internal static bool IsFrontLight(VehicleLight light) + { + return light == VehicleLight.Front || light == VehicleLight.FrontLeft || light == VehicleLight.FrontRight; + } + + internal static bool IsLeftLight(VehicleLight light) + { + //Debug.LogFormat("Light type: {0} ({1})", light, light == VehicleLight.FrontLeft || light == VehicleLight.RearLeft); + return light == VehicleLight.FrontLeft || light == VehicleLight.RearLeft; + } + + internal static string GetLightName(VehicleLight light) + { + if (light == VehicleLight.All || light == VehicleLight.Front || light == VehicleLight.Rear) throw new System.Exception("Light must be right or left, can't be general!"); + string lightName = light.ToString(); + + return string.Format("{0}Light", (IsFrontLight(light) ? lightName.Substring(5) : lightName.Substring(4)).ToLower()); + } + + internal static VehicleLight? GetVehicleLightParent(VehicleLight light) + { + if (light == VehicleLight.All || light == VehicleLight.Front || light == VehicleLight.Rear) return null; + string lightName = light.ToString(); + + return (VehicleLight)System.Enum.Parse(typeof(VehicleLight), IsFrontLight(light) ? lightName.Substring(0, 5) : lightName.Substring(0, 4)); + } + + internal static bool IsValidIndividualLight(VehicleLight light) + { + return !(light == VehicleLight.All || light == VehicleLight.Front || light == VehicleLight.Rear); + } + + internal static void SetLightProps(VehicleLight vehicleLight, ref Light light, bool isBlinker = false) + { + if (light == null) return; + if (!isBlinker) + switch (vehicleLight) + { + case VehicleLight.Front: + case VehicleLight.FrontLeft: + case VehicleLight.FrontRight: + light.type = LightType.Spot; + light.range = 60; + light.spotAngle = 90; + light.intensity = frontLightIntensity; + break; + + case VehicleLight.Rear: + case VehicleLight.RearLeft: + case VehicleLight.RearRight: + light.type = LightType.Spot; + light.range = 20; + light.spotAngle = 50; + light.intensity = 1; + light.color = Color.red; + break; + } + else + { + light.type = LightType.Spot; + light.range = 10; + light.spotAngle = 140; + light.intensity = .8f; + light.color = new Color(1, .5f, 0); + } + } + + internal static IEnumerable GetLightObjects(GameObject gameObject) + { + return gameObject.GetComponentsInChildren().Select(x => x.gameObject); + } + + internal static VehicleLight ParseFromBit(int bit) + { + return (VehicleLight)((int)Mathf.Pow(2, bit)); + } + + #endregion "Lights" + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleAPI.cs.meta b/Assets/Scripts/Behaviours/Vehicles/VehicleAPI.cs.meta new file mode 100644 index 00000000..bfff6b64 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleAPI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6769bcaa50fdb304196b9d895d4de703 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleBlinker.cs b/Assets/Scripts/Behaviours/Vehicles/VehicleBlinker.cs new file mode 100644 index 00000000..65814564 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleBlinker.cs @@ -0,0 +1,123 @@ +using SanAndreasUnity.Behaviours.Vehicles; +using System; +using UnityEngine; + +public class VehicleBlinker : MonoBehaviour +{ + #region "Fields" + + #region "Public Fields" + + public float repeatInterval = .5f; + + #endregion "Public Fields" + + #region "Init private fields" + + private VehicleLight lightType; + private Transform parent; + private Vehicle vehicle; + + #endregion "Init private fields" + + #region "Ordinary private fields" + + private bool _blinkerSwitch; + private MeshRenderer blinkerRenderer; + private float defaultIntensity; + + #endregion "Ordinary private fields" + + #endregion "Fields" + + public static VehicleBlinker Init(Transform blinker, VehicleLight light, Vehicle vh) + { + VehicleBlinker vehicleBlinker = blinker.gameObject.AddComponent(); + + vehicleBlinker.parent = blinker; + vehicleBlinker.lightType = light; + vehicleBlinker.vehicle = vh; + + return vehicleBlinker; + } + + private bool IsLeftSide + { + get + { + return VehicleAPI.IsLeftLight(lightType); + } + } + + private bool ShouldBePowered + { + get + { + return (IsLeftSide && vehicle.blinkerMode == VehicleBlinkerMode.Left || !IsLeftSide && vehicle.blinkerMode == VehicleBlinkerMode.Right) || vehicle.blinkerMode == VehicleBlinkerMode.Emergency; + } + } + + private bool blinkerSwitch + { + get + { + return _blinkerSwitch; + } + + set + { + _blinkerSwitch = value; + ToggleBlinker(_blinkerSwitch); + } + } + + // Use this for initialization + private void Start() + { + if (!VehicleAPI.IsValidIndividualLight(lightType)) throw new Exception("Light sides need to have a valid value, revise your code."); + + GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Capsule); + + //If you uncomment this wheels won't steer + //Destroy(obj.GetComponent()); + + obj.name = string.Format("Blinker ({0})", lightType.ToString()); + obj.transform.parent = parent; + obj.transform.position = parent.position + Vector3.right * (IsLeftSide ? -1 : 1) * .2f; + //obj.transform.localRotation = Quaternion.Euler(new Vector3(0, 30 * (IsLeftSide ? -1 : 1), 0)); + obj.transform.localScale = Vector3.one * .2f; + + blinkerRenderer = obj.GetComponent(); + + blinkerRenderer.material = Resources.Load("Materials/Blinker"); + defaultIntensity = blinkerRenderer.material.GetFloat("_MKGlowPower"); + + blinkerSwitch = false; + + InvokeRepeating("Cycle", 0, repeatInterval); + } + + // Update is called once per frame + private void Update() + { + // Must review + if (vehicle.HasDriver && !ShouldBePowered && blinkerSwitch) + { + //Debug.Log("Turning off blinkers!"); + blinkerSwitch = false; + } + } + + private void Cycle() + { + if (!(vehicle.HasDriver && ShouldBePowered)) + return; + + blinkerSwitch = !blinkerSwitch; + } + + private void ToggleBlinker(bool active) + { + blinkerRenderer.material.SetFloat("_MKGlowPower", active ? defaultIntensity : 0); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleBlinker.cs.meta b/Assets/Scripts/Behaviours/Vehicles/VehicleBlinker.cs.meta new file mode 100644 index 00000000..fc94ca66 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleBlinker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 288ee6b28ddc0f94ca17a7f2cc84f6c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs b/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs new file mode 100644 index 00000000..55eefbf8 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs @@ -0,0 +1,35 @@ +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + [RequireComponent(typeof(Vehicle))] + public class VehicleController : MonoBehaviour + { + private Vehicle _vehicle; + + + private void Awake() + { + _vehicle = GetComponent(); + } + + private void Update() + { + if (!GameManager.CanPlayerReadInput()) return; + + var accel = Input.GetAxis("Vertical"); + var brake = Input.GetButton("Brake") ? 1.0f : 0.0f; + var speed = Vector3.Dot(_vehicle.Velocity, _vehicle.transform.forward); + + if (speed * accel < 0f) + { + brake = Mathf.Max(brake, 0.75f); + accel = 0f; + } + + _vehicle.Accelerator = accel; + _vehicle.Steering = Input.GetAxis("Horizontal"); + _vehicle.Braking = brake; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs.meta b/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs.meta new file mode 100644 index 00000000..4d3f0a33 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 213dcc4c9a02ec447abb697c038e1b43 +timeCreated: 1428261642 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/VehiclePhysicsConstants.cs b/Assets/Scripts/Behaviours/Vehicles/VehiclePhysicsConstants.cs new file mode 100644 index 00000000..6b343952 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehiclePhysicsConstants.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + public class VehiclePhysicsConstants : MonoBehaviour + { + public static VehiclePhysicsConstants Instance { get; private set; } + + [AttributeUsage(AttributeTargets.Field)] + private class WatchedAttribute : Attribute { } + + private Dictionary _fields; + + public static event Action Changed; + + [Watched] public float DragScale = 1 / 100f; + [Watched] public float AccelerationScale = 50f; + [Watched] public float BreakingScale = 1.0f; + [Watched] public float SuspensionForceScale = 10000f; + [Watched] public float SuspensionDampingScale = 1000f; + [Watched] public float MassScale = 1f; + + [Watched] public float ForwardFrictionExtremumSlip = 0.5f; + [Watched] public float ForwardFrictionExtremumValue = 1.5f; + [Watched] public float ForwardFrictionAsymptoteSlip = 20.0f; + [Watched] public float ForwardFrictionAsymptoteValue = 0.5f; + + [Watched] public float SideFrictionExtremumSlip = 0.5f; + [Watched] public float SideFrictionExtremumValue = 1.5f; + [Watched] public float SideFrictionAsymptoteSlip = 20.0f; + [Watched] public float SideFrictionAsymptoteValue = 0.5f; + + [Watched] public float AntiRollScale = 1f; + + public bool HasChanged { get; private set; } + + public VehiclePhysicsConstants() + { + Instance = this; + } + + private void DiscoverFields() + { + _fields = new Dictionary(); + + foreach (var field in GetType().GetFields()) + { + if (field.DeclaringType != GetType()) continue; + if (field.FieldType.IsClass) continue; + if (field.GetCustomAttributes(typeof(WatchedAttribute), false).Length == 0) continue; + _fields.Add(field, null); + } + } + + private void CheckForChanges() + { + HasChanged = false; + + if (_fields == null) + { + DiscoverFields(); + } + + foreach (var field in _fields) + { + var cur = field.Key.GetValue(this); + if (!cur.Equals(field.Value)) + { + HasChanged = true; + break; + } + } + + if (!HasChanged) return; + + foreach (var field in _fields.Keys.ToArray()) + { + _fields[field] = field.GetValue(this); + } + + if (Changed != null) + { + Changed(this); + } + } + + private void FixedUpdate() + { + CheckForChanges(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/VehiclePhysicsConstants.cs.meta b/Assets/Scripts/Behaviours/Vehicles/VehiclePhysicsConstants.cs.meta new file mode 100644 index 00000000..1911208e --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehiclePhysicsConstants.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 82a245a7166802b41bcb706255d566f1 +timeCreated: 1428275160 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleSpawner.cs b/Assets/Scripts/Behaviours/Vehicles/VehicleSpawner.cs new file mode 100644 index 00000000..b48bc761 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleSpawner.cs @@ -0,0 +1,55 @@ +//using Facepunch.Networking; +using SanAndreasUnity.Importing.Items.Placements; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + public class VehicleSpawner : MapObject + { + public static VehicleSpawner Create(ParkedVehicle info) + { + //Debug.Log("-333"); + var vs = new GameObject().AddComponent(); + vs.Initialize(info); + return vs; + } + + public ParkedVehicle Info { get; private set; } + + public void Initialize(ParkedVehicle info) + { + Info = info; + + name = string.Format("Vehicle Spawner ({0})", info.CarId); + + Initialize(info.Position, Quaternion.AngleAxis(info.Angle, Vector3.up)); + + gameObject.SetActive(false); + gameObject.isStatic = true; + } + + private void OnDrawGizmos() + { + Gizmos.color = Color.red; + Gizmos.DrawCube(transform.position + Vector3.up * 128f, new Vector3(1f, 256f, 1f)); + } + + protected override float OnRefreshLoadOrder(Vector3 from) + { + if (HasLoaded) return float.PositiveInfinity; + var dist = Vector3.Distance(from, transform.position); + if (dist > 100f) return float.PositiveInfinity; + + var ray = new Ray(transform.position, Vector3.down); + if (!Physics.Raycast(ray, 2f)) return float.PositiveInfinity; + + return dist; + } + + protected override void OnLoad() + { + //Debug.Log("-222"); + Vehicle.Create(this); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleSpawner.cs.meta b/Assets/Scripts/Behaviours/Vehicles/VehicleSpawner.cs.meta new file mode 100644 index 00000000..8e622109 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleSpawner.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 01e61dd7a83ca3845a075843764e20ee +timeCreated: 1428252231 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs new file mode 100644 index 00000000..49d62fe1 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs @@ -0,0 +1,191 @@ +using SanAndreasUnity.Importing.Vehicles; +using SanAndreasUnity.Utilities; +using System.Linq; +using UnityEngine; +using VConsts = SanAndreasUnity.Behaviours.Vehicles.VehiclePhysicsConstants; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + [RequireComponent(typeof(Rigidbody))] + public partial class Vehicle + { + private Rigidbody _rigidBody; + + [Range(-1, 1)] + public float Accelerator; + + [Range(-1, 1)] + public float Steering; + + [Range(0, 1)] + public float Braking = 1f; + + public Vector3 Velocity { get { return _rigidBody.velocity; } } + + public float AverageWheelHeight { get { return _wheels.Count == 0 ? transform.position.y : _wheels.Average(x => x.Child.position.y); } } + + public Handling.Car HandlingData { get; private set; } + + private void InitializePhysics() + { + //Debug.Log("aaa"); + + _geometryParts.AttachCollisionModel(transform, true); + + //Debug.Log("bbb"); + + _rigidBody = gameObject.GetComponent(); + + HandlingData = Handling.Get(Definition.HandlingName); + + VConsts.Changed += UpdateValues; + + var vals = VConsts.Instance; + + foreach (var wheel in _wheels) + { + var front = (wheel.Alignment & WheelAlignment.Front) == WheelAlignment.Front; + + //Debug.LogFormat("Handling is Null?: {0}", HandlingData == null); + /*b = HandlingData == null; + Debug.Log(b); + Debug.Break();*/ + + wheel.Parent.position -= Vector3.up * HandlingData.SuspensionLowerLimit; + + var scale = front ? Definition.WheelScaleFront : Definition.WheelScaleRear; + + var mf = wheel.Child.GetComponent(); + if (mf != null) + { + var size = mf.sharedMesh.bounds.size.y; + wheel.Child.localScale = Vector3.one * scale / size; + } + + wheel.Collider = wheel.Parent.gameObject.AddComponent(); + wheel.Collider.radius = scale * .5f; + wheel.Collider.suspensionDistance = HandlingData.SuspensionUpperLimit - HandlingData.SuspensionLowerLimit; + } + + UpdateValues(vals); + } + + private void UpdateValues(VConsts vals) + { + _rigidBody.drag = HandlingData.Drag * vals.DragScale; + _rigidBody.mass = HandlingData.Mass * vals.MassScale; + _rigidBody.centerOfMass = HandlingData.CentreOfMass; + + foreach (var wheel in _wheels) + { + var spring = wheel.Collider.suspensionSpring; + + spring.damper = HandlingData.SuspensionDampingLevel * vals.SuspensionDampingScale; + spring.spring = HandlingData.SuspensionForceLevel * vals.SuspensionForceScale; + spring.targetPosition = 0.5f; + + wheel.Collider.suspensionSpring = spring; + + var friction = wheel.Collider.sidewaysFriction; + friction.extremumSlip = vals.SideFrictionExtremumSlip; + friction.extremumValue = vals.SideFrictionExtremumValue; + friction.asymptoteSlip = vals.SideFrictionAsymptoteSlip; + friction.asymptoteValue = vals.SideFrictionAsymptoteValue; + friction.stiffness = 1f; + wheel.Collider.sidewaysFriction = friction; + + friction = wheel.Collider.forwardFriction; + friction.extremumSlip = vals.ForwardFrictionExtremumSlip; + friction.extremumValue = vals.ForwardFrictionExtremumValue; + friction.asymptoteSlip = vals.ForwardFrictionAsymptoteSlip; + friction.asymptoteValue = vals.ForwardFrictionAsymptoteValue; + friction.stiffness = 1f; + wheel.Collider.forwardFriction = friction; + } + } + + private float DriveBias(Wheel wheel) + { + switch (HandlingData.TransmissionDriveType) + { + case DriveType.Forward: + return wheel.IsFront ? 1f : 0f; + + case DriveType.Rear: + return wheel.IsRear ? 1f : 0f; + + default: + return 1f; + } + } + + private bool ShouldSteer(Wheel wheel) + { + // TODO: look at flags + return wheel.IsFront; + } + + private float BrakeBias(Wheel wheel) + { + return wheel.IsFront + ? 1f - HandlingData.BrakeBias : wheel.IsRear + ? HandlingData.BrakeBias : .5f; + } + + private void PhysicsFixedUpdate() + { + //Debug.LogFormat("{0}?: {1}", _rigidBody == null, gameObject.GetGameObjectPath()); + //Debug.Break(); + + var groundRay = new Ray(transform.position + Vector3.up, -Vector3.up); + //if (_rigidBody != null) // Must review: Why this is now null? + try + { + if (!Physics.SphereCast(groundRay, 0.25f, transform.position.y + 256f, (-1) ^ LayerMask)) + { + _rigidBody.velocity = Vector3.zero; + _rigidBody.angularVelocity = Vector3.zero; + _rigidBody.useGravity = false; + } + else + { + _rigidBody.useGravity = true; + } + } catch { } + + var vals = VConsts.Instance; + + foreach (var wheel in _wheels) + { + if (ShouldSteer(wheel)) + { + /*if (Steering != 0) + { + Debug.Log(HandlingData.SteeringLock); + Debug.Break(); + }*/ + wheel.Collider.steerAngle = HandlingData.SteeringLock * Steering; + } + + wheel.Collider.motorTorque = + Accelerator * HandlingData.TransmissionEngineAccel + * vals.AccelerationScale * DriveBias(wheel); + + wheel.Collider.brakeTorque = + Braking * HandlingData.BrakeDecel + * vals.BreakingScale * BrakeBias(wheel); + + if (wheel.Complement != null) wheel.UpdateTravel(); + } + + foreach (var wheel in _wheels.Where(x => x.Complement != null)) + { + if (wheel.Travel == wheel.Complement.Travel) continue; + if (!wheel.Collider.isGrounded) continue; + + var force = (wheel.Complement.Travel - wheel.Travel) * vals.AntiRollScale; + _rigidBody.AddForceAtPosition(wheel.Parent.transform.up * force, wheel.Parent.position); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs.meta b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs.meta new file mode 100644 index 00000000..fb4c0228 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d8f9f6ece0c4c05448b73287bcdf0907 +timeCreated: 1428261849 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Vehicles/Vehicle_Spawning.cs b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Spawning.cs new file mode 100644 index 00000000..e5354541 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Spawning.cs @@ -0,0 +1,513 @@ +using SanAndreasUnity.Importing.Conversion; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; +using SanAndreasUnity.Importing.Vehicles; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using VehicleDef = SanAndreasUnity.Importing.Items.Definitions.VehicleDef; + +namespace SanAndreasUnity.Behaviours.Vehicles +{ + public partial class Vehicle + { + [Flags] + public enum WheelAlignment + { + None = 0, + + Front = 1, + Mid = 2, + Rear = 4, + + Left = 8, + Right = 16, + + LeftRightMask = Left | Right, + FrontMidRearMask = Front | Mid | Rear, + + RightFront = Right | Front, + LeftFront = Left | Front, + RightMid = Right | Mid, + LeftMid = Left | Mid, + RightRear = Right | Rear, + LeftRear = Left | Rear, + } + + [Flags] + public enum SeatAlignment + { + None = 0, + + Front = 1, + Back = 2, + + Left = 4, + Right = 8, + + FrontBackMask = Front | Back, + LeftRightMask = Left | Right, + + FrontRight = Front | Right, + FrontLeft = Front | Left, + BackRight = Back | Right, + BackLeft = Back | Left, + } + + public enum DoorAlignment + { + None, + RightFront, + LeftFront, + RightRear, + LeftRear, + } + + private static VehicleDef[] _sRandomSpawnable; + private static int _sMaxSpawnableIndex; + + private static VehicleDef[] GetRandomSpawnableDefs(out int maxIndex) + { + var all = Item.GetDefinitions().ToArray(); + + var defs = all + .Where(x => x.Frequency > 0 && x.VehicleType == VehicleType.Car) + .ToArray(); + + maxIndex = defs.Sum(x => x.Frequency); + + return defs; + } + + private static VehicleDef GetRandomDef() + { + if (_sRandomSpawnable == null) + { + _sRandomSpawnable = GetRandomSpawnableDefs(out _sMaxSpawnableIndex); + } + + var index = UnityEngine.Random.Range(0, _sMaxSpawnableIndex); + foreach (var def in _sRandomSpawnable) + { + index -= def.Frequency; + if (index < 0) return def; + } + + throw new Exception("Unable to find cars to spawn"); + } + + + /// + /// Gets the position for spawning based on current position of player. + /// + public static void GetPositionForSpawning(out Vector3 pos, out Quaternion rot) { + + pos = Vector3.zero; + rot = Quaternion.identity; + + //if (null == PlayerController.Instance) + // return; + + var cont = PlayerController.Instance; + + Vector3 spawnOffset = new Vector3 (0, 2, 5); + + pos = cont.transform.position + cont.transform.forward * spawnOffset.z + cont.transform.up * spawnOffset.y + + cont.transform.right * spawnOffset.x; + rot = Quaternion.LookRotation(-cont.transform.right, Vector3.up); + + } + + public static Vehicle Create(VehicleSpawner spawner) + { + //Debug.Log("-111"); + return Create(spawner.Info.CarId, spawner.Info.Colors, spawner.transform.position, + spawner.transform.rotation); + } + + public static Vehicle Create(int carId, Vector3 position, Quaternion rotation) + { + return Create (carId, null, position, rotation); + } + + public static Vehicle CreateInFrontOfPlayer(int carId) { + + Vector3 pos; + Quaternion rot; + + GetPositionForSpawning (out pos, out rot); + + return Create (carId, pos, rot); + } + + public static Vehicle Create(int carId, int[] colors, Vector3 position, Quaternion rotation) + { + //Debug.Log("-000"); + var inst = new GameObject().AddComponent(); + + VehicleDef def; + if (carId == -1) + { + def = GetRandomDef(); + } + else + { + def = Item.GetDefinition(carId); + } + + inst.Initialize(def, colors); + + inst.transform.position = position - Vector3.up * inst.AverageWheelHeight; + inst.transform.localRotation = rotation; + +#if CLIENT + if (Networking.Server.Instance != null) + { + Networking.Server.Instance.GlobalGroup.Add(inst); + } +#endif + + OutOfRangeDestroyer destroyer = inst.gameObject.AddComponent(); + destroyer.timeUntilDestroyed = 5; + destroyer.range = 300; + + return inst; + } + + private Geometry.GeometryParts _geometryParts; + + public class Wheel + { + public WheelAlignment Alignment { get; set; } + + public bool IsLeftHand + { + get { return (Alignment & WheelAlignment.Left) == WheelAlignment.Left; } + } + + public bool IsRightHand + { + get { return (Alignment & WheelAlignment.Right) == WheelAlignment.Right; } + } + + public bool IsFront + { + get { return (Alignment & WheelAlignment.Front) == WheelAlignment.Front; } + } + + public bool IsMid + { + get { return (Alignment & WheelAlignment.Mid) == WheelAlignment.Mid; } + } + + public bool IsRear + { + get { return (Alignment & WheelAlignment.Rear) == WheelAlignment.Rear; } + } + + public Transform Parent { get; set; } + public Transform Child { get; set; } + public WheelCollider Collider { get; set; } + public Wheel Complement { get; set; } + + public float Travel { get; private set; } + + public void UpdateTravel() + { + Travel = 1f; + + WheelHit hit; + if (Collider.GetGroundHit(out hit)) + { + Travel = (-Parent.transform.InverseTransformPoint(hit.point).y - Collider.radius) / Collider.suspensionDistance; + } + } + + public Quaternion Roll { get; set; } + } + + public class Seat + { + public SeatAlignment Alignment { get; set; } + + public Transform Parent { get; set; } + + /// Ped that is occupying this seat. + public Ped OccupyingPed { get; internal set; } + + public bool IsTaken { get { return this.OccupyingPed != null; } } + + public bool IsLeftHand + { + get { return (Alignment & SeatAlignment.Left) == SeatAlignment.Left; } + } + + public bool IsRightHand + { + get { return (Alignment & SeatAlignment.Right) == SeatAlignment.Right; } + } + + public bool IsFront + { + get { return (Alignment & SeatAlignment.Front) == SeatAlignment.Front; } + } + + public bool IsBack + { + get { return (Alignment & SeatAlignment.Back) == SeatAlignment.Back; } + } + + public bool IsDriver + { + get { return Alignment == SeatAlignment.FrontLeft; } + } + } + + private FrameContainer _frames; + + private readonly List _wheels = new List(); + private readonly List _seats = new List(); + + public List Wheels { get { return _wheels; } } + public List Seats { get { return _seats; } } + + private WheelAlignment GetWheelAlignment(string frameName) + { + switch (frameName) + { + case "wheel_rf_dummy": + return WheelAlignment.RightFront; + + case "wheel_lf_dummy": + return WheelAlignment.LeftFront; + + case "wheel_rm_dummy": + return WheelAlignment.RightMid; + + case "wheel_lm_dummy": + return WheelAlignment.LeftMid; + + case "wheel_rb_dummy": + return WheelAlignment.RightRear; + + case "wheel_lb_dummy": + return WheelAlignment.LeftRear; + + default: + return WheelAlignment.None; + } + } + + private DoorAlignment GetDoorAlignment(string frameName) + { + switch (frameName) + { + case "door_rf_dummy": + return DoorAlignment.RightFront; + + case "door_lf_dummy": + return DoorAlignment.LeftFront; + + case "door_rr_dummy": + return DoorAlignment.RightRear; + + case "door_lr_dummy": + return DoorAlignment.LeftRear; + + default: + return DoorAlignment.None; + } + } + + public Transform GetPart(string name) + { + var frame = _frames.GetByName(name); + return frame != null ? frame.transform : null; + } + + private void AttachSeat(Transform parent, SeatAlignment alignment) + { + _seats.Add(new Seat { Parent = parent, Alignment = alignment }); + } + + private void Initialize(VehicleDef def, int[] colors = null) + { + Definition = def; + + if (colors != null && colors[0] != -1) + { + SetColors(colors); + } + else + { + var defaultClrs = CarColors.GetCarDefaults(Definition.ModelName); + + if (defaultClrs != null) + { + SetColors(defaultClrs[UnityEngine.Random.Range(0, defaultClrs.Count)]); + } + else + { + Debug.LogWarningFormat("No colours defined for {0}!", def.GameName); + } + } + + name = Definition.GameName; + + _geometryParts = Geometry.Load(Definition.ModelName, + TextureDictionary.Load(Definition.TextureDictionaryName), + TextureDictionary.Load("vehicle"), + TextureDictionary.Load("misc")); + + _frames = _geometryParts.AttachFrames(transform, MaterialFlags.Vehicle); + + var wheelFrame = _frames.FirstOrDefault(x => x.Name == "wheel"); + + if (wheelFrame == null) + { + Debug.LogWarningFormat("No wheels defined for {0}!", def.GameName); + Destroy(gameObject); + return; + } + + foreach (var frame in _frames) + { + if (!frame.Name.StartsWith("wheel_")) continue; + if (!frame.Name.EndsWith("_dummy")) continue; + + var childFrames = _frames.Where(x => x.ParentIndex == frame.Index); + + // disable all children of wheel dummies + foreach (var childFrame in childFrames) + { + childFrame.gameObject.SetActive(false); + } + + var wheelAlignment = GetWheelAlignment(frame.Name); + + Wheel inst; + + // see if this wheel dummy has a wheel child + var wheel = childFrames.FirstOrDefault(x => x.Name == "wheel"); + + if (wheel == null) + { + var copy = Instantiate(wheelFrame.transform); + copy.SetParent(frame.transform, false); + + _wheels.Add(inst = new Wheel + { + Alignment = wheelAlignment, + Parent = frame.transform, + Child = copy, + }); + } + else + { + // all children of wheel dummies get set to inactive so activate this one + wheel.gameObject.SetActive(true); + + _wheels.Add(inst = new Wheel + { + Alignment = wheelAlignment, + Parent = frame.transform, + Child = wheel.transform, + }); + } + + if (inst.IsLeftHand) + { + frame.transform.Rotate(Vector3.up, 180.0f); + } + + inst.Complement = _wheels.FirstOrDefault(x => + (x.Alignment & WheelAlignment.LeftRightMask) != (inst.Alignment & WheelAlignment.LeftRightMask) && + (x.Alignment & WheelAlignment.FrontMidRearMask) == (inst.Alignment & WheelAlignment.FrontMidRearMask)); + + if (inst.Complement != null) + { + inst.Complement.Complement = inst; + } + } + + InitializePhysics(); + + foreach (var pair in _frames.Where(x => x.Name.StartsWith("door_"))) + { + var doorAlignment = GetDoorAlignment(pair.Name); + + if (doorAlignment == DoorAlignment.None) continue; + + var hinge = pair.gameObject.AddComponent(); + hinge.axis = Vector3.up; + hinge.useLimits = true; + + var limit = 90.0f * ((doorAlignment == DoorAlignment.LeftFront || doorAlignment == DoorAlignment.LeftRear) ? 1.0f : -1.0f); + hinge.limits = new JointLimits { min = Mathf.Min(0, limit), max = Mathf.Max(0, limit), }; + hinge.connectedBody = gameObject.GetComponent(); + } + + var frontSeat = GetPart("ped_frontseat"); + var backSeat = GetPart("ped_backseat"); + + if (frontSeat != null) + { + var frontSeatMirror = new GameObject("ped_frontseat").transform; + frontSeatMirror.SetParent(frontSeat.parent, false); + frontSeatMirror.localPosition = Vector3.Scale(frontSeat.localPosition, new Vector3(-1f, 1f, 1f)); + + if (frontSeat.localPosition.x > 0f) + { + AttachSeat(frontSeat, SeatAlignment.FrontRight); + AttachSeat(frontSeatMirror, SeatAlignment.FrontLeft); + } + else + { + AttachSeat(frontSeatMirror, SeatAlignment.FrontRight); + AttachSeat(frontSeat, SeatAlignment.FrontLeft); + } + + DriverTransform = GetSeat(SeatAlignment.FrontLeft).Parent; + } + + if (backSeat != null) + { + var backSeatMirror = new GameObject("ped_backseat").transform; + backSeatMirror.SetParent(backSeat.parent, false); + backSeatMirror.localPosition = Vector3.Scale(backSeat.localPosition, new Vector3(-1f, 1f, 1f)); + + if (backSeat.localPosition.x > 0f) + { + AttachSeat(backSeat, SeatAlignment.BackRight); + AttachSeat(backSeatMirror, SeatAlignment.BackLeft); + } + else + { + AttachSeat(backSeatMirror, SeatAlignment.BackRight); + AttachSeat(backSeat, SeatAlignment.BackLeft); + } + } + + // Add vehicle damage + + //GameObject carObject = GameObject.Find(Definition.GameName.ToLower()); + + //Debug.Log(gameObject.name); + + var dam = gameObject.AddComponent(); + dam.damageParts = new Transform[] { transform.GetChild(0).Find("engine") }; + dam.deformMeshes = gameObject.GetComponentsInChildren(); + dam.displaceParts = gameObject.GetComponentsInChildren().Where(x => x.GetComponent() != null || x.GetComponent() != null).ToArray(); + dam.damageFactor = VehicleAPI.constDamageFactor; + dam.collisionIgnoreHeight = -.4f; + dam.collisionTimeGap = .1f; + + //OptimizeVehicle(); + + dam.deformColliders = gameObject.GetComponentsInChildren(); + + gameObject.SetLayerRecursive(Layer); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/Vehicles/Vehicle_Spawning.cs.meta b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Spawning.cs.meta new file mode 100644 index 00000000..d395a5d1 --- /dev/null +++ b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Spawning.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7ccccfc8cfd50004db931795c8570de9 +timeCreated: 1428261642 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapon.cs b/Assets/Scripts/Behaviours/Weapon.cs new file mode 100644 index 00000000..be9c5f44 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapon.cs @@ -0,0 +1,670 @@ +using SanAndreasUnity.Importing.Conversion; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; +using SanAndreasUnity.Importing.Weapons; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours.Weapons; +using UnityEngine; +using System.Linq; +using System.Collections.Generic; +using SanAndreasUnity.Importing.Animation; +using System.Reflection; + +namespace SanAndreasUnity.Behaviours +{ + public static class WeaponSlot + { + public static readonly int Hand = 0, + Melee = 1, + Pistol = 2, + Shotgun = 3, + Submachine = 4, // uzi, mp5, tec9 + Machine = 5, // ak47, m4 + Rifle = 6, + Heavy = 7, // rocket launcher, flame thrower, minigun + SatchelCharge = 8, + Misc = 9, // spraycan, extinguisher, camera + Misc2 = 10, // dildo, vibe, flowers, cane + Special = 11, // parachute, goggles + Detonator = 12, + + Count = 13; + } + + public static class WeaponId + { + + public static readonly int Pistol = 346; + public static readonly int PistolSilenced = 347; + public static readonly int DesertEagle = 348; + + public static readonly int Shotgun = 349; + public static readonly int SawnOff = 350; + public static readonly int SPAS12 = 351; + + public static readonly int MicroUzi = 352; + public static readonly int Tec9 = 372; + public static readonly int MP5 = 353; + + public static readonly int AK47 = 355; + public static readonly int M4 = 356; + + public static readonly int CountryRifle = 357; + public static readonly int SniperRifle = 358; + + public static readonly int RocketLauncher = 359; + public static readonly int RocketLauncherHS = 360; + public static readonly int FlameThrower = 361; + public static readonly int MiniGun = 362; + + } + +// public class WeaponData +// { +// public string type = ""; +// public string fireType = ""; +// public float targetRange = 0; +// public float weaponRange = 0; +// public int modelId = -1; +// public int slot = -1; +// public AnimGroup animGroup = AnimGroup.None; +// public int clipCapacity = 0; +// public int damage = 0; +// } + + public class Weapon : MonoBehaviour + { + private WeaponDef definition = null; + public WeaponDef Definition { get { return this.definition; } } + + private WeaponData data = null; + public WeaponData Data { get { return this.data; } } + + private WeaponData.GunAimingOffset gunAimingOffset; + public WeaponData.GunAimingOffset GunAimingOffset { get { return this.gunAimingOffset; } } + + public int SlotIndex { get { return this.Data.weaponslot; } } + + public bool IsGun { get { return this.data.gunData != null; } } + + public int AmmoClipSize { get { return this.data.gunData != null ? this.data.gunData.ammoClip : 0 ; } } + public int AmmoInClip { get; set; } + public int AmmoOutsideOfClip { get; set; } + public int TotalAmmo { get { return this.AmmoInClip + this.AmmoOutsideOfClip; } } + + public Texture2D HudTexture { get; private set; } + + protected Ped m_ped { get; private set; } + public Ped PedOwner { get { return m_ped; } internal set { m_ped = value; } } + + + private static List s_weaponTypes = new List (); + + protected WeaponsManager WeaponsSettings { get { return WeaponsManager.Instance; } } + + private static GameObject s_weaponsContainer = null; + + public static Texture2D CrosshairTexture { get; set; } + public static Texture2D FistTexture { get; set; } + + public AnimationState AimAnimState { get; set; } + private float m_aimAnimTimeForAimWithArmWeapon = 0f; + //public bool IsInsideFireAnim { get { return this.AimAnimState != null && this.AimAnimState.enabled && this.AimAnimState.time > this.AimAnimMaxTime; } } + public Transform GunFlash { get; private set; } + + + // weapon sounds are located in SFX -> GENRL -> BANK 137 + // these indexes represent indexes of sounds in that bank + public static Dictionary weaponSoundIndexes = new Dictionary() { + {WeaponId.Pistol, 6}, // not correct + {WeaponId.PistolSilenced, 24}, + {WeaponId.DesertEagle, 6}, + {WeaponId.Shotgun, 21}, + {WeaponId.SawnOff, 21}, + {WeaponId.SPAS12, 22}, + {WeaponId.Tec9, 1}, + {WeaponId.MicroUzi, 0}, + {WeaponId.MP5, 18}, + {WeaponId.AK47, 4}, + {WeaponId.M4, 3}, + {WeaponId.CountryRifle, 26}, + {WeaponId.SniperRifle, 26}, + {WeaponId.MiniGun, 11}, + // {WeaponId.RocketLauncher, 68}, + // {WeaponId.RocketLauncherHS, 68}, + }; + + // used to play weapon sound + AudioSource m_audioSource; + + + + static Weapon () + { + // obtain all weapon types + var myType = typeof (Weapon); + foreach (Assembly a in System.AppDomain.CurrentDomain.GetAssemblies()) + { + s_weaponTypes.AddRange (a.GetTypes ().Where (t => t.IsSubclassOf (myType))); + } + + } + + + public static Weapon Load (int modelId) + { + WeaponDef def = Item.GetDefinition (modelId); + if (null == def) + return null; + + WeaponData weaponData = WeaponData.LoadedWeaponsData.FirstOrDefault (wd => wd.modelId1 == def.Id); + if (null == weaponData) + return null; + + var geoms = Geometry.Load (def.ModelName, def.TextureDictionaryName); + if (null == geoms) + return null; + + if (null == s_weaponsContainer) { + s_weaponsContainer = new GameObject ("Weapons"); + // weaponsContainer.SetActive (false); + } + + GameObject go = new GameObject (def.ModelName); + go.transform.SetParent (s_weaponsContainer.transform); + + geoms.AttachFrames (go.transform, MaterialFlags.Default); + + Weapon weapon = AddWeaponComponent (go, weaponData); + weapon.definition = def; + weapon.data = weaponData; + // cache gun aiming offset + if (weapon.data.gunData != null) + weapon.gunAimingOffset = weapon.data.gunData.aimingOffset; + + // load hud texture + try { + weapon.HudTexture = TextureDictionary.Load( def.TextureDictionaryName ).GetDiffuse( def.TextureDictionaryName + "icon" ).Texture; + } catch { + Debug.LogErrorFormat ("Failed to load hud icon for weapon: model {0}, txd {1}", def.ModelName, def.TextureDictionaryName); + } + + // weapon sound + F.RunExceptionSafe (() => { + if (weaponSoundIndexes.ContainsKey (modelId)) + { + var audioSource = go.GetOrAddComponent (); + audioSource.playOnAwake = false; + Debug.LogFormat("loading weapon sound, bank index {0}", weaponSoundIndexes [modelId] ); + var audioClip = Audio.AudioManager.CreateAudioClipFromSfx ("GENRL", 136, 0, + Audio.AudioManager.SfxGENRL137Timings[ weaponSoundIndexes [modelId] ] ); + audioSource.clip = audioClip; + weapon.m_audioSource = audioSource; + } + }); + + weapon.InitWeapon(); + + return weapon; + } + + private static Weapon AddWeaponComponent (GameObject go, WeaponData data) + { + // find type which inherits Weapon class, and whose name matches the one in data + + string typeName = data.weaponType.Replace ("_", ""); + + var type = s_weaponTypes.Where (t => 0 == string.Compare (t.Name, typeName, true)).FirstOrDefault (); + + if (type != null) { + return (Weapon)go.AddComponent (type); + } else { + return go.AddComponent (); + } + + } + + + public bool HasFlag( GunFlag gunFlag ) { + + if (this.data != null && this.data.gunData != null) + return this.data.gunData.HasFlag (gunFlag); + + return false; + } + + public static string ExtractAnimGroupName(string assocGroupId) + { + if( assocGroupId.EndsWith( "bad" ) ) + return assocGroupId.Substring( 0, assocGroupId.Length - 3 ); + if( assocGroupId.EndsWith( "pro" ) ) + return assocGroupId.Substring( 0, assocGroupId.Length - 3 ); + + return assocGroupId; + } + + + protected virtual void Awake () + { + this.GunFlash = this.transform.FindChildRecursive("gunflash"); + } + + /// + /// Called after creating a weapon and assigning it's parameters, such are WeaponData and HUD texture. + /// Use this method to assign aim animations and timings, or initialize anything else related to weapon. + /// + protected virtual void InitWeapon() + { + // set default weapon anims and other params + + string animGroup = ExtractAnimGroupName( this.Data.gunData.AssocGroupId ); + + this.CanCrouchAim = this.HasFlag( GunFlag.CROUCHFIRE ); + + if( this.HasFlag( GunFlag.CROUCHFIRE ) ) + this.CrouchAimAnim = new AnimId( animGroup, animGroup + "_crouchfire" ); + else + this.CrouchAimAnim = new AnimId( "RIFLE", "RIFLE_crouchfire" ); + + this.CrouchAimAnimMaxTime = WeaponsManager.ConvertAnimTime (this.Data.gunData.animLoop2Start); + this.CrouchAimAnimFireMaxTime = WeaponsManager.ConvertAnimTime (this.Data.gunData.animLoop2End); + + this.CrouchSpineRotationOffset = WeaponsSettings.crouchSpineRotationOffset; + + } + + protected virtual void Start () + { + + } + + protected virtual void Update () + { + + if (WeaponsSettings.drawLineFromGun) + { + Vector3 start, end; + this.GetLineFromGun (out start, out end); + GLDebug.DrawLine (start, end, Color.red, 0, true); + } + + } + + + public virtual bool CanSprintWithIt { + get { + if (this.HasFlag (GunFlag.AIMWITHARM)) + return true; + + if (this.SlotIndex == WeaponSlot.Heavy || this.SlotIndex == WeaponSlot.Machine || this.SlotIndex == WeaponSlot.Rifle + || this.SlotIndex == WeaponSlot.Shotgun) + return false; + + return true; + } + } + + public bool IsHeavy { get { return this.HasFlag (GunFlag.HEAVY); } } + + public bool CanCrouchAim { get; set; } + + public virtual bool CanTurnInDirectionOtherThanAiming { + get { + if (this.HasFlag (GunFlag.AIMWITHARM)) + return true; + return false; + } + } + + public virtual AnimId IdleAnim { + get { + if (this.HasFlag (GunFlag.AIMWITHARM)) { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Idle); + } else { + return new AnimId (AnimGroup.MyWalkCycle, AnimIndex.IdleArmed); + } + } + } + + public virtual AnimId WalkAnim { + get { + if (this.HasFlag (GunFlag.AIMWITHARM)) { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Walk); + } else { + return new AnimId (AnimGroup.Gun, AnimIndex.WALK_armed); + } + } + } + + public virtual AnimId RunAnim { + get { + if (this.HasFlag (GunFlag.AIMWITHARM)) { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Run); + } else { + return new AnimId (AnimGroup.Gun, AnimIndex.run_armed); + } + } + } + + public virtual AnimId GetAnimBasedOnMovement (bool canSprint) + { + Ped ped = m_ped; + + if (ped.IsRunOn) { + + return this.RunAnim; + + } else if (ped.IsWalkOn) { + + return this.WalkAnim; + + } else if (ped.IsSprintOn) { + + if (canSprint) { + return new AnimId (AnimGroup.MyWalkCycle, AnimIndex.sprint_civi); + } else { + return this.IdleAnim; + } + + } else { + // player is standing + + return this.IdleAnim; + } + + } + + public virtual AnimId AimAnim { + get { + return new AnimId (AnimGroup.Rifle, AnimIndex.RIFLE_fire); + } + } + + public virtual AnimId AimAnimLowerPart + { + get + { + return new AnimId(AnimGroup.MyWalkCycle, AnimIndex.GUN_STAND); + } + } + + public AnimId CrouchAimAnim { get; set; } + + public virtual float AimAnimMaxTime { + get { + return Weapons.WeaponsManager.ConvertAnimTime (this.data.gunData.animLoopStart); + } + } + + public virtual float AimAnimFireMaxTime { + get { + return Weapons.WeaponsManager.ConvertAnimTime (this.data.gunData.animLoopEnd); + } + } + + public float CrouchAimAnimMaxTime { get; set; } + + public float CrouchAimAnimFireMaxTime { get; set; } + + public virtual float GunFlashDuration { + get { + return Weapons.WeaponsManager.Instance.GunFlashDuration; + } + } + + public Vector3 CrouchSpineRotationOffset { get; set; } + + + public bool IsAimingBack () { + + if (null == m_ped) + return false; + + if (!this.HasFlag (GunFlag.AIMWITHARM)) + return false; + + if (!m_ped.IsAiming) + return false; + + Vector3 aimDirLocal = m_ped.transform.InverseTransformDirection (m_ped.AimDirection); + + float oppositeSideAngle = Vector3.Angle( Vector3.forward, aimDirLocal.WithXAndZ () ); + return oppositeSideAngle > WeaponsSettings.AIMWITHARM_maxAimAngle; + } + + // TODO: this function should be removed, and new one should be created: OnAnimsUpdated + public virtual void UpdateAnimWhileHolding () + { + Ped ped = m_ped; + ped.PlayerModel.PlayAnim (this.GetAnimBasedOnMovement (this.CanSprintWithIt)); + } + + public virtual void EnableOrDisableGunFlash () + { + Ped ped = m_ped; + + // enable/disable gun flash + if (this.GunFlash != null) { + + bool shouldBeVisible = false; + +// if (this.HasFlag (GunFlag.AIMWITHARM)) { +// shouldBeVisible = m_aimAnimTimeForAimWithArmWeapon.BetweenExclusive (this.AimAnimMaxTime, this.AimAnimMaxTime + this.GunFlashDuration); +// } +// else + { + + if (AimAnimState != null && AimAnimState.enabled) { + // aim anim is being played + + if (AimAnimState.time.BetweenExclusive (this.AimAnimMaxTime, this.AimAnimMaxTime + this.GunFlashDuration)) { + // muzzle flash should be visible + shouldBeVisible = true; + } + } + } + + shouldBeVisible &= ped.IsFiring; + + this.GunFlash.gameObject.SetActive (shouldBeVisible); + } + + } + + public virtual void UpdateGunFlashRotation () + { + + if (null == this.GunFlash) + return; + + if (!this.GunFlash.gameObject.activeInHierarchy) + return; + + float randomFactor = Random.Range (0.75f, 1.25f); + float delta = WeaponsManager.Instance.GunFlashRotationSpeed * Time.deltaTime * randomFactor; + + this.GunFlash.rotation *= Quaternion.AngleAxis (delta, Vector3.right); + + } + + + #region Firing + + public float MaxRange { get { return this.Data.weaponRange; } } + + public float Damage { get { return this.Data.gunData.damage; } } + + public virtual void PlayFireSound () + { + + if (m_audioSource && m_audioSource.clip) + { + if(!m_audioSource.isPlaying) + { +// int bankIndex = weaponSoundIndexes [this.Definition.Id]; + +// Audio.AudioManager.SfxGENRL137Timings [bankIndex]; + +// int startTimeMs = 0; +// int endTimeMs = 0; +// +// float startTime = startTimeMs / 1000f; +// float endTime = endTimeMs / 1000f; + +// Debug.LogFormat("playing weapon sound, start time {0}, end time {1}, bank index {2}", startTime, endTime, bankIndex); + +// m_audioSource.Stop(); +// m_audioSource.time = startTime; +// m_audioSource.Play(); +// m_audioSource.SetScheduledEndTime( AudioSettings.dspTime + (endTime - startTime) ); + + // Debug.LogFormat("playing weapon sound"); + m_audioSource.Stop(); + m_audioSource.time = 0f; + m_audioSource.Play(); + + } + } + + } + + public virtual void FireProjectile () + { + // obtain fire position and direction + + Vector3 firePos = this.GetFirePos (); + Vector3 fireDir = this.GetFireDir (); + + // raycast against all (non-breakable ?) objects + + RaycastHit hit; + if (this.ProjectileRaycast (firePos, fireDir, out hit)) + { + // if target object has damageable script, inflict damage to it + + var damageable = hit.transform.GetComponent (); + if (damageable) + { + // ray hit something that can be damaged + // damage it + damageable.Damage( new DamageInfo() { amount = this.Damage } ); + } + } + + } + + public bool ProjectileRaycast (Vector3 source, Vector3 dir, out RaycastHit hit) + { + return Physics.Raycast (source, dir, out hit, this.MaxRange, WeaponsManager.Instance.projectileRaycastMask); + } + + public void GetLineFromGun (out Vector3 start, out Vector3 end) + { + float distance = this.MaxRange; + Vector3 firePos = this.GetFirePos (); + Vector3 fireDir = this.GetFireDir (); + RaycastHit hit; + if (this.ProjectileRaycast (firePos, fireDir, out hit)) + { + distance = hit.distance; + } + + start = firePos; + end = firePos + fireDir * distance; + } + + public virtual Vector3 GetFirePos () + { + Vector3 firePos; + + if (this.GunFlash != null) + firePos = this.GunFlash.transform.position; + else + firePos = this.transform.TransformPoint (this.Data.gunData.fireOffset); + + return firePos; + } + + public virtual Vector3 GetFireDir () + { + + if (m_ped) + { + if (this.IsAimingBack ()) + return m_ped.transform.up; + + if (m_ped.IsLocalPlayer && m_ped.Camera != null) + { + // find ray going into the world + Ray ray = m_ped.Camera.GetRayFromCenter (); + + // raycast + RaycastHit hit; + if (this.ProjectileRaycast (ray.origin, ray.direction, out hit)) + { + return (hit.point - this.GetFirePos ()).normalized; + } + + // if any object is hit, direction will be from fire position to hit point + + // if not, direction will be same as aim direction + + } + + return m_ped.WeaponHolder.AimDirection; + } + else if (this.GunFlash) + return this.GunFlash.transform.right; + else + return this.transform.right; + } + + #endregion + + + public virtual void OnDrawGizmosSelected () + { + // draw rays from gun + + + Vector3 firePos = this.GetFirePos (); + + // ray based on transform + Gizmos.color = Color.yellow; + GizmosDrawCastedRay (firePos, this.transform.right); + + // ray based on gun flash transform + if (this.GunFlash != null) + { + Gizmos.color = F.OrangeColor; + GizmosDrawCastedRay (firePos, this.GunFlash.transform.right); + } + + // ray based on aiming direction + if (m_ped != null) + { + Gizmos.color = Color.red; + GizmosDrawCastedRay (firePos, m_ped.WeaponHolder.AimDirection); + } + + // ray based on firing direction + Gizmos.color = Color.black; + GizmosDrawCastedRay (firePos, this.GetFireDir ()); + + } + + public void GizmosDrawCastedRay (Vector3 source, Vector3 dir) + { + float distance = 100f; + RaycastHit hit; + if (this.ProjectileRaycast (source, dir, out hit)) + { + distance = hit.distance; + } + + Gizmos.DrawLine (source, source + dir * distance); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapon.cs.meta b/Assets/Scripts/Behaviours/Weapon.cs.meta new file mode 100644 index 00000000..bdcb39f0 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapon.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 78a7a7807c3ab1a4b9d7df4a57e9e60a +timeCreated: 1474314287 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/WeaponHolder.cs b/Assets/Scripts/Behaviours/WeaponHolder.cs new file mode 100644 index 00000000..68c8d2f3 --- /dev/null +++ b/Assets/Scripts/Behaviours/WeaponHolder.cs @@ -0,0 +1,407 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Importing.Animation; +using SanAndreasUnity.Importing.Weapons; +using System.Linq; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.Behaviours { + + [DefaultExecutionOrder(-70)] + public class WeaponHolder : MonoBehaviour { + + private Ped m_ped; + public PedModel PlayerModel { get { return m_ped.PlayerModel; } } + public Camera Camera { get { return m_ped.Camera; } } + + private Weapon[] weapons = new Weapon[(int)WeaponSlot.Count]; + public Weapon[] AllWeapons { get { return this.weapons.Where (w => w != null).ToArray (); } } + + private int currentWeaponSlot = -1; + public int CurrentWeaponSlot { get { return this.currentWeaponSlot; } } + public bool IsHoldingWeapon { get { return this.currentWeaponSlot > 0; } } + + public bool autoAddWeapon = false; + + + #region Aiming + + // public bool IsAimOn { get; set; } + // private bool m_isAiming = false; + public bool IsAiming { + get { return m_ped.CurrentState != null && m_ped.CurrentState is Peds.States.IAimState; } +// private set { +// if (value == m_isAiming) +// return; +// if (value) { +// m_timeWhenStartedAiming = Time.time; +// m_frameWhenStartedAiming = Time.frameCount; +// } +// m_isAiming = value; +// } + } + // private float m_timeWhenStartedAiming = 0f; + // public float TimeSinceStartedAiming { get { return Time.time - m_timeWhenStartedAiming; } } + // private int m_frameWhenStartedAiming = 0; + // public int NumFramesSinceStartedAiming { get { return Time.frameCount - m_frameWhenStartedAiming; } } + + public Vector3 AimDirection { + get { + if (this.IsAiming && this.Camera != null) + return this.Camera.transform.forward; + else + return this.transform.forward; + } + } + + //[SerializeField] [Range(0,1)] private float m_aimWithRifleMinAnimTime = 0.0f; + //public float AimWithRifleMinAnimTime { get { return m_aimWithRifleMinAnimTime; } set { m_aimWithRifleMinAnimTime = value; } } + + [SerializeField] [Range(0,4)] private float m_aimWithRifleMaxAnimTime = 0.7f; + public float AimWithRifleMaxAnimTime { get { return m_aimWithRifleMaxAnimTime; } set { m_aimWithRifleMaxAnimTime = value; } } + + // [SerializeField] [Range(0,1)] private float m_aimWithArmMaxAnimTime = 1.0f; + + public Vector3 cameraAimOffset = new Vector3 (0.7f, 0.2f, -1); + + #endregion + + #region Firing + + public bool IsFiring { + get { return m_ped.CurrentState != null && m_ped.CurrentState is Peds.States.IFireState; } + } + // public bool IsFireOn { get; set; } + // public float TimeWhenStartedFiring { get; private set; } + // public float TimeSinceStartedFiring { get { return Time.time - this.TimeWhenStartedFiring; } } + + #endregion + + + public Weapon CurrentWeapon { get ; private set ; } + private Transform CurrentWeaponTransform { get { return CurrentWeapon != null ? CurrentWeapon.transform : null; } } + + private int m_frameWhenSwitchedWeapon = 0; + public int NumFramesSinceSwitchedWeapon { get { return Time.frameCount - m_frameWhenSwitchedWeapon; } } + + + public Vector3 SpineOffset; + + public enum WeaponAttachType + { + None, + RightHand, + BothFingers + } + + public WeaponAttachType weaponAttachType = WeaponAttachType.RightHand; + + + public bool rotatePlayerInDirectionOfAiming = true; + + + + void Awake () { + + m_ped = this.GetComponent (); + + } + + void Start () + { + PlayerModel.onLateUpdate += this.UpdateWeaponTransform; + } + + void OnLoaderFinished () + { + if (this.autoAddWeapon) + { + this.AddRandomWeapons (); + + if (!this.IsHoldingWeapon) + { + this.SwitchWeapon (WeaponSlot.Pistol); + } + } + } + + void Update () { + + if (!Loader.HasLoaded) + return; + + + //this.UpdateWeaponTransform (); + + if (CurrentWeapon != null) { + CurrentWeapon.EnableOrDisableGunFlash (); + CurrentWeapon.UpdateGunFlashRotation (); + } + + // reload weapon ammo clip + if (CurrentWeapon != null) { + if (CurrentWeapon.AmmoClipSize > 0 && CurrentWeapon.AmmoInClip <= 0) { + int amountToRefill = Mathf.Min (CurrentWeapon.AmmoClipSize, CurrentWeapon.AmmoOutsideOfClip); + CurrentWeapon.AmmoInClip = amountToRefill; + CurrentWeapon.AmmoOutsideOfClip -= amountToRefill; + } + } + + } + + void LateUpdate_jdghrjgjr() + { + // all things that manipulate skeleton must be placed in LateUpdate(), because otherwise Animator will + // override them + + // order of these functions is important + + + UpdateAnims (); + + // RotatePlayerInDirectionOfAiming (); + + // this should be done AFTER the player has rotated in direction of aiming + RotateSpine (); + + // this should be done after all other skeleton changes + // idk why this boolean has to be checked - there are some race conditions with animations + // - if we don't check it, weapons will start shaking + // if (this.IsAiming) + UpdateWeaponTransform (); + + } + + + private void UpdateAnims () + { + + } + + private void RotateSpine () + { + + } + + public void UpdateWeaponTransform () + { + + // update transform of weapon + if (CurrentWeaponTransform != null) { + + if (this.weaponAttachType == WeaponAttachType.BothFingers) { + if (PlayerModel.RightFinger != null && PlayerModel.LeftFinger != null) { + + CurrentWeaponTransform.transform.position = PlayerModel.RightFinger.transform.position; + + Vector3 dir = (PlayerModel.LeftFinger.transform.position - PlayerModel.RightFinger.transform.position).normalized; + Quaternion q = Quaternion.LookRotation (dir, transform.up); + Vector3 upNow = q * Vector3.up; + dir = Quaternion.AngleAxis (-90, upNow) * dir; + CurrentWeaponTransform.transform.rotation = Quaternion.LookRotation (dir, transform.up); + } + } else if (this.weaponAttachType == WeaponAttachType.RightHand) { + if (PlayerModel.RightHand != null) { + + Vector3 weaponPos = PlayerModel.RightHand.position; + Transform rotationTr = PlayerModel.RightHand; + + // add aim offset + // var aimOffset = CurrentWeapon.GunAimingOffset; + // if (aimOffset != null) + // weaponPos += rotationTr.forward * aimOffset.aimZ + rotationTr.right * aimOffset.aimX; + + CurrentWeaponTransform.transform.position = weaponPos; + CurrentWeaponTransform.transform.rotation = rotationTr.rotation; + } + } + + } + + } + + public void RotatePlayerInDirectionOfAiming () + { + if (!this.IsAiming) + return; + + Peds.States.BaseAimMovementState.RotatePedInDirectionOfAiming (m_ped); + } + + + public void SwitchWeapon( bool next ) + { + + if (currentWeaponSlot < 0) + currentWeaponSlot = 0; + + int delta = next ? 1 : -1; + + for (int i = currentWeaponSlot + delta, count = 0; + i != currentWeaponSlot && count < weapons.Length; + i += delta, count++) { + + if (i < 0) + i = weapons.Length - 1; + if (i >= weapons.Length) + i = 0; + + if ( (int)WeaponSlot.Hand == i || weapons [i] != null ) { + // this is a hand slot or there is a weapon in this slot + // switch to it + SwitchWeapon (i); + break; + } + } + + } + + public void SwitchWeapon (int slotIndex) + { + if (slotIndex == currentWeaponSlot) + return; + + if (CurrentWeapon != null) { + // hide the weapon + HideWeapon( CurrentWeapon ); + } + + if (slotIndex >= 0) { + + CurrentWeapon = weapons [slotIndex]; + + // show the weapon + if (CurrentWeapon != null) + UnHideWeapon (CurrentWeapon); + + } else { + CurrentWeapon = null; + } + + currentWeaponSlot = slotIndex; + + m_frameWhenSwitchedWeapon = Time.frameCount; + + m_ped.StopFiring (); + + this.UpdateWeaponTransform (); + + } + + private static void HideWeapon (Weapon weapon) + { + weapon.gameObject.SetActive (false); + } + + private static void UnHideWeapon (Weapon weapon) + { + weapon.gameObject.SetActive (true); + } + + public void SetWeaponAtSlot (Importing.Items.Definitions.WeaponDef weaponDef, int slot) + { + this.SetWeaponAtSlot (weaponDef.Id, slot); + } + + public void SetWeaponAtSlot (int weaponId, int slotIndex) + { + + // destroy current weapon at this slot + if (weapons [slotIndex] != null) { + DestroyWeapon (weapons [slotIndex]); + } + + weapons [slotIndex] = Weapon.Load (weaponId); + + weapons [slotIndex].PedOwner = m_ped; + + if (slotIndex == currentWeaponSlot) { + // update current weapon variable + CurrentWeapon = weapons [slotIndex]; + + // update it's transform + this.UpdateWeaponTransform (); + } else { + // hide the newly created weapon + HideWeapon (weapons[slotIndex]); + } + + } + + public Weapon GetWeaponAtSlot (int slotIndex) + { + return this.weapons [slotIndex]; + } + + public void RemoveAllWeapons() { + + this.SwitchWeapon (-1); + + for (int i = 0; i < this.weapons.Length; i++) { + if (this.weapons [i] != null) + DestroyWeapon (this.weapons [i]); + this.weapons [i] = null; + } + + } + + private static void DestroyWeapon (Weapon w) + { + Destroy (w.gameObject); + w.PedOwner = null; + } + + + public void AddRandomWeapons () + { + + int[] slots = new int[] { WeaponSlot.Pistol, WeaponSlot.Shotgun, WeaponSlot.Submachine, + WeaponSlot.Machine, WeaponSlot.Rifle, WeaponSlot.Heavy + }; + + var groups = WeaponData.LoadedWeaponsData.Where( wd => slots.Contains( wd.weaponslot ) ) + .DistinctBy( wd => wd.weaponType ) + .GroupBy( wd => wd.weaponslot ); + + foreach (var grp in groups) { + + int count = grp.Count (); + if (count < 1) + continue; + + int index = Random.Range (0, count); + WeaponData chosenWeaponData = grp.ElementAt (index); + + this.SetWeaponAtSlot (chosenWeaponData.modelId1, grp.Key); + + // add some ammo + Weapon weapon = this.GetWeaponAtSlot( grp.Key ); + AddRandomAmmoAmountToWeapon (weapon); + } + + } + + public static void AddRandomAmmoAmountToWeapon (Weapon weapon) + { + weapon.AmmoInClip = weapon.AmmoClipSize; + weapon.AmmoOutsideOfClip += weapon.AmmoClipSize * Random.Range( 0, 11 ); + weapon.AmmoOutsideOfClip += Random.Range (50, 200); + } + + + void OnDrawGizmosSelected () + { + // draw gizmos for current weapon + + if (CurrentWeapon != null) { + CurrentWeapon.OnDrawGizmosSelected (); + } + + // draw line from camera + F.GizmosDrawLineFromCamera (); + + } + + } + +} diff --git a/Assets/Scripts/Behaviours/WeaponHolder.cs.meta b/Assets/Scripts/Behaviours/WeaponHolder.cs.meta new file mode 100644 index 00000000..8b84df74 --- /dev/null +++ b/Assets/Scripts/Behaviours/WeaponHolder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 104b2f17607c64562aea9bbcedc03368 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons.meta b/Assets/Scripts/Behaviours/Weapons.meta new file mode 100644 index 00000000..a77ed7c1 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0f89454c3f0de4edebf24bd2841d5fec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/CountryRifle.cs b/Assets/Scripts/Behaviours/Weapons/CountryRifle.cs new file mode 100644 index 00000000..f135ff12 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/CountryRifle.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class CountryRifle : Weapon + { + + protected override void InitWeapon () + { + base.InitWeapon(); + this.CrouchAimAnim = new AnimId("RIFLE", "RIFLE_crouchfire"); + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/CountryRifle.cs.meta b/Assets/Scripts/Behaviours/Weapons/CountryRifle.cs.meta new file mode 100644 index 00000000..e5b1e227 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/CountryRifle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a22f243f732d545a5a1a0bc9184e3b7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/DesertEagle.cs b/Assets/Scripts/Behaviours/Weapons/DesertEagle.cs new file mode 100644 index 00000000..003656d0 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/DesertEagle.cs @@ -0,0 +1,47 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class DesertEagle : Weapon + { + + + protected override void InitWeapon () + { + base.InitWeapon(); + this.CrouchSpineRotationOffset = WeaponsManager.Instance.crouchSpineRotationOffset2; + } + + public override AnimId IdleAnim { + get { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Idle); + } + } + + public override AnimId WalkAnim { + get { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Walk); + } + } + + public override AnimId RunAnim { + get { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Run); + } + } + + public override AnimId AimAnim { + get { + if (this.Data.gunData.AssocGroupId.EndsWith ("bad")) + return new AnimId (AnimGroup.Python, AnimIndex.python_fire_poor); + else + return new AnimId (AnimGroup.Python, AnimIndex.python_fire); + } + } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/DesertEagle.cs.meta b/Assets/Scripts/Behaviours/Weapons/DesertEagle.cs.meta new file mode 100644 index 00000000..bba53f14 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/DesertEagle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 428b7731ff67045a6859658dd2f5282c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/FThrower.cs b/Assets/Scripts/Behaviours/Weapons/FThrower.cs new file mode 100644 index 00000000..4961798e --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/FThrower.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class FThrower : Weapon + { + +// public override AnimId AimAnim { +// get { +// return new AnimId (AnimGroup.Flame, AnimIndex.FLAME_fire); +// } +// } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/FThrower.cs.meta b/Assets/Scripts/Behaviours/Weapons/FThrower.cs.meta new file mode 100644 index 00000000..135eefb0 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/FThrower.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f5d899d10d89435d8dc5949e7aa3d30 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/MP5.cs b/Assets/Scripts/Behaviours/Weapons/MP5.cs new file mode 100644 index 00000000..7e507da7 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/MP5.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class MP5 : Weapon + { + + public override AnimId AimAnim { + get { + return new AnimId (AnimGroup.Uzi, AnimIndex.UZI_fire); + } + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/MP5.cs.meta b/Assets/Scripts/Behaviours/Weapons/MP5.cs.meta new file mode 100644 index 00000000..31f90e06 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/MP5.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff4cec32be31b4643b77c6da93c4c44b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/MicroUzi.cs b/Assets/Scripts/Behaviours/Weapons/MicroUzi.cs new file mode 100644 index 00000000..2f152fde --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/MicroUzi.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class MicroUzi : Weapon + { + + protected override void InitWeapon () + { + base.InitWeapon(); + this.CrouchSpineRotationOffset = WeaponsManager.Instance.crouchSpineRotationOffset2; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/MicroUzi.cs.meta b/Assets/Scripts/Behaviours/Weapons/MicroUzi.cs.meta new file mode 100644 index 00000000..34d8f43d --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/MicroUzi.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20eeb42c44c58482d9f1709bb0de2e35 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/Minigun.cs b/Assets/Scripts/Behaviours/Weapons/Minigun.cs new file mode 100644 index 00000000..c2c9baf3 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Minigun.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class Minigun : Weapon + { + +// public override AnimId AimAnim { +// get { +// return new AnimId (AnimGroup.Flame, AnimIndex.FLAME_fire); +// } +// } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/Minigun.cs.meta b/Assets/Scripts/Behaviours/Weapons/Minigun.cs.meta new file mode 100644 index 00000000..b15326ba --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Minigun.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90d2f69b3146e4eb1bb9742f05bfd40c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/Pistol.cs b/Assets/Scripts/Behaviours/Weapons/Pistol.cs new file mode 100644 index 00000000..ff857a79 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Pistol.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class Pistol : Weapon + { + + protected override void InitWeapon () + { + base.InitWeapon(); + this.CrouchSpineRotationOffset = WeaponsManager.Instance.crouchSpineRotationOffset2; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/Pistol.cs.meta b/Assets/Scripts/Behaviours/Weapons/Pistol.cs.meta new file mode 100644 index 00000000..f9b424a9 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Pistol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4836ea5872907439284943b514013872 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/PistolSilenced.cs b/Assets/Scripts/Behaviours/Weapons/PistolSilenced.cs new file mode 100644 index 00000000..7a7de17c --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/PistolSilenced.cs @@ -0,0 +1,43 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class PistolSilenced : Weapon + { + + protected override void InitWeapon () + { + base.InitWeapon(); + this.CrouchAimAnim = new AnimId("SILENCED", "SilenceCrouchfire"); + this.CrouchSpineRotationOffset = WeaponsManager.Instance.crouchSpineRotationOffset2; + } + + public override AnimId IdleAnim { + get { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Idle); + } + } + + public override AnimId WalkAnim { + get { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Walk); + } + } + + public override AnimId RunAnim { + get { + return new AnimId (AnimGroup.WalkCycle, AnimIndex.Run); + } + } + + public override AnimId AimAnim { + get { + return new AnimId (AnimGroup.Silenced, AnimIndex.Silence_fire); + } + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/PistolSilenced.cs.meta b/Assets/Scripts/Behaviours/Weapons/PistolSilenced.cs.meta new file mode 100644 index 00000000..05ea33da --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/PistolSilenced.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6710eaa87124d4091afd73b87426cb54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/RLauncher.cs b/Assets/Scripts/Behaviours/Weapons/RLauncher.cs new file mode 100644 index 00000000..da834c4d --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/RLauncher.cs @@ -0,0 +1,56 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class RLauncher : Weapon + { + + + public override AnimId IdleAnim { + get { + return new AnimId (AnimGroup.Rocket, AnimIndex.idle_rocket); + } + } + + public override AnimId WalkAnim { + get { + return new AnimId (AnimGroup.Rocket, AnimIndex.walk_rocket); + } + } + + public override AnimId RunAnim { + get { + return new AnimId (AnimGroup.Rocket, AnimIndex.run_rocket); + } + } + + public override AnimId AimAnim { + get { + return new AnimId (AnimGroup.Rocket, AnimIndex.RocketFire); + } + } + + public override void UpdateAnimWhileHolding () + { + Ped ped = m_ped; + + if (ped.IsSprintOn) { + // because anim reports incorrect velocity (it gives positive velocity, but it should give 0), + // we have to make some fixes + + ped.PlayerModel.PlayAnim (this.IdleAnim); + //state.normalizedTime = 0f; + //player.AnimComponent.Sample (); + //state.enabled = false; + ped.PlayerModel.RootFrame.LocalVelocity = Vector3.zero; + } else { + base.UpdateAnimWhileHolding (); + } + } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/RLauncher.cs.meta b/Assets/Scripts/Behaviours/Weapons/RLauncher.cs.meta new file mode 100644 index 00000000..09a125d8 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/RLauncher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d36bc0f0b5194348bdcc1fa9d839a02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/Sawnoff.cs b/Assets/Scripts/Behaviours/Weapons/Sawnoff.cs new file mode 100644 index 00000000..47af14ad --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Sawnoff.cs @@ -0,0 +1,19 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class Sawnoff : Weapon + { + + protected override void InitWeapon () + { + base.InitWeapon(); + this.CrouchAimAnim = new AnimId("COLT45", "colt45_crouchfire"); + this.CrouchSpineRotationOffset = WeaponsManager.Instance.crouchSpineRotationOffset2; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/Sawnoff.cs.meta b/Assets/Scripts/Behaviours/Weapons/Sawnoff.cs.meta new file mode 100644 index 00000000..a16e968c --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Sawnoff.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2336d9a13d447483a9551f0c3cd0a6aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/Shotgun.cs b/Assets/Scripts/Behaviours/Weapons/Shotgun.cs new file mode 100644 index 00000000..05c25f83 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Shotgun.cs @@ -0,0 +1,21 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class Shotgun : Weapon + { + + public override AnimId AimAnim { + get { + if (this.Data.gunData.AssocGroupId.EndsWith ("bad")) + return new AnimId (AnimGroup.Shotgun, AnimIndex.shotgun_fire_poor); + else + return new AnimId (AnimGroup.Shotgun, AnimIndex.shotgun_fire); + } + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/Shotgun.cs.meta b/Assets/Scripts/Behaviours/Weapons/Shotgun.cs.meta new file mode 100644 index 00000000..2e372bb9 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Shotgun.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f00414bab2372437ea7d9edfd130613e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/SniperRifle.cs b/Assets/Scripts/Behaviours/Weapons/SniperRifle.cs new file mode 100644 index 00000000..d596addb --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/SniperRifle.cs @@ -0,0 +1,19 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class SniperRifle : Weapon + { + + protected override void InitWeapon () + { + base.InitWeapon(); + this.CrouchAimAnim = new AnimId("RIFLE", "RIFLE_crouchfire"); + } + + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/SniperRifle.cs.meta b/Assets/Scripts/Behaviours/Weapons/SniperRifle.cs.meta new file mode 100644 index 00000000..e1c4d4ff --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/SniperRifle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0e1ab8d796c0470981900229ed11d3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/Spas12.cs b/Assets/Scripts/Behaviours/Weapons/Spas12.cs new file mode 100644 index 00000000..49c7037b --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Spas12.cs @@ -0,0 +1,19 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class Spas12 : Weapon + { + + + public override AnimId AimAnim { + get { + return new AnimId (AnimGroup.Buddy, AnimIndex.buddy_fire); + } + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/Spas12.cs.meta b/Assets/Scripts/Behaviours/Weapons/Spas12.cs.meta new file mode 100644 index 00000000..17420587 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Spas12.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 001cb737fc41e485c97f2b45b1fbc1cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/Tec9.cs b/Assets/Scripts/Behaviours/Weapons/Tec9.cs new file mode 100644 index 00000000..f5fcd21a --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Tec9.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using SanAndreasUnity.Importing.Animation; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class Tec9 : Weapon + { + + protected override void InitWeapon () + { + base.InitWeapon(); + this.CrouchSpineRotationOffset = WeaponsManager.Instance.crouchSpineRotationOffset2; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/Tec9.cs.meta b/Assets/Scripts/Behaviours/Weapons/Tec9.cs.meta new file mode 100644 index 00000000..305aeace --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/Tec9.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3023bb9fcaa1e4ad6ad7919585110f07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/Weapons/WeaponsManager.cs b/Assets/Scripts/Behaviours/Weapons/WeaponsManager.cs new file mode 100644 index 00000000..a3175d16 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/WeaponsManager.cs @@ -0,0 +1,69 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.Weapons +{ + + public class WeaponsManager : MonoBehaviour { + + [SerializeField] [Range(2.5f, 4.5f)] private float m_animConvertMultiplier = 3.5f; + public float AnimConvertMultiplier { get { return m_animConvertMultiplier; } set { m_animConvertMultiplier = value; } } + + [SerializeField] [Range(0.0f, 2.0f)] private float m_gunFlashDuration = 0.035f; + public float GunFlashDuration { get { return m_gunFlashDuration; } set { m_gunFlashDuration = value; } } + + [SerializeField] [Range(0.0f, 7200.0f)] private float m_gunFlashRotationSpeed = 1800.0f; + public float GunFlashRotationSpeed { get { return m_gunFlashRotationSpeed; } set { m_gunFlashRotationSpeed = value; } } + + [Space(10)] + [Header("AIMWITHARM")] + + public Vector3 AIMWITHARM_headRotationOffset = Vector3.zero; + + public Vector3 AIMWITHARM_clavicleRotationOffset = Vector3.zero; + public Vector3 AIMWITHARM_upperArmRotationOffset = Vector3.zero; + public Vector3 AIMWITHARM_foreArmRotationOffset = Vector3.zero; + public Vector3 AIMWITHARM_handRotationOffset = Vector3.zero; + + public bool AIMWITHARM_controlUpperArm = true; + public bool AIMWITHARM_controlForeArm = true; + public bool AIMWITHARM_controlHand = true; + + // relative to player + public Vector3 AIMWITHARM_upperArmStartRotationEulers = new Vector3 (-1.686f, 164.627f, -97.904f); + public Vector3 AIMWITHARM_upperArmEndRotationEulers = new Vector3 (150f, -90f, 0f); + + [Range(5, 175)] public float AIMWITHARM_maxAimAngle = 90f; + + [Range(0, 90)] public float AIMWITHARM_maxHeadRotationAngle = 75f; + + [Space(15)] + + public Vector3 crouchSpineRotationOffset; + public Vector3 crouchSpineRotationOffset2; + + [Space(15)] + + public LayerMask projectileRaycastMask = Physics.DefaultRaycastLayers; + + public bool drawLineFromGun = false; + + + public static WeaponsManager Instance { get; private set; } + + + + void Awake () + { + Instance = this; + + } + + public static float ConvertAnimTime (float timeInFile) + { + return timeInFile * Instance.AnimConvertMultiplier / 100.0f; + } + + } + +} diff --git a/Assets/Scripts/Behaviours/Weapons/WeaponsManager.cs.meta b/Assets/Scripts/Behaviours/Weapons/WeaponsManager.cs.meta new file mode 100644 index 00000000..ff9b1289 --- /dev/null +++ b/Assets/Scripts/Behaviours/Weapons/WeaponsManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b19ecbdc94cb426782bb12647cbe133 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/World.meta b/Assets/Scripts/Behaviours/World.meta new file mode 100644 index 00000000..4fa9484f --- /dev/null +++ b/Assets/Scripts/Behaviours/World.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8cc94ac42dea2ec43b890dac6325a4f2 +folderAsset: yes +timeCreated: 1428252231 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/World/Cell.cs b/Assets/Scripts/Behaviours/World/Cell.cs new file mode 100644 index 00000000..ff21130d --- /dev/null +++ b/Assets/Scripts/Behaviours/World/Cell.cs @@ -0,0 +1,301 @@ +using SanAndreasUnity.Behaviours.Vehicles; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Placements; +using SanAndreasUnity.Utilities; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using UnityEngine; + +//using Facepunch.Networking; + +namespace SanAndreasUnity.Behaviours.World +{ + public class Cell : MonoBehaviour + { + private Stopwatch _timer; + private List _leaves; + + private Dictionary m_insts; + private MapObject[] m_cars; + + public Division RootDivision { get; private set; } + + public List CellIds = new List { 0, 13 }; + + public Camera PreviewCamera; + + public List focusPoints = new List (); + + public Water Water; + + public static Cell Instance { get ; private set; } + + // Statistics + private int totalNumObjects = 0; + + private int numLeavesLoadedThisFrame = 0; + private int numObjectsLoadedThisFrame = 0; + private float[] measuredTimes = new float[3]; + private int numDivisionsUpdatedLoadOrder = 0; + private int numMapObjectsUpdatedLoadOrder = 0; + private Division containingDivision = null; + + // variable used by Division class + public float divisionLoadOrderDistanceFactor = 16; + + // variable used by Division class + public float divisionRefreshDistanceDelta = 20; + + [Range(0.1f, 3f)] + public float divisionsUpdateInterval = 0.3f; + + // variable used by MapObject class + public float maxDrawDistance = 500; + + public bool loadParkedVehicles = true; + + + + private void Awake() + { + if (null == Instance) + Instance = this; + + } + + private void Start() + { + //InvokeRepeating("UpdateDivisions", 0f, 0.1f); + StartCoroutine( this.UpdateDivisionsCoroutine () ); + } + + + internal void CreateStaticGeometry () + { + if (RootDivision == null) + { + RootDivision = Division.Create(transform); + RootDivision.SetBounds( + new Vector2(-3000f, -3000f), + new Vector2(+3000f, +3000f)); + } + + var placements = Item.GetPlacements(CellIds.ToArray()); + + m_insts = new Dictionary (48 * 1024); + foreach (var plcm in placements) { + m_insts.Add (plcm, StaticGeometry.Create ()); + } + //m_insts = placements.ToDictionary(x => x, x => StaticGeometry.Create()); + + UnityEngine.Debug.Log("Num static geometries " + m_insts.Count); + + totalNumObjects = m_insts.Count; + } + + internal void InitStaticGeometry () + { + foreach (var inst in m_insts) + { + inst.Value.Initialize(inst.Key, m_insts); + } + } + + internal void LoadParkedVehicles () + { + if (loadParkedVehicles) + { + var parkedVehicles = Item.GetPlacements (CellIds.ToArray ()); + m_cars = parkedVehicles.Select (x => VehicleSpawner.Create (x)) + .Cast () + .ToArray (); + + UnityEngine.Debug.Log ("Num parked vehicles " + m_cars.Length); + } + } + + internal void AddMapObjectsToDivisions () + { + var enumerable = m_insts.Values.Cast (); + + if (m_cars != null) + enumerable = enumerable.Concat (m_cars); + + RootDivision.AddRange (enumerable); + + } + + internal void LoadWater () + { + if (Water != null) + { + Water.Initialize(new WaterFile(Config.GetPath("water_path"))); + } + } + + internal void FinalizeLoad () + { + // set layer recursively for all game objects + // this.gameObject.SetLayerRecursive( this.gameObject.layer ); + + _timer = new Stopwatch(); + _leaves = RootDivision.ToList(); + + } + + + private void Update() + { + + if (!Loader.HasLoaded) + return; + + //this.Setup (); + + if (null == _leaves) + return; + + _timer.Reset(); + _timer.Start(); + numLeavesLoadedThisFrame = 0; + numObjectsLoadedThisFrame = 0; + + foreach (var div in _leaves) + { + if (float.IsPositiveInfinity(div.LoadOrder)) + break; + + numObjectsLoadedThisFrame += div.LoadWhile(() => _timer.Elapsed.TotalSeconds < 1d / 60d); + + if (_timer.Elapsed.TotalSeconds >= 1d / 60d) + { + // break; + } + else + { + numLeavesLoadedThisFrame++; + } + } + + measuredTimes[2] = (float)_timer.Elapsed.TotalMilliseconds; + + } + + System.Collections.IEnumerator UpdateDivisionsCoroutine () + { + + while (true) + { + // wait 100 ms + float timePassed = 0; + while (timePassed < this.divisionsUpdateInterval) + { + yield return null; + timePassed += Time.unscaledDeltaTime; + } + + F.RunExceptionSafe (() => this.UpdateDivisions ()); + + } + + } + + private void UpdateDivisions() + { + if (!Loader.HasLoaded) + return; + + if (_leaves == null) return; + + this.focusPoints.RemoveAll (t => null == t); + + if (this.focusPoints.Count < 1) + return; + + numDivisionsUpdatedLoadOrder = 0; + numMapObjectsUpdatedLoadOrder = 0; + containingDivision = null; + + _timer.Reset(); + _timer.Start(); + + List positions = this.focusPoints.Select (f => f.position).ToList (); + + bool toLoad = false; // _leaves.Aggregate(false, (current, leaf) => current | leaf.RefreshLoadOrder(pos)); + + UnityEngine.Profiling.Profiler.BeginSample ("Update divisions", this); + + foreach (Division leaf in _leaves) + { + Vector3 pos = leaf.GetClosestPosition (positions); + + int count = 0; + toLoad |= leaf.RefreshLoadOrder(pos, out count); + if (count > 0) + { + numDivisionsUpdatedLoadOrder++; + numMapObjectsUpdatedLoadOrder += count; + } + + if (null == containingDivision && leaf.Contains(pos)) + { + containingDivision = leaf; + } + } + + UnityEngine.Profiling.Profiler.EndSample (); + + measuredTimes[0] = (float)_timer.Elapsed.TotalMilliseconds; + + if (!toLoad) return; + + _timer.Reset(); + _timer.Start(); + UnityEngine.Profiling.Profiler.BeginSample ("Sort leaves", this); + _leaves.Sort(); + UnityEngine.Profiling.Profiler.EndSample (); + measuredTimes[1] = (float)_timer.Elapsed.TotalMilliseconds; + } + + /* + private static Rect windowRect = new Rect(10, 10, 250, 330); + private const int windowID = 0; + + private void OnGUI() + { + if (!Loader.HasLoaded) + return; + + if (!PlayerController._showMenu) + return; + + windowRect = GUILayout.Window(windowID, windowRect, showWindow, "World statistics"); + } + */ + + public void showWindow(int windowID) + { + GUILayout.Label("total num divisions " + (null == _leaves ? 0 : _leaves.Count)); + GUILayout.Label("total num objects " + totalNumObjects); + GUILayout.Label("geometry parts loaded " + SanAndreasUnity.Importing.Conversion.Geometry.NumGeometryPartsLoaded); + GUILayout.Label("num objects in current division " + (containingDivision != null ? containingDivision.NumObjects : 0)); + GUILayout.Label("num divisions updated " + numDivisionsUpdatedLoadOrder); + GUILayout.Label("num objects updated " + numMapObjectsUpdatedLoadOrder); + GUILayout.Label("num divisions loading this frame " + numLeavesLoadedThisFrame); + GUILayout.Label("num objects loading this frame " + numObjectsLoadedThisFrame); + + GUILayout.Space(10); + + string[] timeNames = new string[] { "refresh load order ", "sort ", "load / update display " }; + int i = 0; + foreach (float time in measuredTimes) + { + GUILayout.Label(timeNames[i] + Mathf.RoundToInt(time)); + i++; + } + + GUI.DragWindow(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/World/Cell.cs.meta b/Assets/Scripts/Behaviours/World/Cell.cs.meta new file mode 100644 index 00000000..b537aa0f --- /dev/null +++ b/Assets/Scripts/Behaviours/World/Cell.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: df6efcfa667fce549bcc3deb68a7e8d5 +timeCreated: 1428252234 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/World/Division.cs b/Assets/Scripts/Behaviours/World/Division.cs new file mode 100644 index 00000000..a62b9795 --- /dev/null +++ b/Assets/Scripts/Behaviours/World/Division.cs @@ -0,0 +1,361 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.Behaviours.World +{ + public class Division : MonoBehaviour, IEnumerable, IComparable + { + private static readonly Comparison _sHorzSort = + (a, b) => Math.Sign(a.CellPos.x - b.CellPos.x); + + private static readonly Comparison _sVertSort = + (a, b) => Math.Sign(a.CellPos.y - b.CellPos.y); + + public static Division Create(Transform parent) + { + var obj = new GameObject(); + var split = obj.AddComponent(); + + obj.transform.SetParent(parent); + + return split; + } + + private const int LeafObjectLimit = 127; + + private Division _childA; + private Division _childB; + + private List _objects; + public int NumObjects { get { return _objects.Count; } } + + public int NumObjectsIncludingChildren + { + get + { + int count = _objects.Count; + if (_childA != null) + count += _childA.NumObjectsIncludingChildren; + if (_childB != null) + count += _childB.NumObjectsIncludingChildren; + return count; + } + } + + private bool _isVertSplit; + private float _splitVal; + + private Vector3 _lastRefreshPos; + + public Vector2 Min { get; private set; } + public Vector2 Max { get; private set; } + + public bool IsSubdivided { get { return _objects == null; } } + + internal float LoadOrder { get; private set; } + + public void SetBounds(Vector2 min, Vector2 max) + { + Min = min; + Max = max; + + var mid = (Max + Min) * .5f; + + if (float.IsNaN(mid.x) || float.IsInfinity(mid.x)) + { + mid.x = 0f; + } + + if (float.IsNaN(mid.y) || float.IsInfinity(mid.y)) + { + mid.y = 0f; + } + + transform.position = new Vector3(mid.x, 0f, mid.y); + + name = String.Format("Split {0}, {1}", min, max); + + _objects = _objects ?? new List(); + } + + private void Subdivide() + { + if (IsSubdivided) + { + throw new InvalidOperationException("Already subdivided"); + } + + if (_objects.Count == 0) + { + throw new InvalidOperationException("Cannot subdivide an empty leaf"); + } + + var min = Max; + var max = Min; + + foreach (var obj in _objects) + { + var pos = obj.CellPos; + min.x = Mathf.Min(pos.x, min.x); + min.y = Mathf.Min(pos.y, min.y); + max.x = Mathf.Max(pos.x, max.x); + max.y = Mathf.Max(pos.y, max.y); + } + + _isVertSplit = max.x - min.x >= max.y - min.y; + + _objects.Sort(_isVertSplit ? _sHorzSort : _sVertSort); + + _childA = Create(transform); + _childB = Create(transform); + + var mid = _objects.Count / 2; + var median = (_objects[mid - 1].CellPos + _objects[mid].CellPos) * .5f; + + if (_isVertSplit) + { + _splitVal = median.x; + _childA.SetBounds(Min, new Vector2(_splitVal, Max.y)); + _childB.SetBounds(new Vector2(_splitVal, Min.y), Max); + } + else + { + _splitVal = median.y; + _childA.SetBounds(Min, new Vector2(Max.x, _splitVal)); + _childB.SetBounds(new Vector2(Min.x, _splitVal), Max); + } + + _childA._objects = _objects; + _childB._objects = new List(); + + _childB._objects.AddRange(_childA._objects.Skip(mid)); + _childA._objects.RemoveRange(mid, _objects.Count - mid); + + _objects = null; + } + + private void AddInternal(MapObject obj) + { + if (IsSubdivided) + { + var comp = _isVertSplit ? obj.CellPos.x : obj.CellPos.y; + (comp < _splitVal ? _childA : _childB).AddInternal(obj); + return; + } + + _objects.Add(obj); + + if (_objects.Count > LeafObjectLimit) Subdivide(); + } + + public void Add(MapObject obj) + { + AddInternal(obj); + UpdateParents(); + } + + public void AddRange(IEnumerable objs) + { + foreach (var obj in objs.OrderBy(x => x.RandomInt)) + { + AddInternal(obj); + } + + UpdateParents(); + } + + private void UpdateParents() + { + if (IsSubdivided) + { + _childA.UpdateParents(); + _childB.UpdateParents(); + } + else + { + if (_objects.Count == 0) return; + + var sum = _objects.Aggregate(new Vector2(), (s, x) => s + x.CellPos); + transform.position = new Vector3(sum.x / _objects.Count, 0f, sum.y / _objects.Count); + + foreach (var obj in _objects) + { + obj.transform.SetParent(transform, true); + } + } + } + + public bool Contains(MapObject obj) + { + return Contains(obj.CellPos); + } + + public bool Contains(Vector3 pos) + { + return pos.x >= Min.x && pos.z >= Min.y && pos.x < Max.x && pos.z < Max.y; + } + + public bool Contains(Vector2 pos) + { + return pos.x >= Min.x && pos.y >= Min.y && pos.x < Max.x && pos.y < Max.y; + } + + private void OnDrawGizmosSelected() + { + if (!IsSubdivided) return; + + Gizmos.color = Color.green; + + var min = new Vector2(Math.Max(Min.x, -8192f), Math.Max(Min.y, -8192f)); + var max = new Vector2(Math.Min(Max.x, +8192f), Math.Min(Max.y, +8192f)); + + if (_isVertSplit) + { + Gizmos.DrawLine(new Vector3(_splitVal, 0f, min.y), new Vector3(_splitVal, 0f, max.y)); + } + else + { + Gizmos.DrawLine(new Vector3(min.x, 0f, _splitVal), new Vector3(max.x, 0f, _splitVal)); + } + } + + public float GetDistance(Vector3 pos) + { + return Mathf.Sqrt(GetDistanceSquared(pos)); + } + + public float GetDistanceSquared(Vector3 pos) + { + if (Contains(pos)) + return 0f; + + float dx = Mathf.Max(Min.x - pos.x, pos.x - Max.x); + float dz = Mathf.Max(Min.y - pos.z, pos.z - Max.y); + + return new Vector2(dx, dz).sqrMagnitude; + } + + public Vector3 GetClosestPosition (List positions) + { + Vector3 closestPos = positions [0]; + float smallestDist2 = float.MaxValue; + Vector2 center = (this.Min + this.Max) * 0.5f; + + for (int i = 0; i < positions.Count; i++) + { + float dist2 = Vector2.SqrMagnitude (positions [i].ToVec2WithXAndZ() - center); + if (dist2 <= smallestDist2) + { + smallestDist2 = dist2; + closestPos = positions [i]; + } + } + + return closestPos; + } + + public bool RefreshLoadOrder(Vector3 from, out int numMapObjectsUpdatedLoadOrder) + { + UnityEngine.Profiling.Profiler.BeginSample ("Division.RefreshLoadOrder", this); + + var toLoad = false; + numMapObjectsUpdatedLoadOrder = 0; + + if (GetDistanceSquared(from) <= Cell.Instance.maxDrawDistance * Cell.Instance.maxDrawDistance) + { + float divisionRefreshDistanceDeltaSquared = Cell.Instance.divisionRefreshDistanceDelta * Cell.Instance.divisionRefreshDistanceDelta; + // float factor = Cell.Instance.divisionLoadOrderDistanceFactor; //16; + // if (Vector3.SqrMagnitude(from - _lastRefreshPos) > GetDistanceSquared(from) / (factor*factor)) { + if (Vector3.SqrMagnitude(from - _lastRefreshPos) > divisionRefreshDistanceDeltaSquared) + { + _lastRefreshPos = from; + foreach (var obj in _objects) + { + bool b = obj.RefreshLoadOrder(from); + if (b) + { + toLoad = true; + numMapObjectsUpdatedLoadOrder++; + } + } + } + else + { + toLoad = _objects.Any(x => !float.IsPositiveInfinity(x.LoadOrder)); + } + } + + if (toLoad) + { + _objects.Sort(); // THIS MAY BE PERFORMANCE DROP + LoadOrder = _objects[0].LoadOrder; + } + else + { + LoadOrder = float.PositiveInfinity; + } + + UnityEngine.Profiling.Profiler.EndSample (); + + return toLoad; + } + + public int LoadWhile(Func predicate) + { + UnityEngine.Profiling.Profiler.BeginSample ("LoadWhile", this); + + int numLoaded = 0; + foreach (var toLoad in _objects) + { + if (float.IsPositiveInfinity(toLoad.LoadOrder)) + break; + + if (toLoad.HasLoaded) + { + // this object is loaded, just show it + toLoad.Show(); + } + else + { + // this object is still not loaded from disk + // check if we should load it + if (predicate()) + { + toLoad.Show(); + numLoaded++; + } + } + } + + UnityEngine.Profiling.Profiler.EndSample (); + + // return predicate(); + // return false ; + return numLoaded; + } + + public IEnumerator GetEnumerator() + { + if (IsSubdivided) + { + return _childA.Concat(_childB).GetEnumerator(); + } + + return new[] { this }.AsEnumerable().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public int CompareTo(Division other) + { + return LoadOrder > other.LoadOrder ? 1 : LoadOrder == other.LoadOrder ? 0 : -1; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/World/Division.cs.meta b/Assets/Scripts/Behaviours/World/Division.cs.meta new file mode 100644 index 00000000..a83897ba --- /dev/null +++ b/Assets/Scripts/Behaviours/World/Division.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b41c44cfa34ff5d4595e41acf7913a84 +timeCreated: 1428252232 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/World/StaticGeometry.cs b/Assets/Scripts/Behaviours/World/StaticGeometry.cs new file mode 100644 index 00000000..b629016a --- /dev/null +++ b/Assets/Scripts/Behaviours/World/StaticGeometry.cs @@ -0,0 +1,248 @@ +using SanAndreasUnity.Importing.Conversion; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; +using SanAndreasUnity.Importing.Items.Placements; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Profiling; + +namespace SanAndreasUnity.Behaviours.World +{ + public class StaticGeometry : MapObject + { + public static StaticGeometry Create() + { + return new GameObject().AddComponent(); + } + + protected Instance Instance { get; private set; } + + private bool _canLoad; + private bool _isGeometryLoaded = false; + private bool _isVisible; + private bool _isFading; + + public bool IsVisible + { + get { return _isVisible; } + private set + { + if (_isVisible == value) return; + + _isVisible = value; + + gameObject.SetActive(true); + StartCoroutine(Fade()); + + if (value && LodChild != null) + { + LodChild.Hide(); + } + } + } + + public StaticGeometry LodParent { get; private set; } + public StaticGeometry LodChild { get; private set; } + + public void Initialize(Instance inst, Dictionary dict) + { + Instance = inst; + Instance.Object = Instance.Object ?? Item.GetDefinition(inst.ObjectId); + + Initialize(inst.Position, inst.Rotation); + + _canLoad = Instance.Object != null; + + name = _canLoad ? Instance.Object.ModelName : string.Format("Unknown ({0})", Instance.ObjectId); + + if (_canLoad && Instance.LodInstance != null) + { + LodChild = dict[Instance.LodInstance]; + LodChild.LodParent = this; + } + + _isVisible = false; + gameObject.SetActive(false); + gameObject.isStatic = true; + } + + public bool ShouldBeVisible(Vector3 from) + { + if (!_canLoad) return false; + + var obj = Instance.Object; + + // if (obj.HasFlag (ObjectFlag.DisableDrawDist)) + // return true; + + // var dist = Vector3.Distance(from, transform.position); + var distSquared = Vector3.SqrMagnitude(from - transform.position); + + if (distSquared > Cell.Instance.maxDrawDistance * Cell.Instance.maxDrawDistance) + return false; + + if (distSquared > obj.DrawDist * obj.DrawDist) + return false; + + if (!HasLoaded || LodParent == null || !LodParent.IsVisible) + return true; + + if (!LodParent.ShouldBeVisible(from)) + return true; + + return false; + + // return (distSquared <= obj.DrawDist * obj.DrawDist || (obj.DrawDist >= 300 && distSquared < 2560*2560)) + // && (!HasLoaded || LodParent == null || !LodParent.IsVisible || !LodParent.ShouldBeVisible(from)); + } + + protected override float OnRefreshLoadOrder(Vector3 from) + { + var visible = ShouldBeVisible(from); + + if (!IsVisible) + { + return visible ? Vector3.SqrMagnitude(from - transform.position) : float.PositiveInfinity; + } + + if (!visible) Hide(); + + return float.PositiveInfinity; + } + + protected override void OnLoad() + { + + if (!_canLoad) return; + + Profiler.BeginSample ("StaticGeometry.OnLoad", this); + + + // this was previously placed after loading geometry + Flags = Enum.GetValues(typeof(ObjectFlag)) + .Cast() + .Where(x => (Instance.Object.Flags & x) == x) + .Select(x => x.ToString()) + .ToList(); + + //var geoms = Geometry.Load(Instance.Object.ModelName, Instance.Object.TextureDictionaryName); + //OnGeometryLoaded (geoms); + + // we could start loading collision model here + // - we can't, because we don't know the name of collision file until clump is loaded + + Geometry.LoadAsync( Instance.Object.ModelName, new string[] {Instance.Object.TextureDictionaryName}, (geoms) => { + if(geoms != null) + { + // we can't load collision model asyncly, because it requires a transform to attach to + // but, we can load collision file asyncly + Importing.Collision.CollisionFile.FromNameAsync( geoms.Collisions != null ? geoms.Collisions.Name : geoms.Name, (cf) => { + OnGeometryLoaded (geoms); + }); + } + }); + + + Profiler.EndSample (); + + } + + private void OnGeometryLoaded (Geometry.GeometryParts geoms) + { + + Profiler.BeginSample ("Add mesh", this); + + var mf = gameObject.AddComponent(); + var mr = gameObject.AddComponent(); + + mf.sharedMesh = geoms.Geometry[0].Mesh; + mr.sharedMaterials = geoms.Geometry[0].GetMaterials(Instance.Object.Flags, + mat => mat.SetTexture(NoiseTexId, NoiseTex)); + + Profiler.EndSample (); + + geoms.AttachCollisionModel(transform); + + Profiler.BeginSample ("Set layer", this); + + if (Instance.Object.HasFlag(ObjectFlag.Breakable)) + { + gameObject.SetLayerRecursive(BreakableLayer); + } + + Profiler.EndSample (); + + _isGeometryLoaded = true; + + } + + private void OnCollisionModelAttached () + { + + + } + + protected override void OnShow() + { + Profiler.BeginSample ("StaticGeometry.OnShow"); + IsVisible = LodParent == null || !LodParent.IsVisible; + Profiler.EndSample (); + } + + private IEnumerator Fade() + { + if (_isFading) yield break; + + _isFading = true; + + // wait until geometry gets loaded + while (!_isGeometryLoaded) + yield return null; + + var mr = GetComponent(); + if (mr == null) + { + _isFading = false; + yield break; + } + + const float fadeRate = 2f; + + var pb = new MaterialPropertyBlock(); + + // continuously change transparency until object becomes fully opaque or fully transparent + + var val = IsVisible ? 0f : -1f; + + for (; ; ) + { + var dest = IsVisible ? 1f : 0f; + var sign = Math.Sign(dest - val); + val += sign * fadeRate * Time.deltaTime; + + if (sign == 0 || sign == 1 && val >= dest || sign == -1 && val <= dest) break; + + pb.SetFloat(FadeId, (float)val); + mr.SetPropertyBlock(pb); + yield return new WaitForEndOfFrame(); + } + + mr.SetPropertyBlock(null); + + if (!IsVisible) + { + gameObject.SetActive(false); + } + + _isFading = false; + } + + public void Hide() + { + IsVisible = false; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/World/StaticGeometry.cs.meta b/Assets/Scripts/Behaviours/World/StaticGeometry.cs.meta new file mode 100644 index 00000000..4cfce1fb --- /dev/null +++ b/Assets/Scripts/Behaviours/World/StaticGeometry.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c2400fe08bb4191409f1e53b32fedcc1 +timeCreated: 1428252232 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/World/Water.cs b/Assets/Scripts/Behaviours/World/Water.cs new file mode 100644 index 00000000..1fb355ff --- /dev/null +++ b/Assets/Scripts/Behaviours/World/Water.cs @@ -0,0 +1,57 @@ +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Placements; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.World +{ + public class Water : MonoBehaviour + { + public GameObject WaterPrefab; + + private void AddFace(WaterFace face) + { + // TODO + if ((face.Flags & WaterFlags.Visible) != WaterFlags.Visible) return; + + var obj = Instantiate(WaterPrefab); + obj.transform.SetParent(transform); + var mid = obj.transform.position = face.Vertices.Aggregate(Vector3.zero, + (s, x) => s + x.Position) / face.Vertices.Length; + + obj.name = string.Format("WaterFace ({0})", mid); + + var mesh = new Mesh(); + + mesh.vertices = face.Vertices.Select(x => x.Position - mid).ToArray(); + mesh.normals = face.Vertices.Select(x => Vector3.up).ToArray(); + + var indices = new int[(face.Vertices.Length - 2) * 3]; + for (var i = 0; i < face.Vertices.Length - 2; ++i) + { + var flip = i & 1; + indices[i * 3 + 0] = i + 1 - flip; + indices[i * 3 + 1] = i + 0 + flip; + indices[i * 3 + 2] = i + 2; + } + + mesh.SetIndices(indices, MeshTopology.Triangles, 0); + + obj.GetComponent().sharedMesh = mesh; + } + + public void Initialize(WaterFile file) + { + if (WaterPrefab == null) + { + Debug.LogWarning("No water prefab set, skipping load!"); + return; + } + + foreach (var face in file.Faces) + { + AddFace(face); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/World/Water.cs.meta b/Assets/Scripts/Behaviours/World/Water.cs.meta new file mode 100644 index 00000000..7d421de7 --- /dev/null +++ b/Assets/Scripts/Behaviours/World/Water.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 57ea334de36794f45af24c665b00e893 +timeCreated: 1428252232 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behaviours/World/WorldController.cs b/Assets/Scripts/Behaviours/World/WorldController.cs new file mode 100644 index 00000000..f50e020d --- /dev/null +++ b/Assets/Scripts/Behaviours/World/WorldController.cs @@ -0,0 +1,117 @@ +using SanAndreasUnity.Utilities; +using System; +using UnityEngine; + +namespace SanAndreasUnity.Behaviours.World +{ + public enum TimeState { Dawn, Noon, Dusk, Midnight } + + // TODO: TimeFactor -> AngleFactor + public class WorldController : MonoBehaviour + { + public const float dayCycleMins = 24, + relMinSecs = 1; // That means that one second in real life in one minute in game + + private static float dayTimeCounter, dayCount; + + public AnimationCurve lightCurve; + public Transform dirLight; + + public TimeState startTimeState; + + private Light light; + + public static float TimeFactor + { + get + { + return (1f / Time.deltaTime) * (dayCycleMins * 60) / 360; + } + } + + public static float AngleFactor + { + get + { + return 360 / ((1f / Time.deltaTime) * (dayCycleMins * 60)); + } + } + + public static bool IsNight + { + get + { + return ((dayTimeCounter * AngleFactor) % 360).BetweenInclusive(180, 360); + } + } + + private void Awake() + { + light = dirLight.GetComponent(); + } + + // Use this for initialization + private void Start() + { + SetTime(startTimeState); + } + + // Update is called once per frame + private void FixedUpdate() + { + //360 = 24 minutos + //x = Time.deltaTime + + if (dirLight != null) + { + float prod = dayTimeCounter * AngleFactor, + angle = prod % 360; + + if (prod > 0 && prod % 360 == 0) + { + ++dayCount; + Debug.Log("Day "+dayCount); + } + + dirLight.rotation = Quaternion.Euler(angle, -130, 0); + dayTimeCounter += AngleFactor; + + // Range: Dusk .. Dawn + if (IsNight) light.intensity = lightCurve.Evaluate(Mathf.InverseLerp(180, 360, angle)); + } + } + + // Must review + public static void SetTime(TimeState time) + { + switch (time) + { + case TimeState.Dawn: + dayTimeCounter = dayCount > 0 ? GetRoundedTime(TimeFactor) : 0; + break; + + case TimeState.Noon: + dayTimeCounter = dayCount > 0 ? GetRoundedTime(90 * TimeFactor) : TimeFactor * 90; + break; + + case TimeState.Dusk: + dayTimeCounter = dayCount > 0 ? GetRoundedTime(180 * TimeFactor) : TimeFactor * 180; + break; + + case TimeState.Midnight: + dayTimeCounter = dayCount > 0 ? GetRoundedTime(270 * TimeFactor) : TimeFactor * 270; + break; + } + + Debug.LogFormat("Time set to {0}! ({1})", time.ToString(), dayTimeCounter); + } + + private static float GetRoundedTime(float X) + { + float completeDay = 360 * TimeFactor; + //Debug.LogWarning("Days: "+dayCount); + + return completeDay * dayCount + X; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Behaviours/World/WorldController.cs.meta b/Assets/Scripts/Behaviours/World/WorldController.cs.meta new file mode 100644 index 00000000..e03d1dfa --- /dev/null +++ b/Assets/Scripts/Behaviours/World/WorldController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f448a6ce85e59e943974de56271f3ce5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor.meta b/Assets/Scripts/Editor.meta new file mode 100644 index 00000000..a9676582 --- /dev/null +++ b/Assets/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ee9ee0fe973d5334c8d39fe80287c315 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/Config.cs b/Assets/Scripts/Editor/Config.cs new file mode 100644 index 00000000..022d3c53 --- /dev/null +++ b/Assets/Scripts/Editor/Config.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; +using UnityEditor; +using UnityEditor.Callbacks; +using UnityEngine; + +namespace SanAndreasUnity.Editor +{ + public class Config : MonoBehaviour + { + [PostProcessBuild] + public static void CopyConfig(BuildTarget target, string pathToBuiltProject) + { + if (!IsStandaloneTarget (target)) + return; + + var destDir = Path.GetDirectoryName(pathToBuiltProject); + + // copy config file + + var dest = Path.Combine(destDir, Utilities.Config.FileName); + File.Copy(Utilities.Config.FilePath, dest, true); + + // copy Data folder + + var dataDir = SanAndreasUnity.Utilities.Config.DataPath; + + dest = Path.Combine(destDir, Path.GetFileNameWithoutExtension(pathToBuiltProject) + "_Data"); + + dest = Path.Combine(dest, "Data"); + + if (Directory.Exists(dest)) + { + Directory.Delete(dest); + } + + FileUtil.CopyFileOrDirectory(dataDir, dest); + } + + private static bool IsStandaloneTarget (BuildTarget target) + { + switch (target) + { + case BuildTarget.StandaloneWindows: + case BuildTarget.StandaloneWindows64: + case BuildTarget.StandaloneLinux: + case BuildTarget.StandaloneLinux64: + case BuildTarget.StandaloneLinuxUniversal: + case BuildTarget.StandaloneOSX: + return true; + } + + return false; + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/Config.cs.meta b/Assets/Scripts/Editor/Config.cs.meta new file mode 100644 index 00000000..f3d3cecc --- /dev/null +++ b/Assets/Scripts/Editor/Config.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6837867a733aff54882619926d2e2ab8 +timeCreated: 1428171580 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/FrameInspector.cs b/Assets/Scripts/Editor/FrameInspector.cs new file mode 100644 index 00000000..f9e07ab4 --- /dev/null +++ b/Assets/Scripts/Editor/FrameInspector.cs @@ -0,0 +1,37 @@ +using UnityEngine; +using UnityEditor; + +namespace SanAndreasUnity.Editor +{ + + [CustomEditor(typeof(Behaviours.Frame))] +// [CanEditMultipleObjects] + public class FrameInspector : UnityEditor.Editor + { + + + void OnEnable() + { + + } + + public override void OnInspectorGUI() + { + + base.DrawDefaultInspector (); + + GUILayout.Space (10); + + var frame = this.target as Behaviours.Frame; + + EditorGUILayout.LabelField ("Bone id: " + frame.BoneId); + EditorGUILayout.LabelField ("Index: " + frame.Index); + EditorGUILayout.ObjectField ("Parent: ", frame.Parent, typeof(Behaviours.Frame), true); + EditorGUILayout.LabelField ("Parent index: " + frame.ParentIndex); + EditorGUILayout.LabelField ("Path: " + frame.Path); + + } + + } + +} diff --git a/Assets/Scripts/Editor/FrameInspector.cs.meta b/Assets/Scripts/Editor/FrameInspector.cs.meta new file mode 100644 index 00000000..0a929f2b --- /dev/null +++ b/Assets/Scripts/Editor/FrameInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62b7945a8e5da4887a6da6987171c419 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch.meta b/Assets/Scripts/Facepunch.meta new file mode 100644 index 00000000..502eeecd --- /dev/null +++ b/Assets/Scripts/Facepunch.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7f1bad01d36c7d64991e55dbf48d4ff5 +folderAsset: yes +timeCreated: 1428847605 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/.gitignore b/Assets/Scripts/Facepunch/.gitignore new file mode 100644 index 00000000..ac472943 --- /dev/null +++ b/Assets/Scripts/Facepunch/.gitignore @@ -0,0 +1,13 @@ +*.* + +!*.cs +!*.cs.meta +!Plugins/*.* +!.* + +Library/ +Build/ +Unity/ +Assets/ +Temp/ +obj/ diff --git a/Assets/Scripts/Facepunch/LICENSE b/Assets/Scripts/Facepunch/LICENSE new file mode 100644 index 00000000..04825eca --- /dev/null +++ b/Assets/Scripts/Facepunch/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Facepunch Studios LTD + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Assets/Scripts/Facepunch/Utilities/ListEx.cs b/Assets/Scripts/Facepunch/Utilities/ListEx.cs new file mode 100644 index 00000000..3cc748d7 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/ListEx.cs @@ -0,0 +1,48 @@ +using UnityEngine; + +namespace System.Collections.Generic +{ + public static class ListEx + { + public static void RemoveRangeWrapped(this List list, int index, int count) + { + int itemCount = list.Count; + + if (count == 0 || itemCount == 0) return; + + if (count >= itemCount) + { + list.Clear(); + + return; + } + + int removeIndex = index; + + if (count < 0) + { + removeIndex += count; + count = -count; + } + + removeIndex = removeIndex.Mod(itemCount); + int backCount = count - (itemCount - removeIndex); + + if (backCount <= 0) + { + list.RemoveRange(removeIndex, count); + } + else + { + list.RemoveRange(removeIndex, count - backCount); + list.RemoveRange(0, backCount); + } + } + + public static int GetOffsetIndex(this List list, int index, int offset) + { + // wrap around the offsetted index + return (index + offset).Mod(list.Count); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/ListEx.cs.meta b/Assets/Scripts/Facepunch/Utilities/ListEx.cs.meta new file mode 100644 index 00000000..64354911 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/ListEx.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 189c40774a2f860438db988b236ecfd8 +timeCreated: 1427296668 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/Utilities/MathEx.cs b/Assets/Scripts/Facepunch/Utilities/MathEx.cs new file mode 100644 index 00000000..71ca3bcb --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/MathEx.cs @@ -0,0 +1,159 @@ +namespace UnityEngine +{ + public static class MathExtension + { + public static float SnapToCenter(this float val, float snapValue) + { + if (snapValue == 0) return val; + + return Mathf.Round((val / snapValue) + 0.5f) * snapValue - 0.5f; + } + + public static float SnapToEdge(this float val, float snapValue) + { + if (snapValue == 0) return val; + + return Mathf.Round(val / snapValue) * snapValue; + } + + public static Vector3 SnapToCenter(this Vector2 val, float snapValue) + { + return new Vector2(val.x.SnapToCenter(snapValue), val.y.SnapToCenter(snapValue)); + } + + public static Vector3 SnapToEdge(this Vector2 val, float snapValue) + { + return new Vector2(val.x.SnapToEdge(snapValue), val.y.SnapToEdge(snapValue)); + } + + public static Vector3 SnapToCenter(this Vector3 val, float snapValue) + { + return new Vector3(val.x.SnapToCenter(snapValue), val.y.SnapToCenter(snapValue), val.z.SnapToCenter(snapValue)); + } + + public static Vector3 SnapToEdge(this Vector3 val, float snapValue) + { + return new Vector3(val.x.SnapToEdge(snapValue), val.y.SnapToEdge(snapValue), val.z.SnapToEdge(snapValue)); + } + + public static Vector3 ToVector3XZ(this Vector2 val) + { + return new Vector3(val.x, 0.0f, val.y); + } + + public static float ClosestPointDistance(this Ray val, Vector3 point) + { + return Vector3.Dot(point - val.origin, val.direction); + } + + public static Vector3 ClosestPoint(this Ray val, Vector3 point) + { + return val.GetPoint(val.ClosestPointDistance(point)); + } + + public static float ClosestRayPointDistance(this Ray val, Ray ray) + { + Vector3 v0 = val.origin; + Vector3 v1 = val.direction; + Vector3 v2 = ray.origin; + Vector3 v3 = ray.direction; + Vector3 v4 = v0 - v2; + + float d0 = 0.0f; + float d1 = 0.0f; + + float dv4v3 = Vector3.Dot(v4, v3); + float dv3v1 = Vector3.Dot(v3, v1); + float dv3v3 = Vector3.Dot(v3, v3); + float dv4v1 = Vector3.Dot(v4, v1); + float dv1v1 = Vector3.Dot(v1, v1); + + float denom = dv1v1 * dv3v3 - dv3v1 * dv3v1; + + if (Mathf.Abs(denom) > Mathf.Epsilon) + { + float numer = dv4v3 * dv3v1 - dv4v1 * dv3v3; + d0 = numer / denom; + } + else + { + d0 = 0.0f; + } + + d1 = (dv4v3 + d0 * dv3v1) / dv3v3; + + if (d1 >= 0.0f) + { + return d0; + } + else + { + d1 = 0.0f; + + return val.ClosestPointDistance(ray.origin); + } + } + + public static Vector3 ClosestRayPoint(this Ray val, Ray ray) + { + return val.GetPoint(val.ClosestRayPointDistance(ray)); + } + + public static int Mod(this int val, int mod) + { + int r = val % mod; + + return r < 0 ? val + mod : r; + } + + public static bool PlaneTest(this Ray ray, Vector3 planeCenter, Quaternion planeRot, Vector2 planeSize, out Vector3 hitPosition, float gridSize = 0.0f, bool edge = true) + { + Plane plane = new Plane(planeRot * Vector3.up, planeCenter); + + hitPosition = Vector3.zero; + float hitDistance = 0.0f; + + if (!plane.Raycast(ray, out hitDistance)) + { + return false; + } + + hitPosition = ray.origin + ray.direction * hitDistance; + + Vector3 hitOffset = hitPosition - planeCenter; + + float distanceLf = Vector3.Dot(hitOffset, planeRot * Vector3.left); + float distanceUp = Vector3.Dot(hitOffset, planeRot * Vector3.forward); + + if (gridSize > 0.0f) + { + if (edge) + { + distanceLf = distanceLf.SnapToEdge(gridSize); + distanceUp = distanceUp.SnapToEdge(gridSize); + } + else + { + distanceLf = distanceLf.SnapToCenter(gridSize); + distanceUp = distanceUp.SnapToCenter(gridSize); + } + } + + hitPosition = planeCenter; + hitPosition += (planeRot * Vector3.left) * distanceLf; + hitPosition += (planeRot * Vector3.forward) * distanceUp; + + return true; + } + + public static float NormalizeAngle(this float ang) + { + return ang - Mathf.Floor((ang + 180f) / 360f) * 360f; + } + + public static float AngleDiff(this float ang, float other) + { + return (other - ang).NormalizeAngle(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/MathEx.cs.meta b/Assets/Scripts/Facepunch/Utilities/MathEx.cs.meta new file mode 100644 index 00000000..2bb829e4 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/MathEx.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 287aac3d791d8b245816760000716a6e +timeCreated: 1427296668 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/Utilities/PerformanceSampler.cs b/Assets/Scripts/Facepunch/Utilities/PerformanceSampler.cs new file mode 100644 index 00000000..5c4a8c3f --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/PerformanceSampler.cs @@ -0,0 +1,374 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; + +//using Facepunch.ConCommands; +//using Facepunch.Networking; +using UnityEngine; +using ThreadState = System.Threading.ThreadState; + +namespace Facepunch.Utilities +{ + public interface IGateKeeper : IDisposable + { + object Owner { get; } + String Name { get; } + int Counter { get; } + + IDisposable Sample(); + } + + public class PerformanceSampler : SingletonComponent + { +#pragma warning disable 0618 + + /// + /// http://stackoverflow.com/questions/285031/how-to-get-non-current-threads-stacktrace + /// + private static StackTrace GetStackTrace(Thread targetThread, out Exception error) + { + var suspend = targetThread.ThreadState != ThreadState.Suspended; + error = null; + + StackTrace stackTrace = null; + + Exception ex = null; + + if (suspend) + { + var ready = new ManualResetEvent(false); + + new Thread(() => + { + // Backstop to release thread in case of deadlock: + ready.Set(); + Thread.Sleep(200); + try + { + targetThread.Resume(); + } + catch (Exception e) + { + ex = e; + } + }).Start(); + + ready.WaitOne(); + targetThread.Suspend(); + } + + try + { + stackTrace = new StackTrace(targetThread, true); + } + catch (Exception e) + { + error = e; + } + finally + { + if (suspend) + { + try + { + targetThread.Resume(); + } + catch (Exception e) + { + error = error ?? e; + } + } + } + + error = error ?? ex; + + return stackTrace; + } + +#pragma warning restore 0618 + + /* [ConCommand(Domain.Shared, "system", "status")] + private static String SystemStatusCommand(ConCommandArgs args) + { + var writer = new StringWriter(); + + writer.WriteLine("Uptime: {0:F1} minutes", Instance.Uptime.TotalMinutes); + writer.WriteLine("Processor time: {0:F1}%", Instance.ProcessorTimePercent); + writer.WriteLine("Total memory: {0:F1} KB", Instance.TotalMemory / 1024d); + writer.WriteLine("Avg GC period: {0:F2} s", Instance.AverageGarbageCollectionPeriod); + writer.WriteLine("Network status: {0}", Server.Instance.NetStatus); + writer.WriteLine("Network thread status: {0}", Server.Instance.Net.NetThread.ThreadState); + writer.WriteLine("Main thread state: {0}", Instance.MainThreadState); + + if (!(Instance.SinceLastUpdate.TotalSeconds > 2d * Instance.SamplePeriod)) return writer.ToString(); + + writer.WriteLine("Main thread has been hanging for {0:F1} minutes!", Instance.SinceLastUpdate.TotalMinutes); + + return writer.ToString(); + } + + [ConCommand(Domain.Shared, "system", "gate-keepers")] + private static String SystemGateKeepersCommand(ConCommandArgs args) + { + var writer = new StringWriter(); + + foreach (var gateKeeper in GateKeepers) { + writer.WriteLine("Owner: {0}, Name: {1}, Count: {2}", gateKeeper.Owner, gateKeeper.Name, gateKeeper.Counter); + } + + return writer.ToString(); + } + */ + + private class GateKeeper : IGateKeeper + { + private class Sampler : IDisposable + { + private readonly GateKeeper _keeper; + + public Sampler(GateKeeper keeper) + { + _keeper = keeper; + } + + public void Dispose() + { + --_keeper.Counter; + } + } + + private readonly Sampler _sampler; + + public object Owner { get; private set; } + public string Name { get; private set; } + public int Counter { get; private set; } + + public GateKeeper(object owner, String name) + { + _sampler = new Sampler(this); + + Owner = owner; + Name = name; + Counter = 0; + } + + public IDisposable Sample() + { + ++Counter; + return _sampler; + } + + public void Dispose() + { + _sGateKeepers.Remove(this); + } + } + + private static readonly List _sGateKeepers = new List(); + + public static IEnumerable GateKeepers { get { return _sGateKeepers.Cast(); } } + + public static IGateKeeper CreateGatekeeper(object owner, String name) + { + var keeper = new GateKeeper(owner, name); + _sGateKeepers.Add(keeper); + return keeper; + } + + private readonly DateTime _startTime; + + private DateTime _lastUpdate; + private TimeSpan _lastProcessorTime; + private DateTime _lastGcPass; + private int _lastGcPasses; + + private Thread _mainThread; + private Thread _watcherThread; + + private bool _stopWatching; + + private readonly AutoResetEvent _sampleWait; + private readonly ManualResetEvent _stopWait; + + private readonly Queue _gcPeriods = new Queue(); + + private readonly Stopwatch _timer = new Stopwatch(); + + public TimeSpan Uptime + { + get { return DateTime.UtcNow - _startTime; } + } + + public ThreadState MainThreadState + { + get { return _mainThread == null ? ThreadState.Unstarted : _mainThread.ThreadState; } + } + + public TimeSpan SinceLastUpdate + { + get { return DateTime.UtcNow - _lastUpdate; } + } + + public double ProcessorTimePercent { get; private set; } + + public double AverageGarbageCollectionPeriod + { + get + { + return _gcPeriods.Count == 0 + ? float.PositiveInfinity + : (_gcPeriods.Sum() + (DateTime.UtcNow - _lastGcPass).TotalSeconds) + / (_gcPeriods.Count + 1); + } + } + + public long TotalMemory { get; private set; } + + [Range(1f, 60f)] + public float SamplePeriod = 2f; + + [Range(1, 200)] + public int GarbageCollectionSamples = 10; + + public PerformanceSampler() + { + _startTime = _lastGcPass = DateTime.UtcNow; + + _sampleWait = new AutoResetEvent(false); + _stopWait = new ManualResetEvent(true); + + Sample(false); + } + + private static void SampleFailed() + { + UnityEngine.Debug.LogErrorFormat("!!! PerformanceSampler has failed to sample (time: {0}) !!!", DateTime.UtcNow); + // UnityEngine.Debug.LogFormat("HangNotifyUrl: {0}", NetConfig.HangNotifyUrl); + + /* + if (String.IsNullOrEmpty(NetConfig.HangNotifyUrl)) return; + + using (var client = new WebClient()) { + client.UploadString(NetConfig.HangNotifyUrl, "POST", new JObject { + {"status", "hanging"}, + {"time", DateTime.UtcNow.ToBinary()}, + {"last_state", SystemStatusCommand(null)}, + {"port", NetConfig.Port} + }.ToString()); + } + */ + } + + private void WatcherEntry() + { + _stopWait.Reset(); + + while (!_stopWatching) + { + if (_sampleWait.WaitOne(TimeSpan.FromSeconds(SamplePeriod * 2d + 10d))) continue; + if (_stopWatching) return; + SampleFailed(); + break; + } + + _stopWait.Set(); + } + + private void Sample(bool watch) + { + if (watch && _watcherThread == null) + { + _watcherThread = new Thread(WatcherEntry); + _watcherThread.Start(); + } + + if (_mainThread == null) _mainThread = Thread.CurrentThread; + + _lastUpdate = DateTime.UtcNow; + _sampleWait.Set(); + + var diff = _timer.Elapsed.TotalSeconds; + + var proc = Process.GetCurrentProcess(); + + var processorTime = proc.TotalProcessorTime; + var gcPasses = GC.CollectionCount(0); + var gcPassDiff = gcPasses - _lastGcPasses; + + _lastGcPasses = gcPasses; + + if (gcPassDiff > 0) + { + var gcTimeDiff = _lastUpdate - _lastGcPass; + + if (gcPassDiff == 1) + { + _gcPeriods.Enqueue(gcTimeDiff.TotalSeconds); + } + else + { + var avg = diff / (gcPassDiff - 1) + (gcTimeDiff.TotalSeconds - diff); + for (var i = 0; i < gcPassDiff; ++i) + { + _gcPeriods.Enqueue(avg); + } + } + + _lastGcPass = _lastUpdate; + + while (_gcPeriods.Count > GarbageCollectionSamples) + { + _gcPeriods.Dequeue(); + } + } + + TotalMemory = GC.GetTotalMemory(false); + + var processorTimeDiff = processorTime.Subtract(_lastProcessorTime); + + ProcessorTimePercent = (float)((processorTimeDiff.TotalSeconds * 100d / Environment.ProcessorCount) / diff); + + _lastProcessorTime = processorTime; + + _timer.Reset(); + _timer.Start(); + } + + public StackTrace GetMainThreadStackTrace(out Exception ex) + { + if (_mainThread.ThreadState == ThreadState.Stopped) + { + ex = new Exception("Thread stopped"); + return null; + } + + return GetStackTrace(_mainThread, out ex); + } + + // ReSharper disable once UnusedMember.Local + private void Update() + { + if (!(_timer.Elapsed.TotalSeconds > SamplePeriod)) return; + + Sample(true); + } + + private void OnDestroy() + { + UnityEngine.Debug.Log("Destroying PerformanceSampler"); + + _stopWatching = true; + _sampleWait.Set(); + + if (_watcherThread != null && !_stopWait.WaitOne(1000)) + { + UnityEngine.Debug.LogWarning("Timeout while stopping watcher thread!"); + _watcherThread.Abort(); + } + + _watcherThread = null; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/PerformanceSampler.cs.meta b/Assets/Scripts/Facepunch/Utilities/PerformanceSampler.cs.meta new file mode 100644 index 00000000..29d6f39c --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/PerformanceSampler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a98e98d51707b164eb99d6aa73952dfc +timeCreated: 1429109692 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/Utilities/RectTransformEx.cs b/Assets/Scripts/Facepunch/Utilities/RectTransformEx.cs new file mode 100644 index 00000000..41e4fe8d --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/RectTransformEx.cs @@ -0,0 +1,25 @@ +using System.Linq; +using UnityEngine.UI; + +namespace UnityEngine +{ + public static class RectTransformEx + { + private static readonly Vector3[] _sCorners = new Vector3[4]; + + public static Vector2 GetWorldSize(this RectTransform trans) + { + trans.GetWorldCorners(_sCorners); + return new Vector2(_sCorners.Max(x => x.x) - _sCorners.Min(x => x.x), _sCorners.Max(x => x.y) - _sCorners.Min(x => x.y)); + } + + public static float GetPreferredTextHeight(this RectTransform trans, Text text) + { + if (text == null) return 0; + + var settings = text.GetGenerationSettings(new Vector2(trans.rect.size.x, 0.0f)); + + return text.cachedTextGeneratorForLayout.GetPreferredHeight(text.text, settings) / text.pixelsPerUnit; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/RectTransformEx.cs.meta b/Assets/Scripts/Facepunch/Utilities/RectTransformEx.cs.meta new file mode 100644 index 00000000..496dd007 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/RectTransformEx.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 524199494ffd4ff45acb452bf109b95a +timeCreated: 1427296668 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/Utilities/ReflectionEx.cs b/Assets/Scripts/Facepunch/Utilities/ReflectionEx.cs new file mode 100644 index 00000000..9eccd29e --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/ReflectionEx.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Linq; + +namespace System.Reflection +{ + public static class ReflectionEx + { + public static bool Matches(this MethodInfo method, MethodInfo delegateInfo) + { + if (!delegateInfo.ReturnType.IsAssignableFrom(method.ReturnType)) return false; + + var mParams = method.GetParameters(); + var dParams = delegateInfo.GetParameters(); + + if (mParams.Length != dParams.Length) return false; + + for (var i = 0; i < mParams.Length; ++i) + { + if (!dParams[i].ParameterType.IsAssignableFrom(mParams[i].ParameterType)) return false; + } + + return true; + } + + public static bool HasAttribute(this ICustomAttributeProvider obj, bool inherit) + where TAttribute : Attribute + { + return obj.GetCustomAttributes(typeof(TAttribute), inherit).Any(); + } + + public static TAttribute GetAttribute(this ICustomAttributeProvider obj, bool inherit) + where TAttribute : Attribute + { + return (TAttribute)obj.GetCustomAttributes(typeof(TAttribute), inherit).FirstOrDefault(); + } + + public static IEnumerable GetAttributes(this ICustomAttributeProvider obj, bool inherit) + where TAttribute : Attribute + { + return obj.GetCustomAttributes(typeof(TAttribute), inherit).Cast(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/ReflectionEx.cs.meta b/Assets/Scripts/Facepunch/Utilities/ReflectionEx.cs.meta new file mode 100644 index 00000000..6f272bbb --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/ReflectionEx.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 226e18327cacf9e499983b493038a46d +timeCreated: 1427296668 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/Utilities/SingletonComponent.cs b/Assets/Scripts/Facepunch/Utilities/SingletonComponent.cs new file mode 100644 index 00000000..5cea18f1 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/SingletonComponent.cs @@ -0,0 +1,35 @@ +using System.Linq; + +namespace UnityEngine +{ + public abstract class SingletonComponent : MonoBehaviour + where TComponent : SingletonComponent + { + private static TComponent _sInstance; + + public static TComponent Instance + { + get { return _sInstance ?? (_sInstance = FindObjectOfType()); } + } + + // ReSharper disable once UnusedMember.Local + private void Awake() + { + if (FindObjectsOfType().Any(x => x != this && x.isActiveAndEnabled)) + { + DestroyImmediate(this); + return; + } + + _sInstance = (TComponent)this; + + DontDestroyOnLoad(gameObject); + + OnAwake(); + } + + protected virtual void OnAwake() + { + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/SingletonComponent.cs.meta b/Assets/Scripts/Facepunch/Utilities/SingletonComponent.cs.meta new file mode 100644 index 00000000..1583e181 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/SingletonComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9ce94c97eec14504599707f5bafd37bd +timeCreated: 1427296668 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/Utilities/SteamEx.cs b/Assets/Scripts/Facepunch/Utilities/SteamEx.cs new file mode 100644 index 00000000..4551ce1c --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/SteamEx.cs @@ -0,0 +1,28 @@ +#if STEAM + +using Steamworks; + +namespace Facepunch.Steam +{ + public static class SteamEx + { + public static string Format(this CSteamID steamID) + { + if (steamID.GetEAccountType() == EAccountType.k_EAccountTypeInvalid || + steamID.GetEAccountType() == EAccountType.k_EAccountTypeIndividual) { + uint accountID = steamID.GetAccountID().m_AccountID; + + if (steamID.GetEUniverse() <= EUniverse.k_EUniversePublic) { + return string.Format("STEAM_0:{0}:{1}", accountID & 1, accountID >> 1); + } else { + return string.Format("STEAM_{2}:{0}:{1}", accountID & 1, accountID >> 1, + (int) steamID.GetEUniverse()); + } + } else { + return steamID.ToString(); + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/SteamEx.cs.meta b/Assets/Scripts/Facepunch/Utilities/SteamEx.cs.meta new file mode 100644 index 00000000..95b433ca --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/SteamEx.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5e9e8f28de69d7b4b911f327eef3c58f +timeCreated: 1427296668 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/Utilities/StreamEx.cs b/Assets/Scripts/Facepunch/Utilities/StreamEx.cs new file mode 100644 index 00000000..60f1227f --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/StreamEx.cs @@ -0,0 +1,62 @@ +namespace System.IO +{ + public static class StreamEx + { + public static void Clear(this Stream stream) + { + stream.Reset(); + stream.SetLength(0); + } + + public static void Reset(this Stream stream) + { + stream.Seek(0, SeekOrigin.Begin); + } + + public static Stream ClearWriteReset(this Stream stream, Action write) + { + stream.Clear(); + write(stream); + stream.Reset(); + + return stream; + } + + public static Stream ClearWriteReset(this Stream stream, byte[] contents) + { + stream.Clear(); + stream.Write(contents, 0, contents.Length); + stream.Reset(); + + return stream; + } + + private const int DefaultCopyBufferSize = 2048; + + public static void CopyTo(this Stream from, Stream dest, byte[] buffer = null) + { + buffer = buffer ?? new byte[DefaultCopyBufferSize]; + var bufferSize = buffer.Length; + + int read; + while ((read = from.Read(buffer, 0, bufferSize)) > 0) + { + dest.Write(buffer, 0, read); + } + } + + public static void CopyTo(this Stream from, Stream dest, int length, byte[] buffer = null) + { + buffer = buffer ?? new byte[DefaultCopyBufferSize]; + var bufferSize = buffer.Length; + + int toRead, read, total = 0; + while ((toRead = Math.Min(length - total, bufferSize)) > 0 + && (read = from.Read(buffer, 0, toRead)) > 0) + { + dest.Write(buffer, 0, read); + total += read; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/StreamEx.cs.meta b/Assets/Scripts/Facepunch/Utilities/StreamEx.cs.meta new file mode 100644 index 00000000..9c986226 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/StreamEx.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2baba2a845843584696d7762a9b2ba3b +timeCreated: 1427296668 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Facepunch/Utilities/TransformEx.cs b/Assets/Scripts/Facepunch/Utilities/TransformEx.cs new file mode 100644 index 00000000..3f2936d8 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/TransformEx.cs @@ -0,0 +1,174 @@ +using System.Collections.Generic; +using System.Linq; + +namespace UnityEngine +{ + public static class TransformEx + { + public static Transform FindChildRecursive(this Transform transform, string strName) + { + if (transform.name.Equals(strName, System.StringComparison.InvariantCultureIgnoreCase)) return transform; + + for (int i = 0; i < transform.childCount; i++) + { + var tran = transform.GetChild(i).FindChildRecursive(strName); + if (tran) return tran; + } + + return null; + } + + // + // Get all of the children in this transform, recursively + // + public static List GetAllChildren(this Transform transform) + { + var list = new List(); + transform.AddAllChildren(list); + return list; + } + + // + // Add all of the children in this transform to this list + // + public static void AddAllChildren(this Transform transform, List list) + { + list.Add(transform); + + for (int i = 0; i < transform.childCount; i++) + { + transform.GetChild(i).AddAllChildren(list); + } + } + + // + // Return all children with the specified tag + // + public static Transform[] GetChildrenWithTag(this Transform transform, string strTag) + { + var children = GetAllChildren(transform); + return children.Where(x => x.CompareTag(strTag)).ToArray(); + } + + // + // Set local position and rotation to 0 + // + public static void Identity(this GameObject go) + { + go.transform.localPosition = Vector3.zero; + go.transform.localRotation = Quaternion.identity; + } + + // + // Create an empty child + // + public static GameObject CreateChild(this GameObject go) + { + var child = new GameObject(); + child.transform.parent = go.transform; + child.Identity(); + + return child; + } + + // + // Create an empty child + // + public static GameObject CreateChild(this GameObject go, string name) + { + var child = new GameObject(name); + child.transform.parent = go.transform; + child.Identity(); + + return child; + } + + // + // Create a prefab as a child of this game object + // + public static GameObject InstantiateChild(this GameObject go, GameObject prefab) + { + var child = GameObject.Instantiate(prefab) as GameObject; + child.transform.parent = go.transform; + child.Identity(); + + return child; + } + + // + // Create a prefab as a child of this game object + // + public static GameObject InstantiateChild(this GameObject go, GameObject prefab, string name) + { + var child = InstantiateChild(go, prefab); + child.name = name; + + return child; + } + + // + // Change the layer of every object on this mother fucker + // + public static void SetLayerRecursive(this GameObject go, int Layer) + { + go.layer = Layer; + + for (int i = 0; i < go.transform.childCount; i++) + { + go.transform.GetChild(i).gameObject.SetLayerRecursive(Layer); + } + } + + // + // Change the layer of every object on this mother fucker + // + public static void SetLayerRecursive(this GameObject go, string layer) + { + var layerint = LayerMask.NameToLayer(layer); + if (layerint == 0) + { + Debug.LogWarning("SetLayerRecursive: couldn't find layer: " + layer); + return; + } + + go.SetLayerRecursive(layerint); + } + + // + // Invoke in x seconds, but only if we're not already invoking + // + public static void InvokeAtomic(this MonoBehaviour mb, string strName, float fDelay) + { + UnityEngine.Profiling.Profiler.BeginSample("InvokeAtomic"); + + if (!mb.IsInvoking(strName)) + { + mb.Invoke(strName, fDelay); + } + + UnityEngine.Profiling.Profiler.EndSample(); + } + + // + // Returns a Bounds object of this object and all of its children's renderers (apart from particle systems) + // + public static Bounds WorkoutRenderBounds(this Transform tx) + { + Bounds b = new Bounds(Vector3.zero, Vector3.zero); + + var renderers = tx.GetComponentsInChildren(); + foreach (var r in renderers) + { + if (r is ParticleRenderer) continue; + if (r is ParticleSystemRenderer) continue; + + if (b.center == Vector3.zero) + b = r.bounds; + else + b.Encapsulate(r.bounds); + } + + return b; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Facepunch/Utilities/TransformEx.cs.meta b/Assets/Scripts/Facepunch/Utilities/TransformEx.cs.meta new file mode 100644 index 00000000..f20b1e23 --- /dev/null +++ b/Assets/Scripts/Facepunch/Utilities/TransformEx.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 31b6ea94cb9db17428839a1c4d7ce124 +timeCreated: 1427296668 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing.meta b/Assets/Scripts/Importing.meta new file mode 100644 index 00000000..32305bbb --- /dev/null +++ b/Assets/Scripts/Importing.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5920a55a4186829478c7c904a0a2acf7 +folderAsset: yes +timeCreated: 1427044917 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Animation.meta b/Assets/Scripts/Importing/Animation.meta new file mode 100644 index 00000000..4594945d --- /dev/null +++ b/Assets/Scripts/Importing/Animation.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ca647c045d6735f47a4d3fa75cd6f491 +folderAsset: yes +timeCreated: 1428341422 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Animation/Section.cs b/Assets/Scripts/Importing/Animation/Section.cs new file mode 100644 index 00000000..dd0fb587 --- /dev/null +++ b/Assets/Scripts/Importing/Animation/Section.cs @@ -0,0 +1,130 @@ +using SanAndreasUnity.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace SanAndreasUnity.Importing.Animation +{ + public abstract class Section + { + public readonly string Identifier; + public readonly long Length; + + protected Section(BinaryReader reader) + { + Identifier = reader.ReadString(4); + Length = reader.ReadUInt32(); + } + } + + public class Clip + { + public readonly string Name; + public readonly Int32 BoneCount; + public readonly Int32 FrameLength; + public readonly Int32 Unknown; + public readonly Bone[] Bones; + public readonly int EndTime; + + public Clip(BinaryReader reader) + { + Name = reader.ReadString(24); + BoneCount = reader.ReadInt32(); + FrameLength = reader.ReadInt32(); + Unknown = reader.ReadInt32(); + + Bones = new Bone[BoneCount]; + + for (int i = 0; i < BoneCount; ++i) + { + Bones[i] = new Bone(reader); + } + + if (BoneCount > 0) + { + EndTime = Bones.Max(x => x.EndTime); + } + } + } + + public class Bone + { + public readonly string Name; + public readonly Int32 FrameType; + public readonly Int32 FrameCount; + public readonly Int32 BoneId; + public readonly Frame[] Frames; + public readonly int EndTime; + + public Bone(BinaryReader reader) + { + Name = reader.ReadString(24); + FrameType = reader.ReadInt32(); + FrameCount = reader.ReadInt32(); + BoneId = reader.ReadInt32(); + + Frames = new Frame[FrameCount]; + + for (int i = 0; i < FrameCount; ++i) + { + Frames[i] = new Frame(reader, FrameType == 4); + } + + if (FrameCount > 0) + { + EndTime = Frames[FrameCount - 1].Time; + } + } + } + + public class Frame + { + public readonly Vector3 Translation; + public readonly Quaternion Rotation; + + public readonly Int16 Time; + + public Frame(BinaryReader reader, bool root) + { + Rotation = new Quaternion(reader, QuaternionCompression.Animation); + + Time = reader.ReadInt16(); + + if (root) + { + Translation = new Vector3(reader, VectorCompression.Animation); + } + } + } + + public class AnimationPackage : Section + { + private readonly Dictionary _namedClips + = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + + public readonly string FileName; + public readonly Int32 ClipCount; + public readonly Clip[] Clips; + + public AnimationPackage(BinaryReader reader) + : base(reader) + { + FileName = reader.ReadString(24); + ClipCount = reader.ReadInt32(); + + Clips = new Clip[ClipCount]; + + for (int i = 0; i < ClipCount; ++i) + { + var clip = Clips[i] = new Clip(reader); + _namedClips.Add(clip.Name, clip); + } + } + + public Clip this[string name] + { + get { return _namedClips[name]; } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Animation/Section.cs.meta b/Assets/Scripts/Importing/Animation/Section.cs.meta new file mode 100644 index 00000000..72ae579a --- /dev/null +++ b/Assets/Scripts/Importing/Animation/Section.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9cad120934d1c3940b94f60a1e067e94 +timeCreated: 1428341423 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Archive.meta b/Assets/Scripts/Importing/Archive.meta new file mode 100644 index 00000000..c9e73bf9 --- /dev/null +++ b/Assets/Scripts/Importing/Archive.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6e45f04284764ec4c87b330e0608f93e +folderAsset: yes +timeCreated: 1427126890 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Archive/ArchiveManager.cs b/Assets/Scripts/Importing/Archive/ArchiveManager.cs new file mode 100644 index 00000000..41df9088 --- /dev/null +++ b/Assets/Scripts/Importing/Archive/ArchiveManager.cs @@ -0,0 +1,108 @@ +using SanAndreasUnity.Importing.RenderWareStream; +using SanAndreasUnity.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; +using System.Runtime.CompilerServices; + +namespace SanAndreasUnity.Importing.Archive +{ + public interface IArchive + { + IEnumerable GetFileNamesWithExtension(string ext); + + bool ContainsFile(string name); + + Stream ReadFile(string name); + } + + /// + /// Handles archive loading and reading. You should never read from archives manually, but always use this class, because it provides thread safety. + /// + public static class ArchiveManager + { + public static string GameDir + { + get { return Config.Get("game_dir"); } + } + + public static string ModelsDir { get { return Path.Combine(GameDir, "models"); } } + public static string DataDir { get { return Path.Combine(GameDir, "data"); } } + + public static string GetPath(params string[] relative) + { + return relative.Aggregate(GameDir, Path.Combine).Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar); + } + + private static readonly List _sLoadedArchives = new List(); + + [MethodImpl(MethodImplOptions.Synchronized)] + public static LooseArchive LoadLooseArchive(string dirPath) + { + var arch = LooseArchive.Load(dirPath); + _sLoadedArchives.Add(arch); + return arch; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public static ImageArchive LoadImageArchive(string filePath) + { + var arch = ImageArchive.Load(filePath); + _sLoadedArchives.Add(arch); + return arch; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public static bool FileExists(string name) + { + return _sLoadedArchives.Any(x => x.ContainsFile(name)); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public static Stream ReadFile(string name) + { + var arch = _sLoadedArchives.FirstOrDefault(x => x.ContainsFile(name)); + if (arch == null) throw new FileNotFoundException(name); + + // get a stream and build memory stream out of it - this will ensure thread safe access + + var stream = arch.ReadFile(name); + + byte[] buffer = new byte[stream.Length]; + stream.Read (buffer, 0, (int) stream.Length); + + stream.Dispose (); + + return new MemoryStream (buffer); + } + + // this method should not be synchronized, because thread would block while + // archive is being read, but the thread only wants to register a job and continue + // [MethodImpl(MethodImplOptions.Synchronized)] + public static void ReadFileAsync(string name, System.Action onFinish) + { + Behaviours.LoadingThread.RegisterJob (new Behaviours.LoadingThread.Job () { + action = () => ReadFile( name ), + callbackFinish = (stream) => { onFinish(stream); }, + }); + } + + [MethodImpl(MethodImplOptions.Synchronized)] // ensure section is read, before another thread can read archives + public static TSection ReadFile(string name) + where TSection : SectionData + { + using (var stream = ReadFile(name)) + { + var section = Section.ReadData(stream) as TSection; + if (section == null) + { + throw new ArgumentException(string.Format("File \"{0}\" is not a {1}!", name, typeof(TSection).Name), "name"); + } + + return section; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Archive/ArchiveManager.cs.meta b/Assets/Scripts/Importing/Archive/ArchiveManager.cs.meta new file mode 100644 index 00000000..13d9b056 --- /dev/null +++ b/Assets/Scripts/Importing/Archive/ArchiveManager.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 36ec46c3853d89340af9ce20943ca933 +timeCreated: 1427130043 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Archive/ImageArchive.cs b/Assets/Scripts/Importing/Archive/ImageArchive.cs new file mode 100644 index 00000000..2fa5bec3 --- /dev/null +++ b/Assets/Scripts/Importing/Archive/ImageArchive.cs @@ -0,0 +1,112 @@ +using SanAndreasUnity.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace SanAndreasUnity.Importing.Archive +{ + public class ImageArchive : IArchive, IDisposable + { + private struct ImageArchiveEntry + { + public readonly UInt32 Offset; + public readonly UInt32 Size; + public UInt32 End { get { return Offset + Size; } } + public readonly String Name; + + public ImageArchiveEntry(BinaryReader reader) + { + Offset = reader.ReadUInt32() << 11; + var sizeSecond = (uint) reader.ReadUInt16(); + var sizeFirst = (uint) reader.ReadUInt16(); + Size = (sizeFirst != 0) ? sizeFirst << 11 : sizeSecond << 11; + Name = reader.ReadString(24); + } + } + + public static ImageArchive Load(String filePath) + { + UnityEngine.Debug.Log("Loading image archive: " + filePath); + return new ImageArchive(new FileStream(filePath, FileMode.Open, FileAccess.Read)); + } + + private readonly Stream _stream; + private readonly List _entries; + private readonly Dictionary _fileDict; + private readonly Dictionary> _extDict; + + public readonly String Version; + public readonly UInt32 EntryCount; + + private ImageArchive(Stream stream) + { + _stream = stream; + + var reader = new BinaryReader(stream); + Version = new String(reader.ReadChars(4)); + EntryCount = reader.ReadUInt32(); + + _entries = new List(); + _fileDict = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + _extDict = new Dictionary>(StringComparer.InvariantCultureIgnoreCase); + + for (var i = 0; i < EntryCount; ++i) + { + var entry = new ImageArchiveEntry(reader); + _entries.Add(entry); + _fileDict.Add(entry.Name, entry); + + //UnityEngine.Debug.Log ("Adding image archive entry: " + entry.Name); + + var ext = Path.GetExtension(entry.Name); + if (ext == null) + { + UnityEngine.Debug.LogWarning("No file extension for: \"" + entry.Name + "\""); + continue; + } + + if (!_extDict.ContainsKey(ext)) + { + _extDict.Add(ext, new List()); + //UnityEngine.Debug.Log("New image archive extension: \"" + ext + "\" for: \"" + entry.Name + "\""); + } + + _extDict[ext].Add(entry.Name); + } + } + + public IEnumerable GetFileNamesWithExtension(string ext) + { + return _extDict.ContainsKey(ext) ? _extDict[ext] : Enumerable.Empty(); + } + + public bool ContainsFile(string name) + { + return _fileDict.ContainsKey(name); + } + + public string GetFileName(long offset) + { + if (_fileDict.Count == 0) return null; + if (offset < _entries.First().Offset) return null; + if (offset >= _entries.Last().End) return null; + return _entries.FirstOrDefault(x => x.Offset <= offset && x.End > offset).Name; + } + + public Stream ReadFile(String name) + { + var entry = _fileDict[name]; + var stream = new FrameStream(_stream, entry.Offset, entry.Size); + + stream.Seek(0, SeekOrigin.Begin); + + return stream; + } + + public void Dispose() + { + _stream.Dispose(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Archive/ImageArchive.cs.meta b/Assets/Scripts/Importing/Archive/ImageArchive.cs.meta new file mode 100644 index 00000000..4979f63c --- /dev/null +++ b/Assets/Scripts/Importing/Archive/ImageArchive.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b786a8fca73b7a5408bcec9e9cb9b811 +timeCreated: 1427126900 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Archive/LooseArchive.cs b/Assets/Scripts/Importing/Archive/LooseArchive.cs new file mode 100644 index 00000000..0a431fb1 --- /dev/null +++ b/Assets/Scripts/Importing/Archive/LooseArchive.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Importing.Archive +{ + public class LooseArchive : IArchive + { + private struct LooseArchiveEntry + { + public readonly string FilePath; + public readonly string Name; + + public LooseArchiveEntry(string filePath) + { + FilePath = filePath; + Name = Path.GetFileName(filePath); + } + } + + private static readonly HashSet _sValidExtensions + = new HashSet { + ".txd", + ".gxt", + ".col", + ".dff", + ".fxp", + ".ifp" + }; + + private readonly Dictionary _fileDict; + private readonly Dictionary> _extDict; + + public static LooseArchive Load(string dirPath) + { + return new LooseArchive(dirPath); + } + + private LooseArchive(string dirPath) + { + Debug.Log("Loading loose archive: " + dirPath); + + _fileDict = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + _extDict = new Dictionary>(StringComparer.InvariantCultureIgnoreCase); + + foreach (var file in Directory.GetFiles(dirPath, "*", SearchOption.AllDirectories)) + { + var ext = Path.GetExtension(file); + + ext = ext.ToLower(); + + if (!_sValidExtensions.Contains(ext)) continue; + + var entry = new LooseArchiveEntry(file); + + if (_fileDict.ContainsKey(entry.Name)) + { + Debug.LogWarningFormat("Already loaded {0}", entry.Name); + continue; + } + + //Debug.Log ("Adding loose archive entry: " + entry.FilePath); + + _fileDict.Add(entry.Name, entry); + + if (ext == null) continue; + + if (!_extDict.ContainsKey(ext)) + { + _extDict.Add(ext, new List()); + } + + _extDict[ext].Add(entry.Name); + } + } + + public IEnumerable GetFileNamesWithExtension(string ext) + { + return _extDict.ContainsKey(ext) ? _extDict[ext] : Enumerable.Empty(); + } + + public bool ContainsFile(string name) + { + return _fileDict.ContainsKey(name); + } + + public System.IO.Stream ReadFile(string name) + { + return File.OpenRead(_fileDict[name].FilePath); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Archive/LooseArchive.cs.meta b/Assets/Scripts/Importing/Archive/LooseArchive.cs.meta new file mode 100644 index 00000000..51640ccf --- /dev/null +++ b/Assets/Scripts/Importing/Archive/LooseArchive.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a4e086e159343284caec17138810f8f7 +timeCreated: 1428239582 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision.meta b/Assets/Scripts/Importing/Collision.meta new file mode 100644 index 00000000..c3226866 --- /dev/null +++ b/Assets/Scripts/Importing/Collision.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e2dcc92e25924ac4eb89fca8c0a4b489 +folderAsset: yes +timeCreated: 1427717986 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/Bounds.cs b/Assets/Scripts/Importing/Collision/Bounds.cs new file mode 100644 index 00000000..2e859899 --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Bounds.cs @@ -0,0 +1,34 @@ +using System.IO; + +namespace SanAndreasUnity.Importing.Collision +{ + public class Bounds + { + public const int Size = sizeof(float) + 3 * Vector3.Size; + + public readonly float Radius; + public readonly Vector3 Center; + public readonly Vector3 Min; + public readonly Vector3 Max; + + public Bounds(BinaryReader reader, Version version) + { + switch (version) + { + case Version.COLL: + Radius = reader.ReadSingle(); + Center = new Vector3(reader); + Min = new Vector3(reader); + Max = new Vector3(reader); + break; + + default: + Min = new Vector3(reader); + Max = new Vector3(reader); + Center = new Vector3(reader); + Radius = reader.ReadSingle(); + break; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/Bounds.cs.meta b/Assets/Scripts/Importing/Collision/Bounds.cs.meta new file mode 100644 index 00000000..3b3e0018 --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Bounds.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e8a635f87ea3d974098d1410120c03bf +timeCreated: 1427717987 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/Box.cs b/Assets/Scripts/Importing/Collision/Box.cs new file mode 100644 index 00000000..12b3aeed --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Box.cs @@ -0,0 +1,20 @@ +using System.IO; + +namespace SanAndreasUnity.Importing.Collision +{ + public class Box + { + public const int Size = 2 * Vector3.Size + Surface.Size; + + public readonly Vector3 Min; + public readonly Vector3 Max; + public readonly Surface Surface; + + public Box(BinaryReader reader, Version version) + { + Min = new Vector3(reader); + Max = new Vector3(reader); + Surface = new Surface(reader); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/Box.cs.meta b/Assets/Scripts/Importing/Collision/Box.cs.meta new file mode 100644 index 00000000..71079a81 --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Box.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c5b8f9835d5e49d448687397297a8f0d +timeCreated: 1427717986 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/CollisionFile.cs b/Assets/Scripts/Importing/Collision/CollisionFile.cs new file mode 100644 index 00000000..d8ee0835 --- /dev/null +++ b/Assets/Scripts/Importing/Collision/CollisionFile.cs @@ -0,0 +1,321 @@ +using SanAndreasUnity.Importing.Archive; +using SanAndreasUnity.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace SanAndreasUnity.Importing.Collision +{ + public class CollisionFile + { + private class CollisionFileInfo + { + private CollisionFile _value; + + public readonly String FileName; + public readonly Version Version; + public readonly long Offset; + public readonly long Length; + public readonly string Name; + public readonly int ModelId; + + public CollisionFile Value { get { return _value ?? (_value = Load()); } set { _value = value; } } + public bool IsLoaded { get { return _value != null; } } + + public CollisionFileInfo(BinaryReader reader, String fileName, Version version) + { + FileName = fileName; + Version = version; + Length = reader.ReadUInt32() + 4; + Name = reader.ReadString(22); + ModelId = reader.ReadInt16(); + Offset = reader.BaseStream.Position - 28; + + reader.BaseStream.Seek(Offset + Length, SeekOrigin.Begin); + } + + private CollisionFile Load() + { + using (var stream = ArchiveManager.ReadFile(FileName)) + { + return new CollisionFile(this, stream); + } + } + + } + + + private static readonly Dictionary _sModelNameDict + = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + + private static readonly Utilities.AsyncLoader s_asyncLoader = + new AsyncLoader (StringComparer.InvariantCultureIgnoreCase); + + + // load collision file infos + public static void Load(string fileName) + { + var thisFile = new List(); + + using (var stream = ArchiveManager.ReadFile(fileName)) + { + var versBuffer = new byte[4]; + var reader = new BinaryReader(stream); + while (stream.Position < stream.Length && stream.Read(versBuffer, 0, 4) == 4) + { + if (versBuffer.All(x => x == 0)) break; + + Version version; + var versString = Encoding.ASCII.GetString(versBuffer); + if (!Enum.TryParse(versString, out version)) + { + if (versString.Substring(0, 3) == "OLL") + { + // Known problem (size off by one). Attempting to fix by adjusting read pointer... + stream.Position -= 1; + version = Version.COLL; + } + else + { + Debug.LogWarningFormat("Error while reading {0} at 0x{1:x} ({2}%)", + fileName, stream.Position - 4, (stream.Position - 4) * 100 / stream.Length); + } + } + + var modelInfo = new CollisionFileInfo(reader, fileName, version); + thisFile.Add(modelInfo); + + if (!_sModelNameDict.ContainsKey(modelInfo.Name)) + { + _sModelNameDict.Add(modelInfo.Name, modelInfo); + } + else + { + _sModelNameDict[modelInfo.Name] = modelInfo; + } + } + } + } + + private static void LoadAsync (string collFileName, CollisionFileInfo collFileInfo, System.Action onFinish) + { + + ArchiveManager.ReadFileAsync (collFileName, (stream) => { + CollisionFile cf = null; + try { + using(stream) + { + cf = new CollisionFile(collFileInfo, stream); + } + } finally { + onFinish (cf); + } + }); + + } + + public static CollisionFile Load(Stream stream) + { + var reader = new BinaryReader(stream); + var version = (Version)Enum.Parse(typeof(Version), reader.ReadString(4)); + var info = new CollisionFileInfo(reader, null, version); + + return new CollisionFile(info, stream); + } + + public static CollisionFile FromName(String name) + { + if (s_asyncLoader.IsObjectLoaded (name)) + return s_asyncLoader.GetLoadedObject (name); + + UnityEngine.Profiling.Profiler.BeginSample ("CollisionFile.FromName()"); + var cf = _sModelNameDict.ContainsKey(name) ? _sModelNameDict[name].Value : null; + UnityEngine.Profiling.Profiler.EndSample (); + + s_asyncLoader.AddToLoadedObjects (name, cf); + + return cf; + } + + public static void FromNameAsync(String name, System.Action onFinish) + { + if (!_sModelNameDict.ContainsKey (name)) + { + // Debug.LogErrorFormat ("Collision model name {0} doesn't exist in dict", name); + onFinish (null); + return; + } + + if (!s_asyncLoader.TryLoadObject (name, onFinish)) + return; + + + // load collision file asyncly + + // get the actual name of collision file + string collFileName = _sModelNameDict [name].FileName; + + LoadAsync( collFileName, _sModelNameDict[name], (result) => + { + // update _value variable in appropriate CollisionFileInfo object + _sModelNameDict[name].Value = result; + + + s_asyncLoader.OnObjectFinishedLoading( name, result, true); + + }); + + } + + + public readonly string Name; + public readonly int ModelId; + + public readonly Bounds Bounds; + public readonly Flags Flags; + + public readonly Sphere[] Spheres; + public readonly Box[] Boxes; + public readonly Vertex[] Vertices; + public readonly FaceGroup[] FaceGroups; + public readonly Face[] Faces; + + private CollisionFile(CollisionFileInfo info, Stream stream) + { + Name = info.Name; + ModelId = info.ModelId; + + var version = info.Version; + + var reader = new BinaryReader(stream); + + stream.Seek(info.Offset + 28, SeekOrigin.Begin); + + Bounds = new Bounds(reader, version); + + int spheres, boxes, verts, faces, faceGroups; + long spheresOffset, boxesOffset, vertsOffset, + facesOffset, faceGroupsOffset; + + switch (version) + { + case Version.COLL: + { + spheres = reader.ReadInt32(); + spheresOffset = stream.Position; + stream.Seek(spheres * Sphere.Size, SeekOrigin.Current); + + reader.ReadInt32(); + + boxes = reader.ReadInt32(); + boxesOffset = stream.Position; + stream.Seek(boxes * Box.Size, SeekOrigin.Current); + + verts = reader.ReadInt32(); + vertsOffset = stream.Position; + stream.Seek(verts * Vertex.SizeV1, SeekOrigin.Current); + + faces = reader.ReadInt32(); + facesOffset = stream.Position; + + faceGroups = 0; + faceGroupsOffset = 0; + + break; + } + default: + { + spheres = reader.ReadUInt16(); + boxes = reader.ReadUInt16(); + faces = reader.ReadUInt16(); + reader.ReadInt16(); + + Flags = (Flags)reader.ReadInt32(); + + spheresOffset = reader.ReadUInt32() + info.Offset; + boxesOffset = reader.ReadUInt32() + info.Offset; + reader.ReadUInt32(); + vertsOffset = reader.ReadUInt32() + info.Offset; + facesOffset = reader.ReadUInt32() + info.Offset; + + if (faces > 0 && (Flags & Flags.HasFaceGroups) == Flags.HasFaceGroups) + { + stream.Seek(facesOffset - 4, SeekOrigin.Begin); + faceGroups = reader.ReadInt32(); + faceGroupsOffset = facesOffset - 4 - FaceGroup.Size * faceGroups; + } + else + { + faceGroups = 0; + faceGroupsOffset = 0; + } + + verts = -1; + + break; + } + } + + Spheres = new Sphere[spheres]; + Boxes = new Box[boxes]; + Faces = new Face[faces]; + FaceGroups = new FaceGroup[faceGroups]; + + if (spheres > 0) + { + stream.Seek(spheresOffset, SeekOrigin.Begin); + for (var i = 0; i < spheres; ++i) + { + Spheres[i] = new Sphere(reader, version); + } + } + + if (boxes > 0) + { + stream.Seek(boxesOffset, SeekOrigin.Begin); + for (var i = 0; i < boxes; ++i) + { + Boxes[i] = new Box(reader, version); + } + } + + if (faces > 0) + { + stream.Seek(facesOffset, SeekOrigin.Begin); + for (var i = 0; i < faces; ++i) + { + Faces[i] = new Face(reader, version); + } + + if (verts == -1) + { + verts = Faces.Max(x => x.GetIndices().Max()) + 1; + } + + Vertices = new Vertex[verts]; + + stream.Seek(vertsOffset, SeekOrigin.Begin); + for (var i = 0; i < verts; ++i) + { + Vertices[i] = new Vertex(reader, version); + } + + if (faceGroups > 0) + { + stream.Seek(faceGroupsOffset, SeekOrigin.Begin); + for (var i = 0; i < faceGroups; ++i) + { + FaceGroups[i] = new FaceGroup(reader); + } + } + } + else + { + Vertices = new Vertex[0]; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/CollisionFile.cs.meta b/Assets/Scripts/Importing/Collision/CollisionFile.cs.meta new file mode 100644 index 00000000..bdf7980c --- /dev/null +++ b/Assets/Scripts/Importing/Collision/CollisionFile.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 37a53e17a3103c64280539f03216a6ff +timeCreated: 1427824199 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/Face.cs b/Assets/Scripts/Importing/Collision/Face.cs new file mode 100644 index 00000000..4821aa5d --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Face.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.IO; + +namespace SanAndreasUnity.Importing.Collision +{ + public class Face + { + public const int SizeV1 = 3 * sizeof(int) + Surface.Size; + public const int Size = 3 * sizeof(ushort) + Surface.Size; + + public readonly int A; + public readonly int B; + public readonly int C; + public readonly Surface Surface; + + public IEnumerable GetIndices() + { + yield return A; + yield return B; + yield return C; + } + + public Face(BinaryReader reader, Version version) + { + switch (version) + { + case Version.COLL: + A = reader.ReadInt32(); + B = reader.ReadInt32(); + C = reader.ReadInt32(); + Surface = new Surface(reader); + break; + + default: + A = reader.ReadUInt16(); + B = reader.ReadUInt16(); + C = reader.ReadUInt16(); + Surface = new Surface(reader, true); + break; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/Face.cs.meta b/Assets/Scripts/Importing/Collision/Face.cs.meta new file mode 100644 index 00000000..a16dd17b --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Face.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c33064c3c9cf4fa40bae0f19aac1337c +timeCreated: 1427717986 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/FaceGroup.cs b/Assets/Scripts/Importing/Collision/FaceGroup.cs new file mode 100644 index 00000000..410ce9ac --- /dev/null +++ b/Assets/Scripts/Importing/Collision/FaceGroup.cs @@ -0,0 +1,22 @@ +using System.IO; + +namespace SanAndreasUnity.Importing.Collision +{ + public class FaceGroup + { + public const int Size = 2 * Vector3.Size + 2 * sizeof(ushort); + + public readonly Vector3 Min; + public readonly Vector3 Max; + public readonly int StartFace; + public readonly int EndFace; + + public FaceGroup(BinaryReader reader) + { + Min = new Vector3(reader); + Max = new Vector3(reader); + StartFace = reader.ReadUInt16(); + EndFace = reader.ReadUInt16(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/FaceGroup.cs.meta b/Assets/Scripts/Importing/Collision/FaceGroup.cs.meta new file mode 100644 index 00000000..1f88cf78 --- /dev/null +++ b/Assets/Scripts/Importing/Collision/FaceGroup.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6ffe64e101e646e45a70751ffdffbb54 +timeCreated: 1427717986 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/Flags.cs b/Assets/Scripts/Importing/Collision/Flags.cs new file mode 100644 index 00000000..61f58704 --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Flags.cs @@ -0,0 +1,11 @@ +namespace SanAndreasUnity.Importing.Collision +{ + public enum Flags : byte + { + None = 0, + ConesReplaceLines = 1, + NotEmpty = 2, + HasFaceGroups = 8, + HasShadowMesh = 16 + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/Flags.cs.meta b/Assets/Scripts/Importing/Collision/Flags.cs.meta new file mode 100644 index 00000000..4f32174c --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Flags.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7c566ba4a5efbf14db218cc8eeedede1 +timeCreated: 1427717986 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/Sphere.cs b/Assets/Scripts/Importing/Collision/Sphere.cs new file mode 100644 index 00000000..4a927d5e --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Sphere.cs @@ -0,0 +1,31 @@ +using System.IO; + +namespace SanAndreasUnity.Importing.Collision +{ + public class Sphere + { + public const int Size = sizeof(float) + Vector3.Size + Surface.Size; + + public readonly float Radius; + public readonly Vector3 Center; + public readonly Surface Surface; + + public Sphere(BinaryReader reader, Version version) + { + switch (version) + { + case Version.COLL: + Radius = reader.ReadSingle(); + Center = new Vector3(reader); + break; + + default: + Center = new Vector3(reader); + Radius = reader.ReadSingle(); + break; + } + + Surface = new Surface(reader); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/Sphere.cs.meta b/Assets/Scripts/Importing/Collision/Sphere.cs.meta new file mode 100644 index 00000000..32e4f9ed --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Sphere.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3761ba7019ba5a44aaf97dd41fc3b473 +timeCreated: 1427717986 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/Surface.cs b/Assets/Scripts/Importing/Collision/Surface.cs new file mode 100644 index 00000000..e70323a7 --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Surface.cs @@ -0,0 +1,39 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.Collision +{ + [Flags] + public enum SurfaceFlags : byte + { + None = 0 + } + + public struct Surface + { + public const int Size = 4 * sizeof(byte); //lol + + public readonly byte Material; + public readonly SurfaceFlags Flags; + public readonly byte Brightness; + public readonly byte Light; + + public Surface(BinaryReader reader, bool simple = false) + { + if (!simple) + { + Material = reader.ReadByte(); + Flags = (SurfaceFlags)reader.ReadByte(); + Brightness = reader.ReadByte(); + Light = reader.ReadByte(); + } + else + { + Material = reader.ReadByte(); + Flags = SurfaceFlags.None; + Brightness = 0; + Light = reader.ReadByte(); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/Surface.cs.meta b/Assets/Scripts/Importing/Collision/Surface.cs.meta new file mode 100644 index 00000000..fd03532f --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Surface.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 77867a06fa8a268438d7cf0122b35466 +timeCreated: 1427717986 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/Version.cs b/Assets/Scripts/Importing/Collision/Version.cs new file mode 100644 index 00000000..771aea9a --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Version.cs @@ -0,0 +1,11 @@ +namespace SanAndreasUnity.Importing.Collision +{ + public enum Version : byte + { + Unknown = 0, + COLL = 1, + COL2 = 2, + COL3 = 3, + COL4 = 4 + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/Version.cs.meta b/Assets/Scripts/Importing/Collision/Version.cs.meta new file mode 100644 index 00000000..5d1e39eb --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Version.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1e103d2e1c19920408d4279e8acfc64e +timeCreated: 1427837338 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Collision/Vertex.cs b/Assets/Scripts/Importing/Collision/Vertex.cs new file mode 100644 index 00000000..31b1b30f --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Vertex.cs @@ -0,0 +1,17 @@ +using System.IO; + +namespace SanAndreasUnity.Importing.Collision +{ + public class Vertex + { + public const int SizeV1 = Vector3.Size; + public const int Size = Vector3.SizeCompressed; + + public readonly Vector3 Position; + + public Vertex(BinaryReader reader, Version version) + { + Position = new Vector3(reader, (version != Version.COLL) ? VectorCompression.Collision : VectorCompression.None); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Collision/Vertex.cs.meta b/Assets/Scripts/Importing/Collision/Vertex.cs.meta new file mode 100644 index 00000000..5e1fbf6c --- /dev/null +++ b/Assets/Scripts/Importing/Collision/Vertex.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4ae9dc35fa2a03e4baf1c27f54a29573 +timeCreated: 1427717986 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Conversion.meta b/Assets/Scripts/Importing/Conversion.meta new file mode 100644 index 00000000..4547fa32 --- /dev/null +++ b/Assets/Scripts/Importing/Conversion.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 56accc94d12846e41a819fb096bcda89 +folderAsset: yes +timeCreated: 1427154765 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Conversion/Animation.cs b/Assets/Scripts/Importing/Conversion/Animation.cs new file mode 100644 index 00000000..0254e363 --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/Animation.cs @@ -0,0 +1,230 @@ +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Importing.Animation; +using SanAndreasUnity.Importing.Archive; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Importing.Conversion +{ + using BFrame = SanAndreasUnity.Behaviours.Frame; + using UVector3 = UnityEngine.Vector3; + using UVector4 = UnityEngine.Vector4; + + public class Animation + { + private const float TimeScale = 1f / 64f; + + private class Axis + { + public string Name { get; set; } + public UVector3 Mask { get; set; } + } + + private static Axis[] s_translateAxes = new Axis[] { + new Axis (){ Name = "x", Mask = new UVector3(1f, 0f, 0f) }, + new Axis (){ Name = "y", Mask = new UVector3(0f, 1f, 0f) }, + new Axis (){ Name = "z", Mask = new UVector3(0f, 0f, 1f) }, + }; + + //private static Dictionary> s_curvesPerClip = new Dictionary> (); + + + private static UnityEngine.AnimationClip Convert(Clip animation, FrameContainer frames, + out UVector3 rootStart, out UVector3 rootEnd) + { + var clip = new UnityEngine.AnimationClip(); + clip.legacy = true; + + var rotateAxes = new[] { + new { Name = "x", Mask = new UVector4(1f, 0f, 0f, 0f) }, + new { Name = "y", Mask = new UVector4(0f, 1f, 0f, 0f) }, + new { Name = "z", Mask = new UVector4(0f, 0f, 1f, 0f) }, + new { Name = "w", Mask = new UVector4(0f, 0f, 0f, 1f) } + }; + + var root = animation.Bones.FirstOrDefault(x => x.BoneId == 0); + if (root != null && root.FrameCount > 0) + { + rootStart = Types.Convert(root.Frames.First().Translation); + rootEnd = Types.Convert(root.Frames.Last().Translation); + } + else + { + rootStart = rootEnd = UVector3.zero; + } + + foreach (var bone in animation.Bones) + { + var bFrames = bone.Frames; + var frame = frames.GetByBoneId(bone.BoneId); + + string bonePath = frame.Path; + + AnimationCurve curve; + + var axisAngle = bFrames.ToDictionary(x => x, x => + { + var q = Types.Convert(x.Rotation); + float ang; UnityEngine.Vector3 axis; + q.ToAngleAxis(out ang, out axis); + return new UVector4(q.x, q.y, q.z, q.w); + }); + + foreach (var axis in rotateAxes) + { + var keys = bFrames + .Select(x => new Keyframe(x.Time * TimeScale, + UVector4.Dot(axisAngle[x], axis.Mask))) + .ToArray(); + + curve = new UnityEngine.AnimationCurve (keys); + + clip.SetCurve(bonePath, typeof(Transform), "localRotation." + axis.Name, + curve); + + //OnCurveAddedToClip (clip, curve); + } + + var converted = bFrames.Select(x => Types.Convert(x.Translation)).ToArray(); + + if (!converted.Any(x => !x.Equals(UVector3.zero))) continue; + + var anyVelocities = false; + var deltaVals = converted.Select((x, i) => + { + var prev = Math.Max(0, i - 1); + var next = Math.Min(i + 1, converted.Length - 1); + + var prevTime = bFrames[prev].Time * TimeScale; + var nextTime = bFrames[next].Time * TimeScale; + + return prevTime == nextTime || !(anyVelocities = true) ? UVector3.zero + : (converted[next] - converted[prev]) / (nextTime - prevTime); + }).ToArray(); + + foreach (var translateAxis in s_translateAxes) + { + var positions = bFrames + .Select((x, i) => new Keyframe(x.Time * TimeScale, + UVector3.Dot(frame.transform.localPosition + converted[i], translateAxis.Mask))) + .ToArray(); + + var deltas = bFrames.Select((x, i) => new Keyframe(x.Time * TimeScale, + UVector3.Dot(deltaVals[i], translateAxis.Mask))).ToArray(); + + clip.SetCurve(bonePath, typeof(Transform), "localPosition." + translateAxis.Name, + new UnityEngine.AnimationCurve(positions)); + + if (!anyVelocities) continue; + + clip.SetCurve(bonePath, typeof(BFrame), "LocalVelocity." + translateAxis.Name, + new UnityEngine.AnimationCurve(deltas)); + } + } + + clip.wrapMode = WrapMode.Loop; + clip.EnsureQuaternionContinuity(); + + return clip; + } + +// public static AnimationCurve[] GetAllCurvesForClip (UnityEngine.AnimationClip clip) +// { +// if (s_curvesPerClip.ContainsKey (clip)) { +// return s_curvesPerClip [clip].ToArray (); +// } else { +// return new AnimationCurve[0]; +// } +// } + + public static void RemovePositionCurves (UnityEngine.AnimationClip clip, FrameContainer frames) + { + + foreach (var frame in frames) { + + string bonePath = frame.Path; + +// foreach (var translateAxis in s_translateAxes) { +// clip.SetCurve (bonePath, typeof(Transform), "localPosition." + translateAxis.Name, null); +// } + + clip.SetCurve (bonePath, typeof(Transform), "m_LocalPosition", null); + } + + } + +// private static void OnCurveAddedToClip (UnityEngine.AnimationClip clip, AnimationCurve curve) +// { +// if (s_curvesPerClip.ContainsKey (clip)) { +// s_curvesPerClip [clip].Add (curve); +// } else { +// s_curvesPerClip.Add (clip, new List (){ curve }); +// } +// } + + + public class Package + { + private readonly AnimationPackage _package; + public AnimationPackage AnimPackage { get { return _package; } } + + private readonly Dictionary _anims + = new Dictionary(); + + public Package(string fileName) + { + using (var reader = new BinaryReader(ArchiveManager.ReadFile(fileName + ".ifp"))) + { + _package = new AnimationPackage(reader); + } + } + + public Animation Load(string clipName, FrameContainer frames) + { + if (_anims.ContainsKey(clipName)) return _anims[clipName]; + var anim = new Animation(_package[clipName], frames); + _anims.Add(clipName, anim); + return anim; + } + } + + + private static readonly Dictionary _sLoaded + = new Dictionary(); + /// All loaded anims. Each entry contains file name and corresponding ifp package. + public static IEnumerable> Loaded { get { return _sLoaded; } } + + + public static Animation Load(string fileName, string clipName, FrameContainer frames) + { + Package package; + if (!_sLoaded.ContainsKey(fileName)) + { + _sLoaded.Add(fileName, package = new Package(fileName)); + } + else + { + package = _sLoaded[fileName]; + } + + return package.Load(clipName, frames); + } + + private readonly UnityEngine.AnimationClip _clip; + private readonly UVector3 _rootStart; + private readonly UVector3 _rootEnd; + + public UnityEngine.AnimationClip Clip { get { return _clip; } } + + public UVector3 RootStart { get { return _rootStart; } } + public UVector3 RootEnd { get { return _rootEnd; } } + + private Animation(Clip anim, FrameContainer frames) + { + _clip = Convert(anim, frames, out _rootStart, out _rootEnd); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Conversion/Animation.cs.meta b/Assets/Scripts/Importing/Conversion/Animation.cs.meta new file mode 100644 index 00000000..4941c19a --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/Animation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1e0f72cef1f057f41ab3d64a021451a8 +timeCreated: 1428354913 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Conversion/CollisionModel.cs b/Assets/Scripts/Importing/Conversion/CollisionModel.cs new file mode 100644 index 00000000..d4d7070e --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/CollisionModel.cs @@ -0,0 +1,250 @@ +using SanAndreasUnity.Importing.Collision; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Object = UnityEngine.Object; +using UnityEngine.Profiling; + +namespace SanAndreasUnity.Importing.Conversion +{ + public class CollisionModel + { + private static UnityEngine.Vector3 Convert(Vector3 vec) + { + return new UnityEngine.Vector3(vec.X, vec.Z, vec.Y); + } + + private static Mesh Convert(IEnumerable faces, int numFaces, IEnumerable vertices, int numVertices) + { + Profiler.BeginSample ("Convert mesh"); + + // create vertices array for the mesh + UnityEngine.Vector3[] meshVertices = new UnityEngine.Vector3[numVertices]; + int i = 0; + foreach (var v in vertices) { + meshVertices [i] = Convert (v.Position); + i++; + } + + var mesh = new Mesh + { + vertices = meshVertices, + subMeshCount = 1 + }; + + // indices + + //var indices = faces.SelectMany(x => x.GetIndices()).ToArray(); + + // each face has 3 indices which form a single triangle, and we should also add another one + // which faces the opposite direction + int[] indices = new int[numFaces * 3 * 2]; + + i = 0; + foreach (var f in faces) { + indices [i++] = f.A; + indices [i++] = f.B; + indices [i++] = f.C; + + // triangle with opposite direction + indices [i++] = f.B; + indices [i++] = f.A; + indices [i++] = f.C; + } + + mesh.SetIndices(indices, MeshTopology.Triangles, 0); + + + Profiler.EndSample (); + + return mesh; + } + + private static Mesh Convert(FaceGroup group, ICollection faces, ICollection vertices) + { + int numFaces = 1 + group.EndFace - group.StartFace; + return Convert(faces.Skip(group.StartFace).Take(numFaces), numFaces, vertices, vertices.Count); + } + + private static GameObject _sTemplateParent; + + private static readonly Dictionary _sLoaded + = new Dictionary(); + + public static void Load(string name, Transform destParent, bool forceConvex = false) + { + Load(name, null, destParent, forceConvex); + } + + public static void Load(CollisionFile file, Transform destParent, bool forceConvex = false) + { + Load(file.Name, file, destParent, forceConvex); + } + + private static void Load(string name, CollisionFile file, Transform destParent, bool forceConvex) + { + CollisionModel col; + + if (_sLoaded.ContainsKey(name)) + { + col = _sLoaded[name]; + if (col == null) return; + + col.Spawn(destParent, forceConvex); + return; + } + + file = file ?? CollisionFile.FromName(name); + if (file == null || (file.Flags & Flags.NotEmpty) != Flags.NotEmpty) + { + _sLoaded.Add(name, null); + return; + } + + col = new CollisionModel(file); + _sLoaded.Add(name, col); + + col.Spawn(destParent, forceConvex); + } + + public static void LoadAsync(string name, CollisionFile file, Transform destParent, bool forceConvex, System.Action onFinish) + { + // load collision file asyncly, and when it's ready just call the other function + + if (file != null) + { + // collision file already loaded + // just call other function + + Utilities.F.RunExceptionSafe( () => Load(file, destParent, forceConvex) ); + onFinish (); + return; + } + + // load collision file asyncly + CollisionFile.FromNameAsync (name, (cf) => { + // loading finished + // call other function + if(cf != null) + Utilities.F.RunExceptionSafe( () => Load( cf, destParent, forceConvex ) ); + onFinish (); + }); + + } + + + private readonly GameObject _template; + private readonly Dictionary _flagGroups; + + private void Add(Surface surface, Action setup) + where TCollider : Collider + { + Profiler.BeginSample ("Add<" + typeof(TCollider).Name + ">"); + + if (!_flagGroups.ContainsKey(surface.Flags)) + { + var group = new GameObject(string.Format("Group {0}", (int)surface.Flags)); + group.transform.SetParent(_template.transform); + + _flagGroups.Add(surface.Flags, group.transform); + } + + var type = typeof(TCollider); + var obj = new GameObject(type.Name, type); + obj.transform.SetParent(_flagGroups[surface.Flags]); + + setup(obj.GetComponent()); + + Profiler.EndSample (); + } + + private CollisionModel(CollisionFile file) + { + Profiler.BeginSample ("CollisionModel()"); + + if (_sTemplateParent == null) + { + _sTemplateParent = new GameObject("Collision Templates"); + _sTemplateParent.SetActive(false); + } + + _template = new GameObject(file.Name); + _template.transform.SetParent(_sTemplateParent.transform); + + _flagGroups = new Dictionary(); + + foreach (var box in file.Boxes) + { + Add(box.Surface, x => + { + var min = Convert(box.Min); + var max = Convert(box.Max); + + x.center = (min + max) * .5f; + x.size = (max - min); + }); + } + + foreach (var sphere in file.Spheres) + { + Add(sphere.Surface, x => + { + x.center = Convert(sphere.Center); + x.radius = sphere.Radius; + }); + } + + if (file.FaceGroups.Length > 0) + { + foreach (var group in file.FaceGroups) + { + Add(file.Faces[group.StartFace].Surface, x => + { + x.sharedMesh = Convert(group, file.Faces, file.Vertices); + }); + } + } + else if (file.Faces.Length > 0) + { + Add(file.Faces[0].Surface, x => + { + x.sharedMesh = Convert(file.Faces, file.Faces.Length, file.Vertices, file.Vertices.Length); + }); + } + + // TODO: MeshCollider + + + Profiler.EndSample (); + } + + public void Spawn(Transform destParent, bool forceConvex) + { + var clone = Object.Instantiate(_template.gameObject); + + clone.name = "Collision"; + clone.transform.SetParent(destParent, false); + + // Debug.Log ("Setting parent (" + destParent.name + ") for " + clone.name); + + if (!forceConvex) return; + + Profiler.BeginSample ("Adjust colliders"); + + foreach (var collider in clone.GetComponentsInChildren()) + { + var meshCollider = collider as MeshCollider; + + collider.gameObject.layer = 2; + + if (meshCollider != null) + { + meshCollider.convex = true; + } + } + + Profiler.EndSample (); + } + } +} diff --git a/Assets/Scripts/Importing/Conversion/CollisionModel.cs.meta b/Assets/Scripts/Importing/Conversion/CollisionModel.cs.meta new file mode 100644 index 00000000..41df8e66 --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/CollisionModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 621a2b291c8768e4bb9a99b700dbd100 +timeCreated: 1427838820 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Conversion/Geometry.cs b/Assets/Scripts/Importing/Conversion/Geometry.cs new file mode 100644 index 00000000..1277d62d --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/Geometry.cs @@ -0,0 +1,677 @@ +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Importing.Archive; +using SanAndreasUnity.Importing.Collision; +using SanAndreasUnity.Importing.Items.Definitions; +using SanAndreasUnity.Importing.RenderWareStream; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Profiling; + +namespace SanAndreasUnity.Importing.Conversion +{ + [Flags] + public enum MaterialFlags + { + Default = 0, + NoBackCull = 1, + Alpha = 2, + Vehicle = 4, + OverrideAlpha = 8 + } + + public class Geometry + { + private static int _sMainTexId = -1; + + protected static int MainTexId + { + get { return _sMainTexId == -1 ? _sMainTexId = Shader.PropertyToID("_MainTex") : _sMainTexId; } + } + + private static int _sMaskTexId = -1; + + protected static int MaskTexId + { + get { return _sMaskTexId == -1 ? _sMaskTexId = Shader.PropertyToID("_MaskTex") : _sMaskTexId; } + } + + private static int _sMetallicId = -1; + + protected static int MetallicId + { + get { return _sMetallicId == -1 ? _sMetallicId = Shader.PropertyToID("_Metallic") : _sMetallicId; } + } + + private static int _sSmoothnessId = -1; + + protected static int SmoothnessId + { + get { return _sSmoothnessId == -1 ? _sSmoothnessId = Shader.PropertyToID("_Smoothness") : _sSmoothnessId; } + } + + private static int _sCarColorIndexId = -1; + + protected static int CarColorIndexId + { + get { return _sCarColorIndexId == -1 ? _sCarColorIndexId = Shader.PropertyToID("_CarColorIndex") : _sCarColorIndexId; } + } + + private static int[] FromTriangleStrip(IList indices) + { + var dst = new List((indices.Count - 2) * 3); + + for (var i = 0; i < indices.Count - 2; ++i) + { + var a = indices[i]; + var b = indices[i + 1 + (i & 1)]; + var c = indices[i + 2 - (i & 1)]; + + if (a == b || b == c || a == c) continue; + + dst.Add(a); + dst.Add(b); + dst.Add(c); + } + + return dst.ToArray(); + } + + private static UnityEngine.Vector3[] CalculateNormals(RenderWareStream.Geometry src, UnityEngine.Vector3[] verts) + { + var norms = new UnityEngine.Vector3[src.VertexCount]; + + for (var i = 0; i < src.FaceCount; ++i) + { + var face = src.Faces[i]; + + var a = verts[face.Vertex0]; + var b = verts[face.Vertex1]; + var c = verts[face.Vertex2]; + + var v = b - a; + var w = c - b; + + var norm = new UnityEngine.Vector3( + v.y * w.z - v.z * w.y, + v.z * w.x - v.x * w.z, + v.x * w.y - v.y * w.x).normalized; + + norms[face.Vertex0] -= norm; + norms[face.Vertex1] -= norm; + norms[face.Vertex2] -= norm; + } + + for (var i = 0; i < src.VertexCount; ++i) + { + if (norms[i].sqrMagnitude <= 0f) + { + norms[i] = UnityEngine.Vector3.up; + } + else + { + norms[i] = norms[i].normalized; + } + } + + return norms; + } + + private static readonly Dictionary _sShaders + = new Dictionary(); + + private static Shader GetShaderNoCache(MaterialFlags flags) + { + var noBackCull = (flags & MaterialFlags.NoBackCull) == MaterialFlags.NoBackCull; + var alpha = (flags & MaterialFlags.Alpha) == MaterialFlags.Alpha; + var vehicle = (flags & MaterialFlags.Vehicle) == MaterialFlags.Vehicle; + + if (vehicle && alpha) + { + return Shader.Find("SanAndreasUnity/VehicleTransparent"); + } + + if (vehicle) + { + return Shader.Find("SanAndreasUnity/Vehicle"); + } + + if (noBackCull && alpha) + { + return Shader.Find("SanAndreasUnity/TransparentNoBackCull"); + } + + if (noBackCull) + { + return Shader.Find("SanAndreasUnity/NoBackCull"); + } + + if (alpha) + { + return Shader.Find("SanAndreasUnity/Transparent"); + } + + return Shader.Find("SanAndreasUnity/Default"); + } + + private static Shader GetShader(MaterialFlags flags) + { + if (_sShaders.ContainsKey(flags)) return _sShaders[flags]; + + var shader = GetShaderNoCache(flags); + _sShaders.Add(flags, shader); + return shader; + } + + private static readonly Color32[] _sKeyColors = new[] { + new Color32(255, 255, 255, 255), + + // Paint job + new Color32(60, 255, 0, 255), + new Color32(255, 0, 175, 255), + new Color32(60, 255, 0, 255), // TODO + new Color32(255, 0, 175, 255), // TODO + + // Head lights + new Color32(255, 175, 0, 255), // L + new Color32(0, 255, 200, 255), // R + + // Tail lights + new Color32(185, 255, 0, 255), // L + new Color32(255, 60, 0, 255) // R + }; + + private static LoadedTexture _sWhiteTex; + + private static LoadedTexture WhiteTex + { + get { return _sWhiteTex ?? (_sWhiteTex = new LoadedTexture(Texture2D.whiteTexture, false)); } + } + + private static UnityEngine.Material Convert(RenderWareStream.Material src, TextureDictionary[] txds, MaterialFlags flags) + { + LoadedTexture diffuse; + LoadedTexture mask = null; + + var overrideAlpha = (flags & MaterialFlags.OverrideAlpha) == MaterialFlags.OverrideAlpha; + var vehicle = (flags & MaterialFlags.Vehicle) == MaterialFlags.Vehicle; + + if (!overrideAlpha && src.Colour.A != 255) + { + flags |= MaterialFlags.Alpha; + } + + if (src.TextureCount > 0) + { + var tex = src.Textures[0]; + diffuse = txds.GetDiffuse(tex.TextureName); + + if (src.TextureCount > 1) + { + Debug.LogFormat("Something has {0} textures!", src.TextureCount); + } + + if (diffuse == null) + { + Debug.LogWarningFormat("Unable to find texture {0}", tex.TextureName); + } + + if (!string.IsNullOrEmpty(tex.MaskName)) + { + mask = txds.GetAlpha(tex.MaskName) ?? diffuse; + } + else if (vehicle) + { + mask = diffuse; + } + + if (!overrideAlpha && mask != null && mask.HasAlpha) + { + flags |= MaterialFlags.Alpha; + } + } + else + { + diffuse = WhiteTex; + } + + var shader = GetShader(flags); + var mat = new UnityEngine.Material(shader); + + var clr = Types.Convert(src.Colour); + + if (vehicle) + { + var found = false; + for (var i = 1; i < _sKeyColors.Length; ++i) + { + var key = _sKeyColors[i]; + if (key.r != clr.r || key.g != clr.g || key.b != clr.b) continue; + mat.SetInt(CarColorIndexId, i); + found = true; + break; + } + + if (found) + { + mat.color = Color.white; + } + else + { + mat.color = clr; + } + } + else + { + mat.color = clr; + } + + if (diffuse != null) mat.SetTexture(MainTexId, diffuse.Texture); + if (mask != null) mat.SetTexture(MaskTexId, mask.Texture); + + mat.SetFloat(MetallicId, src.Specular); + mat.SetFloat(SmoothnessId, src.Smoothness); + + return mat; + } + + private static Mesh Convert(RenderWareStream.Geometry src) + { + var mesh = new Mesh(); + + // ReSharper disable ConvertClosureToMethodGroup + mesh.vertices = src.Vertices.Select(x => Types.Convert(x)).ToArray(); + + if (src.Normals != null) + { + mesh.normals = src.Normals.Select(x => Types.Convert(x)).ToArray(); + } + + if (src.Colours != null) + { + mesh.colors32 = src.Colours.Select(x => Types.Convert(x)).ToArray(); + } + + if (src.TexCoords != null && src.TexCoords.Length > 0) + { + mesh.uv = src.TexCoords[0].Select(x => Types.Convert(x)).ToArray(); + } + // ReSharper restore ConvertClosureToMethodGroup + + if (src.Normals == null) + { + mesh.normals = CalculateNormals(src, mesh.vertices); + } + + mesh.subMeshCount = src.MaterialSplits.Length; + + var isTriangleStrip = (src.Flags & GeometryFlag.TriangleStrips) == GeometryFlag.TriangleStrips; + + var subMesh = 0; + foreach (var split in src.MaterialSplits) + { + var indices = isTriangleStrip + ? FromTriangleStrip(split.FaceIndices) + : split.FaceIndices; + mesh.SetIndices(indices, MeshTopology.Triangles, subMesh++); + } + + mesh.RecalculateBounds(); + + return mesh; + } + + private static GeometryFrame Convert(RenderWareStream.Frame src, IEnumerable atomics) + { + var atomic = atomics.FirstOrDefault(x => x.FrameIndex == src.Index); + + return new GeometryFrame(src, atomic); + } + + private static Transform[] Convert(HierarchyAnimation hAnim, Dictionary transforms, IEnumerable frames) + { + var dict = frames.Where(x => x.Source.HAnim != null) + .ToDictionary(x => x.Source.HAnim.NodeId, x => transforms[x]); + + return hAnim.Nodes.Select(x => dict[x.NodeId]).ToArray(); + } + + public class GeometryFrame + { + public const string DefaultName = "unnamed"; + + public readonly RenderWareStream.Frame Source; + + public readonly string Name; + public readonly UnityEngine.Vector3 Position; + public readonly UnityEngine.Quaternion Rotation; + + public readonly int ParentIndex; + public readonly int GeometryIndex; + + public GeometryFrame(RenderWareStream.Frame src, RenderWareStream.Atomic atomic) + { + Source = src; + + Name = src.Name != null ? src.Name.Value : DefaultName; + ParentIndex = src.ParentIndex; + GeometryIndex = atomic == null ? -1 : (int)atomic.GeometryIndex; + + Position = Types.Convert(src.Position); + Rotation = UnityEngine.Quaternion.LookRotation(Types.Convert(src.MatrixForward), Types.Convert(src.MatrixUp)); + } + + public override int GetHashCode() + { + return Source.Index; + } + } + + public class GeometryParts + { + private readonly CollisionFile _collisions; + public CollisionFile Collisions { get { return _collisions; } } + + public readonly string Name; + public readonly Geometry[] Geometry; + public readonly GeometryFrame[] Frames; + + public GeometryParts(string name, Clump clump, TextureDictionary[] txds) + { + Name = name; + + Geometry = clump.GeometryList.Geometry + .Select(x => new Geometry(x, Convert(x), txds)) + .ToArray(); + + Frames = clump.FrameList.Frames + .Select(x => Convert(x, clump.Atomics)) + .ToArray(); + + _collisions = clump.Collision; + } + + public void AttachCollisionModel(Transform destParent, bool forceConvex = false) + { + Profiler.BeginSample ("AttachCollisionModel"); + if (_collisions != null) + { + CollisionModel.Load(_collisions, destParent, forceConvex); + } + else + { + CollisionModel.Load(Name, destParent, forceConvex); + } + Profiler.EndSample (); + } + + public FrameContainer AttachFrames(Transform destParent, MaterialFlags flags) + { + var transforms = Frames.ToDictionary(x => x, x => + { + var trans = new GameObject(x.Name).transform; + trans.localPosition = x.Position; + trans.localRotation = x.Rotation; + return trans; + }); + + var container = destParent.gameObject.AddComponent(); + + foreach (var frame in Frames) + { + if (frame.ParentIndex != -1) + { + transforms[frame].SetParent(transforms[Frames[frame.ParentIndex]], false); + } + else + { + transforms[frame].SetParent(destParent, false); + } + + if (frame.GeometryIndex != -1) + { + var gobj = transforms[frame].gameObject; + var geometry = Geometry[frame.GeometryIndex]; + + HierarchyAnimation hAnim = null; + var parent = frame; + while ((hAnim = parent.Source.HAnim) == null || hAnim.NodeCount == 0) + { + if (parent.ParentIndex == -1) + { + hAnim = null; + break; + } + parent = Frames[parent.ParentIndex]; + } + + Renderer renderer; + if (hAnim != null) + { + var smr = gobj.AddComponent(); + + var bones = Convert(hAnim, transforms, Frames); + + smr.rootBone = bones[0]; + smr.bones = bones; + + smr.sharedMesh = geometry.Mesh; + + if (smr.sharedMesh != null) + { + smr.sharedMesh.bindposes = geometry.SkinToBoneMatrices + .Select(x => x.transpose) + .ToArray(); + } + + renderer = smr; + } + else + { + var mf = gobj.AddComponent(); + mf.sharedMesh = geometry.Mesh; + + renderer = gobj.AddComponent(); + } + + renderer.sharedMaterials = geometry.GetMaterials(flags); + + // filter these out for now + if (frame.Name.EndsWith("_vlo") || + frame.Name.EndsWith("_dam")) + { + gobj.SetActive(false); + } + } + } + + container.Initialize(Frames, transforms); + + return container; + } + } + + + private static Utilities.AsyncLoader s_asyncLoader = new Utilities.AsyncLoader (); + + public static int NumGeometryPartsLoaded { get { return s_asyncLoader.GetNumObjectsLoaded (); } } + + + public static GeometryParts Load(string modelName, params string[] texDictNames) + { + return Load(modelName, texDictNames.Select(x => TextureDictionary.Load(x)).ToArray()); + } + + public static void LoadAsync(string modelName, string[] texDictNames, System.Action onFinish) + { + // load each texture asyncly (or load them all at once ?) + + // copy array to local variable + texDictNames = texDictNames.ToArray (); + + if (0 == texDictNames.Length) + { + LoadAsync( modelName, new TextureDictionary[0], onFinish ); + return; + } + + + var loadedTextDicts = new List (); + + for (int i = 0; i < texDictNames.Length; i++) + { + // bool isLast = i == texDictNames.Length - 1; + + TextureDictionary.LoadAsync (texDictNames [i], (texDict) => { + + loadedTextDicts.Add (texDict); + + if (loadedTextDicts.Count == texDictNames.Length) + { + // finished loading all tex dicts + LoadAsync (modelName, loadedTextDicts.ToArray (), onFinish); + } + }); + } + + } + + public static GeometryParts Load(string modelName, params TextureDictionary[] txds) + { + modelName = modelName.ToLower(); + + if (s_asyncLoader.IsObjectLoaded(modelName)) + { + return s_asyncLoader.GetLoadedObject (modelName); + } + + Profiler.BeginSample ("ReadClump"); + var clump = ArchiveManager.ReadFile(modelName + ".dff"); + Profiler.EndSample (); + + if (clump.GeometryList == null) + { + throw new Exception("Invalid mesh"); + } + + Profiler.BeginSample ("Create GeometryParts"); + var loaded = new GeometryParts(modelName, clump, txds); + Profiler.EndSample (); + + s_asyncLoader.AddToLoadedObjects (modelName, loaded); + + return loaded; + } + + public static void LoadAsync(string modelName, TextureDictionary[] txds, System.Action onFinish) + { + modelName = modelName.ToLower(); + + if (!s_asyncLoader.TryLoadObject (modelName, onFinish)) + { + // callback is either called or registered + return; + } + + + GeometryParts loadedGeoms = null; + + LoadingThread.RegisterJob (new LoadingThread.Job () { + action = () => { + // read archive file in background thread + var clump = ArchiveManager.ReadFile(modelName + ".dff"); + return clump; + }, + callbackSuccess = (Clump clump) => { + if (clump.GeometryList == null) + { + throw new Exception("Invalid mesh"); + } + + // create geometry parts in main thread + loadedGeoms = new GeometryParts(modelName, clump, txds); + + }, + callbackFinish = (result) => { + s_asyncLoader.OnObjectFinishedLoading( modelName, loadedGeoms, loadedGeoms != null ); + } + }); + + } + + public readonly Mesh Mesh; + + private readonly RenderWareStream.Geometry _geom; + public readonly TextureDictionary[] _textureDictionaries; + private readonly Dictionary _materials; + + public readonly UnityEngine.Matrix4x4[] SkinToBoneMatrices; + + private Geometry(RenderWareStream.Geometry geom, Mesh mesh, TextureDictionary[] textureDictionaries) + { + Mesh = mesh; + + if (geom.Skinning != null) + { + Mesh.boneWeights = Types.Convert(geom.Skinning.VertexBoneIndices, geom.Skinning.VertexBoneWeights); + SkinToBoneMatrices = Types.Convert(geom.Skinning.SkinToBoneMatrices); + } + + _geom = geom; + _textureDictionaries = textureDictionaries; + _materials = new Dictionary(); + } + + public UnityEngine.Material[] GetMaterials(ObjectFlag flags) + { + return GetMaterials(flags, x => { }); + } + + public UnityEngine.Material[] GetMaterials(ObjectFlag flags, + Action setupMaterial) + { + var matFlags = MaterialFlags.Default | MaterialFlags.OverrideAlpha; + + if ((flags & ObjectFlag.NoBackCull) == ObjectFlag.NoBackCull) + { + matFlags |= MaterialFlags.NoBackCull; + } + + if ((flags & (ObjectFlag.Alpha1 | ObjectFlag.Alpha2)) != 0 + && (flags & ObjectFlag.DisableShadowMesh) == ObjectFlag.DisableShadowMesh) + { + matFlags |= MaterialFlags.Alpha; + } + + return GetMaterials(matFlags, setupMaterial); + } + + public UnityEngine.Material[] GetMaterials(MaterialFlags flags) + { + return GetMaterials(flags, x => { }); + } + + public UnityEngine.Material[] GetMaterials(MaterialFlags flags, + Action setupMaterial) + { + if (_materials.ContainsKey(flags)) + { + return _materials[flags]; + } + + var mats = _geom.Materials.Select(x => + { + var mat = Convert(x, _textureDictionaries, flags); + setupMaterial(mat); + return mat; + }).ToArray(); + + mats = _geom.MaterialSplits.Select(x => mats[x.MaterialIndex]).ToArray(); + + _materials.Add(flags, mats); + + return mats; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Conversion/Geometry.cs.meta b/Assets/Scripts/Importing/Conversion/Geometry.cs.meta new file mode 100644 index 00000000..bd4f4941 --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/Geometry.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ac1c41c7051cab048b2776e6c91e95a4 +timeCreated: 1427154765 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Conversion/TextureDictionary.cs b/Assets/Scripts/Importing/Conversion/TextureDictionary.cs new file mode 100644 index 00000000..a1662385 --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/TextureDictionary.cs @@ -0,0 +1,397 @@ +using SanAndreasUnity.Importing.Archive; +using SanAndreasUnity.Importing.RenderWareStream; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Importing.Conversion +{ + public static class TextureDictionaryExtensions + { + public static LoadedTexture GetDiffuse(this TextureDictionary[] txds, string name) + { + foreach (var txd in txds) + { + var tex = txd.GetDiffuse(name); + if (tex != null) return tex; + } + + return null; + } + + public static LoadedTexture GetAlpha(this TextureDictionary[] txds, string name) + { + foreach (var txd in txds) + { + var tex = txd.GetAlpha(name); + if (tex != null) return tex; + } + + return null; + } + } + + public class LoadedTexture + { + public readonly Texture2D Texture; + public readonly bool HasAlpha; + + public LoadedTexture(Texture2D tex, bool hasAlpha) + { + Texture = tex; + HasAlpha = hasAlpha; + } + } + + public class TextureDictionary + { + private static byte[] ConvertDXT3ToDXT5(byte[] data) + { + for (var i = 0; i < data.Length; i += 16) + { + ulong packed = 0; + + for (var j = 0; j < 16; ++j) + { + var s = 1 | ((j & 1) << 2); + var c = (data[i + (j >> 1)] >> s) & 0x7; + + switch (c) + { + case 0: + c = 1; + break; + + case 7: + c = 0; + break; + + default: + c = 8 - c; + break; + } + + packed |= ((ulong)c << (3 * j)); + } + + data[i + 0] = 0xff; + data[i + 1] = 0x00; + + for (var j = 0; j < 6; ++j) + { + data[i + 2 + j] = (byte)((packed >> (j << 3)) & 0xff); + } + } + + return data; + } + + private static byte[] ConvertBGRToRGB(byte[] data) + { + for (var i = 0; i < data.Length; i += 4) + { + var t = data[i]; + data[i] = data[i + 2]; + data[i + 2] = t; + } + + return data; + } + + private static readonly byte[] _sR5G5B5Lookup = Enumerable.Range(0, 0x20) + .Select(x => (byte)Math.Round(((double)x / 0x1f) * 0xff)) + .ToArray(); + + private static byte[] ConvertA1R5G5B5ToARGB32(byte[] data) + { + var dest = new byte[data.Length << 1]; + + for (var i = 0; i < data.Length - 1; i += 2) + { + var val = data[i] | (data[i + 1] << 8); + var d = i << 1; + + dest[d + 0] = (byte)((val & 1) == 1 ? 0xff : 0); + dest[d + 1] = _sR5G5B5Lookup[(val >> 1) & 0x1f]; + dest[d + 2] = _sR5G5B5Lookup[(val >> 6) & 0x1f]; + dest[d + 3] = _sR5G5B5Lookup[(val >> 11) & 0x1f]; + } + + return dest; + } + + private static LoadedTexture Convert(TextureNative src) + { + TextureFormat format; + + var loadMips = (src.Format & RasterFormat.ExtMipMap) == RasterFormat.ExtMipMap; + var autoMips = (src.Format & RasterFormat.ExtAutoMipMap) == RasterFormat.ExtAutoMipMap; + + switch (src.Format & RasterFormat.NoExt) + { + case RasterFormat.BGRA8: + case RasterFormat.BGR8: + format = TextureFormat.RGBA32; + break; + + case RasterFormat.LUM8: + format = TextureFormat.Alpha8; + break; + + case RasterFormat.R4G4B4A4: + format = TextureFormat.RGBA4444; + break; + + case RasterFormat.A1R5G5B5: + format = TextureFormat.ARGB32; + break; + + case RasterFormat.R5G6B5: + format = TextureFormat.RGB565; + break; + + default: + throw new NotImplementedException(string.Format("RasterFormat.{0}", src.Format & RasterFormat.NoExt)); + } + + switch (src.Compression) + { + case CompressionMode.None: + break; + + case CompressionMode.DXT1: + format = TextureFormat.DXT1; + break; + + case CompressionMode.DXT3: + format = TextureFormat.DXT5; + break; + + default: + throw new NotImplementedException(string.Format("CompressionMode.{0}", src.Compression)); + } + + var tex = new Texture2D(src.Width, src.Height, format, false /*loadMips*/); + + switch (src.FilterFlags) + { + case Filter.None: + case Filter.Nearest: + case Filter.MipNearest: + tex.filterMode = FilterMode.Point; + break; + + case Filter.Linear: + case Filter.MipLinear: + case Filter.LinearMipNearest: + tex.filterMode = FilterMode.Bilinear; + break; + + case Filter.LinearMipLinear: + case Filter.Unknown: + tex.filterMode = FilterMode.Trilinear; + break; + } + + var data = src.ImageData; + + switch (src.Format & RasterFormat.NoExt) + { + case RasterFormat.BGR8: + case RasterFormat.BGRA8: + data = ConvertBGRToRGB(data); + break; + } + + switch (src.Compression) + { + case CompressionMode.DXT3: + data = ConvertDXT3ToDXT5(data); + break; + } + + tex.LoadRawTextureData(data); + tex.Apply(loadMips || autoMips, + false /* true */); // makeNoLongerReadable: needed to flip GUI textures. doubles memory used for textures! + + return new LoadedTexture(tex, src.Alpha); + } + + + private static readonly Dictionary _sParents = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + + private static readonly Utilities.AsyncLoader s_asyncLoader = + new Utilities.AsyncLoader (StringComparer.InvariantCultureIgnoreCase); + + + public static TextureDictionary Load(string name) + { + name = name.ToLower(); + if (s_asyncLoader.IsObjectLoaded (name)) + return s_asyncLoader.GetLoadedObject (name); + + UnityEngine.Profiling.Profiler.BeginSample ("TextureDictionary.Load"); + + var txd = new TextureDictionary(ArchiveManager.ReadFile(name + ".txd")); + s_asyncLoader.AddToLoadedObjects(name, txd); + + UnityEngine.Profiling.Profiler.EndSample (); + + return txd; + } + + public static void LoadAsync(string name, System.Action onFinish) + { + name = name.ToLower(); + + if (!s_asyncLoader.TryLoadObject (name, onFinish)) + return; + + + // read archive file asyncly + + TextureDictionary loadedTxd = null; + + Behaviours.LoadingThread.RegisterJob (new Behaviours.LoadingThread.Job () { + action = () => { + return ArchiveManager.ReadFile(name + ".txd"); + }, + callbackSuccess = (RenderWareStream.TextureDictionary td) => { + UnityEngine.Profiling.Profiler.BeginSample ("TextureDictionary()"); + loadedTxd = new TextureDictionary (td); + UnityEngine.Profiling.Profiler.EndSample (); + + }, + callbackFinish = (result) => { + s_asyncLoader.OnObjectFinishedLoading( name, loadedTxd, loadedTxd != null ); + } + }); + + } + + public static void AddParent(string dictName, string parentName) + { + dictName = dictName.ToLower(); + parentName = parentName.ToLower(); + + if (_sParents.ContainsKey(dictName)) return; + + _sParents.Add(dictName, parentName); + + if (s_asyncLoader.IsObjectLoaded(dictName)) + { + s_asyncLoader.GetLoadedObject(dictName).ParentName = parentName; + } + } + + private class Texture + { + private LoadedTexture _converted; + private bool _attemptedConversion; + + public string DiffuseName { get { return Native.DiffuseName; } } + public string AlphaName { get { return Native.AlphaName; } } + + public bool IsDiffuse { get { return !string.IsNullOrEmpty(DiffuseName); } } + public bool IsAlpha { get { return !string.IsNullOrEmpty(AlphaName); } } + + public LoadedTexture Converted + { + get + { + if (_attemptedConversion) return _converted; + _attemptedConversion = true; + _converted = Convert(Native); + return _converted; + } + } + + public readonly TextureNative Native; + + public Texture(TextureNative native) + { + Native = native; + } + } + + private readonly Dictionary _diffuse; + private readonly Dictionary _alpha; + private TextureDictionary _parent; + + public string ParentName { get; set; } + + public TextureDictionary Parent + { + get { return _parent ?? (_parent = Load(ParentName)); } + } + + public IEnumerable DiffuseNames + { + get { return _diffuse.Keys; } + } + + public IEnumerable AlphaNames + { + get { return _alpha.Keys; } + } + + private TextureDictionary(RenderWareStream.TextureDictionary txd) + { + _diffuse = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + _alpha = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + + foreach (var native in txd.Textures) + { + var tex = new Texture(native); + + if (tex.IsDiffuse) + { + _diffuse.Add(tex.DiffuseName, tex); + } + + if (tex.IsAlpha) + { + if (_alpha.ContainsKey(tex.AlphaName)) + { + Debug.LogWarningFormat("Tried to re-add {0} (diffuse {1} vs {2})", + tex.AlphaName, tex.DiffuseName, _alpha[tex.AlphaName].DiffuseName); + continue; + } + + _alpha.Add(tex.AlphaName, tex); + } + } + } + + public TextureNative GetDiffuseNative(string name) + { + if (!_diffuse.ContainsKey(name)) + { + return ParentName != null ? Parent.GetDiffuseNative(name) : null; + } + + return _diffuse[name].Native; + } + + public LoadedTexture GetDiffuse(string name) + { + if (!_diffuse.ContainsKey(name)) + { + return ParentName != null ? Parent.GetDiffuse(name) : null; + } + + return _diffuse[name].Converted; + } + + public LoadedTexture GetAlpha(string name) + { + if (!_alpha.ContainsKey(name)) + { + return ParentName != null ? Parent.GetAlpha(name) : null; + } + + return _alpha[name].Converted; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Conversion/TextureDictionary.cs.meta b/Assets/Scripts/Importing/Conversion/TextureDictionary.cs.meta new file mode 100644 index 00000000..9a7dbf44 --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/TextureDictionary.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b5b09735aa719404abe49b6b9b3b5793 +timeCreated: 1427203966 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Conversion/Types.cs b/Assets/Scripts/Importing/Conversion/Types.cs new file mode 100644 index 00000000..147d5c64 --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/Types.cs @@ -0,0 +1,88 @@ +using SanAndreasUnity.Importing.RenderWareStream; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Importing.Conversion +{ + public class Types + { + public static UnityEngine.Vector2 Convert(Vector2 vec) + { + return new UnityEngine.Vector2(vec.X, vec.Y); + } + + public static UnityEngine.Vector3 Convert(Vector3 vec) + { + return new UnityEngine.Vector3(vec.X, vec.Z, vec.Y); + } + + public static Color32 Convert(Color4 clr) + { + return new Color32(clr.R, clr.G, clr.B, clr.A); + } + + public static UnityEngine.BoneWeight Convert(SkinBoneIndices boneIndices, SkinBoneWeights boneWeights) + { + return new UnityEngine.BoneWeight + { + boneIndex0 = (int)boneIndices.Indices[0], + boneIndex1 = (int)boneIndices.Indices[1], + boneIndex2 = (int)boneIndices.Indices[2], + boneIndex3 = (int)boneIndices.Indices[3], + + weight0 = boneWeights.Weights[0], + weight1 = boneWeights.Weights[1], + weight2 = boneWeights.Weights[2], + weight3 = boneWeights.Weights[3], + }; + } + + public static UnityEngine.BoneWeight[] Convert(SkinBoneIndices[] boneIndices, SkinBoneWeights[] boneWeights) + { + return Enumerable.Range(0, (int)boneIndices.Length).Select(x => Convert(boneIndices[x], boneWeights[x])).ToArray(); + } + + public static UnityEngine.Vector4 Convert(Vector4 vec) + { + return new UnityEngine.Vector4(vec.X, vec.Z, vec.Y, vec.W); + } + + public static UnityEngine.Quaternion Convert(Quaternion quat) + { + return new UnityEngine.Quaternion(quat.X, quat.Z, quat.Y, -quat.W); + } + + public static UnityEngine.Matrix4x4 Convert(Matrix4x4 mat) + { + UnityEngine.Vector4 v0 = Convert(mat.V0); + UnityEngine.Vector4 v1 = Convert(mat.V2); + UnityEngine.Vector4 v2 = Convert(mat.V1); + UnityEngine.Vector4 v3 = Convert(mat.V3); + + return new UnityEngine.Matrix4x4 + { + m00 = v0.x, + m01 = v0.y, + m02 = v0.z, + m03 = 0f, + m10 = v1.x, + m11 = v1.y, + m12 = v1.z, + m13 = 0f, + m20 = v2.x, + m21 = v2.y, + m22 = v2.z, + m23 = 0f, + m30 = v3.x, + m31 = v3.y, + m32 = v3.z, + m33 = 1f, + }; + } + + public static UnityEngine.Matrix4x4[] Convert(Matrix4x4[] mat) + { + return Enumerable.Range(0, (int)mat.Length).Select(x => Convert(mat[x])).ToArray(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Conversion/Types.cs.meta b/Assets/Scripts/Importing/Conversion/Types.cs.meta new file mode 100644 index 00000000..16ff863a --- /dev/null +++ b/Assets/Scripts/Importing/Conversion/Types.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f3fd4a2110453084e9ee36ca9d4354b8 +timeCreated: 1428774705 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items.meta b/Assets/Scripts/Importing/Items.meta new file mode 100644 index 00000000..c0fcba1e --- /dev/null +++ b/Assets/Scripts/Importing/Items.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f80fc2eb9f620f0418704d67743a2f04 +folderAsset: yes +timeCreated: 1427209777 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Definitions.meta b/Assets/Scripts/Importing/Items/Definitions.meta new file mode 100644 index 00000000..436d5d7d --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: db5120e932acda643931ad8976a5e27a +folderAsset: yes +timeCreated: 1428168719 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Definitions/CarColors.cs b/Assets/Scripts/Importing/Items/Definitions/CarColors.cs new file mode 100644 index 00000000..76b0c330 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/CarColors.cs @@ -0,0 +1,76 @@ +namespace SanAndreasUnity.Importing.Items.Definitions +{ + [Section("col")] + public class ColorDef : Definition + { + public readonly byte R; + public readonly byte G; + public readonly byte B; + + public ColorDef(string line) + : base(line.Replace('.', ',')) + { + R = GetByte(0); + G = GetByte(1); + B = GetByte(2); + } + } + + public abstract class CarColorDef : Definition + { + public struct ColorIndices + { + public readonly int A; + public readonly int B; + public readonly int C; + public readonly int D; + + public ColorIndices(int a, int b, int c = -1, int d = -1) + { + A = a; + B = b; + C = c; + D = d; + } + } + + public readonly string Name; + public readonly ColorIndices[] Colors; + + public readonly bool Is4Color; + + protected CarColorDef(string line, int indicesPerEntry) + : base(line) + { + Name = GetString(0); + Colors = new ColorIndices[(Parts - 1) / indicesPerEntry]; + Is4Color = indicesPerEntry >= 4; + } + } + + [Section("car")] + public class CarColor2Def : CarColorDef + { + public CarColor2Def(string line) + : base(line, 2) + { + for (var i = 0; i < Colors.Length; ++i) + { + Colors[i] = new ColorIndices(GetInt(i * 2 + 1), GetInt(i * 2 + 2)); + } + } + } + + [Section("car4")] + public class CarColor4Def : CarColorDef + { + public CarColor4Def(string line) + : base(line, 4) + { + for (var i = 0; i < Colors.Length; ++i) + { + Colors[i] = new ColorIndices(GetInt(i * 4 + 1), GetInt(i * 4 + 2), GetInt(i * 4 + 3), GetInt(i * 4 + 4)); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Definitions/CarColors.cs.meta b/Assets/Scripts/Importing/Items/Definitions/CarColors.cs.meta new file mode 100644 index 00000000..42016500 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/CarColors.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8e13df1536c5d3241b82109db509ea7e +timeCreated: 1429097715 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Definitions/ObjectDef.cs b/Assets/Scripts/Importing/Items/Definitions/ObjectDef.cs new file mode 100644 index 00000000..d8234b4f --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/ObjectDef.cs @@ -0,0 +1,58 @@ +using System; + +namespace SanAndreasUnity.Importing.Items.Definitions +{ + [Flags] + public enum ObjectFlag : uint + { + None = 0, + WetEffect = 1, + RenderAtNight = 2, + Alpha1 = 4, + Alpha2 = 8, + RenderAtDay = 16, + Interior = 32, + DisableShadowMesh = 64, + NoCull = 128, + DisableDrawDist = 256, + Breakable = 512, + BreakableCrack = 1024, + GarageDoor = 2048, + MultiClumpCollide = 4096, + WeatherBrightness = 32768, + ExplodeHit = 65536, + MultiClumpSpray = 1048576, + NoBackCull = 2097152 + } + + [Section("objs")] + public class ObjectDef : Definition, IObjectDefinition + { + public readonly int Id; + + int IObjectDefinition.Id + { + get { return Id; } + } + + public readonly string ModelName; + public readonly string TextureDictionaryName; + + public readonly float DrawDist; + public readonly ObjectFlag Flags; + + public ObjectDef(string line) : base(line) + { + Id = GetInt(0); + ModelName = GetString(1); + TextureDictionaryName = GetString(2); + DrawDist = GetSingle(3); + Flags = (ObjectFlag)GetInt(4); + } + + public bool HasFlag(ObjectFlag flag) + { + return (Flags & flag) == flag; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Definitions/ObjectDef.cs.meta b/Assets/Scripts/Importing/Items/Definitions/ObjectDef.cs.meta new file mode 100644 index 00000000..c5c24f0c --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/ObjectDef.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 819e4ed5c46f278438a6f1027b6939a3 +timeCreated: 1428168719 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Definitions/PedestrianDef.cs b/Assets/Scripts/Importing/Items/Definitions/PedestrianDef.cs new file mode 100644 index 00000000..894219e7 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/PedestrianDef.cs @@ -0,0 +1,71 @@ +using System; +using System.Globalization; + +namespace SanAndreasUnity.Importing.Items.Definitions +{ + [Flags] + public enum PedestrianType + { + Player1 = 0, + + Civilian = 8, + CivMale = Civilian | 0, + CivFemale = Civilian | 1, + + Criminal = 16, + Prostitute = Criminal | 1, + + EmergencyServices = 32, + Cop = EmergencyServices | 0, + Medic = EmergencyServices | 1, + FireMan = EmergencyServices | 2, + + GangMember = 64, + Gang1 = GangMember | 0, + Gang2 = GangMember | 1, + Gang3 = GangMember | 2, + Gang4 = GangMember | 3, + Gang5 = GangMember | 4, + Gang6 = GangMember | 5, + Gang7 = GangMember | 6, + Gang8 = GangMember | 7 + } + + [Section("peds")] + public class PedestrianDef : Definition, IObjectDefinition + { + public readonly int Id; + + int IObjectDefinition.Id + { + get { return Id; } + } + + public readonly string ModelName; + public readonly string TextureDictionaryName; + public readonly PedestrianType DefaultType; + public readonly string BehaviourName; + public readonly string AnimGroupName; + public readonly uint CanDriveMask; + public readonly uint Flags; + public readonly string AnimFileName; + public readonly int Radio1; + public readonly int Radio2; + + public PedestrianDef(string line) + : base(line) + { + Id = GetInt(0); + ModelName = GetString(1); + TextureDictionaryName = GetString(2); + DefaultType = (PedestrianType)Enum.Parse(typeof(PedestrianType), GetString(3), true); + BehaviourName = GetString(4); + AnimGroupName = GetString(5); + CanDriveMask = (uint)GetInt(6, NumberStyles.HexNumber); + Flags = (uint)GetInt(7); + AnimFileName = GetString(8); + Radio1 = GetInt(9); + Radio2 = GetInt(10); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Definitions/PedestrianDef.cs.meta b/Assets/Scripts/Importing/Items/Definitions/PedestrianDef.cs.meta new file mode 100644 index 00000000..c01d218f --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/PedestrianDef.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9d2437fafbbde754fb8609c316be3e26 +timeCreated: 1428342566 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Definitions/TextureDictionaryParentDef.cs b/Assets/Scripts/Importing/Items/Definitions/TextureDictionaryParentDef.cs new file mode 100644 index 00000000..6f534afb --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/TextureDictionaryParentDef.cs @@ -0,0 +1,14 @@ +using SanAndreasUnity.Importing.Conversion; + +namespace SanAndreasUnity.Importing.Items.Definitions +{ + [Section("txdp")] + public class TextureDictionaryParentDef : Definition + { + public TextureDictionaryParentDef(string line) + : base(line) + { + TextureDictionary.AddParent(GetString(0), GetString(1)); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Definitions/TextureDictionaryParentDef.cs.meta b/Assets/Scripts/Importing/Items/Definitions/TextureDictionaryParentDef.cs.meta new file mode 100644 index 00000000..6eb3911f --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/TextureDictionaryParentDef.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 411617c73586d204f972012b90774581 +timeCreated: 1428168719 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Definitions/VehicleDef.cs b/Assets/Scripts/Importing/Items/Definitions/VehicleDef.cs new file mode 100644 index 00000000..b6b13385 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/VehicleDef.cs @@ -0,0 +1,81 @@ +using System; +using System.Globalization; + +namespace SanAndreasUnity.Importing.Items.Definitions +{ + public enum VehicleType + { + Trailer, + Bmx, + Bike, + Train, + Boat, + Plane, + Heli, + Quad, + MTruck, + Car + } + + [Section("cars")] + public class VehicleDef : Definition, IObjectDefinition + { + public readonly int Id; + + int IObjectDefinition.Id + { + get { return Id; } + } + + public readonly string ModelName; + public readonly string TextureDictionaryName; + + public readonly VehicleType VehicleType; + + public readonly string HandlingName; + public readonly string GameName; + public readonly string AnimsName; + public readonly string ClassName; + + public readonly int Frequency; + public readonly int Flags; + public readonly int CompRules; + + public readonly bool HasWheels; + + public readonly int WheelId; + public readonly float WheelScaleFront; + public readonly float WheelScaleRear; + + public readonly int UpgradeId; + + public VehicleDef(string line) : base(line) + { + Id = GetInt(0); + + ModelName = GetString(1); + TextureDictionaryName = GetString(2); + + VehicleType = (VehicleType)Enum.Parse(typeof(VehicleType), GetString(3), true); + + HandlingName = GetString(4); + GameName = GetString(5); + AnimsName = GetString(6); + ClassName = GetString(7); + + Frequency = GetInt(8); + Flags = GetInt(9); + CompRules = GetInt(10, NumberStyles.HexNumber); + + HasWheels = Parts >= 15; + + if (HasWheels) + { + WheelId = GetInt(11); + WheelScaleFront = GetSingle(12); + WheelScaleRear = GetSingle(13); + UpgradeId = GetInt(14); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Definitions/VehicleDef.cs.meta b/Assets/Scripts/Importing/Items/Definitions/VehicleDef.cs.meta new file mode 100644 index 00000000..8233e123 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/VehicleDef.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b04940d8e73567b428badaf55470b94b +timeCreated: 1428168719 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Definitions/WeaponDef.cs b/Assets/Scripts/Importing/Items/Definitions/WeaponDef.cs new file mode 100644 index 00000000..faa54455 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/WeaponDef.cs @@ -0,0 +1,32 @@ +namespace SanAndreasUnity.Importing.Items.Definitions +{ + [Section("weap")] + public class WeaponDef : Definition, IObjectDefinition + { + public readonly int Id; + + int IObjectDefinition.Id + { + get { return Id; } + } + + public readonly string ModelName; + public readonly string TextureDictionaryName; + public readonly string AnimationFileName; + public readonly int NumMeshes; // always 1 + public readonly float DrawDistance; + public readonly int Flags; // doesn't seem to be read by the game + + public WeaponDef(string line) + : base(line) + { + Id = GetInt(0); + ModelName = GetString(1); + TextureDictionaryName = GetString(2); + AnimationFileName = GetString(3); + NumMeshes = GetInt(4); + DrawDistance = GetSingle(5); + Flags = GetInt(6); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Definitions/WeaponDef.cs.meta b/Assets/Scripts/Importing/Items/Definitions/WeaponDef.cs.meta new file mode 100644 index 00000000..8864d1d4 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Definitions/WeaponDef.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a72884a1fba7eee41b7973b596eb1c10 +timeCreated: 1474299027 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Item.cs b/Assets/Scripts/Importing/Items/Item.cs new file mode 100644 index 00000000..03012128 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Item.cs @@ -0,0 +1,147 @@ +using SanAndreasUnity.Importing.Archive; +using SanAndreasUnity.Importing.Items.Placements; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace SanAndreasUnity.Importing.Items +{ + public static class Item + { + private static readonly List _zones = new List(); + + private static readonly Dictionary _definitions + = new Dictionary(); + + private static readonly Dictionary> _placements + = new Dictionary>(); + + public static void ReadLoadList(string path) + { + var ws = new[] { ' ', '\t' }; + + using (var reader = File.OpenText(path)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + line = line.Trim(); + + if (line.Length == 0) continue; + if (line.StartsWith("#")) continue; + + var index = line.IndexOfAny(ws); + if (index == -1) continue; + + var type = line.Substring(0, index); + var args = line.Substring(index).TrimStart(); + + args = args.Replace("DATA\\MAPS\\", "data/maps/"); + args = args.Replace(".IDE", ".ide"); + args = args.Replace(".IPL", ".ipl"); + args = args.Replace('\\', Path.DirectorySeparatorChar); + + switch (type.ToLower()) + { + case "ide": + ReadIde(args); + break; + + case "ipl": + ReadIpl(args); + break; + } + } + } + } + + public static void ReadIde(string path) + { + var file = new ItemFile(ArchiveManager.GetPath(path)); + foreach (var obj in file.GetItems().OfType()) + { + _definitions.Add(obj.Id, obj); + } + } + + public static void ReadIpl(string path) + { + var file = new ItemFile(ArchiveManager.GetPath(path)); + foreach (var zone in file.GetSection("zone")) + { + _zones.Add(zone); + } + + var insts = file.GetSection("inst"); + + var list = new List(); + list.AddRange(insts); + + var cars = new List(file.GetSection("cars")); + + var streamFormat = Path.GetFileNameWithoutExtension(path).ToLower() + "_stream{0}.ipl"; + var missed = 0; + for (var i = 0; ; ++i) + { + var streamPath = string.Format(streamFormat, i); + if (!ArchiveManager.FileExists(streamPath)) + { + ++missed; + + if (missed > 10) break; + continue; + } + + file = new ItemFile(ArchiveManager.ReadFile(streamPath)); + list.AddRange(file.GetSection("inst")); + cars.AddRange(file.GetSection("cars")); + } + + list.ResolveLod(); + + var lastCell = -1; + foreach (var inst in list) + { + var cell = inst.CellId & 0xff; + if (lastCell != cell && !_placements.ContainsKey(lastCell = cell)) + { + _placements.Add(cell, new List()); + } + + _placements[cell].Add(inst); + } + + if (!_placements.ContainsKey(0)) + { + _placements.Add(0, new List()); + } + + _placements[0].AddRange(cars.Cast()); + } + + public static TDefinition GetDefinition(int id) + where TDefinition : Definition, IObjectDefinition + { + return !_definitions.ContainsKey(id) ? null : (TDefinition)_definitions[id]; + } + + public static IEnumerable GetDefinitions() + where TDefinition : Definition + { + return _definitions.Values.OfType(); + } + + public static int GetNumDefinitions() + where TDefinition : Definition + { + return _definitions.Count (pair => pair.Value is TDefinition); + } + + public static IEnumerable GetPlacements(params int[] cellIds) + where TPlacement : Placement + { + return cellIds.SelectMany(x => _placements.ContainsKey(x) + ? _placements[x].OfType() : Enumerable.Empty()); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Item.cs.meta b/Assets/Scripts/Importing/Items/Item.cs.meta new file mode 100644 index 00000000..6c7fef80 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Item.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d424e8a1f15f40e408ab38d8937cf892 +timeCreated: 1427213903 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/ItemFile.cs b/Assets/Scripts/Importing/Items/ItemFile.cs new file mode 100644 index 00000000..694bd36e --- /dev/null +++ b/Assets/Scripts/Importing/Items/ItemFile.cs @@ -0,0 +1,247 @@ +using SanAndreasUnity.Importing.Items.Placements; +using SanAndreasUnity.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +#if !ENABLE_IL2CPP +using System.Linq.Expressions; +#endif +using System.Reflection; + +namespace SanAndreasUnity.Importing.Items +{ + public class SectionAttribute : Attribute + { + public readonly string Section; + + public SectionAttribute(string section) + { + Section = section; + } + } + + public abstract class ItemBase + { + private readonly string[] _parts; + + public int Parts { get { return _parts.Length; } } + + protected ItemBase(string line, bool commaSeparated = true) + { + var ws = new[] { ' ', '\t' }; + + if (commaSeparated) + { + _parts = line.Split(',') + .SelectMany(x => x.Split(ws, StringSplitOptions.RemoveEmptyEntries)) + .Select(x => x.Trim()) + .ToArray(); + } + else + { + _parts = line.Split(ws, StringSplitOptions.RemoveEmptyEntries) + .Select(x => x.Trim()) + .Where(x => x.Length > 0) + .ToArray(); + } + } + + protected ItemBase(BinaryReader reader) + { + } + + public string GetString(int index) + { + return _parts[index]; + } + + public byte GetByte(int index) + { + return byte.Parse(_parts[index], CultureInfo.InvariantCulture); + } + + public int GetInt(int index) + { + return int.Parse(_parts[index], CultureInfo.InvariantCulture); + } + + public int GetInt(int index, NumberStyles numberStyles) + { + return int.Parse(_parts[index], numberStyles); + } + + public float GetSingle(int index) + { + return float.Parse(_parts[index], CultureInfo.InvariantCulture); + } + + public double GetDouble(int index) + { + return double.Parse(_parts[index], CultureInfo.InvariantCulture); + } + } + + public abstract class Definition : ItemBase + { + protected Definition(string line, bool commaSeparated = true) + : base(line, commaSeparated) { } + } + + public interface IObjectDefinition + { + int Id { get; } + } + + public abstract class Placement : ItemBase + { + protected Placement(string line, bool commaSeparated = true) + : base(line, commaSeparated) { } + + protected Placement(BinaryReader reader) + : base(reader) { } + } + + public class ItemFile + where TType : ItemBase + { + private delegate TType ItemCtor(string line); + + private static readonly Dictionary _sCtors; + + static ItemFile() + { + _sCtors = new Dictionary(); + + foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) + { + var attrib = (SectionAttribute)type.GetCustomAttributes(typeof(SectionAttribute), false).FirstOrDefault(); + if (attrib == null) continue; + + if (!typeof(TType).IsAssignableFrom(type)) continue; + + var ctor = type.GetConstructor(new[] { typeof(string) }); + +#if !ENABLE_IL2CPP + var line = Expression.Parameter(typeof(string), "line"); + var call = Expression.New(ctor, line); + var cast = Expression.Convert(call, typeof(TType)); + var lamb = Expression.Lambda(cast, line); + + _sCtors.Add(attrib.Section, lamb.Compile()); +#else + _sCtors.Add(attrib.Section, line => (TType) ctor.Invoke(new object[] { line })); +#endif + } + } + + private readonly Dictionary> _sections + = new Dictionary>(); + + public ItemFile(string path) + { + List curSection = null; + ItemCtor curCtor = null; + + using (var reader = File.OpenText(path)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + var hashIndex = line.IndexOf('#'); + if (hashIndex != -1) + { + line = line.Substring(0, hashIndex); + } + + line = line.Trim(); + + if (line.Length == 0) continue; + + if (curSection == null) + { + line = line.ToLower(); + + if (_sections.ContainsKey(line)) + { + curSection = _sections[line]; + } + else + { + curSection = new List(); + _sections.Add(line, curSection); + } + + if (_sCtors.ContainsKey(line)) + { + curCtor = _sCtors[line]; + } + + continue; + } + + if (line.Equals("end")) + { + curSection = null; + curCtor = null; + continue; + } + + if (curCtor == null) continue; + + curSection.Add(curCtor(line)); + } + } + } + + public ItemFile(Stream stream) + { + var reader = new BinaryReader(stream); + + if (reader.ReadString(4) != "bnry") throw new Exception("Not a binary IPL file."); + + var instCount = reader.ReadInt32(); + stream.Seek(12, SeekOrigin.Current); + var carsCount = reader.ReadInt32(); + stream.Seek(4, SeekOrigin.Current); + var instOffset = reader.ReadInt32(); + stream.Seek(28, SeekOrigin.Current); + var carsOffset = reader.ReadInt32(); + + var insts = new List(); + _sections.Add("inst", insts); + + stream.Seek(instOffset, SeekOrigin.Begin); + for (var j = 0; j < instCount; ++j) + { + insts.Add((TType)(ItemBase)new Instance(reader)); + } + + var cars = new List(); + _sections.Add("cars", cars); + + stream.Seek(carsOffset, SeekOrigin.Begin); + for (var j = 0; j < carsCount; ++j) + { + cars.Add((TType)(ItemBase)new ParkedVehicle(reader)); + } + } + + public IEnumerable GetSection(string name) + where TItem : TType + { + name = name.ToLower(); + + return !_sections.ContainsKey(name) + ? Enumerable.Empty() + : _sections[name].Cast(); + } + + public IEnumerable GetItems() + where TItem : TType + { + return _sections.SelectMany(x => x.Value.OfType()); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/ItemFile.cs.meta b/Assets/Scripts/Importing/Items/ItemFile.cs.meta new file mode 100644 index 00000000..f1511175 --- /dev/null +++ b/Assets/Scripts/Importing/Items/ItemFile.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d9593e66fa9aabd4c85225017fa91fce +timeCreated: 1427209779 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Placements.meta b/Assets/Scripts/Importing/Items/Placements.meta new file mode 100644 index 00000000..ee455e93 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 354ad431ea0e75a488397a5f3751892b +folderAsset: yes +timeCreated: 1428168719 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Placements/Instance.cs b/Assets/Scripts/Importing/Items/Placements/Instance.cs new file mode 100644 index 00000000..6846feb7 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements/Instance.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.IO; + +namespace SanAndreasUnity.Importing.Items.Placements +{ + public static class InstanceExtensions + { + public static void ResolveLod(this IList insts) + { + foreach (var inst in insts) + { + if (inst.LodIndex != -1) + { + var lod = inst.LodInstance = insts[inst.LodIndex]; + lod.IsLod = true; + } + } + } + } + + [Section("inst")] + public class Instance : Placement + { + public readonly int ObjectId; + public readonly string LodGeometry; + public readonly int CellId; + public readonly UnityEngine.Vector3 Position; + public readonly UnityEngine.Quaternion Rotation; + public readonly int LodIndex; + + public Instance LodInstance { get; internal set; } + public Definitions.ObjectDef Object { get; internal set; } + + public bool IsLod { get; internal set; } + + //private string DebugX, DebugY, DebugZ; + + public Instance(string line) : base(line) + { + /*string strX = string.Format("X => Value: {0} - Parsed: {1}", GetString(3), GetSingle(3)), + strY = string.Format("Y => Value: {0} - Parsed: {1}", GetString(5), GetSingle(5)), + strZ = string.Format("Z => Value: {0} - Parsed: {1}", GetString(4), GetSingle(4)); + + DebugX = strX; + DebugY = strY; + DebugZ = strZ;*/ + + ObjectId = GetInt(0); + LodGeometry = GetString(1); + CellId = GetInt(2); + Position = new UnityEngine.Vector3(GetSingle(3), GetSingle(5), GetSingle(4)); + Rotation = new UnityEngine.Quaternion(GetSingle(6), GetSingle(8), GetSingle(7), GetSingle(9)); + LodIndex = GetInt(10); + } + + public Instance(BinaryReader reader) : base(reader) + { + var posX = reader.ReadSingle(); + var posZ = reader.ReadSingle(); + var posY = reader.ReadSingle(); + + Position = new UnityEngine.Vector3(posX, posY, posZ); + + var rotX = reader.ReadSingle(); + var rotZ = reader.ReadSingle(); + var rotY = reader.ReadSingle(); + var rotW = reader.ReadSingle(); + + Rotation = new UnityEngine.Quaternion(rotX, rotY, rotZ, rotW); + + ObjectId = reader.ReadInt32(); + CellId = reader.ReadInt32(); + LodIndex = reader.ReadInt32(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Placements/Instance.cs.meta b/Assets/Scripts/Importing/Items/Placements/Instance.cs.meta new file mode 100644 index 00000000..dcadcb39 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements/Instance.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d93ae1892dc267747b76dfbd51ef437e +timeCreated: 1428168719 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Placements/ParkedVehicle.cs b/Assets/Scripts/Importing/Items/Placements/ParkedVehicle.cs new file mode 100644 index 00000000..d437c673 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements/ParkedVehicle.cs @@ -0,0 +1,81 @@ +using System.IO; +using UnityEngine; + +namespace SanAndreasUnity.Importing.Items.Placements +{ + [Section("cars")] + public class ParkedVehicle : Placement + { + public readonly UnityEngine.Vector3 Position; + public readonly float Angle; + public readonly int CarId; + public readonly int[] Colors; + public readonly bool ForceSpawn; + public readonly float AlarmProbability; + public readonly float LockedProbability; + + public ParkedVehicle(UnityEngine.Vector3 pos, float ang, int carId, + int primaryColor = -1, int secondaryColor = -1) + : base("") + { + Position = pos; + Angle = ang; + CarId = carId; + + Colors = new int[4]; + + Colors[0] = primaryColor; + Colors[1] = secondaryColor; + Colors[2] = -1; + Colors[3] = -1; + } + + public ParkedVehicle(string line) + : base(line) + { + Position = new UnityEngine.Vector3( + GetSingle(0), + GetSingle(1), + GetSingle(2)); + + Angle = GetSingle(3) * Mathf.Rad2Deg; + CarId = GetInt(4); + + Colors = new int[4]; + + Colors[0] = GetInt(5); + Colors[1] = GetInt(6); + Colors[2] = -1; + Colors[3] = -1; + + ForceSpawn = GetInt(7) > 0; + AlarmProbability = GetInt(8) / 100f; + LockedProbability = GetInt(9) / 100f; + } + + public ParkedVehicle(BinaryReader reader) + : base(reader) + { + var posX = reader.ReadSingle(); + var posZ = reader.ReadSingle(); + var posY = reader.ReadSingle(); + + Position = new UnityEngine.Vector3(posX, posY, posZ); + + Angle = reader.ReadSingle() * Mathf.Rad2Deg; + CarId = reader.ReadInt32(); + + Colors = new int[4]; + + Colors[0] = reader.ReadInt32(); + Colors[1] = reader.ReadInt32(); + + ForceSpawn = reader.ReadInt32() > 0; + AlarmProbability = reader.ReadInt32() / 100f; + LockedProbability = reader.ReadInt32() / 100f; + + Colors[2] = reader.ReadInt32(); + Colors[3] = reader.ReadInt32(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Placements/ParkedVehicle.cs.meta b/Assets/Scripts/Importing/Items/Placements/ParkedVehicle.cs.meta new file mode 100644 index 00000000..0d11688d --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements/ParkedVehicle.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7934ae468f9463e44a0f33e930799760 +timeCreated: 1428179142 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Placements/WaterFace.cs b/Assets/Scripts/Importing/Items/Placements/WaterFace.cs new file mode 100644 index 00000000..4e697289 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements/WaterFace.cs @@ -0,0 +1,53 @@ +using System; + +namespace SanAndreasUnity.Importing.Items.Placements +{ + [Flags] + public enum WaterFlags + { + None = 0, + Visible = 1, + Shallow = 2 + } + + public class WaterFace : Placement + { + public class Vertex + { + public readonly UnityEngine.Vector3 Position; + public readonly UnityEngine.Vector2 CurrentSpeed; + public readonly float WaveHeight; + + public Vertex(WaterFace face, int offset) + { + Position = new UnityEngine.Vector3( + face.GetSingle(offset + 0), + face.GetSingle(offset + 2), + face.GetSingle(offset + 1)); + + CurrentSpeed = new UnityEngine.Vector2( + face.GetSingle(offset + 3), + face.GetSingle(offset + 4)); + + WaveHeight = face.GetSingle(offset + 6); + } + } + + public readonly Vertex[] Vertices; + public readonly WaterFlags Flags; + + public WaterFace(string line) + : base(line, false) + { + var vertCount = (Parts - 1) / 7; + Vertices = new Vertex[vertCount]; + + for (var i = 0; i < vertCount; ++i) + { + Vertices[i] = new Vertex(this, i * 7); + } + + Flags = (WaterFlags)GetInt(Parts - 1); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Placements/WaterFace.cs.meta b/Assets/Scripts/Importing/Items/Placements/WaterFace.cs.meta new file mode 100644 index 00000000..298f71ef --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements/WaterFace.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 11852a5be7a9d534e8b356f76ef0c894 +timeCreated: 1428168810 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/Placements/Zone.cs b/Assets/Scripts/Importing/Items/Placements/Zone.cs new file mode 100644 index 00000000..1f24b134 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements/Zone.cs @@ -0,0 +1,19 @@ +namespace SanAndreasUnity.Importing.Items.Placements +{ + [Section("zone")] + public class Zone : Placement + { + public readonly string Name; + + public readonly UnityEngine.Vector3 Min; + public readonly UnityEngine.Vector3 Max; + + public Zone(string line) : base(line) + { + Name = GetString(0); + + Min = new UnityEngine.Vector3(GetSingle(2), GetSingle(4), GetSingle(3)); + Max = new UnityEngine.Vector3(GetSingle(5), GetSingle(7), GetSingle(6)); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/Placements/Zone.cs.meta b/Assets/Scripts/Importing/Items/Placements/Zone.cs.meta new file mode 100644 index 00000000..1715f9e2 --- /dev/null +++ b/Assets/Scripts/Importing/Items/Placements/Zone.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 219821d64f83eef459286c738dc4f51c +timeCreated: 1428168719 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Items/WaterFile.cs b/Assets/Scripts/Importing/Items/WaterFile.cs new file mode 100644 index 00000000..fef29515 --- /dev/null +++ b/Assets/Scripts/Importing/Items/WaterFile.cs @@ -0,0 +1,35 @@ +using SanAndreasUnity.Importing.Items.Placements; +using System.Collections.Generic; +using System.IO; + +namespace SanAndreasUnity.Importing.Items +{ + public class WaterFile + { + public readonly WaterFace[] Faces; + + public WaterFile(string path) + { + var faces = new List(); + + using (var reader = File.OpenText(path)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + line = line.Trim(); + + if (line.Length == 0) continue; + if (line.StartsWith("#")) continue; + if (line.StartsWith("processed")) continue; + + faces.Add(new WaterFace(line)); + } + } + + UnityEngine.Debug.Log("Loading water file: \"" + path + "\" with " + faces.Count + " faces"); + + Faces = faces.ToArray(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Items/WaterFile.cs.meta b/Assets/Scripts/Importing/Items/WaterFile.cs.meta new file mode 100644 index 00000000..bcbeddb2 --- /dev/null +++ b/Assets/Scripts/Importing/Items/WaterFile.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f819482f3f209bb4db4f464d0b1554cb +timeCreated: 1428159429 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream.meta b/Assets/Scripts/Importing/RenderWareStream.meta new file mode 100644 index 00000000..a3cc71d7 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 59cb84c0d5ca13f45a63288dace87e18 +folderAsset: yes +timeCreated: 1427714783 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Atomic.cs b/Assets/Scripts/Importing/RenderWareStream/Atomic.cs new file mode 100644 index 00000000..2ced8e5e --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Atomic.cs @@ -0,0 +1,32 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public enum AtomicFlag + { + CollisionTest = 0x01, + Render = 0x04, + } + + [SectionType(0x14)] + public class Atomic : SectionData + { + public readonly UInt32 FrameIndex; + public readonly UInt32 GeometryIndex; + public readonly AtomicFlag Flags; + public readonly UInt32 Unused; + + public Atomic(SectionHeader header, Stream stream) + : base(header, stream) + { + var data = ReadSection(); // Struct + var reader = new BinaryReader(new MemoryStream(data.Value)); + + FrameIndex = reader.ReadUInt32(); + GeometryIndex = reader.ReadUInt32(); + Flags = (AtomicFlag)reader.ReadUInt32(); + Unused = reader.ReadUInt32(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Atomic.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Atomic.cs.meta new file mode 100644 index 00000000..960aeb31 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Atomic.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e69d977f72e838347b85a8925bfe6335 +timeCreated: 1428202131 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Clump.cs b/Assets/Scripts/Importing/RenderWareStream/Clump.cs new file mode 100644 index 00000000..30718eae --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Clump.cs @@ -0,0 +1,56 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(TypeId)] + public class Clump : SectionData + { + public const Int32 TypeId = 16; + + public readonly UInt32 AtomicCount; + public readonly UInt32 LightCount; + public readonly UInt32 CameraCount; + + public readonly FrameList FrameList; + public readonly GeometryList GeometryList; + public readonly Atomic[] Atomics; + + public readonly Collision.CollisionFile Collision; + + public Clump(SectionHeader header, Stream stream) + : base(header, stream) + { + var data = ReadSection(); // Struct + if (data == null) return; + + var reader = new BinaryReader(new MemoryStream(data.Value)); + + AtomicCount = reader.ReadUInt32(); + LightCount = reader.ReadUInt32(); + CameraCount = reader.ReadUInt32(); + + FrameList = ReadSection(); // Frame List + GeometryList = ReadSection(); // Geometry List + + Atomics = new Atomic[AtomicCount]; + + for (int i = 0; i < AtomicCount; ++i) + { + Atomics[i] = ReadSection(); // Atomic + } + + var section = ReadSection(); + var extension = section as Extension; + + if (extension != null) + { + var collision = extension.FirstOrDefault(); + if (collision != null) + { + Collision = collision.Collision; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Clump.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Clump.cs.meta new file mode 100644 index 00000000..b847810f --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Clump.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 571690ccb3c58e745ad206cbfb77cc82 +timeCreated: 1427138803 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/CollisionModel.cs b/Assets/Scripts/Importing/RenderWareStream/CollisionModel.cs new file mode 100644 index 00000000..f51d0c44 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/CollisionModel.cs @@ -0,0 +1,17 @@ +using SanAndreasUnity.Importing.Collision; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(0x0253F2FA)] + public class CollisionModel : SectionData + { + public readonly CollisionFile Collision; + + public CollisionModel(SectionHeader header, Stream stream) + : base(header, stream) + { + Collision = CollisionFile.Load(stream); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/CollisionModel.cs.meta b/Assets/Scripts/Importing/RenderWareStream/CollisionModel.cs.meta new file mode 100644 index 00000000..25fd4084 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/CollisionModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 54c2b993556c3d842ba2dd8fd7c3cbc6 +timeCreated: 1428255224 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Data.cs b/Assets/Scripts/Importing/RenderWareStream/Data.cs new file mode 100644 index 00000000..323ba233 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Data.cs @@ -0,0 +1,17 @@ +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(1)] + public class Data : SectionData + { + public readonly byte[] Value; + + public Data(SectionHeader header, Stream stream) + : base(header, stream) + { + Value = new byte[header.Size]; + stream.Read(Value, 0, (int)header.Size); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Data.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Data.cs.meta new file mode 100644 index 00000000..fade5152 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Data.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 85490879f9d0d6f4ca5dc67231f113f2 +timeCreated: 1427138803 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Extension.cs b/Assets/Scripts/Importing/RenderWareStream/Extension.cs new file mode 100644 index 00000000..cfe802d6 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Extension.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(3)] + public class Extension : SectionData + { + public readonly SectionData[] Sections; + + public Extension(SectionHeader header, Stream stream) + : base(header, stream) + { + var sections = new List(); + while (stream.Position < stream.Length) + { + sections.Add(ReadSection(header.GetParent())); + } + + Sections = sections.ToArray(); + } + + public void ForEach(Action action) + where TSection : SectionData + { + foreach (var section in Sections.OfType()) + { + action(section); + } + } + + public TSection FirstOrDefault() + where TSection : SectionData + { + return Sections.OfType().FirstOrDefault(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Extension.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Extension.cs.meta new file mode 100644 index 00000000..e65f7dc5 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Extension.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f0e9d7ce3338cd4498326453686aed0e +timeCreated: 1428253274 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/FrameList.cs b/Assets/Scripts/Importing/RenderWareStream/FrameList.cs new file mode 100644 index 00000000..18986e80 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/FrameList.cs @@ -0,0 +1,75 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public class Frame + { + public Frame(int index, BinaryReader reader) + { + Index = index; + MatrixRight = new Vector3(reader); + MatrixForward = new Vector3(reader); + MatrixUp = new Vector3(reader); + Position = new Vector3(reader); + ParentIndex = reader.ReadInt32(); + MatrixFlags = reader.ReadUInt32(); + } + + public String Name { get; internal set; } + public HierarchyAnimation HAnim { get; internal set; } + + public readonly Int32 Index; + public readonly Int32 ParentIndex; + + public readonly Vector3 Position; + + public readonly Vector3 MatrixRight; + public readonly Vector3 MatrixUp; + public readonly Vector3 MatrixForward; + + public readonly UInt32 MatrixFlags; + } + + [SectionType(14)] + public class FrameList : SectionData + { + public readonly UInt32 FrameCount; + + public readonly Frame[] Frames; + + public FrameList(SectionHeader header, Stream stream) + : base(header, stream) + { + var data = ReadSection(); + var reader = new BinaryReader(new MemoryStream(data.Value)); + + FrameCount = reader.ReadUInt32(); + + Frames = new Frame[FrameCount]; + + for (var i = 0; i < FrameCount; ++i) + { + Frames[i] = new Frame(i, reader); + } + + for (var i = 0; i < FrameCount; ++i) + { + var extension = ReadSection(); + + var frameName = extension.FirstOrDefault(); + var hierarchyAnimation = extension.FirstOrDefault(); + + if (frameName != null) + { + Frames[i].Name = frameName.Name; + } + + if (hierarchyAnimation != null) + { + Frames[i].HAnim = hierarchyAnimation; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/FrameList.cs.meta b/Assets/Scripts/Importing/RenderWareStream/FrameList.cs.meta new file mode 100644 index 00000000..da272a29 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/FrameList.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7531b91ce43804d4d8c957c3a9b01424 +timeCreated: 1428191657 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/FrameName.cs b/Assets/Scripts/Importing/RenderWareStream/FrameName.cs new file mode 100644 index 00000000..d2538094 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/FrameName.cs @@ -0,0 +1,16 @@ +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(0x253F2FE)] + public class FrameName : SectionData + { + public readonly String Name; + + public FrameName(SectionHeader header, Stream stream) + : base(header, stream) + { + Name = new String(header, stream); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/FrameName.cs.meta b/Assets/Scripts/Importing/RenderWareStream/FrameName.cs.meta new file mode 100644 index 00000000..2ec5eb5f --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/FrameName.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a8a6d52f67ecc3f4e9a6752bcf309eb5 +timeCreated: 1428191657 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Geometry.cs b/Assets/Scripts/Importing/RenderWareStream/Geometry.cs new file mode 100644 index 00000000..7d7854ed --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Geometry.cs @@ -0,0 +1,161 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public enum GeometryFlag : ushort + { + TriangleStrips = 1, + VertexTranslation = 2, + TexCoords = 4, + Colors = 8, + Normals = 16, + DynamicVertexLighting = 32, + ModulateMaterialColor = 64, + TexCoords2 = 128, + } + + public struct FaceInfo + { + public readonly GeometryFlag Flags; + public readonly UInt16 Vertex0; + public readonly UInt16 Vertex1; + public readonly UInt16 Vertex2; + + public int[] Indices { get { return new int[] { Vertex0, Vertex1, Vertex2 }; } } + + public FaceInfo(BinaryReader reader) + { + Vertex1 = reader.ReadUInt16(); + Vertex0 = reader.ReadUInt16(); + Flags = (GeometryFlag)reader.ReadUInt16(); + Vertex2 = reader.ReadUInt16(); + } + } + + public struct BoundingSphere + { + public readonly Vector3 Offset; + public readonly float Radius; + + public BoundingSphere(BinaryReader reader) + { + Offset = new Vector3(reader); + Radius = reader.ReadSingle(); + } + } + + [SectionType(15)] + public class Geometry : SectionData + { + public readonly GeometryFlag Flags; + public readonly UInt32 FaceCount; + public readonly UInt32 VertexCount; + public readonly UInt32 FrameCount; + + public readonly float Ambient; + public readonly float Diffuse; + public readonly float Specular; + + public readonly Color4[] Colours; + public readonly Vector2[][] TexCoords; + public readonly FaceInfo[] Faces; + + public readonly BoundingSphere BoundingSphere; + + public readonly UInt32 HasPosition; + public readonly UInt32 HasNormals; + + public readonly Vector3[] Vertices; + public readonly Vector3[] Normals; + + public readonly Material[] Materials; + public readonly MaterialSplit[] MaterialSplits; + + public readonly Skin Skinning; + + public Geometry(SectionHeader header, Stream stream) + : base(header, stream) + { + var dataHeader = SectionHeader.Read(stream); + var reader = new BinaryReader(stream); + + Flags = (GeometryFlag)reader.ReadUInt16(); + var uvCount = reader.ReadByte(); // uv count + reader.ReadByte(); // native flags + FaceCount = reader.ReadUInt32(); + VertexCount = reader.ReadUInt32(); + FrameCount = reader.ReadUInt32(); + + if (dataHeader.Version == 4099) + { + Ambient = reader.ReadSingle(); + Diffuse = reader.ReadSingle(); + Specular = reader.ReadSingle(); + } + + if ((Flags & GeometryFlag.Colors) != 0) + { + Colours = new Color4[VertexCount]; + for (var i = 0; i < VertexCount; ++i) + { + Colours[i] = new Color4(reader); + } + } + + if ((Flags & (GeometryFlag.TexCoords | GeometryFlag.TexCoords2)) != 0) + { + TexCoords = new Vector2[uvCount][]; + for (var j = 0; j < uvCount; ++j) + { + var uvs = TexCoords[j] = new Vector2[VertexCount]; + for (var i = 0; i < VertexCount; ++i) + { + uvs[i] = new Vector2(reader); + } + } + } + + Faces = new FaceInfo[FaceCount]; + for (var i = 0; i < FaceCount; ++i) + { + Faces[i] = new FaceInfo(reader); + } + + BoundingSphere = new BoundingSphere(reader); + + HasPosition = reader.ReadUInt32(); + HasNormals = reader.ReadUInt32(); + + if (HasPosition > 1 || HasNormals > 1) + { + throw new Exception("Well there you go"); + } + + if ((Flags & GeometryFlag.VertexTranslation) != 0) + { + Vertices = new Vector3[VertexCount]; + for (var i = 0; i < VertexCount; ++i) + { + Vertices[i] = new Vector3(reader); + } + } + + if ((Flags & GeometryFlag.Normals) != 0) + { + Normals = new Vector3[VertexCount]; + for (var i = 0; i < VertexCount; ++i) + { + Normals[i] = new Vector3(reader); + } + } + + Materials = ReadSection().Materials; + + var extensions = ReadSection(); + + MaterialSplits = extensions.FirstOrDefault().MaterialSplits; + Skinning = extensions.FirstOrDefault(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Geometry.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Geometry.cs.meta new file mode 100644 index 00000000..af740e79 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Geometry.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5d229c0916a1d804d9c1c351c80680b1 +timeCreated: 1427138803 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/GeometryList.cs b/Assets/Scripts/Importing/RenderWareStream/GeometryList.cs new file mode 100644 index 00000000..4697dd8f --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/GeometryList.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(26)] + public class GeometryList : SectionData + { + public readonly UInt32 GeometryCount; + public readonly Geometry[] Geometry; + + public GeometryList(SectionHeader header, Stream stream) + : base(header, stream) + { + var data = ReadSection(); + + GeometryCount = BitConverter.ToUInt32(data.Value, 0); + Geometry = new Geometry[GeometryCount]; + + for (var i = 0; i < GeometryCount; ++i) + { + Geometry[i] = ReadSection(); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/GeometryList.cs.meta b/Assets/Scripts/Importing/RenderWareStream/GeometryList.cs.meta new file mode 100644 index 00000000..5931cd9a --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/GeometryList.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4e4e737c532ed1d4b957a4c7d2f084de +timeCreated: 1427138803 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/HierarchyAnimation.cs b/Assets/Scripts/Importing/RenderWareStream/HierarchyAnimation.cs new file mode 100644 index 00000000..bfebb0d2 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/HierarchyAnimation.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public enum HierarchyAnimationFlags + { + None = 0, + SubHierarchy = 1, + NoMatrices = 2, + UpdateLocalMatrices = 4096, + UpdateGlobalMatrices = 8192, + LocalSpaceMatrices = 16384, + } + + public enum HierarchyAnimationNodeFlags + { + None = 0, + PopParentMatrix = 1, + PushParentMatrix = 2, + } + + public class HierarchyAnimationNode : IEnumerable + { + private readonly List _children; + + public readonly UInt32 NodeId; + public readonly UInt32 NodeIndex; + public readonly HierarchyAnimationNodeFlags Flags; + + public bool Push + { + get + { + return (Flags & HierarchyAnimationNodeFlags.PushParentMatrix) + == HierarchyAnimationNodeFlags.PushParentMatrix; + } + } + + public bool Pop + { + get + { + return (Flags & HierarchyAnimationNodeFlags.PopParentMatrix) + == HierarchyAnimationNodeFlags.PopParentMatrix; + } + } + + public HierarchyAnimationNode(BinaryReader reader) + { + _children = new List(); + + NodeId = reader.ReadUInt32(); + NodeIndex = reader.ReadUInt32(); + Flags = (HierarchyAnimationNodeFlags)reader.ReadUInt32(); + } + + public void AddChild(HierarchyAnimationNode child) + { + _children.Add(child); + } + + public IEnumerator GetEnumerator() + { + return _children.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return _children.GetEnumerator(); + } + } + + [SectionType(0x011e)] + public class HierarchyAnimation : SectionData + { + public readonly UInt32 Version; + public readonly UInt32 NodeId; + public readonly UInt32 NodeCount; + + public readonly HierarchyAnimationNode Root; + public readonly HierarchyAnimationNode[] Nodes; + + public readonly HierarchyAnimationFlags Flags; + public readonly UInt32 KeyFrameSize; + + public HierarchyAnimation(SectionHeader header, Stream stream) + : base(header, stream) + { + var reader = new BinaryReader(stream); + + Version = reader.ReadUInt32(); + NodeId = reader.ReadUInt32(); + NodeCount = reader.ReadUInt32(); + + Nodes = new HierarchyAnimationNode[NodeCount]; + + if (NodeCount > 0) + { + Flags = (HierarchyAnimationFlags)reader.ReadUInt32(); + KeyFrameSize = reader.ReadUInt32(); + + for (int i = 0; i < NodeCount; ++i) + { + Nodes[i] = new HierarchyAnimationNode(reader); + } + + var stack = new Stack(); + stack.Push(Root = Nodes[0]); + + foreach (var node in Nodes.Skip(1)) + { + stack.Peek().AddChild(node); + + if (node.Push) + { + stack.Push(node); + } + else if (node.Pop) + { + var n = node; + do + { + n = stack.Pop(); + } while (n.Pop); + } + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/HierarchyAnimation.cs.meta b/Assets/Scripts/Importing/RenderWareStream/HierarchyAnimation.cs.meta new file mode 100644 index 00000000..8ac71121 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/HierarchyAnimation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5c0eb0d2cf4f194409351c4342b9fc85 +timeCreated: 1428336651 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Material.cs b/Assets/Scripts/Importing/RenderWareStream/Material.cs new file mode 100644 index 00000000..0a1d29a8 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Material.cs @@ -0,0 +1,100 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public struct Color4 + { + public readonly byte R; + public readonly byte G; + public readonly byte B; + public readonly byte A; + + public Color4(BinaryReader reader) + { + R = reader.ReadByte(); + G = reader.ReadByte(); + B = reader.ReadByte(); + A = reader.ReadByte(); + } + } + + [SectionType(7)] + public class Material : SectionData + { + public readonly Color4 Colour; + public readonly UInt32 TextureCount; + public readonly Texture[] Textures; + + public readonly UInt32 Flags; + public readonly Single Ambient; + public readonly Single Specular; + public readonly Single Smoothness; + + public Material(SectionHeader header, Stream stream) + : base(header, stream) + { + SectionHeader.Read(stream); + var reader = new BinaryReader(stream); + + Flags = reader.ReadUInt32(); + Colour = new Color4(reader); + reader.ReadUInt32(); + TextureCount = reader.ReadUInt32(); + Textures = new Texture[TextureCount]; + Ambient = reader.ReadSingle(); + Smoothness = reader.ReadSingle(); + Specular = 1f - reader.ReadSingle(); + + for (var i = 0; i < TextureCount; ++i) + { + Textures[i] = ReadSection(); + } + + var extensions = ReadSection(); + + var smoothness = Smoothness; + var specular = Specular; + + extensions.ForEach(x => specular = x.Intensity); + extensions.ForEach(x => smoothness = x.SpecularLevel); + + Smoothness = smoothness; + Specular = specular; + } + } + + [SectionType(0x0253F2FC)] + public class ReflectionMaterial : SectionData + { + public readonly Vector2 Scale; + public readonly Vector2 Translation; + + public readonly float Intensity; + + public ReflectionMaterial(SectionHeader header, Stream stream) + : base(header, stream) + { + var reader = new BinaryReader(stream); + + Scale = new Vector2(reader); + Translation = new Vector2(reader); + + Intensity = reader.ReadSingle(); + } + } + + [SectionType(0x0253F2F6)] + public class SpecularMaterial : SectionData + { + public readonly float SpecularLevel; + + public SpecularMaterial(SectionHeader header, Stream stream) + : base(header, stream) + { + var reader = new BinaryReader(stream); + + SpecularLevel = reader.ReadSingle(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Material.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Material.cs.meta new file mode 100644 index 00000000..81beef30 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Material.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e1c8a8e5ce5bbb54a819618a4fc0fe25 +timeCreated: 1427138804 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/MaterialList.cs b/Assets/Scripts/Importing/RenderWareStream/MaterialList.cs new file mode 100644 index 00000000..0dc9fb2a --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/MaterialList.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(8)] + public class MaterialList : SectionData + { + public readonly UInt32 MaterialCount; + public readonly Material[] Materials; + + public MaterialList(SectionHeader header, Stream stream) + : base(header, stream) + { + var data = ReadSection(); + MaterialCount = BitConverter.ToUInt32(data.Value, 0); + + Materials = new Material[MaterialCount]; + + for (var i = 0; i < MaterialCount; ++i) + { + Materials[i] = ReadSection(); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/MaterialList.cs.meta b/Assets/Scripts/Importing/RenderWareStream/MaterialList.cs.meta new file mode 100644 index 00000000..6287711c --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/MaterialList.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: da74a451d42a2cf4dae0e2375f00752a +timeCreated: 1427138804 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/MaterialSplitList.cs b/Assets/Scripts/Importing/RenderWareStream/MaterialSplitList.cs new file mode 100644 index 00000000..9cdf3585 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/MaterialSplitList.cs @@ -0,0 +1,50 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public class MaterialSplit + { + public readonly UInt32 VertexCount; + public readonly UInt32 MaterialIndex; + public readonly Int32[] FaceIndices; + + public MaterialSplit(Stream stream) + { + var reader = new BinaryReader(stream); + VertexCount = reader.ReadUInt32(); + FaceIndices = new Int32[VertexCount]; + MaterialIndex = reader.ReadUInt32(); + + for (var i = 0; i < VertexCount; ++i) + { + FaceIndices[i] = (Int32)reader.ReadUInt32(); + } + } + } + + [SectionType(1294)] + public class MaterialSplitList : SectionData + { + public readonly bool TriangleStrip; + public readonly UInt32 SplitCount; + public readonly UInt32 FaceCount; + public readonly MaterialSplit[] MaterialSplits; + + public MaterialSplitList(SectionHeader header, Stream stream) + : base(header, stream) + { + var reader = new BinaryReader(stream); + + TriangleStrip = reader.ReadUInt32() == 1; + SplitCount = reader.ReadUInt32(); + MaterialSplits = new MaterialSplit[SplitCount]; + FaceCount = reader.ReadUInt32(); + + for (var i = 0; i < SplitCount; ++i) + { + MaterialSplits[i] = new MaterialSplit(stream); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/MaterialSplitList.cs.meta b/Assets/Scripts/Importing/RenderWareStream/MaterialSplitList.cs.meta new file mode 100644 index 00000000..737e52cb --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/MaterialSplitList.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ea7ef5fca0882834fbe72705a9e65690 +timeCreated: 1427152243 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Section.cs b/Assets/Scripts/Importing/RenderWareStream/Section.cs new file mode 100644 index 00000000..c933a49c --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Section.cs @@ -0,0 +1,177 @@ +using SanAndreasUnity.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +#if !ENABLE_IL2CPP +using System.Linq.Expressions; +#endif +using System.Reflection; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public struct SectionHeader + { + public static SectionHeader Read(Stream stream, SectionData parent = null) + { + return new SectionHeader(stream, parent); + } + + private readonly SectionData _parent; + + public readonly UInt32 Type; + public readonly UInt32 Size; + public readonly UInt16 Version; + + private SectionHeader(Stream stream, SectionData parent) + { + _parent = parent; + + var reader = new BinaryReader(stream); + Type = reader.ReadUInt32(); + Size = reader.ReadUInt32(); + reader.ReadUInt16(); // Unknown + Version = reader.ReadUInt16(); + } + + public SectionData GetParent() + { + return _parent; + } + + public TSection GetParent() + where TSection : SectionData + { + return (TSection)_parent; + } + + public override string ToString() + { + return string.Format("{0}, Size: {1}, Vers: {2}", Type, Size, Version); + } + } + + public class SectionTypeAttribute : Attribute + { + public readonly UInt32 Value; + + public SectionTypeAttribute(UInt32 value) + { + Value = value; + } + } + + public abstract class SectionData + { + private delegate SectionData CtorDelegate(SectionHeader header, Stream stream); + + private static readonly Dictionary _sDataCtors + = new Dictionary(); + + private static CtorDelegate CreateDelegate(Type type) + { + var ctor = type.GetConstructor(new[] { typeof(SectionHeader), typeof(Stream) }); + + if (ctor == null) + { + throw new Exception(string.Format("Type {0} ")); + } + +#if !ENABLE_IL2CPP + var header = Expression.Parameter(typeof(SectionHeader), "header"); + var stream = Expression.Parameter(typeof(Stream), "stream"); + + var call = Expression.New(ctor, header, stream); + var cast = Expression.Convert(call, typeof(SectionData)); + + return Expression.Lambda(cast, header, stream).Compile(); +#else + return (header, stream) => (SectionData) ctor.Invoke(new object[] {header, stream}); +#endif + } + + private static void FindTypes() + { + _sDataCtors.Clear(); + + foreach (var t in Assembly.GetExecutingAssembly().GetTypes()) + { + if (t.BaseType != typeof(SectionData)) continue; + + var attrib = (SectionTypeAttribute)t.GetCustomAttributes(typeof(SectionTypeAttribute), false).FirstOrDefault(); + + if (attrib != null) + { + _sDataCtors.Add(attrib.Value, CreateDelegate(t)); + } + } + } + + public static SectionData Read(SectionHeader header, Stream stream) + { + return Read(header, stream); + } + + public static T Read(SectionHeader header, Stream stream) + where T : SectionData + { + if (_sDataCtors.Count == 0) FindTypes(); + if (!_sDataCtors.ContainsKey(header.Type)) + { + if (typeof(T) == typeof(SectionData)) return null; + throw new Exception(string.Format("Unexpected section header {0}.", header.Type)); + } + return (T)_sDataCtors[header.Type](header, stream); + } + + private readonly SectionHeader _header; + private readonly Stream _stream; + + protected SectionData(SectionHeader header, Stream stream) + { + _header = header; + _stream = stream; + } + + protected TSection ReadSection(SectionData parent = null) + where TSection : SectionData + { + return Section.ReadData(_stream, parent ?? this); + } + } + + public struct Section + where TData : SectionData + { + public static Section Read(Stream stream, SectionData parent = null) + { + return new Section(stream, parent); + } + + public static TData ReadData(Stream stream, SectionData parent = null) + { + return new Section(stream, parent).Data; + } + + public readonly SectionHeader Header; + public readonly TData Data; + + public UInt32 Type { get { return Header.Type; } } + + private Section(Stream stream, SectionData parent) + { + Header = SectionHeader.Read(stream, parent); + + var end = stream.Position + Header.Size; + + Data = SectionData.Read(Header, new FrameStream(stream, stream.Position, Header.Size)); + + stream.Seek(end, SeekOrigin.Begin); + } + + public override string ToString() + { + return Header.ToString(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Section.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Section.cs.meta new file mode 100644 index 00000000..7fed67f2 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Section.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2f9e65036fbab8540a615c6d69d97174 +timeCreated: 1427130043 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Skin.cs b/Assets/Scripts/Importing/RenderWareStream/Skin.cs new file mode 100644 index 00000000..1187b54d --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Skin.cs @@ -0,0 +1,89 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public struct SkinBoneWeights + { + public readonly Single[] Weights; + + public SkinBoneWeights(BinaryReader reader) + { + Weights = new Single[4]; + + for (int i = 0; i < Weights.Length; ++i) + { + Weights[i] = reader.ReadSingle(); + } + } + } + + public struct SkinBoneIndices + { + public readonly byte[] Indices; + + public SkinBoneIndices(BinaryReader reader) + { + Indices = reader.ReadBytes(4); + } + } + + [SectionType(0x0116)] + public class Skin : SectionData + { + public readonly SkinBoneIndices[] VertexBoneIndices; + public readonly SkinBoneWeights[] VertexBoneWeights; + + public readonly Matrix4x4[] SkinToBoneMatrices; + + public readonly byte[] MeshBoneRemapIndices; + + public Skin(SectionHeader header, Stream stream) + : base(header, stream) + { + var reader = new BinaryReader(stream); + + Int32 boneCount = (Int32)reader.ReadByte(); + Int32 boneIdCount = (Int32)reader.ReadByte(); + UInt16 weightsPerVertex = reader.ReadUInt16(); + + byte[] boneIds = reader.ReadBytes(boneIdCount); + + var vertexCount = header.GetParent().VertexCount; + + VertexBoneIndices = new SkinBoneIndices[vertexCount]; + VertexBoneWeights = new SkinBoneWeights[vertexCount]; + + for (int i = 0; i < vertexCount; ++i) + { + VertexBoneIndices[i] = new SkinBoneIndices(reader); + } + + for (int i = 0; i < vertexCount; ++i) + { + VertexBoneWeights[i] = new SkinBoneWeights(reader); + } + + SkinToBoneMatrices = new Matrix4x4[boneCount]; + + for (int i = 0; i < boneCount; ++i) + { + if (boneIdCount == 0) + { + reader.BaseStream.Seek(4, SeekOrigin.Current); + } + + SkinToBoneMatrices[i] = new Matrix4x4(reader); + } + + UInt32 boneLimit = reader.ReadUInt32(); + UInt32 meshCount = reader.ReadUInt32(); + UInt32 RLE = reader.ReadUInt32(); + + if (meshCount > 0) + { + MeshBoneRemapIndices = reader.ReadBytes((Int32)(boneCount + 2 * (RLE + meshCount))); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Skin.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Skin.cs.meta new file mode 100644 index 00000000..25930ece --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Skin.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8dd26acc38556e945999bafb77de083d +timeCreated: 1428357227 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/String.cs b/Assets/Scripts/Importing/RenderWareStream/String.cs new file mode 100644 index 00000000..7ee21abf --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/String.cs @@ -0,0 +1,18 @@ +using SanAndreasUnity.Utilities; +using System.IO; +using System.Text; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(2)] + public class String : SectionData + { + public readonly string Value; + + public String(SectionHeader header, Stream stream) + : base(header, stream) + { + Value = Encoding.UTF8.GetString(stream.ReadBytes((int)header.Size)).TrimNullChars(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/String.cs.meta b/Assets/Scripts/Importing/RenderWareStream/String.cs.meta new file mode 100644 index 00000000..53a0852d --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/String.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6711278da63a14240a1d0ed1c9972509 +timeCreated: 1427138803 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/Texture.cs b/Assets/Scripts/Importing/RenderWareStream/Texture.cs new file mode 100644 index 00000000..8b6c40ad --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Texture.cs @@ -0,0 +1,73 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + public enum Filter : ushort + { + None = 0x0, + Nearest = 0x1, + Linear = 0x2, + MipNearest = 0x3, + MipLinear = 0x4, + LinearMipNearest = 0x5, + LinearMipLinear = 0x6, + Unknown = 0x1101 + } + + public enum WrapMode : byte + { + None = 0, + Wrap = 1, + Mirror = 2, + Clamp = 3 + } + + public enum CompressionMode : byte + { + None = 0, + DXT1 = 1, + DXT3 = 3 + } + + [Flags] + public enum RasterFormat : uint + { + Default = 0x0000, + A1R5G5B5 = 0x0100, + R5G6B5 = 0x0200, + R4G4B4A4 = 0x0300, + LUM8 = 0x0400, + BGRA8 = 0x0500, + BGR8 = 0x0600, + R5G5B5 = 0x0a00, + + NoExt = 0x0fff, + + ExtAutoMipMap = 0x1000, + ExtPal8 = 0x2000, + ExtPal4 = 0x4000, + ExtMipMap = 0x8000 + } + + [SectionType(6)] + public class Texture : SectionData + { + public readonly Filter FilterMode; + public readonly string TextureName; + public readonly string MaskName; + + public Texture(SectionHeader header, Stream stream) + : base(header, stream) + { + SectionHeader.Read(stream); + var reader = new BinaryReader(stream); + + FilterMode = (Filter)reader.ReadUInt16(); + reader.ReadUInt16(); // Unknown + + TextureName = ReadSection().Value; + MaskName = ReadSection().Value; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/Texture.cs.meta b/Assets/Scripts/Importing/RenderWareStream/Texture.cs.meta new file mode 100644 index 00000000..77318aa6 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/Texture.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0119b53288d0bb247af24f3dc05912ea +timeCreated: 1427138803 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/TextureDictionary.cs b/Assets/Scripts/Importing/RenderWareStream/TextureDictionary.cs new file mode 100644 index 00000000..0c6ffd41 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/TextureDictionary.cs @@ -0,0 +1,28 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(22)] + public class TextureDictionary : SectionData + { + public UInt16 TextureCount; + public TextureNative[] Textures; + + public TextureDictionary(SectionHeader header, Stream stream) + : base(header, stream) + { + SectionHeader.Read(stream); + var reader = new BinaryReader(stream); + + TextureCount = reader.ReadUInt16(); + Textures = new TextureNative[TextureCount]; + reader.ReadUInt16(); // Unknown + + for (var i = 0; i < TextureCount; ++i) + { + Textures[i] = ReadSection(); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/TextureDictionary.cs.meta b/Assets/Scripts/Importing/RenderWareStream/TextureDictionary.cs.meta new file mode 100644 index 00000000..2e317db3 --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/TextureDictionary.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f83e339bf18a42742881e657ba5ec795 +timeCreated: 1427138804 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/RenderWareStream/TextureNative.cs b/Assets/Scripts/Importing/RenderWareStream/TextureNative.cs new file mode 100644 index 00000000..40ddedfa --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/TextureNative.cs @@ -0,0 +1,106 @@ +using SanAndreasUnity.Utilities; +using System; +using System.IO; + +namespace SanAndreasUnity.Importing.RenderWareStream +{ + [SectionType(21)] + public class TextureNative : SectionData + { + public readonly UInt32 PlatformID; + public readonly Filter FilterFlags; + public readonly WrapMode WrapV; + public readonly WrapMode WrapU; + public readonly string DiffuseName; + public readonly string AlphaName; + public readonly RasterFormat Format; + public readonly bool Alpha; + public readonly CompressionMode Compression; + public readonly UInt16 Width; + public readonly UInt16 Height; + public readonly byte BPP; + public readonly byte MipMapCount; + public readonly byte RasterType; + public readonly Int32 ImageDataSize; + + public readonly byte[] ImageData; + public readonly byte[] ImageLevelData; + + public TextureNative(SectionHeader header, Stream stream) + : base(header, stream) + { + SectionHeader.Read(stream); + var reader = new BinaryReader(stream); + + PlatformID = reader.ReadUInt32(); + FilterFlags = (Filter)reader.ReadUInt16(); + WrapV = (WrapMode)reader.ReadByte(); + WrapU = (WrapMode)reader.ReadByte(); + DiffuseName = reader.ReadString(32); + AlphaName = reader.ReadString(32); + Format = (RasterFormat)reader.ReadUInt32(); + + if (PlatformID == 9) + { + var dxt = reader.ReadString(4); + switch (dxt) + { + case "DXT1": + Compression = CompressionMode.DXT1; + break; + + case "DXT3": + Compression = CompressionMode.DXT3; + break; + + default: + Compression = CompressionMode.None; + break; + } + } + else + { + Alpha = reader.ReadUInt32() == 0x1; + } + + Width = reader.ReadUInt16(); + Height = reader.ReadUInt16(); + BPP = (byte)(reader.ReadByte() >> 3); + MipMapCount = reader.ReadByte(); + RasterType = reader.ReadByte(); + + if (RasterType != 0x4) + { + throw new Exception("Unexpected RasterType, expected 0x04."); + } + + if (PlatformID == 9) + { + Alpha = (reader.ReadByte() & 0x1) == 0x1; + } + else + { + Compression = (CompressionMode)reader.ReadByte(); + } + + ImageDataSize = reader.ReadInt32(); + + ImageData = reader.ReadBytes(ImageDataSize); + + if ((Format & RasterFormat.ExtMipMap) != 0) + { + var tot = ImageDataSize; + for (var i = 0; i < MipMapCount; ++i) + { + tot += ImageDataSize >> (2 * i); + } + + ImageLevelData = reader.ReadBytes(tot); + } + else + { + ImageLevelData = ImageData; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/RenderWareStream/TextureNative.cs.meta b/Assets/Scripts/Importing/RenderWareStream/TextureNative.cs.meta new file mode 100644 index 00000000..cacd9e6d --- /dev/null +++ b/Assets/Scripts/Importing/RenderWareStream/TextureNative.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 73062ec79d451b14380d5f9f07bd0260 +timeCreated: 1427138803 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Types.cs b/Assets/Scripts/Importing/Types.cs new file mode 100644 index 00000000..816febcd --- /dev/null +++ b/Assets/Scripts/Importing/Types.cs @@ -0,0 +1,133 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Importing +{ + public enum VectorCompression + { + None, + Collision, + Animation, + } + + public enum QuaternionCompression + { + None, + Animation, + } + + public struct Vector2 + { + public readonly Single X; + public readonly Single Y; + + public Vector2(BinaryReader reader) + { + X = reader.ReadSingle(); + Y = reader.ReadSingle(); + } + } + + public struct Vector3 + { + public const int Size = 3 * sizeof(float); + public const int SizeCompressed = 3 * sizeof(short); + + public readonly Single X; + public readonly Single Y; + public readonly Single Z; + + public Vector3(BinaryReader reader, VectorCompression compression = VectorCompression.None) + { + if (compression == VectorCompression.None) + { + X = reader.ReadSingle(); + Y = reader.ReadSingle(); + Z = reader.ReadSingle(); + } + else + { + float compressionScale; + + switch (compression) + { + case VectorCompression.Collision: + compressionScale = 128.0f; + break; + + case VectorCompression.Animation: + compressionScale = 1024.0f; + break; + + default: + compressionScale = 1.0f; + break; + } + + X = reader.ReadInt16() / compressionScale; + Y = reader.ReadInt16() / compressionScale; + Z = reader.ReadInt16() / compressionScale; + } + } + } + + public struct Vector4 + { + public readonly Single X; + public readonly Single Y; + public readonly Single Z; + public readonly Single W; + + public Vector4(BinaryReader reader) + { + X = reader.ReadSingle(); + Y = reader.ReadSingle(); + Z = reader.ReadSingle(); + W = reader.ReadSingle(); + } + } + + public struct Quaternion + { + public readonly Single X; + public readonly Single Y; + public readonly Single Z; + public readonly Single W; + + public Quaternion(BinaryReader reader, QuaternionCompression compression = QuaternionCompression.None) + { + if (compression == QuaternionCompression.None) + { + X = reader.ReadSingle(); + Y = reader.ReadSingle(); + Z = reader.ReadSingle(); + W = reader.ReadSingle(); + } + else + { + float compressionScale = 4096.0f; + + X = reader.ReadInt16() / compressionScale; + Y = reader.ReadInt16() / compressionScale; + Z = reader.ReadInt16() / compressionScale; + W = reader.ReadInt16() / compressionScale; + } + } + } + + public struct Matrix4x4 + { + public readonly Vector4 V0; + public readonly Vector4 V1; + public readonly Vector4 V2; + public readonly Vector4 V3; + + public Matrix4x4(BinaryReader reader) + { + V0 = new Vector4(reader); + V1 = new Vector4(reader); + V2 = new Vector4(reader); + V3 = new Vector4(reader); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Types.cs.meta b/Assets/Scripts/Importing/Types.cs.meta new file mode 100644 index 00000000..c7be5560 --- /dev/null +++ b/Assets/Scripts/Importing/Types.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3098f34e7b6252044b01a9005b1a160c +timeCreated: 1427717986 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Vehicles.meta b/Assets/Scripts/Importing/Vehicles.meta new file mode 100644 index 00000000..963951d7 --- /dev/null +++ b/Assets/Scripts/Importing/Vehicles.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 05d5bc7b7fd65eb4580555a43bccaa1d +folderAsset: yes +timeCreated: 1429097715 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Vehicles/AnimationGroup.cs b/Assets/Scripts/Importing/Vehicles/AnimationGroup.cs new file mode 100644 index 00000000..03ab54e2 --- /dev/null +++ b/Assets/Scripts/Importing/Vehicles/AnimationGroup.cs @@ -0,0 +1,340 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; + +namespace SanAndreasUnity.Importing.Animation +{ + public enum AnimGroup + { + None = 0, + WalkCycle, + Car, + MyWalkCycle, + + Colt45, + Silenced, + Python, + Shotgun, + Buddy, + Tec, + Uzi, + Rifle, + Rocket, + Flame, + Grenade, + + Gun, + Weapons, + + _Count + } + + public enum AnimIndex + { + None = -1, + + // AnimGroup.WalkCycle + Walk = 0, + + Run = 1, + Panicked = 2, + Idle = 3, + RoadCross = 4, + WalkStart = 5, + + // mywalkcycle + IdleArmed = 0, + FuckU = 1, + GUN_STAND = 2, + sprint_civi = 3, + + // AnimGroup.Car + Sit = 0, + SitPassenger = 1, + DriveLeft = 2, + DriveRight = 3, + GetInLeft = 4, + GetInRight = 5, + GetOutLeft = 6, + GetOutRight = 7, + CAR_closedoor_LHS = 8, + CAR_closedoor_RHS, + CAR_close_LHS, + CAR_close_RHS, + + // Gun + GunMove_BWD = 2, + GunMove_FWD, + GunMove_L, + GunMove_R, + run_armed = 12, + WALK_armed = 17, + + // Colt45 + colt45_fire = 0, + COLT45_RELOAD, + colt45_crouchfire, + colt45_fire_2hands, + twoguns_crouchfire, + colt45_crouchreload, + sawnoff_reload, + + // Silenced + CrouchReload = 0, + SilenceCrouchfire, + Silence_fire, + Silence_reload, + + // Python + python_crouchfire = 0, + python_crouchreload, + python_fire, + python_fire_poor, + python_reload, + + // Shotgun + shotgun_crouchfire = 0, + shotgun_fire, + shotgun_fire_poor, + + // Buddy + buddy_crouchfire = 0, + buddy_crouchreload, + buddy_fire, + buddy_fire_poor, + buddy_fire_reload, + + // Tec + TEC_crouchfire = 0, + TEC_crouchreload, + TEC_fire, + TEC_reload, + + // Uzi + UZI_crouchfire = 0, + UZI_crouchreload, + UZI_fire, + UZI_fire_poor, + UZI_reload, + + // Rifle + RIFLE_crouchfire = 0, + RIFLE_crouchload, + RIFLE_fire, + RIFLE_fire_poor, + RIFLE_load, + + // Rocket + idle_rocket = 0, + RocketFire, + run_rocket, + walk_rocket, + WALK_start_rocket, + + // Flame + FLAME_fire = 0, + + // Grenade + WEAPON_start_throw = 0, + WEAPON_throw, + WEAPON_throwu, + + // so we can dynamically access all anims of the anim group + Index0 = 0, + Index1, + Index2, + Index3, + Index4, + Index5, + Index6, + Index7, + Index8, + Index9, + Index10, + Index11, + Index12, + Index13, + Index14, + Index15, + Index16, + Index17, + Index18, + Index19, + Index20, + Index21, + Index22, + Index23, + Index24, + Index25, + Index26, + Index27, + Index28, + Index29, + Index30, + + } + + public static class AnimIndexUtil + { + + public static AnimIndex Get(int index) + { + string name = "Index" + index; + return (AnimIndex)Enum.Parse(typeof(AnimIndex), name); + } + } + + /* + public class AnimIndex { + public static string Walk = "walk_civi"; + public static string Run = "run_civi"; + public static string Panicked = "sprint_panic"; + public static string Idle = "idle_stance"; + + public static string Sit = "CAR_sit"; + public static string SitPassenger = "CAR_sitp" ; + public static string DriveLeft = "Drive_L"; + public static string DriveRight = "Drive_R"; + public static string GetInLeft = "CAR_getin_LHS"; + public static string GetInRight = "CAR_getin_RHS"; + public static string GetOutLeft = "CAR_getout_LHS"; + public static string GetOutRight = "CAR_getout_RHS"; + + public static string IdleArmed = "IDLE_ARMED"; + } + */ + + public struct AnimId + { + private AnimGroup animGroup; + public AnimGroup AnimGroup { get { return this.animGroup; } } + + private AnimIndex animIndex; + public AnimIndex AnimIndex { get { return this.animIndex; } } + + private string fileName; + public string FileName { get { return this.fileName; } } + + private string animName; + public string AnimName { get { return this.animName; } } + + private bool usesAnimGroup; + public bool UsesAnimGroup { get { return this.usesAnimGroup; } } + + + public AnimId (AnimGroup animGroup, AnimIndex animIndex) + { + this.animGroup = animGroup; + this.animIndex = animIndex; + this.fileName = null; + this.animName = null; + this.usesAnimGroup = true; + } + + public AnimId (string fileName, string animName) + { + this.animGroup = AnimGroup.None; + this.animIndex = AnimIndex.None; + this.fileName = fileName; + this.animName = animName; + this.usesAnimGroup = false; + } + + } + + public class AnimationGroup + { + private static readonly Regex _sHeaderRegex = new Regex("^" + + @"\s*(?[a-z0-9_]+)\s*," + + @"\s*(?[a-z0-9_]+)\s*," + + @"\s*(?[a-z0-9_]+)\s*," + + @"\s*(?[0-9]+)\s*$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + private static readonly Regex _sEndRegex = new Regex(@"^\s*end\s*", + RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public static readonly Dictionary> _sGroups + = new Dictionary>(); + /// + /// Key is a name of anim group. Value is dictionary, in which the key is anim group type and value is info about anim group. + /// + public static IEnumerable>> AllLoadedGroups + { get { return _sGroups; } } + + + public static void Load(string path) + { + using (var reader = File.OpenText(path)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + var match = _sHeaderRegex.Match(line); + if (!match.Success) continue; + + var group = new AnimationGroup(match, reader); + + if (!_sGroups.ContainsKey(group.Name)) + { + _sGroups.Add(group.Name, new Dictionary()); + } + + _sGroups[group.Name].Add(group.Type, group); + } + } + } + + private static AnimationGroup GetInternal(string name, AnimGroup type) + { + Dictionary groupDict; + if (!_sGroups.TryGetValue(name, out groupDict)) return null; + + AnimationGroup group; + return groupDict.TryGetValue(type, out group) ? group : null; + } + + public static AnimationGroup Get(string name, AnimGroup type) + { + return GetInternal(name, type) ?? GetInternal("default", type); + } + + + private readonly string[] _animations; + public string[] Animations { get { return _animations; } } + + public readonly string Name; + public readonly string FileName; + public readonly AnimGroup Type; + + + private AnimationGroup(Match match, StreamReader reader) + { + Name = match.Groups["groupName"].Value; + FileName = match.Groups["fileName"].Value; + Type = (AnimGroup)Enum.Parse(typeof(AnimGroup), match.Groups["animType"].Value, true); + + var animCount = int.Parse(match.Groups["animCount"].Value); + _animations = new String[animCount]; + + var i = 0; + string line; + while ((line = reader.ReadLine()) != null && !_sEndRegex.IsMatch(line)) + { + line = line.Trim(); + if (line.Length == 0) continue; + _animations[i++] = line; + } + } + + public string this[AnimIndex type] + { + get { return _animations[(int)type]; } + } + + public bool HasAnimation(string animName) + { + return System.Array.IndexOf(_animations, animName) >= 0; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Vehicles/AnimationGroup.cs.meta b/Assets/Scripts/Importing/Vehicles/AnimationGroup.cs.meta new file mode 100644 index 00000000..f94d461f --- /dev/null +++ b/Assets/Scripts/Importing/Vehicles/AnimationGroup.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 02025b54d5219194c90cd270460e5620 +timeCreated: 1428779283 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Vehicles/CarColors.cs b/Assets/Scripts/Importing/Vehicles/CarColors.cs new file mode 100644 index 00000000..9a61ab06 --- /dev/null +++ b/Assets/Scripts/Importing/Vehicles/CarColors.cs @@ -0,0 +1,60 @@ +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.Importing.Vehicles +{ + public class CarColors + { + private static Color32[] _sColors; + private static Dictionary _sCarColors; + + public static void Load(string path) + { + var file = new ItemFile(path); + + Debug.LogFormat("Entries: {0}", file.GetItems().Count()); + + _sColors = file.GetItems().Select(x => new Color32(x.R, x.G, x.B, 255)).ToArray(); + _sCarColors = file.GetItems().ToDictionary(x => x.Name, x => new CarColors(x)); + } + + public static CarColors GetCarDefaults(string carName) + { + return _sCarColors.ContainsKey(carName) ? _sCarColors[carName] : null; + } + + public static Color32[] FromIndices(params int[] indices) + { + return indices.Select(x => _sColors[x]).ToArray(); + } + + private readonly CarColorDef _def; + private readonly int[][] _vals; + + public int Count { get { return _def.Colors.Length; } } + + private CarColors(CarColorDef def) + { + _def = def; + _vals = _def.Colors.Select(x => + { + var arr = new int[def.Is4Color ? 4 : 2]; + arr[0] = x.A; + // To fix "moonbeam" having an invalid second color + arr[1] = x.B < _sColors.Length ? x.B : x.A; + if (!def.Is4Color) return arr; + arr[2] = x.C; + arr[3] = x.D; + return arr; + }).ToArray(); + } + + public int[] this[int index] + { + get { return _vals[index]; } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Vehicles/CarColors.cs.meta b/Assets/Scripts/Importing/Vehicles/CarColors.cs.meta new file mode 100644 index 00000000..50462144 --- /dev/null +++ b/Assets/Scripts/Importing/Vehicles/CarColors.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c971d61741719aa438dd80b09d9f8e37 +timeCreated: 1429097715 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Vehicles/Handling.cs b/Assets/Scripts/Importing/Vehicles/Handling.cs new file mode 100644 index 00000000..26b538ac --- /dev/null +++ b/Assets/Scripts/Importing/Vehicles/Handling.cs @@ -0,0 +1,273 @@ +using SanAndreasUnity.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace SanAndreasUnity.Importing.Vehicles +{ + public enum DriveType + { + Forward, + Rear, + FourWheel + } + + public enum EngineType + { + Petrol, + Diesel, + Electric + } + + public static class Handling + { + #region Reflection + + [Flags] + private enum ColumnFlags + { + Default = 0, + HexNumber = 1 + } + + [AttributeUsage(AttributeTargets.Property)] + private class ColumnAttribute : Attribute + { + public readonly int Value; + public readonly ColumnFlags Flags; + + public bool IsHexNumber + { + get { return (Flags & ColumnFlags.HexNumber) == ColumnFlags.HexNumber; } + } + + public ColumnAttribute(int value, ColumnFlags flags = ColumnFlags.Default) + { + Value = value; + Flags = flags; + } + } + + [AttributeUsage(AttributeTargets.Class)] + private class PrefixAttribute : Attribute + { + public readonly char Value; + + public PrefixAttribute(char value) + { + Value = value; + } + } + + public interface IEntry { } + + public interface IVehicleEntry : IEntry + { + string Id { get; set; } + } + + public abstract class Entry : IEntry + where TEntry : Entry + { + private static Dictionary> _sParsers; + + private static void GenerateParsers() + { + _sParsers = new Dictionary>(); + + var type = typeof(TEntry); + + foreach (var prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) + { + var attrib = (ColumnAttribute)prop.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault(); + if (attrib == null) continue; + + var set = prop.GetSetMethod(true); + if (set == null) + throw new Exception("Set method is inaccessible"); + + _sParsers.Add(attrib.Value, (s, instance) => + { + set.Invoke(instance, new object[] { prop.PropertyType != typeof(string) ? Convert.ChangeType(attrib.IsHexNumber ? s.FromHex(prop.PropertyType, CultureInfo.InvariantCulture) : s, prop.PropertyType, CultureInfo.InvariantCulture) : s }); + }); + } + } + + protected Entry(string line) + { + if (_sParsers == null) + GenerateParsers(); + + var split = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); + var self = (TEntry)this; + + for (var i = 0; i < split.Length; ++i) + if (_sParsers.ContainsKey(i)) + _sParsers[i](split[i], self); + } + } + + private static Dictionary> _sCtors; + + private static IEnumerable _sEntries; + + private static void GenerateCtors() + { + _sCtors = new Dictionary>(); + + foreach (var type in typeof(Handling).GetNestedTypes()) + { + if (type.IsAbstract) continue; + if (type.IsInterface) continue; + if (!typeof(IEntry).IsAssignableFrom(type)) continue; + var attrib = (PrefixAttribute)type.GetCustomAttributes(typeof(PrefixAttribute), true).FirstOrDefault(); + var prefix = attrib != null ? attrib.Value : '\0'; + + _sCtors.Add(prefix, s => { return (IEntry)Activator.CreateInstance(type, new object[] { s }); }); + } + } + + #endregion Reflection + + public class Car : Entry, IVehicleEntry + { + [Column(0)] public string Id { get; set; } + [Column(1)] public float Mass { get; set; } + [Column(2)] public float TurnMass { get; set; } + [Column(3)] public float Drag { get; set; } + [Column(4)] private float _CentreOfMassX { get; set; } + [Column(5)] private float _CentreOfMassZ { get; set; } + [Column(6)] private float _CentreOfMassY { get; set; } + [Column(7)] public int BoyantPercent { get; set; } + [Column(8)] public float TractionMult { get; set; } + [Column(9)] public float TractionLoss { get; set; } + [Column(10)] public float TractionBias { get; set; } + + [Column(11)] public int TransmissionGears { get; set; } + [Column(12)] public float TransmissionMaxVel { get; set; } + [Column(13)] public float TransmissionEngineAccel { get; set; } + [Column(14)] public float TransmissionEngineInertia { get; set; } + [Column(15)] private string _TransmissionDriveType { get; set; } + [Column(16)] private string _TransmissionEngineType { get; set; } + + [Column(17)] public float BrakeDecel { get; set; } + [Column(18)] public float BrakeBias { get; set; } + [Column(19)] private int _AntiLockBrakes { get; set; } + [Column(20)] public float SteeringLock { get; set; } + + [Column(21)] public float SuspensionForceLevel { get; set; } + [Column(22)] public float SuspensionDampingLevel { get; set; } + [Column(23)] public float SuspensionHighSpeedDamping { get; set; } + [Column(24)] public float SuspensionUpperLimit { get; set; } + [Column(25)] public float SuspensionLowerLimit { get; set; } + [Column(26)] public float SuspensionFrontRearBias { get; set; } + [Column(27)] public float SuspensionAntiDriveMult { get; set; } + + [Column(28)] public float SeatOffsetDistance { get; set; } + [Column(29)] public float CollisionDamageMult { get; set; } + [Column(30)] public int MonetaryValue { get; set; } + + [Column(31, ColumnFlags.HexNumber)] private ulong _ModelFlags { get; set; } + [Column(32, ColumnFlags.HexNumber)] private ulong _HandlingFlags { get; set; } + + [Column(33)] private int _FrontLights { get; set; } + [Column(34)] private int _RearLights { get; set; } + + [Column(35)] public int AnimGroup { get; set; } + + public UnityEngine.Vector3 CentreOfMass + { + get { return new UnityEngine.Vector3(_CentreOfMassX, _CentreOfMassY, _CentreOfMassZ); } + } + + public DriveType TransmissionDriveType + { + get + { + switch (_TransmissionDriveType) + { + case "F": return DriveType.Forward; + case "R": return DriveType.Rear; + case "4": return DriveType.FourWheel; + default: throw new FormatException(); + } + } + } + + public EngineType TransmissionEngineType + { + get + { + switch (_TransmissionEngineType) + { + case "P": return EngineType.Petrol; + case "D": return EngineType.Diesel; + case "E": return EngineType.Electric; + default: throw new FormatException(); + } + } + } + + public bool AntiLockBrakes { get { return _AntiLockBrakes != 0; } } + + public Car(string line) : base(line) + { + } + } + + public static void Load(string path) + { + _sEntries = LoadInternal(path); + } + + private static IEnumerable LoadInternal(string path) + { + if (_sCtors == null) + GenerateCtors(); + + //throw new Exception("Constructor count: " + _sCtors.Count); + + using (var reader = File.OpenText(path)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + line = line.Trim(); + + if (line.Length == 0) continue; + if (line.StartsWith(";")) continue; + + var prefix = line[0]; + + if (char.IsLetterOrDigit(prefix)) + { + yield return _sCtors['\0'](line); + continue; + } + + foreach (var pair in _sCtors) + { + if (pair.Key != prefix) continue; + yield return pair.Value(line.Substring(1).TrimStart()); + break; + } + } + } + } + + public static TEntry Get(String id) + where TEntry : IVehicleEntry + { + //throw new Exception("Number of car loaded: " + _sEntries.Count); + var entries = _sEntries.OfType(); + + if (entries == null || (entries != null && (entries.Count() == 0 || entries.All(x => x == null)))) + throw new Exception(string.Format("Cars didn't loaded!\nEntries null?: {0}\nEntries count: {1}\nIf this two vars are false & 0, that means that all car instances are null.", entries == null, entries.Count())); + + return entries.FirstOrDefault(x => x.Id == id); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Importing/Vehicles/Handling.cs.meta b/Assets/Scripts/Importing/Vehicles/Handling.cs.meta new file mode 100644 index 00000000..2eb8ea80 --- /dev/null +++ b/Assets/Scripts/Importing/Vehicles/Handling.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cb892a051c5e1614ab45de275776da09 +timeCreated: 1428267958 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Weapons.meta b/Assets/Scripts/Importing/Weapons.meta new file mode 100644 index 00000000..d69171df --- /dev/null +++ b/Assets/Scripts/Importing/Weapons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 32301451fc1d349ac85015e8bdbb46ea +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Importing/Weapons/WeaponsData.cs b/Assets/Scripts/Importing/Weapons/WeaponsData.cs new file mode 100644 index 00000000..a9490573 --- /dev/null +++ b/Assets/Scripts/Importing/Weapons/WeaponsData.cs @@ -0,0 +1,268 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.Importing.Weapons +{ + public class WeaponData + { + + // common for all weapons + + public readonly string firstChar; + public readonly string weaponType; + public readonly string eFireType; + public readonly float targetRange, weaponRange; + public readonly int modelId1, modelId2; + // int reloadSampleTime1, reloadSampleTime2; + public readonly int weaponslot; + + // for gun weapons only + public readonly GunData gunData; + + + public class GunData + { + public readonly string AssocGroupId; + + public readonly int ammoClip; + + public readonly int damage; + + public readonly UnityEngine.Vector3 fireOffset; + + public readonly int skillLevel;// 0:POOR 1:STD 2:PRO + public readonly int reqStatLevel; // req stat level to get this weapon skill level + + public readonly float accuracy;// (0.5 - 2.0f) + public readonly float moveSpeed;// (0.5 - 1.5) + + public readonly int animLoopStart, animLoopEnd, animLoopFire; + public readonly int animLoop2Start, animLoop2End, animLoop2Fire; // for crouching + + public readonly int breakoutTime; + + public readonly string hexFlags; + + private List m_flags = new List (0); + public IEnumerable Flags { get { return m_flags; } } + + // old_shot_data + + public readonly float speed, radius; + public readonly float lifespan, spread; + + + public GunData(string[] parts) { + + LoadWithReflection (parts, this, "m_flags"); + + // calculate flags + var enumValues = System.Enum.GetValues( typeof(GunFlag) ); + foreach(var enumValue in enumValues) { + if( HasFlag( this.hexFlags, (GunFlag) enumValue) ) + m_flags.Add( (GunFlag) enumValue ); + } + + } + + public bool HasFlag (GunFlag flag) + { + return m_flags.Contains (flag); + } + + public static bool HasFlag (string hexFlags, GunFlag flag) { + // reverse hex flags + hexFlags = new string( hexFlags.Reverse().ToArray() ); + + // find index of flag + int index = s_groupedFlags.FindIndex( grp => grp.Contains(flag) ); + if (index < 0) + return false; + + // find char with this index + if (index >= hexFlags.Length) + return false; + char c = hexFlags [index]; + + int hex = ParseInt (c.ToString (), System.Globalization.NumberStyles.HexNumber); + return (hex & ( 1 << s_groupedFlags [index].IndexOf (flag) )) != 0; + } + + public GunAimingOffset aimingOffset { + get { + return WeaponData.LoadedGunAimingOffsets.FirstOrDefault (offset => offset.animGroup == AssocGroupId); + } + } + + } + + private static GunFlag[][] s_groupedFlags = new GunFlag[5][] { + new GunFlag[]{ GunFlag.CANAIM, GunFlag.AIMWITHARM, GunFlag.FIRSTPERSON, GunFlag.ONLYFREEAIM }, + new GunFlag[]{ GunFlag.MOVEAIM, GunFlag.MOVEFIRE }, + new GunFlag[]{ GunFlag.THROW, GunFlag.HEAVY, GunFlag.CONTINUOUSFIRE, GunFlag.TWIN_PISTOL }, + new GunFlag[]{ GunFlag.RELOAD, GunFlag.CROUCHFIRE, GunFlag.RELOAD2START, GunFlag.LONG_RELOAD }, + new GunFlag[]{ GunFlag.SLOWSDWN, GunFlag.RANDSPEED, GunFlag.EXPANDS } + }; + + public class GunAimingOffset + { + + public readonly string firstChar; + + public readonly string animGroup; + + public readonly float aimX, aimZ; + public UnityEngine.Vector3 Aim { get { return new UnityEngine.Vector3 (this.aimX, 0, this.aimZ); } } + + public readonly float duckX, duckZ; + + public readonly int rloadA, rloadB; + public readonly int crouchRLoadA, crouchRLoadB; + + + public GunAimingOffset(string line) + { + LoadWithReflection (SplitLine (line), this); + } + + } + + + private static List m_loadedWeaponData = new List (); + public static IEnumerable LoadedWeaponsData { get { return m_loadedWeaponData; } } + + private static List m_loadedGunAimingOffsets = new List (); + public static IEnumerable LoadedGunAimingOffsets { get { return m_loadedGunAimingOffsets; } } + + + public static void Load (string path) + { + + m_loadedWeaponData.Clear (); + m_loadedGunAimingOffsets.Clear (); + + using (var reader = File.OpenText (path)) { + string line; + while ((line = reader.ReadLine ()) != null) { + line = line.Trim (); + + if (line.Length == 0) + continue; + if (line.StartsWith ("#")) + continue; + + if (line.StartsWith ("$")) { + // weapon + m_loadedWeaponData.Add (new WeaponData (line)); + } else if (line.StartsWith ("%")) { + // gun aiming offset + m_loadedGunAimingOffsets.Add (new GunAimingOffset (line)); + } + + } + } + + UnityEngine.Debug.Log ("Loaded weapons data - " + m_loadedWeaponData.Count + " entries"); + + } + + + public WeaponData (string line) { + + var parts = SplitLine (line); + + int numEntriesUsed = LoadWithReflection (parts, this, "gunData"); + + if (this.firstChar == "$") { + // this weapon is gun - load gun data + var gunParts = parts.Skip (numEntriesUsed).ToArray (); + this.gunData = new GunData (gunParts); + } + + } + + + public static string[] SplitLine (string line) + { + return line.Split (new string[]{ "\t", " " }, System.StringSplitOptions.RemoveEmptyEntries); + } + + public static int LoadWithReflection(string[] parts, T obj, params string[] fieldsToIgnore) { + + var fields = typeof(T).GetFields (System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic + | System.Reflection.BindingFlags.Public); + + // UnityEngine.Debug.Log ("Parsing weapons data line parts:\n" + string.Join("\n", parts)); + + int partIndex = 0; + + foreach (var field in fields) { + + if (partIndex >= parts.Length) + break; + + if (fieldsToIgnore.Contains (field.Name)) + continue; + + string part = parts [partIndex]; + + if (field.FieldType == typeof(int)) { + field.SetValue (obj, ParseInt (part)); + } else if (field.FieldType == typeof(float)) { + field.SetValue (obj, ParseFloat (part)); + } else if (field.FieldType == typeof(string)) { + field.SetValue (obj, part); + } else if (field.FieldType == typeof(UnityEngine.Vector3)) { + UnityEngine.Vector3 vec3 = new UnityEngine.Vector3 (); + + vec3.x = ParseFloat (part); + partIndex++; + + part = parts [partIndex]; + vec3.y = ParseFloat (part); + partIndex++; + + part = parts [partIndex]; + vec3.z = ParseFloat (part); + + field.SetValue (obj, vec3); + } + + // UnityEngine.Debug.LogFormat ("new value {0}, index {1}, field name {2}", field.GetValue (obj), partIndex, + // field.Name); + + partIndex++; + } + + return partIndex; + } + + private static float ParseFloat (string str) + { + return float.Parse( str, System.Globalization.CultureInfo.InvariantCulture ); + } + + private static int ParseInt (string str) + { + return int.Parse( str, System.Globalization.CultureInfo.InvariantCulture ); + } + + private static int ParseInt (string str, System.Globalization.NumberStyles numberStyles) + { + return int.Parse( str, numberStyles, System.Globalization.CultureInfo.InvariantCulture ); + } + + } + + public enum GunFlag + { + CANAIM, AIMWITHARM, FIRSTPERSON, ONLYFREEAIM, + MOVEAIM, MOVEFIRE, + THROW, HEAVY, CONTINUOUSFIRE, TWIN_PISTOL, + RELOAD, CROUCHFIRE, RELOAD2START, LONG_RELOAD, + SLOWSDWN, RANDSPEED, EXPANDS + } + +} diff --git a/Assets/Scripts/Importing/Weapons/WeaponsData.cs.meta b/Assets/Scripts/Importing/Weapons/WeaponsData.cs.meta new file mode 100644 index 00000000..c1fdf6f0 --- /dev/null +++ b/Assets/Scripts/Importing/Weapons/WeaponsData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08d249c2bc7564ee5a29f2e45db29c00 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Settings.meta b/Assets/Scripts/Settings.meta new file mode 100644 index 00000000..dfb10f8e --- /dev/null +++ b/Assets/Scripts/Settings.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d9c0ee89ef5db4e3c854a37100778618 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Settings/CameraSettings.cs b/Assets/Scripts/Settings/CameraSettings.cs new file mode 100644 index 00000000..3337462b --- /dev/null +++ b/Assets/Scripts/Settings/CameraSettings.cs @@ -0,0 +1,34 @@ +using UnityEngine; +using SanAndreasUnity.UI; + +namespace SanAndreasUnity.Settings { + + public class CameraSettings : MonoBehaviour { + + OptionsWindow.FloatInput m_farClipPlaneInput = new OptionsWindow.FloatInput() { + description = "Far clip plane", + minValue = 100, + maxValue = 5000, + isAvailable = () => Camera.main != null, + getValue = () => Camera.main.farClipPlane, + setValue = (value) => { Camera.main.farClipPlane = value; }, + }; + OptionsWindow.FloatInput m_fieldOfViewInput = new OptionsWindow.FloatInput() { + description = "Field of view", + minValue = 20, + maxValue = 120, + isAvailable = () => Camera.main != null, + getValue = () => Camera.main.fieldOfView, + setValue = (value) => { Camera.main.fieldOfView = value; }, + }; + + + + void Awake () + { + OptionsWindow.RegisterInputs ("CAMERA", m_farClipPlaneInput, m_fieldOfViewInput); + } + + } + +} diff --git a/Assets/Scripts/Settings/CameraSettings.cs.meta b/Assets/Scripts/Settings/CameraSettings.cs.meta new file mode 100644 index 00000000..764d8bbc --- /dev/null +++ b/Assets/Scripts/Settings/CameraSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c960baf8e8064cf5b80a1e60a5b79e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Settings/MiscSettings.cs b/Assets/Scripts/Settings/MiscSettings.cs new file mode 100644 index 00000000..e2cabf89 --- /dev/null +++ b/Assets/Scripts/Settings/MiscSettings.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using UnityEngine; +using System.Linq; +using SanAndreasUnity.UI; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Behaviours.Weapons; + +namespace SanAndreasUnity.Settings { + + public class MiscSettings : MonoBehaviour { + + OptionsWindow.FloatInput m_timeScaleInput = new OptionsWindow.FloatInput( "Time scale", 0f, 4f ) { + getValue = () => Time.timeScale, + setValue = (value) => { Time.timeScale = value; } + }; + OptionsWindow.FloatInput m_gravityInput = new OptionsWindow.FloatInput( "Gravity", -10f, 50f ) { + getValue = () => -Physics.gravity.y, + setValue = (value) => { Physics.gravity = new Vector3(Physics.gravity.x, -value, Physics.gravity.z); }, + persistType = OptionsWindow.InputPersistType.OnStart + }; + OptionsWindow.BoolInput m_displayHealthBarsInput = new OptionsWindow.BoolInput ("Display health bar above peds") { + isAvailable = () => PedManager.Instance != null, + getValue = () => PedManager.Instance.displayHealthBarAbovePeds, + setValue = (value) => { PedManager.Instance.displayHealthBarAbovePeds = value; }, + persistType = OptionsWindow.InputPersistType.OnStart + }; + OptionsWindow.BoolInput m_displayMinimapInput = new OptionsWindow.BoolInput ("Display minimap") { + isAvailable = () => MiniMap.Instance != null, + getValue = () => MiniMap.Instance.gameObject.activeSelf, + setValue = (value) => { MiniMap.Instance.gameObject.SetActive (value); }, + persistType = OptionsWindow.InputPersistType.AfterLoaderFinishes + }; + OptionsWindow.BoolInput m_runInBackgroundInput = new OptionsWindow.BoolInput ("Run in background") { + getValue = () => Application.runInBackground, + setValue = (value) => { Application.runInBackground = value; }, + persistType = OptionsWindow.InputPersistType.AfterLoaderFinishes + }; + OptionsWindow.BoolInput m_drawLineFromGunInput = new OptionsWindow.BoolInput ("Draw line from gun") { + isAvailable = () => WeaponsManager.Instance != null, + getValue = () => WeaponsManager.Instance.drawLineFromGun, + setValue = (value) => { WeaponsManager.Instance.drawLineFromGun = value; }, + persistType = OptionsWindow.InputPersistType.OnStart + }; + + + + void Awake () + { + var inputs = new OptionsWindow.Input[] { m_timeScaleInput, m_gravityInput, m_displayHealthBarsInput, m_displayMinimapInput, + m_runInBackgroundInput, m_drawLineFromGunInput + }; + + foreach (var input in inputs) + { + input.category = "MISC"; + OptionsWindow.RegisterInput (input); + } + + } + + + } + +} diff --git a/Assets/Scripts/Settings/MiscSettings.cs.meta b/Assets/Scripts/Settings/MiscSettings.cs.meta new file mode 100644 index 00000000..33038df2 --- /dev/null +++ b/Assets/Scripts/Settings/MiscSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f92118c7df2474d4a9935fb6dec5f26e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Settings/PlayerSettings.cs b/Assets/Scripts/Settings/PlayerSettings.cs new file mode 100644 index 00000000..5476baa9 --- /dev/null +++ b/Assets/Scripts/Settings/PlayerSettings.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.UI; + +namespace SanAndreasUnity.Settings { + + public class PlayerSettings : MonoBehaviour { + + OptionsWindow.FloatInput m_jumpSpeedInput = new OptionsWindow.FloatInput() { + description = "Jump speed", + minValue = 3, + maxValue = 30, + isAvailable = () => Ped.Instance != null, + getValue = () => Ped.Instance.jumpSpeed, + setValue = (value) => { Ped.Instance.jumpSpeed = value; }, + }; + OptionsWindow.FloatInput m_turnSpeedInput = new OptionsWindow.FloatInput() { + description = "Turn speed", + minValue = 3, + maxValue = 30, + isAvailable = () => Ped.Instance != null, + getValue = () => Ped.Instance.TurnSpeed, + setValue = (value) => { Ped.Instance.TurnSpeed = value; }, + }; + OptionsWindow.FloatInput m_enterVehicleRadiusInput = new OptionsWindow.FloatInput() { + description = "Enter vehicle radius", + minValue = 1, + maxValue = 15, + isAvailable = () => Ped.Instance != null, + getValue = () => Ped.Instance.EnterVehicleRadius, + setValue = (value) => { Ped.Instance.EnterVehicleRadius = value; }, + }; + + OptionsWindow.BoolInput m_showSpeedometerInput = new OptionsWindow.BoolInput() { + description = "Show speedometer", + isAvailable = () => PlayerController.Instance != null, + getValue = () => PlayerController._showVel, + setValue = (value) => { PlayerController._showVel = value; }, + }; + OptionsWindow.FloatInput m_mouseSensitivityXInput = new OptionsWindow.FloatInput() { + description = "Mouse sensitivity x", + minValue = 0.2f, + maxValue = 10f, + isAvailable = () => PlayerController.Instance != null, + getValue = () => PlayerController.Instance.CursorSensitivity.x, + setValue = (value) => { PlayerController.Instance.CursorSensitivity.x = value; }, + }; + OptionsWindow.FloatInput m_mouseSensitivityYInput = new OptionsWindow.FloatInput() { + description = "Mouse sensitivity y", + minValue = 0.2f, + maxValue = 10f, + isAvailable = () => PlayerController.Instance != null, + getValue = () => PlayerController.Instance.CursorSensitivity.y, + setValue = (value) => { PlayerController.Instance.CursorSensitivity.y = value; }, + }; + + + + void Awake () + { + OptionsWindow.RegisterInputs ("PLAYER", m_jumpSpeedInput, m_turnSpeedInput, m_enterVehicleRadiusInput, + m_showSpeedometerInput, m_mouseSensitivityXInput, m_mouseSensitivityYInput); + } + + } + +} diff --git a/Assets/Scripts/Settings/PlayerSettings.cs.meta b/Assets/Scripts/Settings/PlayerSettings.cs.meta new file mode 100644 index 00000000..f0ada6bb --- /dev/null +++ b/Assets/Scripts/Settings/PlayerSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc581ee14e49f45bd8c98693d8ad173f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Settings/QualitySettings.cs b/Assets/Scripts/Settings/QualitySettings.cs new file mode 100644 index 00000000..711ad21c --- /dev/null +++ b/Assets/Scripts/Settings/QualitySettings.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using UnityEngine; +using System.Linq; +using SanAndreasUnity.UI; +using SanAndreasUnity.Utilities; +using Quality = UnityEngine.QualitySettings; + +namespace SanAndreasUnity.Settings { + + public class QualitySettings : MonoBehaviour { + + static string[] s_qualitySettingsNames; + + OptionsWindow.FloatInput m_fpsInput = new OptionsWindow.FloatInput( "Max fps", 0f, 200f ) { + getValue = () => Behaviours.GameManager.GetMaxFps (), + setValue = (value) => { Behaviours.GameManager.SetMaxFps (value.RoundToInt ()); }, + persistType = OptionsWindow.InputPersistType.OnStart + }; + OptionsWindow.MultipleOptionsInput m_antiAliasingInput = new OptionsWindow.MultipleOptionsInput() { + description = "Anti aliasing", + getValue = () => Quality.antiAliasing, + setValue = (value) => { Quality.antiAliasing = value; }, + Options = new int[]{0, 2, 4} + }; + OptionsWindow.FloatInput m_shadowDistanceInput = new OptionsWindow.FloatInput( "Shadow distance", 0f, 200f ) { + getValue = () => Quality.shadowDistance, + setValue = (value) => { Quality.shadowDistance = value; } + }; + OptionsWindow.EnumInput m_shadowProjectionInput = new OptionsWindow.EnumInput() { + description = "Shadow projection", + getValue = () => Quality.shadowProjection, + setValue = (value) => { Quality.shadowProjection = value; } + }; + OptionsWindow.EnumInput m_shadowResolutionInput = new OptionsWindow.EnumInput() { + description = "Shadow resolution", + getValue = () => Quality.shadowResolution, + setValue = (value) => { Quality.shadowResolution = value; } + }; + OptionsWindow.EnumInput m_shadowQualityInput = new OptionsWindow.EnumInput() { + description = "Shadows", + getValue = () => Quality.shadows, + setValue = (value) => { Quality.shadows = value; } + }; + OptionsWindow.MultipleOptionsInput m_shadowCascadesInput = new OptionsWindow.MultipleOptionsInput() { + description = "Num shadow cascades", + getValue = () => Quality.shadowCascades, + setValue = (value) => { Quality.shadowCascades = value; }, + Options = new int[]{1, 2, 4} + }; + OptionsWindow.EnumInput m_anisotropicFilteringInput = new OptionsWindow.EnumInput() { + description = "Anisotropic filtering", + getValue = () => Quality.anisotropicFiltering, + setValue = (value) => { Quality.anisotropicFiltering = value; } + }; + OptionsWindow.MultipleOptionsInput m_qualityLevelInput = new OptionsWindow.MultipleOptionsInput() { + description = "Quality level", + getValue = () => s_qualitySettingsNames[ Quality.GetQualityLevel() ], + setValue = (value) => { Quality.SetQualityLevel (System.Array.FindIndex (s_qualitySettingsNames, n => n == value)); } + }; + + + + void Awake () + { + + s_qualitySettingsNames = m_qualityLevelInput.Options = Quality.names; + + var inputs = new OptionsWindow.Input[]{ m_fpsInput, m_antiAliasingInput, m_qualityLevelInput, m_shadowQualityInput, m_shadowDistanceInput, + m_shadowProjectionInput, m_shadowResolutionInput, m_shadowCascadesInput, m_anisotropicFilteringInput }; + + foreach (var input in inputs) + { + input.category = "QUALITY"; + OptionsWindow.RegisterInput (input); + } + + } + + + } + +} diff --git a/Assets/Scripts/Settings/QualitySettings.cs.meta b/Assets/Scripts/Settings/QualitySettings.cs.meta new file mode 100644 index 00000000..66266375 --- /dev/null +++ b/Assets/Scripts/Settings/QualitySettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c3852056a1bf469ab2128fe025acd57 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Settings/WorldSettings.cs b/Assets/Scripts/Settings/WorldSettings.cs new file mode 100644 index 00000000..533e0b16 --- /dev/null +++ b/Assets/Scripts/Settings/WorldSettings.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours.World; +using SanAndreasUnity.UI; + +namespace SanAndreasUnity.Settings { + + public class WorldSettings : MonoBehaviour { + + OptionsWindow.FloatInput m_maxDrawDistanceInput = new OptionsWindow.FloatInput() { + description = "Max draw distance", + minValue = 50, + maxValue = 1000, + isAvailable = () => Cell.Instance != null, + getValue = () => Cell.Instance.maxDrawDistance, + setValue = (value) => { Cell.Instance.maxDrawDistance = value; }, + persistType = OptionsWindow.InputPersistType.AfterLoaderFinishes + }; + + + void Awake () + { + OptionsWindow.RegisterInputs ("WORLD", m_maxDrawDistanceInput); + } + + } + +} diff --git a/Assets/Scripts/Settings/WorldSettings.cs.meta b/Assets/Scripts/Settings/WorldSettings.cs.meta new file mode 100644 index 00000000..cb9008de --- /dev/null +++ b/Assets/Scripts/Settings/WorldSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0b1df49a9e0a49d8947a7026c7371d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI.meta b/Assets/Scripts/UI.meta new file mode 100644 index 00000000..1c98e7c1 --- /dev/null +++ b/Assets/Scripts/UI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 05e29d3a045144a8487ce8e9eb1ae017 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/AnimationsWindow.cs b/Assets/Scripts/UI/AnimationsWindow.cs new file mode 100644 index 00000000..895ea828 --- /dev/null +++ b/Assets/Scripts/UI/AnimationsWindow.cs @@ -0,0 +1,227 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Importing.Animation; +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Utilities; +using System.Linq; + +namespace SanAndreasUnity.UI { + + public class AnimationsWindow : PauseMenuWindow { + + private Vector2 m_scrollViewPos = Vector2.zero; + private bool m_displayPackages = true; + private bool m_displayWalkcycleAnims = false; + private bool m_displayAnimStats = false; + private float m_minScrollViewHeight = 200; + private float m_maxScrollViewHeight = 600; + private int m_selectedPackageIndex = 0; + + + AnimationsWindow() { + + // set default parameters + + this.windowName = "Animations"; + this.useScrollView = false; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + this.windowRect = Utilities.GUIUtils.GetCenteredRect( new Vector2( 500, Screen.height * 0.85f ) ); + } + + + protected override void OnWindowGUI () + { + + bool playerExists = Ped.Instance != null; + + + // float headerHeight = m_displayAnimStats ? 300 : 100; + + // m_headerScrollViewPos = GUILayout.BeginScrollView (m_headerScrollViewPos, GUILayout.Height(headerHeight)); + + if (playerExists) + Ped.Instance.shouldPlayAnims = !GUILayout.Toggle( !Ped.Instance.shouldPlayAnims, "Override player anims" ); + + m_displayPackages = GUILayout.Toggle(m_displayPackages, "Display packages"); + + m_displayWalkcycleAnims = GUILayout.Toggle( m_displayWalkcycleAnims, "Display walkcycle anims"); + + m_displayAnimStats = GUILayout.Toggle( m_displayAnimStats, "Display anim stats"); + + // display anim stats + if (m_displayAnimStats && playerExists) { + DisplayAnimStats (); + } + + // GUILayout.EndScrollView (); + + GUILayout.Space (10); + + + if (m_displayPackages) + { + // display loaded ifp packages and their anims + this.DisplayPackages (playerExists); + } + else + { + // display anim groups and their anims + this.DisplayAnimGroups (playerExists); + } + + + } + + private void DisplayAnimStats () + { + + GUILayout.Space (5); + + var model = Ped.Instance.PlayerModel; + + int numActiveClips = model.AnimComponent.OfType().Where(a => a.enabled).Count(); + GUILayout.Label("Currently played anims [" + numActiveClips + "] :"); + + // display all currently played clips + + foreach (AnimationState animState in model.AnimComponent) { + + if (!animState.enabled) + continue; + + DisplayStatsForAnim (animState); + } + + + if (model.LastAnimState != null) { + GUILayout.Space (3); + GUILayout.Label ("Last played anim:"); + DisplayStatsForAnim (model.LastAnimState); + } + + if (model.LastSecondaryAnimState != null) { + GUILayout.Space (3); + GUILayout.Label ("Last secondary played anim:"); + DisplayStatsForAnim (model.LastSecondaryAnimState); + } + + GUILayout.Space (7); + + GUILayout.Label ("Root frame velocity: " + model.RootFrame.LocalVelocity); + + } + + private void DisplayStatsForAnim (AnimationState animState) + { + // GUILayout.BeginHorizontal (); + + var clip = animState.clip; + + GUILayout.Label (string.Format ("name: {0}, length: {1}, frame rate: {2}, wrap mode: {3}, speed: {4}, " + + "normalized speed: {5}, time: {6}, normalized time: {7}, time perc: {8}", + clip.name, animState.length, clip.frameRate, animState.wrapMode, animState.speed, animState.normalizedSpeed, + animState.time, animState.normalizedTime, animState.GetTimePerc () + )); + + // GUILayout.EndHorizontal (); + } + + private void DisplayAnimGroups(bool playerExists) + { + + m_scrollViewPos = GUILayout.BeginScrollView (m_scrollViewPos, GUILayout.MinHeight(m_minScrollViewHeight), GUILayout.MaxHeight(m_maxScrollViewHeight)); + + float elementHeight = 25; + + foreach (var pair in Importing.Animation.AnimationGroup.AllLoadedGroups) { + + GUILayout.Space (5); + GUILayout.Label ("Name: " + pair.Key); + + foreach (var pair2 in pair.Value) { + + if (!m_displayWalkcycleAnims && pair2.Key == AnimGroup.WalkCycle) + continue; + + GUILayout.Label ("Type: " + pair2.Key); + + var animGroup = pair2.Value; + + for (int i=0; i < animGroup.Animations.Length; i++) { + string animName = animGroup.Animations[i]; + + if (playerExists) { + // display button which will play the anim + if (GUILayout.Button (animName, GUILayout.Height(elementHeight))) { + this.PlayAnim(new AnimId(animGroup.Type, AnimIndexUtil.Get(i))); + } + } else { + GUILayout.Label (animName, GUILayout.Height(elementHeight)); + } + } + } + } + + GUILayout.EndScrollView(); + + } + + void DisplayPackages(bool playerExists) + { + var packages = Importing.Conversion.Animation.Loaded.ToArray (); + if (packages.Length < 1) + { + GUILayout.Label ("There are no loaded ifp packages"); + return; + } + + float animHeight = 25; + + GUILayout.Label ("Ifp name:"); + m_selectedPackageIndex = GUILayout.Toolbar(m_selectedPackageIndex, packages.Select(p => p.Key).ToArray()); + + var package = packages [m_selectedPackageIndex].Value.AnimPackage; + var clips = package.Clips; + + GUILayout.Space (10); + + m_scrollViewPos = GUILayout.BeginScrollView (m_scrollViewPos, GUILayout.MinHeight(m_minScrollViewHeight), GUILayout.MaxHeight(m_maxScrollViewHeight)); + + for (int i = 0; i < clips.Length; i++) + { + var clip = clips [i]; + if (playerExists) + { + if (GUILayout.Button (clip.Name, GUILayout.Height(animHeight))) + { + // play this anim + this.PlayAnim(new AnimId (package.FileName, clip.Name)); + } + } + else + { + GUILayout.Label (clip.Name, GUILayout.Height(animHeight)); + } + } + + GUILayout.EndScrollView (); + + } + + void PlayAnim(AnimId animId) + { + Ped.Instance.PlayerModel.ResetModelState (); + var state = Ped.Instance.PlayerModel.PlayAnim (animId); + state.wrapMode = WrapMode.Loop; + } + + } + +} diff --git a/Assets/Scripts/UI/AnimationsWindow.cs.meta b/Assets/Scripts/UI/AnimationsWindow.cs.meta new file mode 100644 index 00000000..99d58598 --- /dev/null +++ b/Assets/Scripts/UI/AnimationsWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 729503e0f7dfa4729ae2141d6422e9f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/AudioWindow.cs b/Assets/Scripts/UI/AudioWindow.cs new file mode 100644 index 00000000..8f37a9c5 --- /dev/null +++ b/Assets/Scripts/UI/AudioWindow.cs @@ -0,0 +1,365 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours.Audio; +using System.Linq; + +namespace SanAndreasUnity.UI { + + public class AudioWindow : PauseMenuWindow { + + public float toolbarAreaHeight = 40; + public float timingAreaHeight = 40; + public float sideBarWidthPerc = 0.25f; + + GTAAudioSharp.GTAAudioStreamsFile m_selectedStreamsFile; + GTAAudioSharp.GTAAudioSFXFile m_selectedSfxFile; + + string m_bankIndexStr = ""; + + Vector2 m_sideBarScrollPos = Vector2.zero; + + AudioSource m_audioSource; + + bool m_isPaused = false; + // GTAAudioSharp.GTAAudioStreamsFile m_playingStreamsFile; + // int m_playingBankIndex = -1; + + bool m_playInterval = false; + string m_playIntervalStartStr = "00:00.000"; + string m_playIntervalEndStr = "00:00.000"; + + + + AudioWindow() { + + // set default parameters + + this.windowName = "Audio"; + this.useScrollView = true; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + float minWidth = 600, maxWidth = 1000, desiredWidth = Screen.width * 0.9f ; + float minHeight = 400, maxHeight = 700, desiredHeight = Screen.height * 0.9f; + this.windowRect = GUIUtils.GetCenteredRect (new Vector2 (Mathf.Clamp (desiredWidth, minWidth, maxWidth), + Mathf.Clamp (desiredHeight, minHeight, maxHeight))); + } + + + protected override void OnWindowGUI () + { + + if (null == AudioManager.AudioFiles) + { + GUILayout.Label ("Audio not loaded"); + return; + } + + + // TOOLBAR AREA + + // buttons for: play, pause, stop + + int selectedButtonIndex = GUILayout.Toolbar (-1, new string[]{ "Play", "Pause", "Stop" }, GUILayout.Height(this.toolbarAreaHeight)); + + if (0 == selectedButtonIndex) + { + // play button + + if (m_selectedStreamsFile != null) + { + int index; + if (int.TryParse (m_bankIndexStr, out index)) + { + StartPlaying (AudioManager.CreateAudioClipFromStream (m_selectedStreamsFile.Name, index)); + } + } + else if (m_selectedSfxFile != null) + { + int index; + if (int.TryParse (m_bankIndexStr, out index)) + { + StartPlaying (AudioManager.CreateAudioClipFromSfx (m_selectedSfxFile.Name, index, 0, null)); + } + + } + } + else if (1 == selectedButtonIndex) + { + // pause button + + this.TogglePause (); + } + else if (2 == selectedButtonIndex) + { + // stop button + + this.StopPlaying (false); + } + + + // TIMINGS AREA + + GUILayout.Space (10); + GUILayout.BeginHorizontal (); + + // elapsed time and total time of currently playing sound + + var timeSpanCurrent = System.TimeSpan.FromSeconds (this.CurrentClipTime); + var timeSpanLength = System.TimeSpan.FromSeconds (this.CurrentClipLength); + GUILayout.Label (string.Format ("{0:D2}:{1:D2} / {2:D2}:{3:D2}", timeSpanCurrent.Minutes, timeSpanCurrent.Seconds, + timeSpanLength.Minutes, timeSpanLength.Seconds), GUILayout.Width(120), GUILayout.Height(this.timingAreaHeight)); + + float newTime = GUILayout.HorizontalSlider (this.CurrentClipTimePerc, 0f, 1f, GUILayout.Height (this.timingAreaHeight)); + + if (newTime != this.CurrentClipTimePerc) + { + this.CurrentClipTimePerc = newTime; + } + + GUILayout.EndHorizontal (); + + // play interval + + GUILayout.BeginHorizontal (); + m_playInterval = GUILayout.Toggle (m_playInterval, "Play interval", GUILayout.Height(20)); + GUILayout.FlexibleSpace (); + if (m_playInterval) + { + // 2 text fields for start and end + + GUILayout.Label ("From:"); + m_playIntervalStartStr = GUILayout.TextField (m_playIntervalStartStr, 10, GUILayout.Width(120)); + GUILayout.Space (10); + GUILayout.Label ("To:"); + m_playIntervalEndStr = GUILayout.TextField (m_playIntervalEndStr, 10, GUILayout.Width(120)); + + GUILayout.FlexibleSpace (); + } + GUILayout.EndHorizontal (); + GUILayout.Space (10); + + + // the rest of the window will be split in 2 parts - left will be the list of all SFXs and streams, and + // right will be the list of sounds in currently selected SFX/stream + + + // float startingY = this.toolbarAreaHeight + this.timingAreaHeight + 40f; + + GUILayout.BeginHorizontal (); + + // SIDEBAR + + // GUILayout.BeginArea (new Rect( 0, startingY, this.WindowSize.x * this.sideBarWidthPerc, this.WindowSize.y - startingY - 40)); + m_sideBarScrollPos = GUILayout.BeginScrollView (m_sideBarScrollPos, GUILayout.Width(this.WindowSize.x * this.sideBarWidthPerc)); + + GUILayout.Label ("Streams"); + +// Rect rect = StartHorizontal (400, 25, 2); +// GUI.Label (rect, "Name"); +// rect = NextElement (rect); +// GUI.Label (rect, "Num banks"); + + foreach (var f in AudioManager.AudioFiles.StreamsAudioFiles) + { +// rect = StartHorizontal (400, 25, 2); +// +// GUI.Label (rect, f.Name); +// +// rect = NextElement (rect); +// GUI.Label (rect, f.NumBanks.ToString ()); + + GUI.enabled = (null == m_selectedStreamsFile || m_selectedStreamsFile.Name != f.Name); + if (GUILayout.Button (string.Format ("{0} [{1}]", f.Name, f.NumBanks))) + { + // select this file + SelectStreamFile (f); + } + GUI.enabled = true; + + } + + GUILayout.Space (20); + + GUILayout.Label ("SFX"); + +// rect = StartHorizontal (400, 25, 3); +// GUI.Label (rect, "Name"); +// rect = NextElement (rect); +// GUI.Label (rect, "Num banks"); +// rect = NextElement (rect); +// GUI.Label (rect, "Num audios"); + + foreach (var f in AudioManager.AudioFiles.SFXAudioFiles) + { +// rect = StartHorizontal(400, 25, 3); +// +// GUI.Label (rect, f.Name); +// +// rect = NextElement (rect); +// GUI.Label (rect, f.NumBanks.ToString ()); +// +// rect = NextElement (rect); +// GUI.Label (rect, f.NumAudios.ToString ()); + + GUI.enabled = (null == m_selectedSfxFile || m_selectedSfxFile.Name != f.Name); + if (GUILayout.Button (string.Format ("{0} [{1}]", f.Name, f.NumBanks))) + { + // select this file + SelectSfxFile (f); + } + GUI.enabled = true; + + } + + GUILayout.EndScrollView (); + // GUILayout.EndArea (); + + // LIST OF SOUNDS IN CURRENTLY SELECTED SFX/STREAM + + // GUILayout.BeginArea (new Rect( this.WindowSize.x * this.sideBarWidthPerc, startingY, this.WindowSize.x - this.WindowSize.x * this.sideBarWidthPerc, + // this.WindowSize.y - startingY - 40)); + + // we can't display a list, because there is no way to enumerate all sounds + // for now, just display text field for bank index + + GUILayout.Space (5); + GUILayout.Label ("Enter bank index:"); + m_bankIndexStr = GUILayout.TextField (m_bankIndexStr, 6, GUILayout.MaxWidth (150)); + GUILayout.FlexibleSpace (); + + // GUILayout.EndArea (); + + GUILayout.EndHorizontal (); + + } + + + static Rect StartHorizontal(float width, float height, int numElements) + { + Rect rect = GUILayoutUtility.GetRect (width, height); + rect.width /= numElements; + return rect; + } + + static Rect NextElement(Rect rect) + { + rect.x += rect.width; + return rect; + } + + + public void StartPlaying(AudioClip clip) + { + StopPlaying (); + + if (null == m_audioSource) + { + var go = new GameObject ("AudioWindowSound"); + go.hideFlags = HideFlags.HideInHierarchy; + m_audioSource = go.AddComponent (); + } + + m_audioSource.clip = clip; + + if (m_playInterval) + { + System.TimeSpan timeSpanStart, timeSpanEnd; + var fp = System.Globalization.CultureInfo.InvariantCulture; + if (System.TimeSpan.TryParseExact (m_playIntervalStartStr, "mm\\:ss\\.fff", fp, out timeSpanStart) + && System.TimeSpan.TryParseExact (m_playIntervalEndStr, "mm\\:ss\\.fff", fp, out timeSpanEnd) + && timeSpanStart.CompareTo (timeSpanEnd) < 0) + { + m_audioSource.time = (float) timeSpanStart.TotalSeconds; + m_audioSource.Play (); + m_audioSource.SetScheduledEndTime (AudioSettings.dspTime + (timeSpanEnd.TotalSeconds - timeSpanStart.TotalSeconds)); + } + + } + else + { + m_audioSource.time = 0f; + m_audioSource.Play (); + } + + } + + public void StopPlaying(bool destroyClip = true) + { + if (m_audioSource) + { + m_audioSource.Stop (); + if (destroyClip) + { + Destroy (m_audioSource.clip); + m_audioSource.clip = null; + } + } + } + + public void TogglePause() + { + if (m_audioSource) + { + m_isPaused = !m_isPaused; + if (m_isPaused) + m_audioSource.Pause (); + else + m_audioSource.UnPause (); + } + } + + public void SelectSfxFile (GTAAudioSharp.GTAAudioSFXFile f) + { + m_selectedSfxFile = f; + m_selectedStreamsFile = null; + } + + public void SelectStreamFile (GTAAudioSharp.GTAAudioStreamsFile f) + { + m_selectedSfxFile = null; + m_selectedStreamsFile = f; + } + + public float CurrentClipTimePerc { + get { + if (m_audioSource && m_audioSource.clip) + { + return m_audioSource.time / m_audioSource.clip.length; + } + return 0f; + } + set { + value = Mathf.Clamp01 (value); + if (m_audioSource && m_audioSource.clip) + { + m_audioSource.time = value * m_audioSource.clip.length; + } + } + } + + public float CurrentClipTime { + get { + return this.CurrentClipTimePerc * this.CurrentClipLength; + } + } + + public float CurrentClipLength { + get { + if (m_audioSource && m_audioSource.clip) + { + return m_audioSource.clip.length; + } + return 0f; + } + } + + } + +} diff --git a/Assets/Scripts/UI/AudioWindow.cs.meta b/Assets/Scripts/UI/AudioWindow.cs.meta new file mode 100644 index 00000000..61185410 --- /dev/null +++ b/Assets/Scripts/UI/AudioWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75e2fbfb7537d48aa93fda618e34a0a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/ChangePathToGTAWindow.cs b/Assets/Scripts/UI/ChangePathToGTAWindow.cs new file mode 100644 index 00000000..78f624b2 --- /dev/null +++ b/Assets/Scripts/UI/ChangePathToGTAWindow.cs @@ -0,0 +1,95 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.UI { + + public class ChangePathToGTAWindow : PauseMenuWindow { + + FileBrowser m_fileBrowser = null; + + + + ChangePathToGTAWindow() + { + + // set default parameters + + this.windowName = "Change path to GTA"; + + } + + void Awake () + { + + } + + void Start () + { + + // adjust rect + this.windowRect = GUIUtils.GetCenteredRect( new Vector2( 600, 400 ) ); + + } + + + protected override void OnWindowOpened () + { + + // create file browser + if (null == m_fileBrowser) + { + m_fileBrowser = new FileBrowser (new Rect (new Vector2 (0, 0), this.WindowSize), "", this.OnSelectedPath) { + BrowserType = FileBrowserType.Directory + }; + } + + // load config + Config.Load (); + + // set current directory to game directory + string currentGameDir = Config.GetPath (Config.const_game_dir); + if (!string.IsNullOrEmpty (currentGameDir)) + { + m_fileBrowser.CurrentDirectory = currentGameDir; + } + else + { + // path is not set + m_fileBrowser.CurrentDirectory = System.IO.Directory.GetCurrentDirectory (); + } + + } + + void OnSelectedPath (string path) + { + + if (string.IsNullOrEmpty (path)) + { + // canceled + this.IsOpened = false; + return; + } + + // save new path + Config.SetString (Config.const_game_dir, path); + Config.SaveUserConfigSafe (); + + this.IsOpened = false; + + } + + protected override void OnWindowGUI () + { + + if (m_fileBrowser != null) + { + m_fileBrowser.OnGUI (); + } + + } + + } + +} diff --git a/Assets/Scripts/UI/ChangePathToGTAWindow.cs.meta b/Assets/Scripts/UI/ChangePathToGTAWindow.cs.meta new file mode 100644 index 00000000..f697dabe --- /dev/null +++ b/Assets/Scripts/UI/ChangePathToGTAWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd9456433955e448eb1b6abd46c39d07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/Console.cs b/Assets/Scripts/UI/Console.cs new file mode 100644 index 00000000..cc5db1ef --- /dev/null +++ b/Assets/Scripts/UI/Console.cs @@ -0,0 +1,342 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace SanAndreasUnity.UI +{ + + public class Console : PauseMenuWindow + { + + #region Inspector Settings + + /// + /// Whether to only keep a certain number of logs, useful if memory usage is a concern. + /// + public bool restrictLogCount = true; + + /// + /// Number of logs to keep before removing old ones. + /// + public int maxLogCount = 1000; + + #endregion + + static readonly GUIContent clearLabel = new GUIContent("Clear", "Clear the contents of the console."); + static readonly GUIContent collapseLabel = new GUIContent("Collapse", "Hide repeated messages."); + + private static readonly LogType[] s_allLogTypes = new LogType[] { + LogType.Log, LogType.Warning, LogType.Error, LogType.Exception, LogType.Assert + }; + + static readonly Dictionary logTypeColors = new Dictionary + { + { LogType.Assert, Color.red }, + { LogType.Error, Color.red }, + { LogType.Exception, Color.red }, + { LogType.Log, Color.white }, + { LogType.Warning, Color.yellow }, + }; + + bool isCollapsed; + public bool IsCollapsed { get { return this.isCollapsed; } set { this.isCollapsed = value; } } + readonly List logs = new List(); + readonly Utilities.ConcurrentQueue queuedLogs = new Utilities.ConcurrentQueue(); + + readonly Dictionary logTypeFilters = new Dictionary + { + { LogType.Assert, true }, + { LogType.Error, true }, + { LogType.Exception, true }, + { LogType.Log, true }, + { LogType.Warning, true }, + }; + + private Dictionary m_numMessagesPerType = new Dictionary (); + + + + Console () + { + this.windowName = "Console"; + this.useScrollView = false; + } + + + #region MonoBehaviour Messages + + void OnDisable() + { + Application.logMessageReceivedThreaded -= HandleLogThreaded; + } + + void OnEnable() + { + Application.logMessageReceivedThreaded += HandleLogThreaded; + } + + void Start () + { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + this.windowRect = Utilities.GUIUtils.GetCenteredRect( new Vector2(550, 400) ); + } + + void Update() + { + UpdateQueuedLogs(); + + } + + #endregion + + static void RestoreContentColor () + { + GUI.contentColor = Color.white; + } + + void DrawCollapsedLog(Log log) + { + GUILayout.BeginHorizontal(); + + GUILayout.Label(log.GetTruncatedMessage()); + GUILayout.FlexibleSpace(); + GUILayout.Label(log.count.ToString(), GUI.skin.box); + + GUILayout.EndHorizontal(); + } + + void DrawExpandedLog(Log log) + { + for (var i = 0; i < log.count; i += 1) + { + GUILayout.Label(log.GetTruncatedMessage()); + } + } + + void DrawLog(Log log) + { + GUI.contentColor = logTypeColors[log.type]; + + if (isCollapsed) + { + DrawCollapsedLog(log); + } + else + { + DrawExpandedLog(log); + } + } + + void DrawLogList() + { + scrollPos = GUILayout.BeginScrollView(scrollPos); + + // Used to determine height of accumulated log labels. + GUILayout.BeginVertical(); + + foreach (LogType logType in s_allLogTypes) + m_numMessagesPerType [logType] = 0; + + foreach (Log log in logs) + { + if (IsLogVisible (log)) + DrawLog (log); + + m_numMessagesPerType [log.type] += (isCollapsed ? 1 : log.count); + } + + GUILayout.EndVertical(); + var innerScrollRect = GUILayoutUtility.GetLastRect(); + GUILayout.EndScrollView(); + var outerScrollRect = GUILayoutUtility.GetLastRect(); + + // If we're scrolled to bottom now, guarantee that it continues to be in next cycle. + if (Event.current.type == EventType.Repaint && IsScrolledToBottom(innerScrollRect, outerScrollRect)) + { + ScrollToBottom(); + } + + // Ensure GUI colour is reset before drawing other components. + GUI.contentColor = Color.white; + } + + void DrawToolbar() + { + GUILayout.BeginHorizontal(); + + foreach (LogType logType in s_allLogTypes) + { + bool currentState = logTypeFilters[logType]; + int count = m_numMessagesPerType [logType]; + string label = logType.ToString() + ( (count > 0) ? (" [" + count + "]") : "" ); + + GUI.contentColor = logTypeColors [logType]; + logTypeFilters[logType] = GUILayout.Toggle (currentState, label, GUILayout.ExpandWidth(false)); + GUILayout.Space(15); + } + + GUILayout.EndHorizontal(); + + RestoreContentColor (); + + GUILayout.BeginHorizontal (); + + if (GUILayout.Button (clearLabel, GUILayout.ExpandWidth(false))) + { + logs.Clear(); + } + + GUILayout.Space (10); + + isCollapsed = GUILayout.Toggle (isCollapsed, collapseLabel, GUILayout.ExpandWidth(false)); + + GUILayout.EndHorizontal (); + } + + void DrawWindow() + { + DrawLogList(); + GUILayout.Space (5); + DrawToolbar(); + } + + protected override void OnWindowGUI () + { + DrawWindow (); + } + + + Log? GetLastLog() + { + if (logs.Count == 0) + { + return null; + } + + return logs.Last(); + } + + void UpdateQueuedLogs() + { + Log log; + while (queuedLogs.TryDequeue(out log)) + { + ProcessLogItem(log); + } + } + + void HandleLogThreaded(string message, string stackTrace, LogType type) + { + var log = new Log + { + count = 1, + message = message, + stackTrace = stackTrace, + type = type, + }; + + // Queue the log into a ConcurrentQueue to be processed later in the Unity main thread, + // so that we don't get GUI-related errors for logs coming from other threads + queuedLogs.Enqueue(log); + } + + void ProcessLogItem(Log log) + { + var lastLog = GetLastLog(); + var isDuplicateOfLastLog = lastLog.HasValue && log.Equals(lastLog.Value); + + if (isDuplicateOfLastLog) + { + // Replace previous log with incremented count instead of adding a new one. + log.count = lastLog.Value.count + 1; + logs[logs.Count - 1] = log; + } + else + { + logs.Add(log); + TrimExcessLogs(); + } + } + + bool IsLogVisible(Log log) + { + return logTypeFilters[log.type]; + } + + bool IsScrolledToBottom(Rect innerScrollRect, Rect outerScrollRect) + { + var innerScrollHeight = innerScrollRect.height; + + // Take into account extra padding added to the scroll container. + var outerScrollHeight = outerScrollRect.height - GUI.skin.box.padding.vertical; + + // If contents of scroll view haven't exceeded outer container, treat it as scrolled to bottom. + if (outerScrollHeight > innerScrollHeight) + { + return true; + } + + // Scrolled to bottom (with error margin for float math) + return Mathf.Approximately(innerScrollHeight, scrollPos.y + outerScrollHeight); + } + + void ScrollToBottom() + { + scrollPos = new Vector2(0, Int32.MaxValue); + } + + void TrimExcessLogs() + { + if (!restrictLogCount) + { + return; + } + + var amountToRemove = logs.Count - maxLogCount; + + if (amountToRemove <= 0) + { + return; + } + + logs.RemoveRange(0, amountToRemove); + } + } + + /// + /// A basic container for log details. + /// + struct Log + { + public int count; + public string message; + public string stackTrace; + public LogType type; + + /// + /// The max string length supported by UnityEngine.GUILayout.Label without triggering this error: + /// "String too long for TextMeshGenerator. Cutting off characters." + /// + private const int MaxMessageLength = 16382; + + public bool Equals(Log log) + { + return message == log.message && stackTrace == log.stackTrace && type == log.type; + } + + /// + /// Return a truncated message if it exceeds the max message length + /// + public string GetTruncatedMessage() + { + if (string.IsNullOrEmpty(message)) return message; + return message.Length <= MaxMessageLength ? message : message.Substring(0, MaxMessageLength); + } + } + + +} \ No newline at end of file diff --git a/Assets/Scripts/UI/Console.cs.meta b/Assets/Scripts/UI/Console.cs.meta new file mode 100644 index 00000000..ec68d291 --- /dev/null +++ b/Assets/Scripts/UI/Console.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c526ed17adca405e83c352cf842f516 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/ControlsWindow.cs b/Assets/Scripts/UI/ControlsWindow.cs new file mode 100644 index 00000000..79190032 --- /dev/null +++ b/Assets/Scripts/UI/ControlsWindow.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace SanAndreasUnity.UI { + + public class ControlsWindow : PauseMenuWindow { + + + + ControlsWindow() { + + // set default parameters + + this.windowName = "Controls"; + this.useScrollView = true; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + this.windowRect = new Rect(Screen.width / 2 - 150, 30, 350, 400); + } + + + protected override void OnWindowGUI () + { + + GUILayout.Label ( GetControlsText() ); + + } + + + public static string GetControlsText() { + + return + "V - Spawn vehicle\n\n" + + "P - Change pedestrian model\n\n" + + "W/A/S/D - Move player\n\n" + + "Left Shift - Jump\n\n" + + "Space - Sprint\n\n" + + "Mouse Scroll - Zoom in / out player camera\n\n" + + "E/Q - Next/previous weapon\n\n" + + "Esc - Toggle pause menu\n\n" + + "T - Fly mode\n\n" + + "R - Fly through mode\n\n" + + "Enter - Enter/exit vehicles\n\n" + + "L - Turn off / on car lights\n\n" + + "F10 - Toggle FPS\n\n" + + "F9 - Toggle velocimeter\n\n" + + "O - Toggle quality\n\n" + + "B - Zoom out minimap\n\n" + + "N - Zoom in minimap\n\n" + + "M - Open the entire map\n\n" + + "F8 - Show more info in the minimap"; + + } + + } + +} diff --git a/Assets/Scripts/UI/ControlsWindow.cs.meta b/Assets/Scripts/UI/ControlsWindow.cs.meta new file mode 100644 index 00000000..889ed5cb --- /dev/null +++ b/Assets/Scripts/UI/ControlsWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e4b0085a8c4174cb5a131d3baa1d8744 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/DayTimeWindow.cs b/Assets/Scripts/UI/DayTimeWindow.cs new file mode 100644 index 00000000..a45a872c --- /dev/null +++ b/Assets/Scripts/UI/DayTimeWindow.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours.World; + +namespace SanAndreasUnity.UI { + + public class DayTimeWindow : PauseMenuWindow { + + + + DayTimeWindow() { + + // set default parameters + + this.windowName = "DayTime"; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + this.windowRect = new Rect(10, Screen.height - 220, 250, 200); + } + + + protected override void OnWindowGUI () + { + + GUILayout.Label("Set Time:"); + + foreach (var en in System.Enum.GetValues(typeof(TimeState))) + { + TimeState e = (TimeState)en; + if (GUILayout.Button(e.ToString())) + WorldController.SetTime(e); + } + + } + + } + +} diff --git a/Assets/Scripts/UI/DayTimeWindow.cs.meta b/Assets/Scripts/UI/DayTimeWindow.cs.meta new file mode 100644 index 00000000..095bd44c --- /dev/null +++ b/Assets/Scripts/UI/DayTimeWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6804c9298f5040f68e0c902f6739ed0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/HUD.cs b/Assets/Scripts/UI/HUD.cs new file mode 100644 index 00000000..6e9ec314 --- /dev/null +++ b/Assets/Scripts/UI/HUD.cs @@ -0,0 +1,165 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.UI { + + public class HUD : MonoBehaviour { + + public static HUD Instance { get; private set; } + + public float crosshairSize = 16; + public ScaleMode crosshairScaleMode = ScaleMode.StretchToFill; + + public ScreenCorner hudScreenCorner = ScreenCorner.TopRight; + public Vector2 hudSize = new Vector2 (100, 100); + public Vector2 hudPadding = new Vector2 (10, 10); + + public Color healthColor = Color.red; + public Color healthBackgroundColor = (Color.red + Color.black) * 0.5f; + + public bool drawRedDotOnScreenCenter = false; + + + + void Awake () { + Instance = this; + } + + void Update () { + + } + + void OnGUI () { + + if (!Loader.HasLoaded) + return; + + if (null == Ped.Instance) + return; + + // draw crosshair + if (Ped.Instance.IsAiming) { + DrawCrosshair( new Vector2(Screen.width * 0.5f, Screen.height * 0.5f), Vector2.one * this.crosshairSize, this.crosshairScaleMode ); + } + + // draw hud + DrawHud( this.hudScreenCorner, this.hudSize, this.hudPadding, this.healthColor, this.healthBackgroundColor ); + + // draw dot in the middle of screen + if (this.drawRedDotOnScreenCenter) + GUIUtils.DrawRect (GUIUtils.GetCenteredRect (new Vector2 (2f, 2f)), Color.red); + + } + + public static void DrawCrosshair (Vector2 screenPos, Vector2 size, ScaleMode scaleMode) { + + if (null == Weapon.CrosshairTexture) + return; + + // crosshair texture is actually only a 4th part of the whole crosshair + // so we have to draw it 4 times + + var oldMatrix = GUI.matrix; + + // upper left + Rect rect = new Rect( screenPos - size * 0.5f, size * 0.5f ); + GUIUtility.RotateAroundPivot (90, rect.center); + GUI.DrawTexture( rect, Weapon.CrosshairTexture, scaleMode ); + + // upper right + rect = new Rect( new Vector2(screenPos.x, screenPos.y - size.y * 0.5f), size * 0.5f ); + GUI.matrix = oldMatrix; + GUIUtility.RotateAroundPivot (180, rect.center); + GUI.DrawTexture( rect, Weapon.CrosshairTexture, scaleMode ); + + // bottom right + rect = new Rect( new Vector2(screenPos.x, screenPos.y), size * 0.5f ); + GUI.matrix = oldMatrix; + GUIUtility.RotateAroundPivot (270, rect.center); + GUI.DrawTexture( rect, Weapon.CrosshairTexture, scaleMode ); + + // bottom left + rect = new Rect( new Vector2(screenPos.x - size.x * 0.5f, screenPos.y), size * 0.5f ); + GUI.matrix = oldMatrix; + GUIUtility.RotateAroundPivot (360, rect.center); + GUI.DrawTexture( rect, Weapon.CrosshairTexture, scaleMode ); + + + GUI.matrix = oldMatrix; + + } + + public static void DrawHud (ScreenCorner screenCorner, Vector2 size, Vector2 padding, Color healthColor, + Color healthBackgroundColor) + { + + var rect = GUIUtils.GetCornerRect (screenCorner, size, padding); + + Ped ped = Ped.Instance; + + // draw icon for current weapon + + Weapon weapon = Ped.Instance.CurrentWeapon; + + Rect texRect = rect; + texRect.width *= 0.4f; + texRect.height *= 0.5f; + + Texture2D tex; + if (weapon != null) + { + tex = weapon.HudTexture; + } + else + { + tex = Weapon.FistTexture; + } + + if (tex != null) { + + var savedMatrix = GUI.matrix; + // we have to flip texture around Y axis + GUIUtility.ScaleAroundPivot (new Vector2 (1.0f, -1.0f), texRect.center); + + // GUI.DrawTexture( texRect, tex, ScaleMode.StretchToFill, true, 0.0f, Color.black, 3f, 5f ); + GUI.DrawTexture (texRect, tex); + + GUI.matrix = savedMatrix; + } + + // ammo + + if (weapon != null && weapon.IsGun) + { + string str = string.Format ("{0}-{1}", weapon.AmmoOutsideOfClip, weapon.AmmoInClip); + + // draw it at the bottom of weapon icon + Vector2 desiredSize = GUIUtils.CalcScreenSizeForText (str, GUIUtils.CenteredLabelStyle); + Rect ammoRect = new Rect (new Vector2 (texRect.position.x, texRect.yMax - desiredSize.y / 2.0f), new Vector2 (texRect.width, desiredSize.y)); + + GUI.Label (ammoRect, str, GUIUtils.CenteredLabelStyle); + } + + + // health bar + + float barHeight = 8f; //rect.height / 10f; + float barWidth = rect.width * 0.5f; + Rect healthBarRect = new Rect (rect.width * 0.5f, texRect.yMax - barHeight, barWidth, barHeight); + DrawBar( healthBarRect, ped.Health / ped.MaxHealth, healthColor, healthBackgroundColor ); + + } + + public static void DrawBar (Rect rect, float fillPerc, Color fillColor, Color backgroundColor) + { + + float borderWidth = 2f; //rect.height / 8f; + + GUIUtils.DrawBar (rect, fillPerc, fillColor, backgroundColor, borderWidth); + } + + } + +} diff --git a/Assets/Scripts/UI/HUD.cs.meta b/Assets/Scripts/UI/HUD.cs.meta new file mode 100644 index 00000000..6906263d --- /dev/null +++ b/Assets/Scripts/UI/HUD.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32c417c622c0c4e2e8e323b02ec0ac9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/MainMenu.cs b/Assets/Scripts/UI/MainMenu.cs new file mode 100644 index 00000000..1d46896b --- /dev/null +++ b/Assets/Scripts/UI/MainMenu.cs @@ -0,0 +1,116 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours; +using UnityEngine.SceneManagement; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.UI +{ + + public class MainMenu : MonoBehaviour { + + public float minButtonHeight = 25f; + public float minButtonWidth = 70f; + public float spaceAtBottom = 15f; + public float spaceBetweenButtons = 5f; + + public bool drawBackground = false; + public Color backgroundColor = Color.black; + public bool drawLogo = false; + + private static List s_registeredMenuItems = new List(); + + private static GUILayoutOption[] s_buttonOptions = new GUILayoutOption[0]; + public static GUILayoutOption[] ButtonLayoutOptions { get { return s_buttonOptions; } } + + + + void Start () + { + + } + + void OnGUI () + { + if (!GameManager.IsInStartupScene) + return; + + // draw main menu gui + + // background + + if (this.drawBackground) + { + GUIUtils.DrawRect (GUIUtils.ScreenRect, this.backgroundColor); + } + + // logo + + if (this.drawLogo) + { + if (GameManager.Instance.logoTexture != null) + { + GUI.DrawTexture (GUIUtils.GetCenteredRect (GameManager.Instance.logoTexture.GetSize ()), GameManager.Instance.logoTexture); + } + } + + // draw buttons at bottom of screen: Main scene, Demo scene, Options, Change path to GTA, Exit + + s_buttonOptions = new GUILayoutOption[]{ GUILayout.MinWidth(minButtonWidth), GUILayout.MinHeight(minButtonHeight) }; + + GUILayout.BeginArea (new Rect (0f, Screen.height - (minButtonHeight + spaceAtBottom), Screen.width, minButtonHeight + spaceAtBottom)); + // GUILayout.Space (5); + // GUILayout.FlexibleSpace (); + + + GUILayout.BeginHorizontal (); + + GUILayout.Space (5); + GUILayout.FlexibleSpace (); + + if (GUILayout.Button ("Start game", s_buttonOptions)) + { + SceneManager.LoadScene ("Main"); + } + + GUILayout.Space (this.spaceBetweenButtons); + + if (GUILayout.Button ("Start demo", s_buttonOptions)) + { + SceneManager.LoadScene ("ModelViewer"); + } + + GUILayout.Space (this.spaceBetweenButtons); + + // draw registered menu items + foreach (var item in s_registeredMenuItems) + { + item (); + GUILayout.Space (this.spaceBetweenButtons); + } + + if (GUILayout.Button ("Exit", s_buttonOptions)) + { + GameManager.ExitApplication (); + } + + GUILayout.FlexibleSpace (); + GUILayout.Space (5); + + GUILayout.EndHorizontal (); + + // add some space below buttons + // GUILayout.Space (spaceAtBottom); + + GUILayout.EndArea (); + + } + + public static void RegisterMenuItem (System.Action action) + { + s_registeredMenuItems.AddIfNotPresent (action); + } + + } + +} diff --git a/Assets/Scripts/UI/MainMenu.cs.meta b/Assets/Scripts/UI/MainMenu.cs.meta new file mode 100644 index 00000000..dc1fcffd --- /dev/null +++ b/Assets/Scripts/UI/MainMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f5b556e077dc4e268ae212027bb0276 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/MapWindow.cs b/Assets/Scripts/UI/MapWindow.cs new file mode 100644 index 00000000..783e628d --- /dev/null +++ b/Assets/Scripts/UI/MapWindow.cs @@ -0,0 +1,724 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.UI { + + public class MapWindow : PauseMenuWindow { + + //private Rect visibleMapRect = new Rect (); + private Vector2 m_focusPos = Vector2.one * MiniMap.mapSize / 2.0f; + private float zoomLevel = 1; + private float infoAreaHeight = 90; + private bool m_clipMapItems = false; + + private Texture2D m_infoAreaTexture; + + private float m_playerPointerSize = 10; + private bool m_drawZones = false; + + private bool m_isWaypointPlaced = false; + private Vector2 m_waypointMapPos = Vector2.zero; + + private Vector2 m_lastMousePosition = Vector2.zero; + + private Vector2 m_infoAreaScrollViewPos = Vector2.zero; + + + + MapWindow() { + + // set default parameters + + this.windowName = "Map"; + this.useScrollView = false; + this.isDraggable = false; + this.isModal = true; + this.m_hasExitButton = false; + this.m_hasMinimizeButton = false; + + } + + void Awake () { + + m_infoAreaTexture = F.CreateTexture (1, 1, Color.grey); + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + this.windowRect = Utilities.GUIUtils.GetCenteredRectPerc (new Vector2 (1.0f, 1.0f)); + + } + + protected override void OnWindowOpened() { + + this.FocusOnPlayer (); + + } + + + public void FocusOnPlayer() { + + if (null == Ped.Instance) + return; + + Vector3 playerWorldPos = Ped.Instance.transform.position; + // Vector2 focusWorldPos = new Vector2 (playerWorldPos.x, playerWorldPos.z); + // Vector2 focusPosNormalized = focusPos / MiniMap.mapEdge; + Vector2 focusPos = MiniMap.WorldPosToMapPos(playerWorldPos); + + // flip y axis + // focusPos.y = MiniMap.mapSize - focusPos.y; + + this.SetFocusPosition (focusPos); + + } + + public void SetFocusPosition(Vector2 pos) { + + // Vector2 bottomLeftPos = pos; + // bottomLeftPos.x -= this.visibleMapRect.width / 2.0f; + // bottomLeftPos.y -= this.visibleMapRect.height / 2.0f; + + // this.visibleMapRect.position = bottomLeftPos; + + this.m_focusPos = pos; + + } + + public Vector2 GetFocusPosition() { + + // return this.visibleMapRect.position + this.visibleMapRect.size / 2.0f; + return this.m_focusPos; + } + + + /// + /// Rect in which the map is displayed, relative to window area. + /// + public Rect GetMapDisplayRect() { + + float mapDisplayWidth = this.windowRect.width; + float mapDisplayHeight = this.windowRect.height - this.infoAreaHeight; + Rect mapDisplayRect = new Rect (0, 0, mapDisplayWidth, mapDisplayHeight); + return mapDisplayRect; + } + + public Vector2 GetVisibleMapSize() { + + Rect mapDisplayRect = this.GetMapDisplayRect (); + + float visibleMapWidth = Mathf.Min( MiniMap.mapSize / 4.0f / this.zoomLevel, MiniMap.mapSize); + float visibleMapHeight = Mathf.Min (visibleMapWidth * mapDisplayRect.height / mapDisplayRect.width, MiniMap.mapSize); + + return new Vector2 (visibleMapWidth, visibleMapHeight); + } + + public Rect GetVisibleMapRect() { + + Vector2 size = GetVisibleMapSize (); + + return new Rect (this.m_focusPos - size / 2.0f, size); + } + +// private void AdjustVisibleMapRectAfterZooming() { +// +// Vector2 focusPos = this.GetFocusPosition (); +// +// // visible map size is changed after zooming +// Vector2 size = this.GetVisibleMapSize (); +// +// this.visibleMapRect = new Rect(focusPos - size / 2.0f, size); +// +// } + + + public static Vector2 ClampPositionInsideMap(Vector2 pos) { + + pos.x = Mathf.Clamp( pos.x, 0.0f, MiniMap.mapSize); + pos.y = Mathf.Clamp( pos.y, 0.0f, MiniMap.mapSize); + + return pos; + } + + private void ClampFocusPos() { + + // clamp focus position inside map + this.SetFocusPosition (ClampPositionInsideMap (this.GetFocusPosition ())); + + // again, clamp focus position, but based on visible map rectangle - the rectangle must not go out of map boundaries, or the texture will stretch +// Vector2 visibleMapSize = this.GetVisibleMapSize(); +// if (visibleMapSize.x < GetMapSize ()) { +// this.m_focusPos.x = Mathf.Clamp (this.m_focusPos.x, GetMinMapPos ().x + visibleMapSize.x / 2.0f, GetMaxMapPos ().x - visibleMapSize.x / 2.0f); +// } +// if (visibleMapSize.y < GetMapSize ()) { +// this.m_focusPos.y = Mathf.Clamp (this.m_focusPos.y, GetMinMapPos ().y + visibleMapSize.y / 2.0f, GetMaxMapPos ().y - visibleMapSize.y / 2.0f); +// } + + } + + public static Vector2 GetMinMapPos() { + return Vector2.zero; + } + + public static Vector2 GetMaxMapPos() { + return Vector2.one * MiniMap.mapSize; + } + + public static float GetMapSize() { + return MiniMap.mapSize; + } + + + public Vector2 ScreenPosToDisplayPos(Vector2 screenPos) { + + Rect displayRect = this.GetMapDisplayRect (); + + Vector2 displayPos = screenPos - displayRect.position; + // flip Y axis + displayPos.y = Screen.height - displayPos.y; + + return displayPos; + } + + public bool GetMapPosUnderMouse(out Vector2 mapPos) { + + mapPos = Vector2.zero; + + Vector2 displayPos = ScreenPosToDisplayPos (m_lastMousePosition); + + // check if it is inside display rect + if (!this.GetMapDisplayRect ().Contains (displayPos)) + return false; + + mapPos = DisplayPosToMapPos (displayPos); + + return true; + } + + public bool GetWorldPosUnderMouse(out Vector3 worldPos) { + + worldPos = Vector3.zero; + + Vector2 mapPos; + if(!this.GetMapPosUnderMouse(out mapPos)) + return false; + + worldPos = MiniMap.MapPosToWorldPos (mapPos); + + return true; + } + + public Vector2 DisplayPosToMapPos(Vector2 displayPos) { + + Rect mapDisplayRect = this.GetMapDisplayRect (); + Rect visibleMapRect = this.GetVisibleMapRect (); + + // don't know why is this needed + // flip Y axis + displayPos.y = mapDisplayRect.height - displayPos.y; + + Vector2 normalizedPos = Rect.PointToNormalized (mapDisplayRect, displayPos); + + Vector2 mapPos = Rect.NormalizedToPoint (visibleMapRect, normalizedPos); + + return mapPos; + } + + + private void TeleportToWaypoint() { + + if (!m_isWaypointPlaced) + return; + + Ped.Instance.Teleport (MiniMap.MapPosToWorldPos (m_waypointMapPos)); + + } + + + void Update() { + + if (Input.GetKeyDown (KeyCode.M)) { + // toggle map + + if (this.IsOpened) { + this.IsOpened = false; + // also close pause menu + PauseMenu.IsOpened = false; + } else { + this.IsOpened = true; + // also open pause menu + PauseMenu.IsOpened = true; + } + + } + + + if (!PauseMenu.IsOpened || !this.IsOpened) + return; + + + // move focused position + + this.m_focusPos += new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw("Vertical")) + * 100 * Time.deltaTime / this.zoomLevel; + + this.ClampFocusPos (); + + + // zoom + + float oldZoomLevel = this.zoomLevel; + + if (Input.GetKey (KeyCode.KeypadPlus)) { + zoomLevel *= 1.1f; + } + + if (Input.GetKey (KeyCode.KeypadMinus)) { + zoomLevel /= 1.1f; + } + + zoomLevel = Mathf.Clamp (zoomLevel, 0.05f, 10f); + + if (oldZoomLevel != this.zoomLevel) { + // this.AdjustVisibleMapRectAfterZooming (); + } + + + // toggle waypoint on map + + if (Input.GetMouseButtonDown (1)) { + + Vector2 mouseMapPos; + if (this.GetMapPosUnderMouse (out mouseMapPos)) { + m_isWaypointPlaced = !m_isWaypointPlaced; + if (m_isWaypointPlaced) + m_waypointMapPos = mouseMapPos; + } + + } + + // focus on player key shortcut + if (Input.GetKeyDown (KeyCode.F)) { + this.FocusOnPlayer (); + } + + // teleport to waypoint key shortcut +// if (Input.GetKeyDown (KeyCode.T)) { +// this.TeleportToWaypoint (); +// } + + // remember last mouse position + m_lastMousePosition = Input.mousePosition; + + + } + + + protected override void OnWindowGUI () + { + + if (null == MiniMap.Instance) + return; + if (null == Ped.Instance) + return; + + + int uiSize = (int) this.windowRect.width; + Texture2D mapTexture = MiniMap.Instance.MapTexture; + Texture2D blackPixel = MiniMap.Instance.BlackPixel; + Texture2D seaPixel = MiniMap.Instance.SeaPixel; + + + Rect mapDisplayRect = this.GetMapDisplayRect (); + Rect visibleMapRect = this.GetVisibleMapRect (); + // this.visibleMapRect.size = this.GetVisibleMapSize(); + + + + //if (!toggleMap) { + if(false) { + + //GUILayout.BeginArea (new Rect (Screen.width - uiSize - 10, uiSize + 20, uiSize, 80)); + + GUIStyle style = new GUIStyle ("label") { alignment = TextAnchor.MiddleCenter }; + + + // draw some info in upper left corner + + Vector2 labelSize = new Vector2 (uiSize, 25); + Rect labelRect = new Rect (Vector2.zero, labelSize); + + GUI.DrawTexture (labelRect, blackPixel); + if (Ped.Instance != null) { + Vector3 pPos = Ped.Instance.transform.position; + GUI.Label (labelRect, + string.Format ("x: {0}, y: {1}, z: {2}", pPos.x.ToString ("F2"), pPos.y.ToString ("F2"), pPos.z.ToString ("F2")), + style); + } + + + // draw zone name + + //Rect zoneRect = new Rect (uiSize / 2 - uiSize / (2 * 3), 25, uiSize / 3, 25); + + //GUI.DrawTexture (zoneRect, blackPixel); + //GUI.Label (zoneRect, ZoneName, style); + + + bool showZoomPanel = true; + if (showZoomPanel) { + // display zoom panel + + Color previousColor = GUI.color; + + Rect zoomPanel = new Rect (uiSize / 2 - uiSize / (2 * 4), 55, uiSize / 4, 25); + + float fAlpha = 1; + + GUI.color = new Color (0, 0, 0, fAlpha); + + // fill everything with black + GUI.DrawTexture (zoomPanel, blackPixel); + + GUI.color = new Color (255, 255, 255, fAlpha); + + // display zoom percentage + float curZoomPercentage = 1; + GUI.Label (zoomPanel, string.Format ("x{0}", curZoomPercentage.ToString ("F2")), style); + + GUI.color = previousColor; + } + + + //GUILayout.EndArea (); + + } else { + + //mapRect = new Vector2 (mapTexture.width, mapTexture.height) * (baseScale * (mapScale / mapMaxScale) * 2); + + // fill everything with black - why ? + //GUI.DrawTexture (new Rect (50, 50, Screen.width - 100, Screen.height - 100), blackPixel); + + // fill everything with sea + GUI.DrawTexture (mapDisplayRect, seaPixel); + + //GUILayout.BeginArea (new Rect (mapUpperLeftCorner, windowSize)); + + //GUILayout.BeginArea (new Rect (mapScroll, mapRect)); + + // draw the map texture + this.DrawMapTexture( mapDisplayRect, visibleMapRect ); + + // what's this ? + //GUI.DrawTexture (new Rect (Vector2.zero, Vector2.one * 16), blackPixel); + + + //GUILayout.EndArea (); + //GUILayout.EndArea (); + + + // draw 2 lines crossing under cursor + Vector2 mouseDisplayPos = ScreenPosToDisplayPos( m_lastMousePosition ); + float linesWidth = 4; + Color linesColor = (Color.yellow + Color.black) / 2.0f; + // vertical line + GUIUtils.DrawRect (new Rect(mouseDisplayPos.x - linesWidth / 2.0f, 0, linesWidth, mapDisplayRect.height), linesColor); + // horizontal line + GUIUtils.DrawRect (new Rect(0, mouseDisplayPos.y - linesWidth / 2.0f, mapDisplayRect.width, linesWidth), linesColor); + + + // draw map items + this.DrawMapItems (mapDisplayRect); + + + // draw info area + this.DrawInfoArea( mapDisplayRect ); + + } + + } + + private void DrawMapTexture(Rect mapDisplayRect, Rect visibleMapRect) { + + Texture2D mapTexture = MiniMap.Instance.MapTexture; + + + //GUI.DrawTexture (new Rect (mapZoomPos, mapRect), mapTexture); + //GUI.DrawTexture (new Rect (Vector2.zero, this.windowRect.size), MiniMap.Instance.MapTexture); + + Rect texCoords = new Rect(visibleMapRect.x / mapTexture.width, visibleMapRect.y / mapTexture.height, + visibleMapRect.width / mapTexture.width, visibleMapRect.height / mapTexture.height); + + texCoords = Utilities.F.Clamp01 (texCoords); + + // adjust display rect + + Rect renderRect = mapDisplayRect; + // float mulX = mapDisplayRect.width / GetMapSize (); + // float mulY = mapDisplayRect.height / GetMapSize (); + + if(visibleMapRect.xMax > GetMapSize()) { + // reduce display width + // renderRect.width -= (visibleMapRect.xMax - GetMapSize()) * mulX ; + float perc = (visibleMapRect.xMax - GetMapSize()) / visibleMapRect.width; + renderRect.xMax -= perc * mapDisplayRect.width; + } + if (visibleMapRect.xMin < 0) { + // increase x pos + // renderRect.xMin += - visibleMapRect.xMin * mulX; + float perc = - visibleMapRect.xMin / visibleMapRect.width; + renderRect.xMin += perc * mapDisplayRect.width; + } + if(visibleMapRect.yMax > GetMapSize()) { + // reduce display height from top + // renderRect.yMin += (visibleMapRect.yMax - GetMapSize()) * mulY ; + float perc = (visibleMapRect.yMax - GetMapSize()) / visibleMapRect.height; + renderRect.yMin += perc * mapDisplayRect.height; + } + if (visibleMapRect.yMin < 0) { + // reduce display height from bottom + // renderRect.yMax -= - visibleMapRect.yMin * mulY; + float perc = - visibleMapRect.yMin / visibleMapRect.height; + renderRect.yMax -= perc * mapDisplayRect.height; + } + + // mapTexture.wrapMode = TextureWrapMode.Clamp; + + GUI.DrawTextureWithTexCoords(renderRect, mapTexture, texCoords); + + } + + private void DrawInfoArea (Rect mapDisplayRect) { + + + Rect infoAreaRect = new Rect (3, mapDisplayRect.yMax, mapDisplayRect.width - 3, this.infoAreaHeight); + + GUILayout.BeginArea (infoAreaRect); + GUI.DrawTexture (new Rect(new Vector2(-infoAreaRect.x, 0), infoAreaRect.size), m_infoAreaTexture); + + m_infoAreaScrollViewPos = GUILayout.BeginScrollView (m_infoAreaScrollViewPos); + + GUILayout.Space (10); + + // first row - controls + GUILayout.BeginHorizontal (GUILayout.MaxWidth (infoAreaRect.width)); + + if (GUILayout.Button ("Focus on player [F]")) { + this.FocusOnPlayer (); + } + if (GUILayout.Button ("Teleport to waypoint")) { + this.TeleportToWaypoint (); + } + GUILayout.Space (5); + GUILayout.Label ("Player size: " + (int) m_playerPointerSize); + m_playerPointerSize = GUILayout.HorizontalSlider (m_playerPointerSize, 1, 50, GUILayout.MinWidth(40)); + m_drawZones = GUILayout.Toggle (m_drawZones, "Draw zones"); + + GUILayout.EndHorizontal (); + + // second row - info + GUILayout.BeginHorizontal (GUILayout.MaxWidth (infoAreaRect.width)); + + GUILayout.Label ("Player world pos: " + Ped.Instance.transform.position); + GUILayout.Space (5); + GUILayout.Label ("Player minimap pos: " + MiniMap.WorldPosToMapPos (Ped.Instance.transform.position)); + GUILayout.Space (5); + GUILayout.Label ("Focus pos: " + this.GetFocusPosition ()); + GUILayout.Space (5); + Vector2 cursorMapPos; + if (this.GetMapPosUnderMouse (out cursorMapPos)) + GUILayout.Label ("Cursor pos: " + cursorMapPos); + GUILayout.Space (5); + GUILayout.Label ("Zoom: " + this.zoomLevel); + // zone name under cursor + GUILayout.Space (5); + Vector3 mouseWorldPos; + if (this.GetWorldPosUnderMouse (out mouseWorldPos)) { + GUILayout.Label ("cursor world pos: " + mouseWorldPos); + GUILayout.Label ("Zone: " + SZone.GetZoneName (mouseWorldPos, true), GUILayout.Width(80)); + } + + GUILayout.EndHorizontal (); + + GUILayout.Space (5); + GUILayout.Label ("Controls: arrows/WASD - move, +/- - zoom, right click - place waypoint"); + + GUILayout.EndScrollView (); + + GUILayout.EndArea (); + + } + + private void DrawMapItems(Rect mapDisplayRect) { + + + if (!m_clipMapItems) { + GUI.EndClip (); + // GUI.EndGroup (); + } else { + GUI.BeginGroup (mapDisplayRect); // ensure that all map items are drawn inside this rect - doesn't work when items are rotated + } + + + // draw player pointer + this.DrawItemOnMapRotated( MiniMap.Instance.PlayerBlip, Ped.Instance.transform.position, Ped.Instance.transform.forward, (int) m_playerPointerSize ); + // this.DrawItemOnMapRotated( MiniMap.Instance.PlayerBlip, Player.Instance.transform.position, Player.Instance.transform.forward, 10 ); + // this.DrawItemOnMap( blackPixel, Player.Instance.transform.position, 50 ); + + // draw all zones + if (m_drawZones) { + + foreach (var zone in SZone.AllZones) { + + Vector2 min = MiniMap.WorldPosToMapPos (zone.vmin); + Vector2 max = MiniMap.WorldPosToMapPos (zone.vmax); + Rect rect = new Rect (min, max - min); + + Rect renderRect; + if (this.GetMapItemRenderRect (rect, out renderRect)) { + GUI.Box (renderRect, ""); + GUIUtils.CenteredLabel (renderRect.center, zone.name); + } + + } + } + + // draw waypoint + if (m_isWaypointPlaced) { + this.DrawItemOnMap (MiniMap.Instance.WaypointTexture, m_waypointMapPos, 12); + } + + + if (!m_clipMapItems) { + // GUI.BeginGroup (new Rect (0, 0, Screen.width, Screen.height)); + GUI.BeginClip (this.windowRect); + } else { + GUI.EndGroup (); + } + + + } + + + public bool GetMapItemRenderRect( Rect itemMapBoundsRect, out Rect renderRect ) { + + renderRect = Rect.zero; + + // Texture2D mapTexture = MiniMap.Instance.MapTexture; + + Rect visibleMapRect = this.GetVisibleMapRect (); + + if (!visibleMapRect.Overlaps (itemMapBoundsRect) && !visibleMapRect.Contains (itemMapBoundsRect)) { + // Debug.LogFormat ("Item rect {0} is not within visible rect {1}", itemRect, visibleMapRect); + return false; + } + + // just convert map pos to screen pos + Rect displayRectNormalized = itemMapBoundsRect.Normalized( visibleMapRect ); + + + + /* + // get intersection between these rects + Rect intersectionRect = itemRect.Intersection (visibleMapRect); + + Rect displayRectNormalized = intersectionRect.Normalized (visibleMapRect); + // displayRectNormalized.y = 1.0f - displayRectNormalized.y; + Rect texCoords = intersectionRect.Normalized (itemRect); + + + // just in case + displayRectNormalized = displayRectNormalized.Clamp01(); + texCoords = texCoords.Clamp01 (); + */ + + + // adjust display rect + + Rect mapDisplayRect = this.GetMapDisplayRect (); + Vector2 renderRectPos = mapDisplayRect.position + Vector2.Scale (mapDisplayRect.size, displayRectNormalized.position); + renderRectPos.y = mapDisplayRect.height - renderRectPos.y; + Vector2 renderRectSize = Vector2.Scale (mapDisplayRect.size, displayRectNormalized.size); + renderRectPos.y -= renderRectSize.y; + renderRect = new Rect (renderRectPos, renderRectSize); + + + // GUI.DrawTextureWithTexCoords(renderRect, itemTexture, texCoords); + + + // Debug.LogFormat ("Drawn item: item rect {0} visible map rect {1} intersection rect {2} displayRectNormalized {3} " + + // "texCoords {4} mapDisplayRect {5} renderRect {6}", itemRect, visibleMapRect, intersectionRect, displayRectNormalized, + // texCoords, mapDisplayRect, renderRect); + + return true; + } + + public void DrawItemOnMap( Texture2D itemTexture, Rect itemRect ) { + + Rect renderRect; + if (GetMapItemRenderRect (itemRect, out renderRect)) { + GUI.DrawTexture (renderRect, itemTexture); + } + + } + + public void DrawItemOnMap( Texture2D itemTexture, Vector2 mapPos, int itemSize ) { + + this.DrawItemOnMap (itemTexture, F.CreateRect (mapPos, Vector2.one * itemSize)); + + } + + public void DrawItemOnMap( Texture2D itemTexture, Vector3 worldPos, int itemSize ) { + + Vector2 mapPos = MiniMap.WorldPosToMapPos (worldPos); + + this.DrawItemOnMap (itemTexture, mapPos, itemSize); + + } + + public void DrawItemOnMapRotated( Texture2D itemTexture, Vector3 worldPos, Vector3 worldDir, int itemSize ) { + + Vector2 mapPos = MiniMap.WorldPosToMapPos (worldPos); + + this.DrawItemOnMapRotated (itemTexture, F.CreateRect (mapPos, Vector2.one * itemSize), worldDir); + + } + + public void DrawItemOnMapRotated( Texture2D itemTexture, Rect itemRect, Vector3 worldDir ) { + + Rect renderRect; + if (!GetMapItemRenderRect (itemRect, out renderRect)) { + return; + } + + + // find angle around Y axis + Vector3 dir = new Vector3(worldDir.x, 0, worldDir.z).normalized; + Quaternion q = Quaternion.LookRotation (dir, Vector3.up); + float angle = q.eulerAngles.y - 180.0f; + + // save matrix + var oldMatrix = GUI.matrix; + + // rotate around center of item + GUIUtility.RotateAroundPivot( angle, renderRect.center ); + + // draw + GUI.DrawTexture (renderRect, itemTexture); + + // restore matrix + GUI.matrix = oldMatrix; + + + } + + + } + +} diff --git a/Assets/Scripts/UI/MapWindow.cs.meta b/Assets/Scripts/UI/MapWindow.cs.meta new file mode 100644 index 00000000..32abf03f --- /dev/null +++ b/Assets/Scripts/UI/MapWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 09e5fb65bfb794372ad6dc715a59c96b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/OptionsWindow.cs b/Assets/Scripts/UI/OptionsWindow.cs new file mode 100644 index 00000000..3e789c4d --- /dev/null +++ b/Assets/Scripts/UI/OptionsWindow.cs @@ -0,0 +1,378 @@ +using System.Collections.Generic; +using UnityEngine; +using System.Linq; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.UI { + + public class OptionsWindow : PauseMenuWindow { + + /// + /// Subscribe to this event to draw gui inside options window. + /// + public static event System.Action onGUI = delegate {}; + + + public enum InputPersistType + { + None, + OnStart, + AfterLoaderFinishes + } + + public abstract class Input + { + public string description = ""; + public InputPersistType persistType = InputPersistType.None; + public string category = ""; + + public abstract void Load (); + public abstract void Save (); + public abstract void Display (); + } + + public abstract class Input : Input + { + public System.Func getValue = () => default(T); + public System.Action setValue = (val) => {}; + public System.Func isAvailable = () => true; + + + public Input () + { + } + + public Input (string description) + { + this.description = description; + } + + public override void Display () + { + if (!this.isAvailable ()) + return; + + var oldValue = this.getValue (); + + var newValue = this.Display (oldValue); + + if (!newValue.Equals( oldValue )) + { + this.setValue (newValue); + } + } + + public abstract T Display (T currentValue); + + public override void Load () { + if (!this.isAvailable ()) + return; + if (!PlayerPrefs.HasKey (this.description)) + return; + string str = PlayerPrefs.GetString (this.description, null); + if (str != null) + { + this.setValue (this.Load (str)); + } + } + public abstract T Load (string str); + + public override void Save () { + if (!this.isAvailable ()) + return; + string str = this.SaveAsString (this.getValue ()); + if (str != null) + PlayerPrefs.SetString (this.description, str); + } + + public virtual string SaveAsString (T value) { + return value.ToString (); + } + + } + + public class FloatInput : Input + { + public float minValue; + public float maxValue; + + public FloatInput () { } + + public FloatInput (string description, float minValue, float maxValue) : base (description) + { + this.minValue = minValue; + this.maxValue = maxValue; + } + + public override float Display (float currentValue) + { + return OptionsWindow.FloatSlider (currentValue, this.minValue, this.maxValue, this.description); + } + + public override float Load (string str) + { + return float.Parse (str, System.Globalization.CultureInfo.InvariantCulture); + } + } + + public class BoolInput : Input + { + public BoolInput () { } + + public BoolInput (string description) : base (description) + { + } + + public override bool Display (bool currentValue) + { + return GUILayout.Toggle (currentValue, this.description); + } + + public override bool Load (string str) + { + return bool.Parse (str); + } + } + + public class EnumInput : Input where T : struct + { + + public override T Display (T currentValue) + { + return OptionsWindow.Enum (currentValue, this.description); + } + + public override T Load (string str) + { + return (T) System.Enum.Parse (typeof(T), str); + } + } + + public class MultipleOptionsInput : Input + { + public T[] Options { get; set; } + + public override T Display (T currentValue) + { + return OptionsWindow.MultipleOptions (currentValue, this.description, this.Options); + } + + public override T Load (string str) + { + int index = this.Options.FindIndex (t => this.SaveAsString (t) == str); + if (index < 0) + throw new System.ArgumentException ( + string.Format ("Error loading multiple options of type {0} - specified option '{1}' was not found", + typeof(T), str)); + + return this.Options [index]; + } + } + + + private static List s_registeredInputs = new List (); + private static int s_currentTabIndex = 0; + private static string[] s_categories; + + + + OptionsWindow() { + + // set default parameters + + this.windowName = "Options"; + this.useScrollView = true; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + float windowWidth = Screen.width * 0.85f; + windowWidth = Mathf.Min (windowWidth, 600); + float windowHeight = Screen.height * 0.8f; + windowHeight = Mathf.Min (windowHeight, windowWidth * 9 / 16); + this.windowRect = Utilities.GUIUtils.GetCenteredRect (new Vector2 (windowWidth, windowHeight)); + + LoadSettings (InputPersistType.OnStart); + + } + + void OnLoaderFinished () + { + LoadSettings (InputPersistType.AfterLoaderFinishes); + } + + + protected override void OnWindowGUIBeforeContent () + { + s_categories = s_registeredInputs.Select (i => i.category).Distinct ().ToArray (); + + if (s_categories.Length > 0) + { + s_currentTabIndex = GUIUtils.TabsControl (s_currentTabIndex, s_categories); + + GUILayout.Space (20); + } + } + + protected override void OnWindowGUI () + { + + // draw inputs + + if (s_categories.Length > 0) + { + foreach (var input in s_registeredInputs.Where( i => i.category == s_categories[s_currentTabIndex] )) + { + input.Display (); + } + } + + /* + var groupings = s_registeredInputs.GroupBy (i => i.category); + foreach (var grouping in groupings) + { + GUILayout.Label ("\n" + grouping.Key + "\n"); + + foreach (var input in grouping) + { + input.Display (); + } + } + */ + + + onGUI (); + + } + + protected override void OnWindowGUIAfterContent () + { + GUILayout.BeginHorizontal (); + GUILayout.FlexibleSpace (); + + // display Save button + if (GUILayout.Button ("Save", GUILayout.ExpandWidth (false))) + SaveSettings (); + + GUILayout.Space (5); + + // display Load button + if (GUILayout.Button ("Load", GUILayout.ExpandWidth (false))) + LoadSettings (); + + GUILayout.EndHorizontal (); + + GUILayout.Space (5); + } + + + /// + /// Displays float slider with description. + /// + public static void FloatSlider(ref float value, float min, float max, string description) { + + GUILayout.Label(description + " : " + value); + value = GUILayout.HorizontalSlider( value, min, max ); + + } + + /// + /// Displays float slider with description. + /// + public static float FloatSlider(float value, float min, float max, string description) { + + GUILayout.Label(description + " : " + value); + float newValue = GUILayout.HorizontalSlider( value, min, max ); + return newValue; + } + + public static T MultipleOptions( T currentValue, string description, params T[] allValues ) { + + GUILayout.Label (description + " : " + currentValue.ToString ()); + + GUILayout.BeginHorizontal (); + + T newValue = currentValue; + + foreach (var v in allValues) { + if (GUILayout.Button (v.ToString ())) { + newValue = v; + } + GUILayout.Space (5); + } + + GUILayout.EndHorizontal (); + + return newValue; + } + + public static T Enum( T currentValue, string description ) where T : struct { + + var values = System.Enum.GetValues (typeof(T)); + + var newValue = MultipleOptions (currentValue, description, values.Cast ().ToArray ()); + return newValue; + } + + public static void DisplayInput( Input input ) + { + input.Display (); + } + + + public static void RegisterInput (Input input) + { + s_registeredInputs.AddIfNotPresent ( input ); + } + + public static void RegisterInputs (string category, params Input[] inputs) + { + foreach (var input in inputs) + { + input.category = category; + RegisterInput (input); + } + } + + public static void LoadSettings (InputPersistType persistType) + { + var inputs = s_registeredInputs.Where (input => input.persistType == persistType).ToArray (); + + Debug.Log ("The following inputs will be loaded: " + string.Join(", ", inputs.Select( i => i.description ))); + + foreach (var input in inputs) + { + F.RunExceptionSafe (() => input.Load ()); + } + + } + + public static void LoadSettings () + { + LoadSettings (InputPersistType.OnStart); + if (Behaviours.Loader.HasLoaded) + LoadSettings (InputPersistType.AfterLoaderFinishes); + } + + public static void SaveSettings () + { + var inputs = s_registeredInputs.Where (input => input.persistType != InputPersistType.None).ToArray (); + + Debug.Log ("The following inputs will be saved: " + string.Join(", ", inputs.Select( i => i.description ))); + + foreach (var input in inputs) + { + F.RunExceptionSafe (() => input.Save ()); + } + + PlayerPrefs.Save (); + + } + + } + +} diff --git a/Assets/Scripts/UI/OptionsWindow.cs.meta b/Assets/Scripts/UI/OptionsWindow.cs.meta new file mode 100644 index 00000000..6a9fef9c --- /dev/null +++ b/Assets/Scripts/UI/OptionsWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8acb19522c6ef4152bd0760482a0a166 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/PauseMenu.cs b/Assets/Scripts/UI/PauseMenu.cs new file mode 100644 index 00000000..9028a269 --- /dev/null +++ b/Assets/Scripts/UI/PauseMenu.cs @@ -0,0 +1,130 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours; +using System.Linq; + +namespace SanAndreasUnity.UI { + + public class PauseMenu : MonoBehaviour { + + private static bool m_isOpened = false; + + public static bool IsOpened + { + get { + return m_isOpened; + } + set { + m_isOpened = value; + } + } + + public static event System.Action onDrawItems = delegate {}; + + // public Color windowsColor = new Color(0.5f, 0.5f, 0.5f, 0.8f); + // private static Texture2D m_windowBackgroundTexture = null; + // private static bool m_changedWindowStyle = false; + + + + void Awake () { + + // m_windowBackgroundTexture = Utilities.F.CreateTexture (1, 1, this.windowsColor); + + } + + void Start () { + + } + + public static PauseMenuWindow[] GetAllWindows() { + return FindObjectsOfType (); + } + + void Update () { + + // toggle pause menu + if (Loader.HasLoaded && Input.GetButtonDown ("Start")) { + + if (IsOpened) { + // if there is a modal window, close it, otherwise close pause menu + var window = GetAllWindows ().FirstOrDefault (w => w.IsOpened && w.IsModal); + if (window != null) { + window.IsOpened = false; + } else { + IsOpened = !IsOpened; + } + } else { + IsOpened = !IsOpened; + } + + } + + // if (IsOpened && Input.GetKeyDown(KeyCode.M)) + // IsOpened = false; + + // if (MiniMap.toggleMap && Input.GetKeyDown(KeyCode.Escape)) + // MiniMap.toggleMap = false; + +// bool isConsoleStateChanged = Console.Instance.m_openKey != Console.Instance.m_closeKey ? +// Input.GetKeyDown(Console.Instance.m_openKey) || Input.GetKeyDown(Console.Instance.m_closeKey) : +// Input.GetKeyDown(Console.Instance.m_openKey); +// +// if (m_playerController != null) { +// // WTF is this ?! +// +// // Fixed: If Escape is pressed, map isn't available +// if (!IsOpened && (Input.GetKeyDown (KeyCode.Escape) || isConsoleStateChanged || Input.GetKeyDown (KeyCode.F1) || (m_playerController.CursorLocked && Input.GetKeyDown (KeyCode.M)))) +// m_playerController.ChangeCursorState (!m_playerController.CursorLocked); +// } + + // unlock and show cursor while pause menu is opened + if (Loader.HasLoaded) { + bool shouldBeLocked = !IsOpened; + if (GameManager.CursorLocked != shouldBeLocked) + GameManager.ChangeCursorState (shouldBeLocked); + } + + } + + void OnGUI() { + + if (!Loader.HasLoaded || !IsOpened) + return; + +// if (!m_changedWindowStyle) { +// m_changedWindowStyle = true; +// GUI.skin.window.normal.background = m_windowBackgroundTexture; +// } + + + // draw title + Utilities.GUIUtils.CenteredLabel (new Vector2 (Screen.width / 2.0f, 20), "PAUSE MENU"); + + + GUI.BeginGroup (new Rect (10, 0, 250, Screen.height)); + + GUILayout.Space (20); + + if (GUILayout.Button ("Resume")) + IsOpened = false; + + GUILayout.Space (10); + + // draw all registered items + onDrawItems (); + + GUILayout.Space (10); + + if (GUILayout.Button ("Exit")) { + GameManager.ExitApplication (); + } + + GUI.EndGroup (); + + } + + } + +} diff --git a/Assets/Scripts/UI/PauseMenu.cs.meta b/Assets/Scripts/UI/PauseMenu.cs.meta new file mode 100644 index 00000000..740f565f --- /dev/null +++ b/Assets/Scripts/UI/PauseMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 661aa8bc19a0e4d3dbb894f6b7b77966 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/PauseMenuWindow.cs b/Assets/Scripts/UI/PauseMenuWindow.cs new file mode 100644 index 00000000..c9ffb266 --- /dev/null +++ b/Assets/Scripts/UI/PauseMenuWindow.cs @@ -0,0 +1,246 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace SanAndreasUnity.UI { + + public class PauseMenuWindow : MonoBehaviour { + + public string windowName = ""; + + [SerializeField] private bool m_isOpenedByDefaultInMainMenu = false; + [SerializeField] private bool m_isOpenedByDefaultInPauseMenu = false; + + private bool m_isOpened = false; + public bool IsOpened { + get { return this.m_isOpened; } + set { + if (m_isOpened == value) + return; + m_isOpened = value; + if (m_isOpened) + this.OnWindowOpened (); + else + this.OnWindowClosed (); + } + } + + private static int lastWindowId = 1352345; + private int windowId = lastWindowId++; + public int WindowId { get { return this.windowId; } } + + public Rect windowRect = Utilities.GUIUtils.GetCenteredRectPerc(new Vector2(0.5f, 0.5f)); + public Vector2 WindowSize { get { return this.windowRect.size; } } + + public bool useScrollView = false; + protected Vector2 scrollPos = Vector2.zero; + + protected bool isDraggable = true; + public bool IsDraggable { get { return this.isDraggable; } } + + protected bool isModal = false; + public bool IsModal { get { return this.isModal; } } + + protected bool m_hasExitButton = true; + protected bool m_hasMinimizeButton = true; + + private bool m_isMinimized = false; + public bool IsMinimized { get { return this.m_isMinimized; } set { m_isMinimized = value; } } + + public const float kMinimizedWindowHeight = 45; + + private bool m_hasStarted = false; + + [SerializeField] private float m_spaceBeforeContent = 0f; + public float SpaceBeforeContent { get { return m_spaceBeforeContent; } set { m_spaceBeforeContent = value; } } + [SerializeField] private float m_spaceAfterContent = 0f; + public float SpaceAfterContent { get { return m_spaceAfterContent; } set { m_spaceAfterContent = value; } } + + [SerializeField] private bool m_registerInMainMenuOnStart = false; + public bool IsRegisteredInMainMenu { get; private set; } + + + + void WindowStart() { + + if (m_registerInMainMenuOnStart) + this.RegisterInMainMenu (); + + if (m_isOpenedByDefaultInMainMenu) + this.IsOpened = true; + + this.OnWindowStart (); + } + + /// + /// Called on first OnGUI(). + /// + protected virtual void OnWindowStart() { + + } + + protected virtual void OnWindowOpened() { + + } + + protected virtual void OnWindowClosed() { + + } + + + protected virtual void OnLoaderFinished () + { + if (m_isOpenedByDefaultInPauseMenu) + { + this.IsOpened = true; + } + } + + + void OnGUI() { + + if (!m_hasStarted) { + m_hasStarted = true; + this.WindowStart (); + } + + if (Behaviours.Loader.IsLoading) + return; + + if (!this.IsOpened) + return; + + if (!Behaviours.GameManager.IsInStartupScene && !PauseMenu.IsOpened) + return; + + + Rect newRect; + Rect inputRect = this.windowRect; + if(this.IsMinimized) + inputRect.height = kMinimizedWindowHeight; + + if (this.isModal) + newRect = GUI.ModalWindow (this.windowId, inputRect, WindowFunction, this.windowName); + else + newRect = GUI.Window( this.windowId, inputRect, WindowFunction, this.windowName ); + + if (this.IsMinimized) + this.windowRect.position = newRect.position; // only copy position + else + this.windowRect = newRect; + + } + + void WindowFunction( int id ) { + + + float buttonWidth = 16; + float buttonHeight = 16; + float buttonYOffset = 2; + + // exit button + if (m_hasExitButton) { + Color exitButtonColor = Color.Lerp (Color.red, Color.white, 0.0f); + // exitButtonColor.a = 0.7f; + if (Utilities.GUIUtils.ButtonWithColor (new Rect (this.windowRect.width - buttonWidth - 2, buttonYOffset, buttonWidth, buttonHeight), + "x", exitButtonColor)) { + this.IsOpened = false; + } + } + + // minimize button + if (m_hasMinimizeButton) { + if (GUI.Button (new Rect (this.windowRect.width - buttonWidth - 2 - buttonWidth - 2, buttonYOffset, buttonWidth, buttonHeight), "-")) { + this.IsMinimized = !this.IsMinimized; + } + } + + + if (!this.IsMinimized) { + // draw contents inside window + + if (this.SpaceBeforeContent > 0) + GUILayout.Space (this.SpaceBeforeContent); + + this.OnWindowGUIBeforeContent (); + + if (this.useScrollView) + this.scrollPos = GUILayout.BeginScrollView (this.scrollPos); + + this.OnWindowGUI (); + + if (this.useScrollView) + GUILayout.EndScrollView (); + + if (this.SpaceAfterContent > 0) + GUILayout.Space (this.SpaceAfterContent); + + this.OnWindowGUIAfterContent (); + } + + + if (this.isDraggable) + GUI.DragWindow (); + + } + + protected virtual void OnWindowGUIBeforeContent() { + + } + + protected virtual void OnWindowGUI() { + + } + + protected virtual void OnWindowGUIAfterContent() { + + } + + + public void RegisterButtonInPauseMenu() { + + PauseMenu.onDrawItems += this.OnPauseMenuGUI; + + } + + public void UnRegisterButtonInPauseMenu() { + + PauseMenu.onDrawItems -= this.OnPauseMenuGUI; + + } + + private void OnPauseMenuGUI() { + + // display button for opening/closing window + + // string text = this.IsOpened ? "Hide " + this.windowName : "Show " + this.windowName; + string text = this.windowName; + + if (GUILayout.Button (text)) { + this.IsOpened = ! this.IsOpened; + } + + } + + public void RegisterInMainMenu () + { + if (this.IsRegisteredInMainMenu) + return; + + this.IsRegisteredInMainMenu = true; + MainMenu.RegisterMenuItem ( () => this.OnMainMenuGUI() ); + } + + private void OnMainMenuGUI () + { + // draw a button in main menu + + if (GUILayout.Button (this.windowName, MainMenu.ButtonLayoutOptions)) + { + this.IsOpened = !this.IsOpened; + } + + } + + } + +} diff --git a/Assets/Scripts/UI/PauseMenuWindow.cs.meta b/Assets/Scripts/UI/PauseMenuWindow.cs.meta new file mode 100644 index 00000000..181eb4cc --- /dev/null +++ b/Assets/Scripts/UI/PauseMenuWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37effc81549f74d9680604a44b45e199 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/PedsWindow.cs b/Assets/Scripts/UI/PedsWindow.cs new file mode 100644 index 00000000..6c0c4750 --- /dev/null +++ b/Assets/Scripts/UI/PedsWindow.cs @@ -0,0 +1,165 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Utilities; +using SanAndreasUnity.Behaviours; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; +using System.Linq; + +namespace SanAndreasUnity.UI { + + public class PedsWindow : PauseMenuWindow { + + public int numPedsPerPage = 40; + + private Vector2 m_scrollPos = Vector2.zero; + private List m_pedDefs = new List (); + private int m_currentPageNumber = 1; + private int m_currentPedIdWithOptions = -1; + + + PedsWindow() { + + // set default parameters + + this.windowName = "Peds"; + this.useScrollView = false; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + this.windowRect = GUIUtils.GetCenteredRect( new Vector2(550, 450) ); + } + + void OnLoaderFinished () + { + m_pedDefs = Item.GetDefinitions ().ToList (); + } + + + protected override void OnWindowGUI () + { + + bool playerExists = Ped.Instance != null; + + + float[] widthPercsLabels = new float[]{ 0.1f, 0.3f, 0.25f, 0.25f }; + float[] widthPercsButtons = new float[]{ 0.1f, 0.15f, 0.15f, 0.2f }; + float rowHeight = 40; + float buttonSpacing = 3; + + + // info about current ped + if (playerExists) { + GUILayout.Label ("Current ped:"); + this.DisplayPed( GetLayoutRect( rowHeight ), Ped.Instance.PedDef, false, true, widthPercsLabels, + widthPercsButtons, buttonSpacing ); + } + + // button to kill all peds + if (GUILayout.Button ("Kill all peds", GUILayout.Width (100))) { + KillAllPeds (); + } + GUILayout.Space (5); + + + // page view numbers + m_currentPageNumber = GUIUtils.DrawPagedViewNumbers( GetLayoutRect(20), m_currentPageNumber, m_pedDefs.Count, this.numPedsPerPage ); + GUILayout.Space (5); + + // column descriptions + GUIUtils.DrawItemsInARowPerc (this.GetLayoutRect (rowHeight), (r, item) => GUI.Label (r, item), + new string[]{ "Id", "Model name", "Default type", "Behaviour name" }, widthPercsLabels); + GUILayout.Space (7); + + + // scroll view with all peds + m_scrollPos = GUILayout.BeginScrollView (m_scrollPos); + + foreach (var def in m_pedDefs.Skip ((m_currentPageNumber - 1) * this.numPedsPerPage).Take (this.numPedsPerPage)) { + + Rect rect = GetLayoutRect (rowHeight); + + this.DisplayPed (rect, def, true, playerExists, widthPercsLabels, widthPercsButtons, buttonSpacing); + + GUILayout.Space (12); + } + + GUILayout.EndScrollView (); + + } + + public void DisplayPed (Rect rect, PedestrianDef def, bool displayOptions, bool playerExists, float[] widthPercsLabels, + float[] widthPercsButtons, float buttonSpacing) + { + + rect.height *= 0.5f; + + GUIUtils.DrawItemsInARowPerc( rect, + (r, item) => GUI.Label(r, item), + new string[]{def.Id.ToString(), def.ModelName, def.DefaultType.ToString(), def.BehaviourName}, + widthPercsLabels); + + + if (displayOptions) { + + rect.position += new Vector2 (0, rect.height); + + int i = 0; + Rect itemRect; + + // display button which will open additional options + itemRect = GUIUtils.GetNextRectInARowPerc (rect, ref i, buttonSpacing, widthPercsButtons); + if (GUI.Button (itemRect, "...")) { + m_currentPedIdWithOptions = def.Id; + } + + if (m_currentPedIdWithOptions == def.Id) { + // display additional options + + if (playerExists) { + itemRect = GUIUtils.GetNextRectInARowPerc (rect, ref i, buttonSpacing, widthPercsButtons); + if (GUI.Button (itemRect, "Switch")) { + Ped.Instance.PlayerModel.Load (def.Id); + } + } + + itemRect = GUIUtils.GetNextRectInARowPerc (rect, ref i, buttonSpacing, widthPercsButtons); + if (GUI.Button (itemRect, "Spawn")) { + Ped.SpawnPed (def.Id); + } + + itemRect = GUIUtils.GetNextRectInARowPerc (rect, ref i, buttonSpacing, widthPercsButtons); + if (GUI.Button (itemRect, "Spawn stalker")) { + Ped.SpawnPedStalker (def.Id); + } + + } + + } + + } + + private Rect GetLayoutRect (float height) + { + return GUILayoutUtility.GetRect (this.WindowSize.x, height); + } + + private static void KillAllPeds () + { + + foreach (var p in Ped.AllPeds) { + if (p == Ped.Instance) + continue; + Destroy (p.gameObject); + } + + } + + } + +} diff --git a/Assets/Scripts/UI/PedsWindow.cs.meta b/Assets/Scripts/UI/PedsWindow.cs.meta new file mode 100644 index 00000000..f13853f5 --- /dev/null +++ b/Assets/Scripts/UI/PedsWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a3ba44be90f64d798a3abe7d45cab8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/TeleportWindow.cs b/Assets/Scripts/UI/TeleportWindow.cs new file mode 100644 index 00000000..1d78378f --- /dev/null +++ b/Assets/Scripts/UI/TeleportWindow.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using UnityEngine; +using System.Linq; +using SanAndreasUnity.Behaviours; + +namespace SanAndreasUnity.UI { + + public class TeleportWindow : PauseMenuWindow { + + // spawn locations + private List _spawns = new List(); + public List Spawns { get { return this._spawns; } } + + + + TeleportWindow() { + + // set default parameters + + this.windowName = "Teleport"; + this.useScrollView = true; + + } + + void OnSceneChanged (SceneChangedMessage msg) { + + _spawns.Clear (); + + if (!GameManager.IsInStartupScene) + _spawns = FindSpawnPlaces ().ToList (); + + this.AdjustWindowRect (); + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + this.AdjustWindowRect (); + } + + + public static Transform[] FindSpawnPlaces () + { + var obj = GameObject.Find("Player Spawns"); + if (obj) + return obj.GetComponentsInChildren (); + return new Transform[0]; + } + + + private void AdjustWindowRect () + { + float width = 260; + float height = Mathf.Min( 0.7f * Screen.height, 10 + 25 * _spawns.Count ); + this.windowRect = new Rect(Screen.width - width - 10, 10, width, height); + } + + protected override void OnWindowGUI () + { + + if (null == Ped.Instance) { + GUILayout.Label ("Player object not found"); + return; + } + + + for (int i = 1; i < _spawns.Count; i++) + { + var spawnLocation = _spawns [i]; + if (null == spawnLocation) + continue; + + if (GUILayout.Button (spawnLocation.name)) + { + Ped.Instance.Teleport (spawnLocation.position, spawnLocation.rotation); + } + } + + } + + } + +} diff --git a/Assets/Scripts/UI/TeleportWindow.cs.meta b/Assets/Scripts/UI/TeleportWindow.cs.meta new file mode 100644 index 00000000..b8de3352 --- /dev/null +++ b/Assets/Scripts/UI/TeleportWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4187a46a1c9ad4590a8b39ab12ce6522 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/UtilitiesWindow.cs b/Assets/Scripts/UI/UtilitiesWindow.cs new file mode 100644 index 00000000..c5b924e1 --- /dev/null +++ b/Assets/Scripts/UI/UtilitiesWindow.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Behaviours; + +namespace SanAndreasUnity.UI { + + public class UtilitiesWindow : PauseMenuWindow { + + + + UtilitiesWindow() { + + // set default parameters + + this.windowName = "Utilities"; + this.useScrollView = true; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + this.windowRect = new Rect(Screen.width / 2 - 100, 10, 200, 180); + } + + + protected override void OnWindowGUI () + { + + if (Ped.Instance) { + // display player position + // Vector2 pos = new Vector2 (_player.transform.position.x + 3000, 6000 - (_player.transform.position.z + 3000)); + GUILayout.Label ("Pos: " + Ped.InstancePos); + } + + if (GUILayout.Button ("Spawn random vehicle")) { + var spawner = FindObjectOfType (); + if (spawner) + spawner.SpawnVehicle (); + } + + if (GUILayout.Button("Change player model")) + { + CharacterModelChanger.ChangePedestrianModel(); + } + + if (GUILayout.Button("Spawn 5 peds")) + { + for (int i = 0; i < 5; i++) + { + Ped.SpawnPed (Ped.RandomPedId); + } + } + + if (GUILayout.Button("Spawn 5 stalker peds")) + { + for (int i = 0; i < 5; i++) + { + Ped.SpawnPedStalker (Ped.RandomPedId); + } + } + + if (GUILayout.Button("Destroy all vehicles")) + { + var vehicles = FindObjectsOfType (); + var vehicleToIgnore = Ped.Instance != null ? Ped.Instance.CurrentVehicle : null; + + foreach (var v in vehicles) { + if (v != vehicleToIgnore) + Destroy (v.gameObject); + } + } + + } + + } + +} diff --git a/Assets/Scripts/UI/UtilitiesWindow.cs.meta b/Assets/Scripts/UI/UtilitiesWindow.cs.meta new file mode 100644 index 00000000..d5ac2e1d --- /dev/null +++ b/Assets/Scripts/UI/UtilitiesWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e43dd3376534c44ea99e33b8a01cadba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/VehicleSpawnerWindow.cs b/Assets/Scripts/UI/VehicleSpawnerWindow.cs new file mode 100644 index 00000000..fd1ddbbf --- /dev/null +++ b/Assets/Scripts/UI/VehicleSpawnerWindow.cs @@ -0,0 +1,109 @@ +using System.Collections.Generic; +using UnityEngine; +using System.Linq; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Importing.Items.Definitions; + +namespace SanAndreasUnity.UI { + + public class VehicleSpawnerWindow : PauseMenuWindow { + + private List> vehicleGroupings = null; + private int[] columnWidths = new int[]{ 120, 120, 30, 70 }; + + + + VehicleSpawnerWindow() { + + // set default parameters + + this.windowName = "Vehicle Spawner"; + this.useScrollView = true; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + + //float windowWidth = 400; + //float windowHeight = Mathf.Min (700, Screen.height * 0.7f); + + //this.windowRect = Utilities.GUIUtils.GetCornerRect (SanAndreasUnity.Utilities.ScreenCorner.TopRight, + // new Vector2 (windowWidth, windowHeight), new Vector2 (20, 20)); + this.windowRect = Utilities.GUIUtils.GetCenteredRectPerc( new Vector2(0.4f, 0.8f) ); + + } + + + void GetVehicleDefs() { + + // get all vehicle definitions + var allVehicles = Item.GetDefinitions (); + + // group them by type + var groupings = allVehicles.GroupBy (v => v.VehicleType); + + this.vehicleGroupings = groupings.ToList (); + } + + + protected override void OnWindowGUI () + { + + if (Behaviours.Loader.HasLoaded && null == this.vehicleGroupings) { + GetVehicleDefs (); + } + + if (null == this.vehicleGroupings) + return; + + + GUILayout.Space (10); + + // for each vehicle, display a button which spawns it + + foreach (var grouping in this.vehicleGroupings) { + + GUILayout.Label (grouping.Key.ToString ()); + + GUILayout.Space (10); + + // table columns +// GUILayout.BeginHorizontal(); +// GUILayout.Label ("Game name", GUILayout.Width (this.columnWidths [0])); +// GUILayout.Label ("Class name", GUILayout.Width (this.columnWidths [1])); +// GUILayout.Label ("Id", GUILayout.Width (this.columnWidths [2])); +// GUILayout.Label ("Frequency", GUILayout.Width (this.columnWidths [3])); +// GUILayout.EndHorizontal (); +// +// GUILayout.Space (10); + + // display all vehicles of this type + foreach (var v in grouping) { + //GUILayout.BeginHorizontal (); + + if (GUILayout.Button (v.GameName, GUILayout.Width(this.columnWidths[0]))) { + Behaviours.Vehicles.Vehicle.CreateInFrontOfPlayer (v.Id); + } + //GUILayout.Label (v.ClassName, GUILayout.Width (this.columnWidths [1])); + //GUILayout.Label (v.Id.ToString(), GUILayout.Width (this.columnWidths [2])); + //GUILayout.Label (v.Frequency.ToString(), GUILayout.Width (this.columnWidths [3])); + + //GUILayout.EndHorizontal (); + } + + GUILayout.Space (10); + } + + + GUILayout.Space (20); + + } + + + } + +} diff --git a/Assets/Scripts/UI/VehicleSpawnerWindow.cs.meta b/Assets/Scripts/UI/VehicleSpawnerWindow.cs.meta new file mode 100644 index 00000000..bb928d75 --- /dev/null +++ b/Assets/Scripts/UI/VehicleSpawnerWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4428e76f4d28f48fdb58f39252b4e240 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/WeaponsWindow.cs b/Assets/Scripts/UI/WeaponsWindow.cs new file mode 100644 index 00000000..bfe231d1 --- /dev/null +++ b/Assets/Scripts/UI/WeaponsWindow.cs @@ -0,0 +1,95 @@ +using System.Collections.Generic; +using UnityEngine; +using SanAndreasUnity.Importing.Items; +using SanAndreasUnity.Behaviours; +using System.Linq; +using SanAndreasUnity.Utilities; + +namespace SanAndreasUnity.UI { + + public class WeaponsWindow : PauseMenuWindow { + + + + WeaponsWindow() { + + // set default parameters + + this.windowName = "Weapons"; + this.useScrollView = true; + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + // adjust rect + this.windowRect = Utilities.GUIUtils.GetCenteredRect( new Vector2( 600, 400 ) ); + } + + + protected override void OnWindowGUIBeforeContent () + { + base.OnWindowGUIBeforeContent (); + + bool playerExists = Ped.Instance != null; + + if (playerExists) + { + GUILayout.BeginHorizontal (); + + if (GUILayout.Button ("Remove all weapons", GUILayout.ExpandWidth(false))) + Ped.Instance.WeaponHolder.RemoveAllWeapons (); + + GUILayout.Space (5); + + if (GUILayout.Button ("Give ammo", GUILayout.ExpandWidth (false))) + { + foreach (var weapon in Ped.Instance.WeaponHolder.AllWeapons) + WeaponHolder.AddRandomAmmoAmountToWeapon (weapon); + } + + GUILayout.EndHorizontal (); + GUILayout.Space (15); + } + + } + + protected override void OnWindowGUI () + { + + // display all weapons from the game + + // add option to add them to player + + + + bool playerExists = Ped.Instance != null; + + + // var defs = Item.GetDefinitions (); + var datas = Importing.Weapons.WeaponData.LoadedWeaponsData.DistinctBy( wd => wd.weaponType ); + + foreach (var data in datas) { + + GUILayout.Label ("Id: " + data.modelId1 + " Name: " + data.weaponType + " Slot: " + data.weaponslot + + " Flags: " + ( null == data.gunData ? "" : string.Join(" ", data.gunData.Flags) ) ); + + if (playerExists) { + if (GUILayout.Button ("Give", GUILayout.Width(70))) { + // give weapon to player + Ped.Instance.WeaponHolder.SetWeaponAtSlot( data.modelId1, data.weaponslot ); + Ped.Instance.WeaponHolder.SwitchWeapon (data.weaponslot); + WeaponHolder.AddRandomAmmoAmountToWeapon( Ped.Instance.WeaponHolder.GetWeaponAtSlot (data.weaponslot) ); + } + } + + GUILayout.Space (5); + } + + } + + } + +} diff --git a/Assets/Scripts/UI/WeaponsWindow.cs.meta b/Assets/Scripts/UI/WeaponsWindow.cs.meta new file mode 100644 index 00000000..246f9ff7 --- /dev/null +++ b/Assets/Scripts/UI/WeaponsWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47b9d4dc7492d4d5892d2931d8a960be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/WorldStatsWindow.cs b/Assets/Scripts/UI/WorldStatsWindow.cs new file mode 100644 index 00000000..517df00c --- /dev/null +++ b/Assets/Scripts/UI/WorldStatsWindow.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace SanAndreasUnity.UI { + + public class WorldStatsWindow : PauseMenuWindow { + + + WorldStatsWindow() { + + // set default parameters + + this.windowName = "World stats"; + this.windowRect = new Rect(10, 10, 250, 330); + + } + + void Start () { + + this.RegisterButtonInPauseMenu (); + + } + + + protected override void OnWindowGUI () + { + + if (Behaviours.World.Cell.Instance != null) { + Behaviours.World.Cell.Instance.showWindow (this.WindowId); + } + + } + + } + +} diff --git a/Assets/Scripts/UI/WorldStatsWindow.cs.meta b/Assets/Scripts/UI/WorldStatsWindow.cs.meta new file mode 100644 index 00000000..9a0d25ce --- /dev/null +++ b/Assets/Scripts/UI/WorldStatsWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a86af676e111c4861b8e0f454c7cb025 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities.meta b/Assets/Scripts/Utilities.meta new file mode 100644 index 00000000..36b5b418 --- /dev/null +++ b/Assets/Scripts/Utilities.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 71d578a17e6a4cd4c893fbabe558ec16 +folderAsset: yes +timeCreated: 1427127911 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/AsyncLoader.cs b/Assets/Scripts/Utilities/AsyncLoader.cs new file mode 100644 index 00000000..f037825c --- /dev/null +++ b/Assets/Scripts/Utilities/AsyncLoader.cs @@ -0,0 +1,133 @@ +using System.Collections.Generic; +using UnityEngine; +using System.Runtime.CompilerServices; + +namespace SanAndreasUnity.Utilities +{ + + public class AsyncLoader + { + + /// + /// All successfully loaded objects. + /// + private readonly Dictionary m_Loaded = new Dictionary(); + + /// + /// Objects currently being loaded. Value represents list of subscribers which will be called when loading is finished. + /// + private readonly Dictionary>> m_Loading = new Dictionary>> (); + + + public AsyncLoader () + { + } + + public AsyncLoader (IEqualityComparer comparer) + { + m_Loaded = new Dictionary (comparer); + m_Loading = new Dictionary>> (comparer); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public int GetNumObjectsLoaded () + { + return m_Loaded.Count; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public int GetNumObjectsLoading () + { + return m_Loading.Count; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public bool IsObjectLoaded (TKey key) + { + return m_Loaded.ContainsKey (key); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public TObj GetLoadedObject (TKey key) + { + return m_Loaded [key]; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public bool CheckIsObjectLoaded (TKey key, System.Action onFinish) + { + if (m_Loaded.ContainsKey(key)) + { + onFinish (m_Loaded [key]); + return true; + } + return false; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public bool CheckIsObjectLoading (TKey key, System.Action onFinish) + { + if (m_Loading.ContainsKey (key)) + { + // this object is loading + // subscribe to finish event + m_Loading[key].Add( onFinish ); + return true; + } + return false; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public bool TryLoadObject (TKey key, System.Action onFinish) + { + if (CheckIsObjectLoaded (key, onFinish)) + return false; + + if (CheckIsObjectLoading (key, onFinish)) + return false; + + // insert it into loading dict + m_Loading [key] = new List>(){onFinish}; + + return true; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public void OnObjectFinishedLoading (TKey key, TObj obj, bool bSuccess) + { + + if (bSuccess) + { + if (m_Loaded.ContainsKey (key)) + { + // this object was loaded in the meantime + // this can happen if someone else is loading objects synchronously + Debug.LogErrorFormat ("Redundant load of object ({0}): {1}", typeof(TObj), key); + } + else + { + m_Loaded.Add (key, obj); + } + } + + + var list = m_Loading[key]; + + // remove from loading dict + m_Loading.Remove( key ); + + // invoke subscribers + foreach(var item in list) + Utilities.F.RunExceptionSafe( () => item(obj)); + + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public void AddToLoadedObjects (TKey key, TObj obj) + { + m_Loaded [key] = obj; + } + + } + +} diff --git a/Assets/Scripts/Utilities/AsyncLoader.cs.meta b/Assets/Scripts/Utilities/AsyncLoader.cs.meta new file mode 100644 index 00000000..3ce3d234 --- /dev/null +++ b/Assets/Scripts/Utilities/AsyncLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e2b0a3b29a83c74d9cd4906420d6175 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/ConcurrentQueue.cs b/Assets/Scripts/Utilities/ConcurrentQueue.cs new file mode 100644 index 00000000..d17c1a17 --- /dev/null +++ b/Assets/Scripts/Utilities/ConcurrentQueue.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; + +namespace SanAndreasUnity.Utilities +{ + + /// + /// Alternative to System.Collections.Concurrent.ConcurrentQueue + /// (It's only available in .NET 4.0 and greater) + /// + /// + /// It's a bit slow (as it uses locks), and only provides a small subset of the interface + /// Overall, the implementation is intended to be simple & robust + /// + public class ConcurrentQueue + { + private readonly System.Object queueLock = new System.Object(); + private readonly Queue queue = new Queue(); + + public void Enqueue(T item) + { + lock (queueLock) + { + queue.Enqueue(item); + } + } + + public bool TryDequeue(out T result) + { + lock (queueLock) + { + if (queue.Count == 0) + { + result = default(T); + return false; + } + + result = queue.Dequeue(); + return true; + } + } + } + +} diff --git a/Assets/Scripts/Utilities/ConcurrentQueue.cs.meta b/Assets/Scripts/Utilities/ConcurrentQueue.cs.meta new file mode 100644 index 00000000..44f50832 --- /dev/null +++ b/Assets/Scripts/Utilities/ConcurrentQueue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a08e17e16c677f42a9157199dc3d272 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/Config.cs b/Assets/Scripts/Utilities/Config.cs new file mode 100644 index 00000000..c12a3029 --- /dev/null +++ b/Assets/Scripts/Utilities/Config.cs @@ -0,0 +1,178 @@ +//using Facepunch.Networking; +using Newtonsoft.Json.Linq; +using SanAndreasUnity.Importing.Archive; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEngine; + +namespace SanAndreasUnity.Utilities +{ + public static class Config + { + public const string const_game_dir = "game_dir"; + + + public static string FileName + { + get { return "config.json"; } + } + + public static string UserFileName + { + get { return "config.user.json"; } + } + + public static string ConfigFilesDirectoryPath + { + get { + #if UNITY_EDITOR || UNITY_STANDALONE + return Directory.GetCurrentDirectory (); + #else + return Application.persistentDataPath; + #endif + } + } + + public static string FilePath + { + get { return Path.Combine(ConfigFilesDirectoryPath, FileName); } + } + + public static string UserFilePath + { + get { return Path.Combine(ConfigFilesDirectoryPath, UserFileName); } + } + + public static string GamePath + { + get + { + return GetPath (const_game_dir); + } + } + + public static string DataPath + { + get + { +#if UNITY_EDITOR + return Path.Combine(Directory.GetCurrentDirectory(), "Data"); +#elif UNITY_STANDALONE + return Path.Combine(Application.dataPath, "Data"); +#else + return Path.Combine(Application.persistentDataPath, "Data"); +#endif + } + } + + + private static JObject _root = new JObject (); + private static JObject _user = new JObject (); + + private static readonly Dictionary _substitutions = new Dictionary (); + + + + private static TVal ConvertVal(JToken val) + { + try + { + return (TVal)Convert.ChangeType(val, typeof(TVal)); + } + catch + { + return val.ToObject(); + } + } + + public static TVal Get(string key) + { + var userVal = _user[key]; + if (userVal != null) + { + try + { + return ConvertVal(userVal); + } + catch + { + Debug.LogWarningFormat("[config] Invalid value for key '{0}'.", key); + } + } + + return ConvertVal(_root[key]); + } + + private static string GetSubstitution(string key) + { + if (_substitutions.ContainsKey(key)) return _substitutions[key]; + + string subs; + if (key == "data_dir") + { + subs = DataPath; + } + else + { + subs = ReplaceSubstitutions(Get(key)); + } + + _substitutions.Add(key, subs); + return subs; + } + + private static readonly Regex _regex = new Regex(@"\$\{(?[a-z0-9_]+)\}", RegexOptions.Compiled); + + private static string ReplaceSubstitutions(string value) + { + return _regex.Replace(value, x => GetSubstitution(x.Groups["key"].Value)); + } + + public static string GetPath(string key) + { + return ReplaceSubstitutions(Get(key)); + } + + public static string[] GetPaths(string key) + { + return Get(key) + .Select(x => ReplaceSubstitutions((string)x)) + .ToArray(); + } + + public static void SetString (string key, string value) + { + _user [key] = value; + } + + public static void Load () + { + _root = new JObject (); + _user = new JObject (); + _substitutions.Clear (); + + + _root = JObject.Parse (File.ReadAllText (FilePath)); + + if (File.Exists (UserFilePath)) + { + _user = JObject.Parse (File.ReadAllText (UserFilePath)); + } + + } + + public static void SaveUserConfig () + { + File.WriteAllText (UserFilePath, _user.ToString (Newtonsoft.Json.Formatting.Indented)); + } + + public static void SaveUserConfigSafe () + { + F.RunExceptionSafe (() => SaveUserConfig ()); + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/Config.cs.meta b/Assets/Scripts/Utilities/Config.cs.meta new file mode 100644 index 00000000..030ac057 --- /dev/null +++ b/Assets/Scripts/Utilities/Config.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 25ec4ed6b4fec874abfdd29f60d05484 +timeCreated: 1428171046 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/DontDestroyOnLoad.cs b/Assets/Scripts/Utilities/DontDestroyOnLoad.cs new file mode 100644 index 00000000..d44fac0d --- /dev/null +++ b/Assets/Scripts/Utilities/DontDestroyOnLoad.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace SanAndreasUnity.Utilities +{ + + public class DontDestroyOnLoad : MonoBehaviour + { + + void Awake () + { + if (null == this.transform.parent) + { + DontDestroyOnLoad (this.gameObject); + } + } + + } + +} diff --git a/Assets/Scripts/Utilities/DontDestroyOnLoad.cs.meta b/Assets/Scripts/Utilities/DontDestroyOnLoad.cs.meta new file mode 100644 index 00000000..fd084705 --- /dev/null +++ b/Assets/Scripts/Utilities/DontDestroyOnLoad.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 409653cfe36614ceab3cbfbf9ed04fce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/F.cs b/Assets/Scripts/Utilities/F.cs new file mode 100644 index 00000000..7c1e8cfc --- /dev/null +++ b/Assets/Scripts/Utilities/F.cs @@ -0,0 +1,705 @@ +using SanAndreasUnity.Behaviours.Vehicles; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace SanAndreasUnity.Utilities +{ + //Static class with extra functions + public static class F + { + //Returns the number with the greatest absolute value + public static float MaxAbs(params float[] nums) + { + float result = 0; + + for (int i = 0; i < nums.Length; i++) + { + if (Mathf.Abs(nums[i]) > Mathf.Abs(result)) + { + result = nums[i]; + } + } + + return result; + } + + //Returns the topmost parent with a certain component + public static Component GetTopmostParentComponent(Transform tr) where T : Component + { + Component getting = null; + + while (tr.parent != null) + { + if (tr.parent.GetComponent() != null) + { + getting = tr.parent.GetComponent(); + } + + tr = tr.parent; + } + + return getting; + } + + // WIP: This causes Unity to crash + /*public static void OptimizeVehicle(this Vehicle v) + { + foreach (var col in v.gameObject.GetComponentsInChildren()) + { + if (!(col is MeshCollider)) + Object.Destroy(col); + } + + foreach (var go in v.gameObject.GetComponentsInChildren()) + go.gameObject.AddComponent(); + }*/ + + public static void OptimizeVehicle(this Vehicle v) + { + var cols = v.gameObject.GetComponentsInChildren().Where(x => x.GetType() != typeof(MeshCollider)); + foreach (var col in cols) + col.enabled = false; + + var filters = v.gameObject.GetComponentsInChildren().Where(x => x.sharedMesh != null); + foreach (var filter in filters) + filter.gameObject.AddComponent(); + } + + public static Mesh GetSharedMesh(this Collider col) + { + if (col is MeshCollider) + { + return ((MeshCollider)col).sharedMesh; + } + else + { + // WIP: Depending on the collider generate a diferent shape + MeshFilter f = col.gameObject.GetComponent(); + return f != null ? f.sharedMesh : null; + } + } + + public static bool BetweenInclusive(this float v, float min, float max) + { + return v >= min && v <= max; + } + + public static bool BetweenExclusive(this float v, float min, float max) + { + return v > min && v < max; + } + + public static int RoundToInt(this float f) + { + return Mathf.RoundToInt (f); + } + + public static double DateTimeToUnixTimestamp(this DateTime dateTime) + { + return (TimeZoneInfo.ConvertTimeToUtc(dateTime) - + new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; + } + + public static string Nl2Br(this string str) + { + return str.Replace(Environment.NewLine, "
"); + } + + public static string OptimizeHTML(this string str) + { + return str.Replace("<", "<").Replace(">", ">").Nl2Br().Replace("
", "[br]"); + } + + public static string CleanElement(this string html, string element) + { + string orEl = string.Format(@"\[{0}\]", element); + + return Regex.Replace(html, orEl, (m) => { return Callback(m, element, html); }); + } + + private static string Callback(Match match, string element, string html) + { + int oc = FindOccurrences(html.Substring(0, match.Index + 1), match.Index); + string befChar = html.Substring(match.Index - (element.Length + 3), 1); + string sep = new string(Convert.ToChar(9), oc); + return string.Format("{3}<{0}>{1}{2}", element, Environment.NewLine, sep, befChar.Replace(Environment.NewLine, " ").IsNullOrWhiteSpace() ? sep : ""); + } + + private static int FindOccurrences(string str, int maxIndex) + { + int lio = str.LastIndexOf("(this T obj) + { + return typeof(T).ToString(); + } + + public static T GetComponentWithName(this Component root, string name) where T : Component + { + return root.GetComponentsInChildren().FirstOrDefault(x => x.name == name); + } + + public static T GetOrAddComponent (this GameObject go) where T : Component + { + T comp = go.GetComponent (); + if (null == comp) + comp = go.AddComponent (); + return comp; + } + + public static T GetComponentOrThrow (this GameObject go) where T : Component + { + T comp = go.GetComponent (); + if (null == comp) + throw new MissingComponentException (string.Format ("Failed to get component of type: {0}, on game object: {1}", typeof(T), go.name)); + return comp; + } + + public static T GetComponentOrThrow (this Component comp) where T : Component + { + return comp.gameObject.GetComponentOrThrow (); + } + + public static T GetComponentOrLogError (this GameObject go) where T : Component + { + T comp = go.GetComponent (); + if (null == comp) + Debug.LogErrorFormat ("Failed to get component of type: {0}, on game object: {1}", typeof(T), go.name); + return comp; + } + + public static T GetComponentOrLogError (this Component comp) where T : Component + { + return comp.gameObject.GetComponentOrLogError (); + } + + public static void MakeChild(this Transform parent, GameObject[] children) + { + MakeChild(parent, children, null); + } + + //Make the game objects children of the parent. + public static void MakeChild(this Transform parent, GameObject[] children, Action actionPerLoop) + { + foreach (GameObject child in children) + { + child.transform.parent = parent; + if (actionPerLoop != null) actionPerLoop(parent, child); + } + } + + public static void SetY(this Transform t, float yPos) { + Vector3 pos = t.position; + pos.y = yPos; + t.position = pos; + } + + public static float Distance(this Transform t, Vector3 pos) + { + return Vector3.Distance (t.position, pos); + } + + public static Quaternion CreateRotationAroundAxes (Vector3 degrees) + { + Quaternion rotation = Quaternion.identity; + + if (degrees.x != 0) + rotation *= Quaternion.AngleAxis (degrees.x, Vector3.right); + + if (degrees.y != 0) + rotation *= Quaternion.AngleAxis (degrees.y, Vector3.up); + + if (degrees.z != 0) + rotation *= Quaternion.AngleAxis (degrees.z, Vector3.forward); + + return rotation; + } + + public static Vector3 TransformDirection (this Quaternion rot, Vector3 dir) + { + return rot * dir; + } + + /// + /// Transforms the rotation from local space to world space. + /// + public static Quaternion TransformRotation (this Transform tr, Quaternion rot) + { + Vector3 localForward = rot * Vector3.forward; + Vector3 localUp = rot * Vector3.up; + + return Quaternion.LookRotation (tr.TransformDirection (localForward), tr.TransformDirection (localUp)); + } + + public static void SetGlobalScale (this Transform tr, Vector3 globalScale) + { + Vector3 parentGlobalScale = tr.parent != null ? tr.parent.lossyScale : Vector3.one; + tr.localScale = Vector3.Scale (globalScale, parentGlobalScale.Inverted () ); + } + + public static Vector3 ClampDirection (Vector3 dir, Vector3 referenceVec, float maxAngle) + { + float angle = Vector3.Angle (dir, referenceVec); + if (angle > maxAngle) { + // needs to be clamped + + return Vector3.RotateTowards( dir, referenceVec, (angle - maxAngle) * Mathf.Deg2Rad, 0f ); + // Vector3.Lerp( dir, referenceVec, ); + } + + return dir; + } + + + public static object FromHex(this string hexString, Type type, CultureInfo info) + { + var argTypes = new[] { typeof(string), typeof(NumberStyles), typeof(IFormatProvider) }; + + var convert = type.GetMethod("Parse", + BindingFlags.Static | BindingFlags.Public, + null, argTypes, null); + + return convert.Invoke(null, new object[] { hexString, NumberStyles.HexNumber, info }); + } + + public static void SafeDestroy(this T obj) where T : Object + { + if (Application.isEditor) + Object.DestroyImmediate(obj); + else + Object.Destroy(obj); + } + + public static void SafeDestroyGameObject(this T component) where T : Component + { + if (component != null) + SafeDestroy(component.gameObject); + } + + public static string FirstCharToUpper(this string input) + { + switch (input) + { + case null: throw new ArgumentNullException(nameof(input)); + case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)); + default: return input.First().ToString().ToUpper() + input.Substring(1); + } + } + + public static string GetGameObjectPath(this GameObject obj) + { + string path = obj.name; + while (obj.transform.parent != null) + { + obj = obj.transform.parent.gameObject; + path = "/" + obj.name + path; + } + return path; + } + + + public static float GetTimePerc (this AnimationState state) + { + return state.time / state.length; + } + + public static void SetTimePerc (this AnimationState state, float perc) + { + state.time = state.length * perc; + } + + + public static void RunExceptionSafe (System.Action function) + { + try { + function(); + } catch(System.Exception ex) { + try { + Debug.LogException (ex); + } catch {} + } + } + + public static void Invoke( this System.Object obj, string methodName, params object[] args ) { + + var method = obj.GetType().GetMethod( methodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public ); + if(method != null) { + method.Invoke( obj, args ); + } + + } + + public static void InvokeExceptionSafe( this System.Object obj, string methodName, params object[] args ) { + + try { + obj.Invoke( methodName, args ); + } catch (System.Exception ex) { + Debug.LogException (ex); + } + + } + + public static void SendMessageToObjectsOfType (string msg, params object[] args) where T : UnityEngine.Object + { + var objects = UnityEngine.Object.FindObjectsOfType (); + + foreach (var obj in objects) { + obj.InvokeExceptionSafe (msg, args); + } + + } + + + public static bool IsCasteable(this object input) + { + try + { + Convert.ChangeType(input, typeof(T)); + return true; + } + catch + { + return false; + } + } + + public static T[] AddValue(this T[] arr, T value) + { + return (new List(arr.ToList()) { value }).ToArray(); + } + + public static T[] Add(this T[] target, T item) + { + if (target == null) + throw new ArgumentNullException(); + + T[] result = new T[target.Length + 1]; + target.CopyTo(result, 0); + result[target.Length] = item; + + return result; + } + + public static IEnumerable DistinctBy(this IEnumerable enumerable, System.Func selector) + { + List> list = new List>(); + + foreach (var elem in enumerable) { + var value = selector (elem); + if (!list.Exists (item => item.Value.Equals (value))) + list.Add (new KeyValuePair (elem, value)); + } + + return list.Select (item => item.Key); + } + + public static int FindIndex (this IEnumerable enumerable, System.Predicate predicate) + { + int i = 0; + foreach (var elem in enumerable) { + if (predicate (elem)) + return i; + i++; + } + return -1; + } + + public static int IndexOf (this IEnumerable enumerable, T value) + { + return enumerable.FindIndex (elem => elem.Equals (value)); + } + + public static bool AddIfNotPresent (this List list, T item) + { + if (!list.Contains (item)) { + list.Add (item); + return true; + } + return false; + } + + + private static Dictionary Texturemap = new Dictionary(); + private static Texture2D Font; + + public static Color[] WriteLetterToTexture(this char chipName, int fontWidth = 12, int fontHeight = 18) + { + if (Font == null) + { + Debug.Log("Loaded chipfont!"); + Font = Resources.Load("Textures/chipfont"); + } + + // Copy each letter to the texture + int cur_id = (int)(chipName - '0'); + + return Font.GetPixels(cur_id * fontWidth, 0, fontWidth, fontHeight); + } + + // WIP: Vector2? offset = null + public static Texture2D WriteTextToTexture(this string chipName, Texture2D texture, int fontWidth = 12, int fontHeight = 18) + { + if (Font == null) + Font = Resources.Load("Textures/chipfont"); + + // If texture already exists, don't create it again + + int offset = 5; + int offset_y = Font.height; + + // Copy each letter to the texture + for (int i = 0; i < chipName.Length; i++) + { + int cur_id = (int)(chipName[i] - '0'); + for (int y = 0; y < fontHeight; y++) + { + for (int x = 0; x < fontWidth; x++) + { + Color tempColor = Font.GetPixel(cur_id * fontWidth + x, offset_y - y); + texture.SetPixel(offset + x, offset_y - y + 10, tempColor); + } + } + offset += fontWidth; + } + + texture.Apply(); + + return texture; + } + + public static Texture2D TextToTexture(this string chipName, int fontWidth = 12, int fontHeight = 18) + { + if (Font == null) + Font = Resources.Load("Textures/chipfont"); + + // If texture already exists, don't create it again + if (!Texturemap.ContainsKey(chipName)) + { + int textureWidth = 100; + // Generate the texture + var texture = new Texture2D(textureWidth, 100, TextureFormat.ARGB32, false); + + for (int y = 0; y < 100; y++) + { + for (int x = 0; x < textureWidth; x++) + { + texture.SetPixel(x, y, Color.clear); + } + } + + int offset = 5; + int offset_y = Font.height; + + // Copy each letter to the texture + for (int i = 0; i < chipName.Length; i++) + { + int cur_id = (int)(chipName[i] - '0'); + for (int y = 0; y < fontHeight; y++) + { + for (int x = 0; x < fontWidth; x++) + { + Color tempColor = Font.GetPixel(cur_id * fontWidth + x, offset_y - y); + texture.SetPixel(offset + x, offset_y - y + 10, tempColor); + } + } + offset += fontWidth; + } + + // Apply all SetPixel calls + texture.Apply(); + + Texturemap[chipName] = texture; + } + + return Texturemap[chipName]; + } + + public static Vector2 GetSize (this Texture2D tex) + { + return new Vector2 (tex.width, tex.height); + } + + // Slow method + public static int CountObjectsInLayer(int layer) + { + int i = 0; + foreach (Transform t in Object.FindObjectsOfType()) + if (t.gameObject.layer == layer) + ++i; + + return i; + } + + public static bool IsGreaterOrEqual(this Vector2 local, Vector2 other) + { + if (local.x >= other.x && local.y >= other.y) + return true; + else + return false; + } + + public static bool IsLesserOrEqual(this Vector2 local, Vector2 other) + { + if (local.x <= other.x && local.y <= other.y) + return true; + else + return false; + } + + public static bool IsGreater(this Vector2 local, Vector2 other, bool orOperator = false) + { + if (orOperator) + { + if (local.x > other.x || local.y > other.y) + return true; + else + return false; + } + else + { + if (local.x > other.x && local.y > other.y) + return true; + else + return false; + } + } + + public static bool IsLesser(this Vector2 local, Vector2 other, bool orOperator = false) + { + if (orOperator) + { + if (local.x < other.x || local.y < other.y) + return true; + else + return false; + } + else + { + if (local.x < other.x && local.y < other.y) + return true; + else + return false; + } + } + + public static Vector2 ToVec2WithXAndZ( this Vector3 vec3 ) { + return new Vector2 (vec3.x, vec3.z); + } + + public static Vector3 WithXAndZ( this Vector3 vec3 ) { + return new Vector3 (vec3.x, 0f, vec3.z); + } + + public static Vector3 Inverted (this Vector3 vec3) + { + return new Vector3 (1.0f / vec3.x, 1.0f / vec3.y, 1.0f / vec3.z); + } + + public static Color OrangeColor { get { return Color.Lerp (Color.yellow, Color.red, 0.5f); } } + + /// + /// Clamps all coordinates between 0 and 1. + /// + public static Rect Clamp01(this Rect rect) { + + float xMin = rect.xMin; + float xMax = rect.xMax; + float yMin = rect.yMin; + float yMax = rect.yMax; + + xMin = Mathf.Clamp01 (xMin); + xMax = Mathf.Clamp01 (xMax); + yMin = Mathf.Clamp01 (yMin); + yMax = Mathf.Clamp01 (yMax); + + return new Rect(xMin, yMin, xMax - xMin, yMax - yMin); + } + + public static bool Contains(this Rect rect, Rect other) { + + return rect.xMax >= other.xMax && rect.xMin <= other.xMin && rect.yMax >= other.yMax && rect.yMin <= other.yMin; + + } + + public static Rect Intersection(this Rect rect, Rect other) { + + float xMax = Mathf.Min (rect.xMax, other.xMax); + float yMax = Mathf.Min (rect.yMax, other.yMax); + + float xMin = Mathf.Max (rect.xMin, other.xMin); + float yMin = Mathf.Max (rect.yMin, other.yMin); + + return new Rect(xMin, yMin, xMax - xMin, yMax - yMin); + } + + public static Rect Normalized(this Rect rect, Rect outter) { + + float xMin = (rect.xMin - outter.xMin) / outter.width; + float xMax = (rect.xMax - outter.xMin) / outter.width; + + float yMin = (rect.yMin - outter.yMin) / outter.height; + float yMax = (rect.yMax - outter.yMin) / outter.height; + + return new Rect(xMin, yMin, xMax - xMin, yMax - yMin); + } + + public static Rect CreateRect(Vector2 center, Vector2 size) { + return new Rect (center - size / 2.0f, size); + } + + public static Texture2D CreateTexture (int width, int height, Color color) { + + Color[] pixels = new Color[width * height]; + + for (int i = 0; i < pixels.Length; i++) + pixels [i] = color; + + Texture2D texture = new Texture2D (width, height); + texture.SetPixels (pixels); + texture.Apply (); + + return texture; + } + + + public static Ray GetRayFromCenter (this Camera cam) + { + Vector3 viewportPos = new Vector3 (0.5f, 0.5f, 0f); + return cam.ViewportPointToRay (viewportPos); + } + + + public static void GizmosDrawLineFromCamera () + { + if (null == Camera.main) + return; + + Ray ray = Camera.main.GetRayFromCenter (); + + Gizmos.DrawLine (ray.origin, ray.origin + ray.direction * Camera.main.farClipPlane); + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/F.cs.meta b/Assets/Scripts/Utilities/F.cs.meta new file mode 100644 index 00000000..fbf32fff --- /dev/null +++ b/Assets/Scripts/Utilities/F.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aed867b325463d442b5f5ecdd33932ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/FrameStream.cs b/Assets/Scripts/Utilities/FrameStream.cs new file mode 100644 index 00000000..de785b2c --- /dev/null +++ b/Assets/Scripts/Utilities/FrameStream.cs @@ -0,0 +1,137 @@ +using System; +using System.IO; + +namespace SanAndreasUnity.Utilities +{ + /// + /// Represents a subsection of another stream, starting from a certain offset and + /// with a given length. + /// + public class FrameStream : Stream + { + private readonly Stream _baseStream; + + private readonly long _offset; + private readonly long _length; + + private long _position; + + public override bool CanRead + { + get { return true; } + } + + public override bool CanSeek + { + get { return true; } + } + + public override bool CanWrite + { + get { return false; } + } + + public override long Length + { + get { return _length; } + } + + public override long Position + { + get + { + return _position; + } + set + { + Seek(value, SeekOrigin.Begin); + } + } + + public long AbsoluteOffset + { + get + { + var frameStream = _baseStream as FrameStream; + if (frameStream == null) return _offset; + return _offset + frameStream.AbsolutePosition; + } + } + + public long AbsolutePosition + { + get + { + return _position + AbsoluteOffset; + } + } + + public FrameStream(Stream baseStream, long offset, long length) + { + _baseStream = baseStream; + + _offset = offset; + _length = length; + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (_position > _length) + { + return 0; + } + + var basePos = _offset + _position; + + if (_baseStream.Position != basePos) + { + _baseStream.Seek(basePos, SeekOrigin.Begin); + } + + var read = _baseStream.Read(buffer, offset, (int)Math.Min(_length - _position, count)); + _position += read; + + return read; + } + + public override long Seek(long offset, SeekOrigin origin) + { + switch (origin) + { + case SeekOrigin.Begin: + _position = offset; + break; + + case SeekOrigin.Current: + _position += offset; + break; + + case SeekOrigin.End: + _position = _length - offset; + break; + } + + if (_position < 0 || _position > _length) + { + throw new ArgumentOutOfRangeException("offset"); + } + + return _baseStream.Seek(_position + _offset, SeekOrigin.Begin) - _offset; + } + + public override void Flush() + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/FrameStream.cs.meta b/Assets/Scripts/Utilities/FrameStream.cs.meta new file mode 100644 index 00000000..49118f2f --- /dev/null +++ b/Assets/Scripts/Utilities/FrameStream.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 50e57e1fd74e6034db728443bef0cfef +timeCreated: 1427127912 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/GLDebug.cs b/Assets/Scripts/Utilities/GLDebug.cs new file mode 100644 index 00000000..293a375b --- /dev/null +++ b/Assets/Scripts/Utilities/GLDebug.cs @@ -0,0 +1,352 @@ +// http://www.unity3d-france.com/unity/phpBB3/viewtopic.php?f=24&t=5409 + +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +public class GLDebug : MonoBehaviour +{ + private struct Line + { + public Vector3 start; + public Vector3 end; + public Color color; + public float startTime; + public float duration; + + public Line (Vector3 start, Vector3 end, Color color, float startTime, float duration) + { + this.start = start; + this.end = end; + this.color = color; + this.startTime = startTime; + this.duration = duration; + } + + public bool DurationElapsed (bool drawLine) + { + if (drawLine) + { + GL.Color (color); + GL.Vertex (start); + GL.Vertex (end); + } + return Time.time - startTime >= duration; + } + } + + private static GLDebug instance; + private static Material matZOn; + private static Material matZOff; + + public KeyCode toggleKey; + public bool displayLines = true; +#if UNITY_EDITOR + public bool displayGizmos = true; +#endif + //public ScreenRect rect = new ScreenRect (0, 0, 150, 20); + + private List linesZOn = new List (); + private List linesZOff = new List (); +// private float milliseconds; + + public Shader zOnShader; + public Shader zOffShader; + + + void Awake () + { + if (instance) + { + DestroyImmediate (this); + return; + } + instance = this; + SetMaterial (); + + if (null == this.GetComponent ()) + { + Debug.LogError ("There should be camera attached to the same game object"); + } + + } + + void SetMaterial () + { + matZOn = new Material(this.zOnShader); + matZOn.hideFlags = HideFlags.HideAndDontSave; + //matZOn.shader.hideFlags = HideFlags.HideAndDontSave; + + matZOff = new Material(this.zOffShader); + matZOff.hideFlags = HideFlags.HideAndDontSave; + //matZOff.shader.hideFlags = HideFlags.HideAndDontSave; + } + + void Update () + { + if (Input.GetKeyDown (toggleKey)) + displayLines = !displayLines; + + if (!displayLines) + { +// Stopwatch timer = Stopwatch.StartNew (); + + linesZOn = linesZOn.Where (l => !l.DurationElapsed (false)).ToList (); + linesZOff = linesZOff.Where (l => !l.DurationElapsed (false)).ToList (); + +// timer.Stop (); +// milliseconds = timer.Elapsed.Ticks / 10000f; + } + } + + /*void OnGUI () + { + GUI.Label (rect, "GLDebug : " + milliseconds.ToString ("f") + " ms"); + }*/ + +#if UNITY_EDITOR + void OnDrawGizmos () + { + if (!displayGizmos || !Application.isPlaying) + return; + for (int i = 0; i < linesZOn.Count; i++) + { + Gizmos.color = linesZOn[i].color; + Gizmos.DrawLine (linesZOn[i].start, linesZOn[i].end); + } + for (int i = 0; i < linesZOff.Count; i++) + { + Gizmos.color = linesZOff[i].color; + Gizmos.DrawLine (linesZOff[i].start, linesZOff[i].end); + } + } +#endif + + void OnPostRender () + { + if (!displayLines) return; + + // Stopwatch timer = Stopwatch.StartNew (); + + matZOn.SetPass (0); + GL.Begin (GL.LINES); + linesZOn = linesZOn.Where (l => !l.DurationElapsed (true)).ToList (); + GL.End (); + + matZOff.SetPass (0); + GL.Begin (GL.LINES); + linesZOff = linesZOff.Where (l => !l.DurationElapsed (true)).ToList (); + GL.End (); + + // timer.Stop (); +// milliseconds = timer.Elapsed.Ticks / 10000f; + } + + private static void DrawLine (Vector3 start, Vector3 end, Color color, float duration = 0, bool depthTest = false) + { + if (duration == 0 && !instance.displayLines) + return; + if (start == end) + return; + if (depthTest) + instance.linesZOn.Add (new Line (start, end, color, Time.time, duration)); + else + instance.linesZOff.Add (new Line (start, end, color, Time.time, duration)); + } + + /// + /// Draw a line from start to end with color for a duration of time and with or without depth testing. + /// If duration is 0 then the line is rendered 1 frame. + /// + /// Point in world space where the line should start. + /// Point in world space where the line should end. + /// Color of the line. + /// How long the line should be visible for. + /// Should the line be obscured by objects closer to the camera ? + public static void DrawLine (Vector3 start, Vector3 end, Color? color = null, float duration = 0, bool depthTest = false) + { + DrawLine (start, end, color ?? Color.white, duration, depthTest); + } + + /// + /// Draw a line from start to start + dir with color for a duration of time and with or without depth testing. + /// If duration is 0 then the ray is rendered 1 frame. + /// + /// Point in world space where the ray should start. + /// Direction and length of the ray. + /// Color of the ray. + /// How long the ray should be visible for. + /// Should the ray be obscured by objects closer to the camera ? + public static void DrawRay (Vector3 start, Vector3 dir, Color? color = null, float duration = 0, bool depthTest = false) + { + if (dir == Vector3.zero) + return; + DrawLine (start, start + dir, color, duration, depthTest); + } + + /// + /// Draw an arrow from start to end with color for a duration of time and with or without depth testing. + /// If duration is 0 then the arrow is rendered 1 frame. + /// + /// Point in world space where the arrow should start. + /// Point in world space where the arrow should end. + /// Length of the 2 lines of the head. + /// Angle between the main line and each of the 2 smaller lines of the head. + /// Color of the arrow. + /// How long the arrow should be visible for. + /// Should the arrow be obscured by objects closer to the camera ? + public static void DrawLineArrow (Vector3 start, Vector3 end, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20, Color? color = null, float duration = 0, bool depthTest = false) + { + DrawArrow (start, end - start, arrowHeadLength, arrowHeadAngle, color, duration, depthTest); + } + + /// + /// Draw an arrow from start to start + dir with color for a duration of time and with or without depth testing. + /// If duration is 0 then the arrow is rendered 1 frame. + /// + /// Point in world space where the arrow should start. + /// Direction and length of the arrow. + /// Length of the 2 lines of the head. + /// Angle between the main line and each of the 2 smaller lines of the head. + /// Color of the arrow. + /// How long the arrow should be visible for. + /// Should the arrow be obscured by objects closer to the camera ? + public static void DrawArrow (Vector3 start, Vector3 dir, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20, Color? color = null, float duration = 0, bool depthTest = false) + { + if (dir == Vector3.zero) + return; + DrawRay (start, dir, color, duration, depthTest); + Vector3 right = Quaternion.LookRotation (dir) * Quaternion.Euler (0, 180 + arrowHeadAngle, 0) * Vector3.forward; + Vector3 left = Quaternion.LookRotation (dir) * Quaternion.Euler (0, 180 - arrowHeadAngle, 0) * Vector3.forward; + DrawRay (start + dir, right * arrowHeadLength, color, duration, depthTest); + DrawRay (start + dir, left * arrowHeadLength, color, duration, depthTest); + } + + /// + /// Draw a square with color for a duration of time and with or without depth testing. + /// If duration is 0 then the square is renderer 1 frame. + /// + /// Center of the square in world space. + /// Rotation of the square in euler angles in world space. + /// Size of the square. + /// Color of the square. + /// How long the square should be visible for. + /// Should the square be obscured by objects closer to the camera ? + public static void DrawSquare (Vector3 pos, Vector3? rot = null, Vector3? scale = null, Color? color = null, float duration = 0, bool depthTest = false) + { + DrawSquare (Matrix4x4.TRS (pos, Quaternion.Euler (rot ?? Vector3.zero), scale ?? Vector3.one), color, duration, depthTest); + } + /// + /// Draw a square with color for a duration of time and with or without depth testing. + /// If duration is 0 then the square is renderer 1 frame. + /// + /// Center of the square in world space. + /// Rotation of the square in world space. + /// Size of the square. + /// Color of the square. + /// How long the square should be visible for. + /// Should the square be obscured by objects closer to the camera ? + public static void DrawSquare (Vector3 pos, Quaternion? rot = null, Vector3? scale = null, Color? color = null, float duration = 0, bool depthTest = false) + { + DrawSquare (Matrix4x4.TRS (pos, rot ?? Quaternion.identity, scale ?? Vector3.one), color, duration, depthTest); + } + /// + /// Draw a square with color for a duration of time and with or without depth testing. + /// If duration is 0 then the square is renderer 1 frame. + /// + /// Transformation matrix which represent the square transform. + /// Color of the square. + /// How long the square should be visible for. + /// Should the square be obscured by objects closer to the camera ? + public static void DrawSquare (Matrix4x4 matrix, Color? color = null, float duration = 0, bool depthTest = false) + { + Vector3 + p_1 = matrix.MultiplyPoint3x4 (new Vector3 ( .5f, 0, .5f)), + p_2 = matrix.MultiplyPoint3x4 (new Vector3 ( .5f, 0, -.5f)), + p_3 = matrix.MultiplyPoint3x4 (new Vector3 (-.5f, 0, -.5f)), + p_4 = matrix.MultiplyPoint3x4 (new Vector3 (-.5f, 0, .5f)); + + DrawLine (p_1, p_2, color, duration, depthTest); + DrawLine (p_2, p_3, color, duration, depthTest); + DrawLine (p_3, p_4, color, duration, depthTest); + DrawLine (p_4, p_1, color, duration, depthTest); + } + + /// + /// Draw a cube with color for a duration of time and with or without depth testing. + /// If duration is 0 then the square is renderer 1 frame. + /// + /// Center of the cube in world space. + /// Rotation of the cube in euler angles in world space. + /// Size of the cube. + /// Color of the cube. + /// How long the cube should be visible for. + /// Should the cube be obscured by objects closer to the camera ? + public static void DrawCube (Vector3 pos, Vector3? rot = null, Vector3? scale = null, Color? color = null, float duration = 0, bool depthTest = false) + { + DrawCube (Matrix4x4.TRS (pos, Quaternion.Euler (rot ?? Vector3.zero), scale ?? Vector3.one), color, duration, depthTest); + } + /// + /// Draw a cube with color for a duration of time and with or without depth testing. + /// If duration is 0 then the square is renderer 1 frame. + /// + /// Center of the cube in world space. + /// Rotation of the cube in world space. + /// Size of the cube. + /// Color of the cube. + /// How long the cube should be visible for. + /// Should the cube be obscured by objects closer to the camera ? + public static void DrawCube (Vector3 pos, Quaternion? rot = null, Vector3? scale = null, Color? color = null, float duration = 0, bool depthTest = false) + { + DrawCube (Matrix4x4.TRS (pos, rot ?? Quaternion.identity, scale ?? Vector3.one), color, duration, depthTest); + } + /// + /// Draw a cube with color for a duration of time and with or without depth testing. + /// If duration is 0 then the square is renderer 1 frame. + /// + /// Transformation matrix which represent the cube transform. + /// Color of the cube. + /// How long the cube should be visible for. + /// Should the cube be obscured by objects closer to the camera ? + public static void DrawCube (Matrix4x4 matrix, Color? color = null, float duration = 0, bool depthTest = false) + { + Vector3 + down_1 = matrix.MultiplyPoint3x4 (new Vector3 ( .5f, -.5f, .5f)), + down_2 = matrix.MultiplyPoint3x4 (new Vector3 ( .5f, -.5f, -.5f)), + down_3 = matrix.MultiplyPoint3x4 (new Vector3 (-.5f, -.5f, -.5f)), + down_4 = matrix.MultiplyPoint3x4 (new Vector3 (-.5f, -.5f, .5f)), + up_1 = matrix.MultiplyPoint3x4 (new Vector3 ( .5f, .5f, .5f)), + up_2 = matrix.MultiplyPoint3x4 (new Vector3 ( .5f, .5f, -.5f)), + up_3 = matrix.MultiplyPoint3x4 (new Vector3 (-.5f, .5f, -.5f)), + up_4 = matrix.MultiplyPoint3x4 (new Vector3 (-.5f, .5f, .5f)); + + DrawLine (down_1, down_2, color, duration, depthTest); + DrawLine (down_2, down_3, color, duration, depthTest); + DrawLine (down_3, down_4, color, duration, depthTest); + DrawLine (down_4, down_1, color, duration, depthTest); + + DrawLine (down_1, up_1, color, duration, depthTest); + DrawLine (down_2, up_2, color, duration, depthTest); + DrawLine (down_3, up_3, color, duration, depthTest); + DrawLine (down_4, up_4, color, duration, depthTest); + + DrawLine (up_1, up_2, color, duration, depthTest); + DrawLine (up_2, up_3, color, duration, depthTest); + DrawLine (up_3, up_4, color, duration, depthTest); + DrawLine (up_4, up_1, color, duration, depthTest); + } + + + // EXTRAS + public static void DrawCircle (Vector3 center, float radius, Color? color = null, float duration = 0, bool depthTest = false) + { +// float degRad = Mathf.PI / 180; + for(float theta = 0.0f; theta < (2*Mathf.PI); theta += 0.2f) + { + Vector3 ci = (new Vector3(Mathf.Cos(theta) * radius + center.x, Mathf.Sin(theta) * radius + center.y, center.z)); + DrawLine (ci, ci+new Vector3(0,0.02f,0), color, duration, depthTest); + } + } + +} + diff --git a/Assets/Scripts/Utilities/GLDebug.cs.meta b/Assets/Scripts/Utilities/GLDebug.cs.meta new file mode 100644 index 00000000..aef00fd6 --- /dev/null +++ b/Assets/Scripts/Utilities/GLDebug.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 27b72409b037b08459c5c96c104ca2fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/GUI.meta b/Assets/Scripts/Utilities/GUI.meta new file mode 100644 index 00000000..7f7f066b --- /dev/null +++ b/Assets/Scripts/Utilities/GUI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dccc1b72c027da84091293c4a668033a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/GUI/FileBrowser.cs b/Assets/Scripts/Utilities/GUI/FileBrowser.cs new file mode 100644 index 00000000..ebea4b3d --- /dev/null +++ b/Assets/Scripts/Utilities/GUI/FileBrowser.cs @@ -0,0 +1,421 @@ +using UnityEngine; +using System; +using System.IO; +using System.Collections.Generic; + +/* + File browser for selecting files or folders at runtime. + */ + +public enum FileBrowserType { + File, + Directory +} + +public class FileBrowser { + + // Called when the user clicks cancel or select + public delegate void FinishedCallback(string path); + // Defaults to working directory + public string CurrentDirectory { + get { + return m_currentDirectory; + } + set { + SetNewDirectory(value); + SwitchDirectoryNow(); + } + } + protected string m_currentDirectory; + // Optional pattern for filtering selectable files/folders. See: + // http://msdn.microsoft.com/en-us/library/wz42302f(v=VS.90).aspx + // and + // http://msdn.microsoft.com/en-us/library/6ff71z1w(v=VS.90).aspx + public string SelectionPattern { + get { + return m_filePattern; + } + set { + m_filePattern = value; + ReadDirectoryContents(); + } + } + protected string m_filePattern; + + protected List m_drives = new List (); + + // Optional image for directories + public Texture2D DirectoryImage { + get { + return m_directoryImage; + } + set { + m_directoryImage = value; + BuildContent(); + } + } + protected Texture2D m_directoryImage; + + // Optional image for files + public Texture2D FileImage { + get { + return m_fileImage; + } + set { + m_fileImage = value; + BuildContent(); + } + } + protected Texture2D m_fileImage; + + // Browser type. Defaults to File, but can be set to Folder + public FileBrowserType BrowserType { + get { + return m_browserType; + } + set { + m_browserType = value; + ReadDirectoryContents(); + } + } + protected FileBrowserType m_browserType; + protected string m_newDirectory; + protected string[] m_currentDirectoryParts; + + protected string[] m_files; + protected GUIContent[] m_filesWithImages; + protected int m_selectedFile; + + protected string[] m_nonMatchingFiles; + protected GUIContent[] m_nonMatchingFilesWithImages; + protected int m_selectedNonMatchingDirectory; + + protected string[] m_directories; + protected GUIContent[] m_directoriesWithImages; + protected int m_selectedDirectory; + + protected string[] m_nonMatchingDirectories; + protected GUIContent[] m_nonMatchingDirectoriesWithImages; + + protected bool m_currentDirectoryMatches; + + protected GUIStyle CentredText { + get { + if (m_centredText == null) { + m_centredText = new GUIStyle(GUI.skin.label); + m_centredText.alignment = TextAnchor.MiddleLeft; + m_centredText.fixedHeight = GUI.skin.button.fixedHeight; + } + return m_centredText; + } + } + protected GUIStyle m_centredText; + + protected string m_name; + protected Rect m_screenRect; + + protected Vector2 m_scrollPosition; + + protected FinishedCallback m_callback; + + // Browsers need at least a rect, name and callback + public FileBrowser(Rect screenRect, string name, FinishedCallback callback) { + m_name = name; + m_screenRect = screenRect; + m_browserType = FileBrowserType.File; + m_callback = callback; + SetNewDirectory(Directory.GetCurrentDirectory()); + SwitchDirectoryNow(); + } + + protected void SetNewDirectory(string directory) { + m_newDirectory = directory; + } + + protected void SwitchDirectoryNow() { + if (m_newDirectory == null || m_currentDirectory == m_newDirectory) { + return; + } + m_currentDirectory = m_newDirectory; + m_scrollPosition = Vector2.zero; + m_selectedDirectory = m_selectedNonMatchingDirectory = m_selectedFile = -1; + ReadDirectoryContents(); + } + + protected void ReadDirectoryContents() { + + // refresh list of drives + try { + m_drives.Clear (); + m_drives.AddRange( Directory.GetLogicalDrives () ); + } catch { + + } + + if (m_currentDirectory == "/") { + m_currentDirectoryParts = new string[] {""}; + m_currentDirectoryMatches = false; + } else { + m_currentDirectoryParts = m_currentDirectory.Split(Path.DirectorySeparatorChar); + if (SelectionPattern != null) { + string[] generation = GetDirectories( + Path.GetDirectoryName(m_currentDirectory), + SelectionPattern + ); + m_currentDirectoryMatches = Array.IndexOf(generation, m_currentDirectory) >= 0; + } else { + m_currentDirectoryMatches = false; + } + } + + if (BrowserType == FileBrowserType.File || SelectionPattern == null) { + m_directories = GetDirectories(m_currentDirectory); + m_nonMatchingDirectories = new string[0]; + } else { + m_directories = GetDirectories(m_currentDirectory, SelectionPattern); + var nonMatchingDirectories = new List(); + foreach (string directoryPath in GetDirectories(m_currentDirectory)) { + if (Array.IndexOf(m_directories, directoryPath) < 0) { + nonMatchingDirectories.Add(directoryPath); + } + } + m_nonMatchingDirectories = nonMatchingDirectories.ToArray(); + for (int i = 0; i < m_nonMatchingDirectories.Length; ++i) { + int lastSeparator = m_nonMatchingDirectories[i].LastIndexOf(Path.DirectorySeparatorChar); + m_nonMatchingDirectories[i] = m_nonMatchingDirectories[i].Substring(lastSeparator + 1); + } + Array.Sort(m_nonMatchingDirectories); + } + + for (int i = 0; i < m_directories.Length; ++i) { + m_directories[i] = m_directories[i].Substring(m_directories[i].LastIndexOf(Path.DirectorySeparatorChar) + 1); + } + + if (BrowserType == FileBrowserType.Directory || SelectionPattern == null) { + m_files = GetFiles(m_currentDirectory); + m_nonMatchingFiles = new string[0]; + } else { + m_files = GetFiles(m_currentDirectory, SelectionPattern); + var nonMatchingFiles = new List(); + foreach (string filePath in GetFiles(m_currentDirectory)) { + if (Array.IndexOf(m_files, filePath) < 0) { + nonMatchingFiles.Add(filePath); + } + } + m_nonMatchingFiles = nonMatchingFiles.ToArray(); + for (int i = 0; i < m_nonMatchingFiles.Length; ++i) { + m_nonMatchingFiles[i] = Path.GetFileName(m_nonMatchingFiles[i]); + } + Array.Sort(m_nonMatchingFiles); + } + + for (int i = 0; i < m_files.Length; ++i) { + m_files[i] = Path.GetFileName(m_files[i]); + } + + Array.Sort(m_files); + + BuildContent(); + + m_newDirectory = null; + } + + static string[] GetFiles (string path, string searchPattern) + { + try { + return Directory.GetFiles( path, searchPattern ); + } catch { + return new string[0]; + } + } + + static string[] GetFiles (string path) + { + try { + return Directory.GetFiles( path ); + } catch { + return new string[0]; + } + } + + static string[] GetDirectories (string path, string searchPattern) + { + try { + return Directory.GetDirectories( path, searchPattern ); + } catch { + return new string[0]; + } + } + + static string[] GetDirectories (string path) + { + try { + return Directory.GetDirectories( path ); + } catch { + return new string[0]; + } + } + + + protected void BuildContent() { + m_directoriesWithImages = new GUIContent[m_directories.Length]; + for (int i = 0; i < m_directoriesWithImages.Length; ++i) { + m_directoriesWithImages[i] = new GUIContent(m_directories[i], DirectoryImage); + } + m_nonMatchingDirectoriesWithImages = new GUIContent[m_nonMatchingDirectories.Length]; + for (int i = 0; i < m_nonMatchingDirectoriesWithImages.Length; ++i) { + m_nonMatchingDirectoriesWithImages[i] = new GUIContent(m_nonMatchingDirectories[i], DirectoryImage); + } + m_filesWithImages = new GUIContent[m_files.Length]; + for (int i = 0; i < m_filesWithImages.Length; ++i) { + m_filesWithImages[i] = new GUIContent(m_files[i], FileImage); + } + m_nonMatchingFilesWithImages = new GUIContent[m_nonMatchingFiles.Length]; + for (int i = 0; i < m_nonMatchingFilesWithImages.Length; ++i) { + m_nonMatchingFilesWithImages[i] = new GUIContent(m_nonMatchingFiles[i], FileImage); + } + } + + public void OnGUI() { + + GUILayout.BeginArea( + m_screenRect, + m_name, + GUI.skin.window + ); + + // display drives + if (m_drives.Count > 0) { + GUILayout.BeginHorizontal(); + + foreach (var drive in m_drives) { + if (GUILayout.Button (drive)) { + SetNewDirectory (drive); + } + } + + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal (); + } + + // display directory parts + GUILayout.BeginHorizontal(); + + for (int parentIndex = 0; parentIndex < m_currentDirectoryParts.Length; ++parentIndex) { + if (parentIndex == m_currentDirectoryParts.Length - 1) { + GUILayout.Label(m_currentDirectoryParts[parentIndex], CentredText); + } else if (GUILayout.Button(m_currentDirectoryParts[parentIndex])) { + string parentDirectoryName = m_currentDirectory; + for (int i = m_currentDirectoryParts.Length - 1; i > parentIndex; --i) { + parentDirectoryName = Path.GetDirectoryName(parentDirectoryName); + } + SetNewDirectory(parentDirectoryName); + } + } + + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + + m_scrollPosition = GUILayout.BeginScrollView( + m_scrollPosition, + false, + true, + GUI.skin.horizontalScrollbar, + GUI.skin.verticalScrollbar, + GUI.skin.box + ); + m_selectedDirectory = xGUILayout.SelectionList( + m_selectedDirectory, + m_directoriesWithImages, + DirectoryDoubleClickCallback + ); + if (m_selectedDirectory > -1) { + m_selectedFile = m_selectedNonMatchingDirectory = -1; + } + m_selectedNonMatchingDirectory = xGUILayout.SelectionList( + m_selectedNonMatchingDirectory, + m_nonMatchingDirectoriesWithImages, + NonMatchingDirectoryDoubleClickCallback + ); + if (m_selectedNonMatchingDirectory > -1) { + m_selectedDirectory = m_selectedFile = -1; + } + GUI.enabled = BrowserType == FileBrowserType.File; + m_selectedFile = xGUILayout.SelectionList( + m_selectedFile, + m_filesWithImages, + FileDoubleClickCallback + ); + GUI.enabled = true; + if (m_selectedFile > -1) { + m_selectedDirectory = m_selectedNonMatchingDirectory = -1; + } + GUI.enabled = false; + xGUILayout.SelectionList( + -1, + m_nonMatchingFilesWithImages + ); + GUI.enabled = true; + GUILayout.EndScrollView(); + + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + + if (SanAndreasUnity.Utilities.GUIUtils.ButtonWithCalculatedSize("Cancel")) { + m_callback(null); + } + + if (BrowserType == FileBrowserType.File) { + GUI.enabled = m_selectedFile > -1; + } else { + if (SelectionPattern == null) { + GUI.enabled = true;//m_selectedDirectory > -1; + } else { + GUI.enabled = m_selectedDirectory > -1 || + ( + m_currentDirectoryMatches && + m_selectedNonMatchingDirectory == -1 && + m_selectedFile == -1 + ); + } + } + + string selectButtonText = BrowserType == FileBrowserType.File ? "Select" : "Select current folder"; + + if (SanAndreasUnity.Utilities.GUIUtils.ButtonWithCalculatedSize (selectButtonText)) { + if (BrowserType == FileBrowserType.File) { + m_callback(Path.Combine(m_currentDirectory, m_files[m_selectedFile])); + } else { +// if (m_selectedDirectory > -1) { +// m_callback(Path.Combine(m_currentDirectory, m_directories[m_selectedDirectory])); +// } else { +// m_callback(m_currentDirectory); +// } + m_callback(m_currentDirectory); + } + } + + GUI.enabled = true; + GUILayout.EndHorizontal(); + GUILayout.EndArea(); + + if (Event.current.type == EventType.Repaint) { + SwitchDirectoryNow(); + } + } + + protected void FileDoubleClickCallback(int i) { + if (BrowserType == FileBrowserType.File) { + m_callback(Path.Combine(m_currentDirectory, m_files[i])); + } + } + + protected void DirectoryDoubleClickCallback(int i) { + SetNewDirectory(Path.Combine(m_currentDirectory, m_directories[i])); + } + + protected void NonMatchingDirectoryDoubleClickCallback(int i) { + SetNewDirectory(Path.Combine(m_currentDirectory, m_nonMatchingDirectories[i])); + } + +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/GUI/FileBrowser.cs.meta b/Assets/Scripts/Utilities/GUI/FileBrowser.cs.meta new file mode 100644 index 00000000..77da4ebb --- /dev/null +++ b/Assets/Scripts/Utilities/GUI/FileBrowser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 229e43233fee52441b6819dd07765a7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/GUI/GUIUtils.cs b/Assets/Scripts/Utilities/GUI/GUIUtils.cs new file mode 100644 index 00000000..b8a45552 --- /dev/null +++ b/Assets/Scripts/Utilities/GUI/GUIUtils.cs @@ -0,0 +1,280 @@ +using UnityEngine; +using System.Collections.Generic; + +namespace SanAndreasUnity.Utilities +{ + public enum ScreenCorner { TopRight, TopLeft, BottomRight, BottomLeft } + + public static class GUIUtils + { + + private static GUIStyle styleWithBackground = new GUIStyle (); + + private static GUIStyle s_centeredLabelStyle = null; + public static GUIStyle CenteredLabelStyle { + get { + if (null == s_centeredLabelStyle) + s_centeredLabelStyle = new GUIStyle (GUI.skin.label) { alignment = TextAnchor.MiddleCenter }; + return s_centeredLabelStyle; + } + } + + public static Rect ScreenRect { get { return new Rect (0, 0, Screen.width, Screen.height); } } + + + + public static Rect GetCornerRect(ScreenCorner corner, Vector2 size, Vector2? padding = null) + { + return GetCornerRect(corner, size.x, size.y, padding); + } + + public static Rect GetCornerRect(ScreenCorner corner, float width, float height, Vector2? padding = null) + { + float padX = 0, + padY = 0; + + if (padding != null) + { + padX = padding.Value.x; + padY = padding.Value.y; + } + + switch (corner) + { + case ScreenCorner.TopLeft: + return new Rect(padX, padY, width, height); + + case ScreenCorner.TopRight: + return new Rect(Screen.width - (width + padX), padY, width, height); + + case ScreenCorner.BottomLeft: + return new Rect(padX, Screen.height - (height + padY), width, height); + + case ScreenCorner.BottomRight: + return new Rect(Screen.width - (width + padX), Screen.height - (height + padY), width, height); + } + + return default(Rect); + } + + public static Rect GetCenteredRect( Vector2 size ) { + + Vector2 pos = new Vector2 (Screen.width * 0.5f, Screen.height * 0.5f); + pos -= size * 0.5f; + + return new Rect (pos, size); + } + + public static Rect GetCenteredRectPerc( Vector2 sizeInScreenPercentage ) { + + return GetCenteredRect (new Vector2 (Screen.width * sizeInScreenPercentage.x, Screen.height * sizeInScreenPercentage.y)); + + } + + public static Vector2 CalcScreenSizeForContent( GUIContent content, GUIStyle style ) { + + return style.CalcScreenSize (style.CalcSize (content)); + } + + public static Vector2 CalcScreenSizeForText( string text, GUIStyle style ) { + + return CalcScreenSizeForContent (new GUIContent (text), style); + } + + public static bool ButtonWithCalculatedSize( string text ) { + + Vector2 size = CalcScreenSizeForText (text, GUI.skin.button); + + return GUILayout.Button (text, GUILayout.Width (size.x), GUILayout.Height (size.y)); + } + + public static bool ButtonWithColor( Rect rect, string text, Color color) { + + var oldColor = GUI.backgroundColor; + GUI.backgroundColor = color; + + bool result = GUI.Button (rect, text); + + GUI.backgroundColor = oldColor; + + return result; + } + + public static void DrawRect (Rect position, Color color, GUIContent content = null) + { + var backgroundColor = GUI.backgroundColor; + GUI.backgroundColor = color; + styleWithBackground.normal.background = Texture2D.whiteTexture; + GUI.Box (position, content ?? GUIContent.none, styleWithBackground); + GUI.backgroundColor = backgroundColor; + } + + public static void DrawBar (Rect rect, float fillPerc, Color fillColor, Color backgroundColor, float borderWidth) + { + fillPerc = Mathf.Clamp01 (fillPerc); + + Rect fillRect = rect; + fillRect.position += Vector2.one * borderWidth; + fillRect.size -= Vector2.one * borderWidth * 2; + + // first fill with black - that will be the border + GUIUtils.DrawRect( rect, Color.black ); + + // fill with background + GUIUtils.DrawRect( fillRect, backgroundColor ); + + // draw filled part + fillRect.width *= fillPerc; + GUIUtils.DrawRect( fillRect, fillColor ); + + } + + public static int TabsControl (int currentTabIndex, params string[] tabNames) + { + return GUILayout.Toolbar (currentTabIndex, tabNames); + } + + public static Rect GetRectForBarAsBillboard (Vector3 worldPos, float worldWidth, float worldHeight, Camera cam) + { + + Vector3 camRight = cam.transform.right; + // Vector3 camUp = cam.transform.up; + +// Vector3 upperLeft = worldPos - camRight * worldWidth * 0.5f + camUp * worldHeight * 0.5f; +// Vector3 upperRight = upperLeft + camRight * worldWidth; +// Vector3 lowerLeft = upperLeft - camUp * worldHeight; +// Vector3 lowerRight = lowerLeft + camRight * worldWidth; + + Vector3 leftWorld = worldPos - camRight * worldWidth * 0.5f; + Vector3 rightWorld = worldPos + camRight * worldWidth * 0.5f; + + Vector3 leftScreen = cam.WorldToScreenPoint (leftWorld); + Vector3 rightScreen = cam.WorldToScreenPoint (rightWorld); + + if (leftScreen.z < 0 || rightScreen.z < 0) + return Rect.zero; + + // transform to gui coordinates + leftScreen.y = Screen.height - leftScreen.y; + rightScreen.y = Screen.height - rightScreen.y; + + float screenWidth = rightScreen.x - leftScreen.x; + float screenHeight = screenWidth * worldHeight / worldWidth; + + return new Rect (new Vector2(leftScreen.x, leftScreen.y - screenHeight * 0.5f), new Vector2(screenWidth, screenHeight) ); + } + + public static void CenteredLabel(Vector2 pos, string text) { + + Vector2 size = CalcScreenSizeForText (text, GUI.skin.label); + + GUI.Label (new Rect (pos - size * 0.5f, size), text); + } + + /// Draws the texture flipped around Y axis. + public static void DrawTextureWithYFlipped(Rect rect, Texture2D tex) { + + var savedMatrix = GUI.matrix; + + GUIUtility.ScaleAroundPivot (new Vector2 (1, -1), rect.center); + + GUI.DrawTexture (rect, tex); + + GUI.matrix = savedMatrix; + } + + public static Rect DrawItemsInARowPerc (Rect rect, System.Action drawItem, string[] items, float[] widthPercs ) { + + Rect itemRect = rect; + float x = rect.position.x; + + for (int i = 0; i < items.Length; i++) { + float width = widthPercs [i] * rect.width; + + itemRect.position = new Vector2 (x, itemRect.position.y); + itemRect.width = width; + + drawItem (itemRect, items [i]); + + x += width; + } + + rect.position += new Vector2 (x, 0f); + rect.width -= x; + return rect; + } + + public static Rect DrawItemsInARow (Rect rect, System.Action drawItem, string[] items, float[] widths ) { + + float[] widthPercs = new float[widths.Length]; + for (int i = 0; i < widths.Length; i++) { + widthPercs [i] = widths [i] / rect.width; + } + + return DrawItemsInARowPerc (rect, drawItem, items, widthPercs); + } + + public static Rect GetNextRectInARowPerc (Rect rowRect, ref int currentRectIndex, float spacing, params float[] widthPercs) { + + float x = rowRect.position.x; + + for (int i = 0; i < currentRectIndex; i++) { + x += widthPercs [i] * rowRect.width; + x += spacing; + } + + float width = widthPercs [currentRectIndex] * rowRect.width; + currentRectIndex++; + + return new Rect( x, rowRect.position.y, width, rowRect.height ); + } + + public static Rect GetNextRectInARow (Rect rowRect, ref int currentRectIndex, float spacing, params float[] widths) { + + float[] widthPercs = new float[widths.Length]; + for (int i = 0; i < widths.Length; i++) { + widthPercs [i] = widths [i] / rowRect.width; + } + + return GetNextRectInARowPerc (rowRect, ref currentRectIndex, spacing, widthPercs); + } + + public static int DrawPagedViewNumbers (Rect rect, int currentPage, int numPages) + { + int resultingPage = currentPage; + + float spacing = 1f; + rect.width = 25f; + + + if (GUI.Button (rect, "<")) { + resultingPage--; + } + rect.position += new Vector2(rect.width + spacing, 0f); + + for (int i = 0; i < numPages; i++) { + var style = currentPage == (i + 1) ? GUI.skin.box : GUI.skin.button; + if (GUI.Button (rect, (i + 1).ToString (), style)) + resultingPage = i + 1; + rect.position += new Vector2(rect.width + spacing, 0f); + } + + if (GUI.Button (rect, ">")) { + resultingPage++; + } + rect.position += new Vector2(rect.width + spacing, 0f); + + + resultingPage = Mathf.Clamp( resultingPage, 1, numPages ); + + return resultingPage; + } + + public static int DrawPagedViewNumbers (Rect rect, int currentPage, int totalNumItems, int numItemsPerPage) + { + int numPages = Mathf.CeilToInt (totalNumItems / (float) numItemsPerPage); + return DrawPagedViewNumbers (rect, currentPage, numPages); + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/GUI/GUIUtils.cs.meta b/Assets/Scripts/Utilities/GUI/GUIUtils.cs.meta new file mode 100644 index 00000000..ac1c0bf7 --- /dev/null +++ b/Assets/Scripts/Utilities/GUI/GUIUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54c9105fbede21845adb37571b796cad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/GUI/TextGizmo.cs b/Assets/Scripts/Utilities/GUI/TextGizmo.cs new file mode 100644 index 00000000..4f67da0d --- /dev/null +++ b/Assets/Scripts/Utilities/GUI/TextGizmo.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace SanAndreasUnity.Utilities +{ + public class TextGizmo + { + private static TextGizmo tg = null; + private Dictionary texturePathLookup; + private Camera editorCamera = null; + private const int CHAR_TEXTURE_HEIGHT = 8; // todo: line breaks + private const int CHAR_TEXTURE_WIDTH = 6; + private const string characters = "abcdefghijklmnopqrstuvwxyz0123456789"; + + public static void Init() + { + tg = new TextGizmo(); + } + + /* singleton constructor */ + + private TextGizmo() + { + editorCamera = Camera.current; + texturePathLookup = new Dictionary(); + for (int c = 0; c < characters.Length; c++) + { + texturePathLookup.Add(characters[c], "TextGizmo/text_" + characters[c] + ".tif"); + } + } + + /* only call this method from a OnGizmos() method */ + + public static void Draw(Vector3 position, string text) + { + if (tg == null) Init(); + + string lowerText = text.ToLower(); + Vector3 screenPoint = tg.editorCamera.WorldToScreenPoint(position); + int offset = 20; + for (int c = 0; c < lowerText.Length; c++) + { + if (tg.texturePathLookup.ContainsKey(lowerText[c])) + { + Vector3 worldPoint = tg.editorCamera.ScreenToWorldPoint(new Vector3(screenPoint.x + offset, screenPoint.y, screenPoint.z)); + + Gizmos.DrawIcon(worldPoint, tg.texturePathLookup[lowerText[c]]); + + offset += CHAR_TEXTURE_WIDTH; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/GUI/TextGizmo.cs.meta b/Assets/Scripts/Utilities/GUI/TextGizmo.cs.meta new file mode 100644 index 00000000..55241a5c --- /dev/null +++ b/Assets/Scripts/Utilities/GUI/TextGizmo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56e1d137930c73144bb33c1de5196b93 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/GUI/xGUILayout.cs b/Assets/Scripts/Utilities/GUI/xGUILayout.cs new file mode 100644 index 00000000..2410b6a1 --- /dev/null +++ b/Assets/Scripts/Utilities/GUI/xGUILayout.cs @@ -0,0 +1,84 @@ +using UnityEngine; + +public class xGUILayout +{ + public delegate void DoubleClickCallback(int index); + + public static int SelectionList(int selected, GUIContent[] list) + { + return SelectionList(selected, list, "button", null); + } + + public static int SelectionList(int selected, GUIContent[] list, GUIStyle elementStyle) + { + return SelectionList(selected, list, elementStyle, null); + } + + public static int SelectionList(int selected, GUIContent[] list, DoubleClickCallback callback) + { + return SelectionList(selected, list, "button", callback); + } + + public static int SelectionList(int selected, GUIContent[] list, GUIStyle elementStyle, DoubleClickCallback callback) + { + for (int i = 0; i < list.Length; ++i) + { + Rect elementRect = GUILayoutUtility.GetRect(list[i], elementStyle); + bool hover = elementRect.Contains(Event.current.mousePosition); + if (hover && Event.current.type == EventType.MouseDown && Event.current.clickCount == 1) // added " && Event.current.clickCount == 1" + { + selected = i; + Event.current.Use(); + } + else if (hover && callback != null && Event.current.type == EventType.MouseDown && Event.current.clickCount == 2) //Changed from MouseUp to MouseDown + { + callback(i); + Event.current.Use(); + } + else if (Event.current.type == EventType.Repaint) + { + elementStyle.Draw(elementRect, list[i], hover, false, i == selected, false); + } + } + return selected; + } + + public static int SelectionList(int selected, string[] list) + { + return SelectionList(selected, list, "button", null); + } + + public static int SelectionList(int selected, string[] list, GUIStyle elementStyle) + { + return SelectionList(selected, list, elementStyle, null); + } + + public static int SelectionList(int selected, string[] list, DoubleClickCallback callback) + { + return SelectionList(selected, list, "button", callback); + } + + public static int SelectionList(int selected, string[] list, GUIStyle elementStyle, DoubleClickCallback callback) + { + for (int i = 0; i < list.Length; ++i) + { + Rect elementRect = GUILayoutUtility.GetRect(new GUIContent(list[i]), elementStyle); + bool hover = elementRect.Contains(Event.current.mousePosition); + if (hover && Event.current.type == EventType.MouseDown) + { + selected = i; + Event.current.Use(); + } + else if (hover && callback != null && Event.current.type == EventType.MouseUp && Event.current.clickCount == 2) + { + callback(i); + Event.current.Use(); + } + else if (Event.current.type == EventType.Repaint) + { + elementStyle.Draw(elementRect, list[i], hover, false, i == selected, false); + } + } + return selected; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/GUI/xGUILayout.cs.meta b/Assets/Scripts/Utilities/GUI/xGUILayout.cs.meta new file mode 100644 index 00000000..1218064c --- /dev/null +++ b/Assets/Scripts/Utilities/GUI/xGUILayout.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10222b6cb1ee1324db5061c7649c32e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/IState.cs b/Assets/Scripts/Utilities/IState.cs new file mode 100644 index 00000000..5e775b26 --- /dev/null +++ b/Assets/Scripts/Utilities/IState.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +namespace SanAndreasUnity.Utilities +{ + + public interface IState { + + void OnBecameActive(); + void OnBecameInactive(); + bool RepresentsState(System.Type type); + bool RepresentsState() where T : IState; + void UpdateState(); + void LateUpdateState(); + void FixedUpdateState(); + + } + +} diff --git a/Assets/Scripts/Utilities/IState.cs.meta b/Assets/Scripts/Utilities/IState.cs.meta new file mode 100644 index 00000000..3ea51d94 --- /dev/null +++ b/Assets/Scripts/Utilities/IState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f502096bd6a1442d0b73c2884a32feec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/Profiler.cs b/Assets/Scripts/Utilities/Profiler.cs new file mode 100644 index 00000000..90c59f9d --- /dev/null +++ b/Assets/Scripts/Utilities/Profiler.cs @@ -0,0 +1,33 @@ +using System; +using System.Diagnostics; + +namespace SanAndreasUnity.Utilities +{ + public static class Profiler + { + private class ProfileFrame : IDisposable + { + private readonly string _name; + private readonly Stopwatch _timer; + + public ProfileFrame(string name) + { + _name = name; + _timer = new Stopwatch(); + _timer.Start(); + } + + public void Dispose() + { + _timer.Stop(); + + UnityEngine.Debug.LogFormat("{0}: {1:F2} ms", _name, _timer.Elapsed.TotalMilliseconds); + } + } + + public static IDisposable Start(string name) + { + return new ProfileFrame(name); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/Profiler.cs.meta b/Assets/Scripts/Utilities/Profiler.cs.meta new file mode 100644 index 00000000..f3ada2a5 --- /dev/null +++ b/Assets/Scripts/Utilities/Profiler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 272dc48038f695d43acf0833c8a35c22 +timeCreated: 1428359558 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/Rotator.cs b/Assets/Scripts/Utilities/Rotator.cs new file mode 100644 index 00000000..47bb19f4 --- /dev/null +++ b/Assets/Scripts/Utilities/Rotator.cs @@ -0,0 +1,35 @@ +using UnityEngine; + +namespace SanAndreasUnity.Utilities +{ + + public class Rotator : MonoBehaviour { + + public Vector3 angles = Vector3.zero; + public bool changeEulers = false; + + + void Update () { + + Vector3 delta = this.angles * Time.deltaTime; + if (delta.sqrMagnitude < float.Epsilon) + return; + + if (this.changeEulers) { + Vector3 eulers = this.transform.localEulerAngles; + eulers += delta; + this.transform.localEulerAngles = eulers; + } else { + + this.transform.rotation *= + Quaternion.AngleAxis (delta.x, Vector3.right) + * Quaternion.AngleAxis (delta.y, Vector3.up) + * Quaternion.AngleAxis (delta.z, Vector3.forward); + + } + + } + + } + +} diff --git a/Assets/Scripts/Utilities/Rotator.cs.meta b/Assets/Scripts/Utilities/Rotator.cs.meta new file mode 100644 index 00000000..0333a58d --- /dev/null +++ b/Assets/Scripts/Utilities/Rotator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 42985861e4d9144258d49089df72c083 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/StateMachine.cs b/Assets/Scripts/Utilities/StateMachine.cs new file mode 100644 index 00000000..fae4ee07 --- /dev/null +++ b/Assets/Scripts/Utilities/StateMachine.cs @@ -0,0 +1,45 @@ +using UnityEngine; + +namespace SanAndreasUnity.Utilities +{ + + public class StateMachine { + + IState m_currentState; + public IState CurrentState { get { return m_currentState; } } + bool m_isSwitchingState = false; + public float TimeWhenSwitchedState { get; private set; } + public long FrameWhenSwitchedState { get; private set; } + + + public void SwitchState(IState newState) { + + if(m_isSwitchingState) + throw new System.Exception("Already switching state"); + + if (newState == m_currentState) + return; + + m_isSwitchingState = true; + + IState oldState = m_currentState; + + m_currentState = newState; + + + if(oldState != null) + oldState.OnBecameInactive(); + + m_isSwitchingState = false; + + this.TimeWhenSwitchedState = Time.time; + this.FrameWhenSwitchedState = Time.frameCount; + + if(m_currentState != null) + m_currentState.OnBecameActive(); + + } + + } + +} diff --git a/Assets/Scripts/Utilities/StateMachine.cs.meta b/Assets/Scripts/Utilities/StateMachine.cs.meta new file mode 100644 index 00000000..d73af19c --- /dev/null +++ b/Assets/Scripts/Utilities/StateMachine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87049d4bb02fc4614b36c80bc088bc39 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/Tools.cs b/Assets/Scripts/Utilities/Tools.cs new file mode 100644 index 00000000..acaee792 --- /dev/null +++ b/Assets/Scripts/Utilities/Tools.cs @@ -0,0 +1,36 @@ +using System; +using System.IO; +using System.Text; + +namespace SanAndreasUnity.Utilities +{ + public static class Tools + { + public static byte[] ReadBytes(this Stream self, int count) + { + var data = new byte[count]; + for (var i = 0; i < count; ++i) + { + var bt = self.ReadByte(); + if (bt == -1) throw new EndOfStreamException(); + + data[i] = (byte)bt; + } + + return data; + } + + public static String ReadString(this BinaryReader reader, int length) + { + var bytes = reader.ReadBytes(length); + return Encoding.UTF8.GetString(bytes).TrimNullChars(); + } + + public static String TrimNullChars(this String str) + { + for (var i = 0; i < str.Length; ++i) if (str[i] == '\0') return str.Substring(0, i); + + return str; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/Tools.cs.meta b/Assets/Scripts/Utilities/Tools.cs.meta new file mode 100644 index 00000000..9190c34a --- /dev/null +++ b/Assets/Scripts/Utilities/Tools.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9068ac64bca552f41a9d126b0ac27cca +timeCreated: 1427127912 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/UI.meta b/Assets/Scripts/Utilities/UI.meta new file mode 100644 index 00000000..cd0ab480 --- /dev/null +++ b/Assets/Scripts/Utilities/UI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cb808958b3d2238438ca3ce2ecaed75e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/UI/Bar.cs b/Assets/Scripts/Utilities/UI/Bar.cs new file mode 100644 index 00000000..7e73dc30 --- /dev/null +++ b/Assets/Scripts/Utilities/UI/Bar.cs @@ -0,0 +1,126 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace SanAndreasUnity.Utilities +{ + + public class Bar : MonoBehaviour { + + public Transform Border { get; private set; } + public Transform Background { get; private set; } + public Transform Fill { get; private set; } + + public Renderer BorderRenderer { get; private set; } + public Renderer BackgroundRenderer { get; private set; } + public Renderer FillRenderer { get; private set; } + + public Color BorderColor { get { return this.BorderRenderer.material.color; } set { this.BorderRenderer.material.color = value; } } + public Color BackgroundColor { get { return this.BackgroundRenderer.material.color; } set { this.BackgroundRenderer.material.color = value; } } + public Color FillColor { get { return this.FillRenderer.material.color; } set { this.FillRenderer.material.color = value; } } + + [SerializeField] private Vector3 m_barSize = new Vector3 (1f, 0.2f, 1f); + public Vector3 BarSize { get { return m_barSize; } set { m_barSize = value; } } + + [SerializeField] private float m_maxHeightOnScreen = 10f; + public float MaxHeightOnScreen { get { return m_maxHeightOnScreen; } set { m_maxHeightOnScreen = value; } } + + public bool faceTowardsCamera = true; + + + + void Awake () + { + this.Border = this.transform.Find ("Border"); + this.Background = this.transform.Find ("Background"); + this.Fill = this.transform.Find ("Fill"); + + this.BorderRenderer = this.Border.GetComponent (); + this.BackgroundRenderer = this.Background.GetComponent (); + this.FillRenderer = this.Fill.GetComponent (); + } + + void Update () + { + Camera cam = Camera.main; + + // update size + this.transform.SetGlobalScale (this.BarSize); + + if (cam) + { + if (this.faceTowardsCamera) + { + // make rotation same as camera's rotation + this.transform.rotation = cam.transform.rotation; + + if (this.MaxHeightOnScreen > 0) + { + // limit height on screen + + // get current height on screen + + Vector3 top = this.transform.position + this.transform.up * this.transform.lossyScale.y * 0.5f; + Vector3 bottom = this.transform.position - this.transform.up * this.transform.lossyScale.y * 0.5f; + + Vector3 screenTop = cam.WorldToScreenPoint( top ); + Vector3 screenBottom = cam.WorldToScreenPoint( bottom ); + + if (screenTop.z >= 0 && screenBottom.z >= 0) + { + float heightOnScreen = Mathf.Abs( screenTop.y - screenBottom.y ); + if (heightOnScreen > this.MaxHeightOnScreen) + { + // reduce height of bar + + float ratio = this.MaxHeightOnScreen / heightOnScreen; + + Vector3 newSize = this.transform.lossyScale; + newSize.y *= ratio; + this.transform.SetGlobalScale( newSize ); + + } + } + + } + } + + } + + } + + public void SetFillPerc (float fillPerc) + { + fillPerc = Mathf.Clamp01 (fillPerc); + + Vector3 scale = this.Fill.localScale; + scale.x = fillPerc; + this.Fill.localScale = scale; + + // reposition it + Vector3 pos = this.Fill.localPosition; + pos.x = - (1.0f - fillPerc) / 2.0f; + this.Fill.localPosition = pos; + } + + /* + public void SetBorderWidth (float borderWidth) + { + // borderWidthPerc = Mathf.Clamp (borderWidthPerc, 0f, 0.5f); + + // stretch border to parent + this.Border.localScale = Vector3.one; + + // reduce width and height of background and fill objects + + Vector3 size = this.BarSize; + size.x -= borderWidth * 2; + size.y -= borderWidth * 2; + + this.Background.SetGlobalScale( size ); + this.Fill.SetGlobalScale( size ); + } + */ + + } + +} diff --git a/Assets/Scripts/Utilities/UI/Bar.cs.meta b/Assets/Scripts/Utilities/UI/Bar.cs.meta new file mode 100644 index 00000000..e0cfebac --- /dev/null +++ b/Assets/Scripts/Utilities/UI/Bar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7111f45c86a74947af5f6831ab01122 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/UI/FPSDisplay.cs b/Assets/Scripts/Utilities/UI/FPSDisplay.cs new file mode 100644 index 00000000..0b42f1d5 --- /dev/null +++ b/Assets/Scripts/Utilities/UI/FPSDisplay.cs @@ -0,0 +1,102 @@ +using System.Collections.Generic; +using UnityEngine; +using System.Linq; + +namespace SanAndreasUnity.Utilities { + + public class FPSDisplay : MonoBehaviour { + + private static int fpsTextureWidth = 75; + private static int fpsTextureHeight = 25; + private static float fpsMaximum = 60.0f; + /*private static float fpsGreen = 50.0f; + private static float fpsRed = 23.0f;*/ + private float fpsDeltaTime = 0.0f; + private Texture2D fpsTexture = null; + private float[] fpsHistory = new float[fpsTextureWidth]; + private int fpsIndex = 0; + + private static bool _showFPS = true; + + + + void Awake () { + + fpsTexture = new Texture2D(fpsTextureWidth, fpsTextureHeight, TextureFormat.RGBA32, false, true); + + } + + void Update () { + + // FPS counting + fpsDeltaTime += (Time.deltaTime - fpsDeltaTime) * 0.1f; + + if (Input.GetKeyDown(KeyCode.F10)) + _showFPS = !_showFPS; + + } + + void OnGUI() { + + + + if (_showFPS) + { + float msec = fpsDeltaTime * 1000.0f; + float fps = 1.0f / fpsDeltaTime; + + // Show FPS counter + GUILayout.BeginArea(GUIUtils.GetCornerRect(ScreenCorner.BottomRight, 100, 25, new Vector2(15 + fpsTexture.width, 10))); + GUILayout.Label(string.Format("{0:0.}fps ({1:0.0}ms)", fps, msec), new GUIStyle("label") { alignment = TextAnchor.MiddleLeft }); + GUILayout.EndArea(); + + if (fpsTexture == null) return; + + // Show FPS history + Color[] colors = new Color[fpsTexture.width * fpsTexture.height]; + + for (int i = 0; i < (fpsTexture.width * fpsTexture.height); i++) + colors[i] = new Color(0.0f, 0.0f, 0.0f, 0.66f); // Half-transparent background for FPS graph + + fpsTexture.SetPixels(colors); + + // Append to history storage + fpsHistory[fpsIndex] = fps; + + int f = fpsIndex; + + if (fps > fpsHistory.Average()) + fpsMaximum = fps; + + // Draw graph into texture + for (int i = fpsTexture.width - 1; i >= 0; i--) + { + float graphVal = (fpsHistory[f] > fpsMaximum) ? fpsMaximum : fpsHistory[f]; //Clamps + int height = (int)(graphVal * fpsTexture.height / (fpsMaximum + 0.1f)); //Returns the height of the desired point with a padding of 0.1f units + + float p = fpsHistory[f] / fpsMaximum, + r = Mathf.Lerp(1, 1 - p, p), + g = Mathf.Lerp(p * 2, p, p); + + fpsTexture.SetPixel(i, height, new Color(r, g, 0)); + f--; + + if (f < 0) + f = fpsHistory.Length - 1; + } + + // Next entry in rolling history buffer + fpsIndex++; + if (fpsIndex >= fpsHistory.Length) + fpsIndex = 0; + + // Draw texture on GUI + fpsTexture.Apply(false, false); + GUI.DrawTexture(GUIUtils.GetCornerRect(ScreenCorner.BottomRight, fpsTexture.width, fpsTexture.height, new Vector2(5, fpsTexture.height - 15)), fpsTexture); + } + + } + + } + +} diff --git a/Assets/Scripts/Utilities/UI/FPSDisplay.cs.meta b/Assets/Scripts/Utilities/UI/FPSDisplay.cs.meta new file mode 100644 index 00000000..56e1baf9 --- /dev/null +++ b/Assets/Scripts/Utilities/UI/FPSDisplay.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6f440c6b65774755ba61e110bc899d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/UI/UIZoomImage.cs b/Assets/Scripts/Utilities/UI/UIZoomImage.cs new file mode 100644 index 00000000..7c8ec244 --- /dev/null +++ b/Assets/Scripts/Utilities/UI/UIZoomImage.cs @@ -0,0 +1,34 @@ +using UnityEngine; +using UnityEngine.EventSystems; + +public class UIZoomImage : MonoBehaviour, IScrollHandler +{ + private Vector3 initialScale; + + [SerializeField] + private float zoomSpeed = 0.1f; + [SerializeField] + private float maxZoom = 10f; + + private void Awake() + { + initialScale = transform.localScale; + } + + public void OnScroll(PointerEventData eventData) + { + var delta = Vector3.one * (eventData.scrollDelta.y * zoomSpeed); + var desiredScale = transform.localScale + delta; + + desiredScale = ClampDesiredScale(desiredScale); + + transform.localScale = desiredScale; + } + + private Vector3 ClampDesiredScale(Vector3 desiredScale) + { + desiredScale = Vector3.Max(initialScale, desiredScale); + desiredScale = Vector3.Min(initialScale * maxZoom, desiredScale); + return desiredScale; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/UI/UIZoomImage.cs.meta b/Assets/Scripts/Utilities/UI/UIZoomImage.cs.meta new file mode 100644 index 00000000..f5e04b0b --- /dev/null +++ b/Assets/Scripts/Utilities/UI/UIZoomImage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55f7ea9a1713a034698f68e0ca4713ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/ZoneHelpers.cs b/Assets/Scripts/Utilities/ZoneHelpers.cs new file mode 100644 index 00000000..98bbaf10 --- /dev/null +++ b/Assets/Scripts/Utilities/ZoneHelpers.cs @@ -0,0 +1,468 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using SanAndreasUnity.Utilities; + +public class ZoneHelpers +{ + public static SZone[] zoneInfoList = + { + new SZone(-2353, 2275, 0, -2153, 2475, 200, "Bayside Marina"), + new SZone(-2741, 2175, 0, -2353, 2722, 200, "Bayside"), + new SZone(-2741, 1268, 0, -2533, 1490, 200, "Battery Point"), + new SZone(-2741, 793, 0, -2533, 1268, 200, "Paradiso"), + new SZone(-2741, 458, 0, -2533, 793, 200, "Santa Flora"), + new SZone(-2994, 458, 0, -2741, 1339, 200, "Palisades"), + new SZone(-2867, 277, 0, -2593, 458, 200, "City Hall"), + new SZone(-2994, 277, 0, -2867, 458, 200, "Ocean Flats"), + new SZone(-2994, -222, 0, -2593, 277, 200, "Ocean Flats"), + new SZone(-2994, -430, 0, -2831, -222, 200, "Ocean Flats"), + new SZone(-2270, -430, 0, -2178, -324, 200, "Foster Valley"), + new SZone(-2178, -599, 0, -1794, -324, 200, "Foster Valley"), + new SZone(-2593, -222, 0, -2411, 54, 200, "Hashbury"), + new SZone(-2533, 968, 0, -2274, 1358, 200, "Juniper Hollow"), + new SZone(-2533, 1358, 0, -1996, 1501, 200, "Esplanade North"), + new SZone(-1996, 1358, 0, -1524, 1592, 200, "Esplanade North"), + new SZone(-1982, 1274, 0, -1524, 1358, 200, "Esplanade North"), + new SZone(-1871, 744, 0, -1701, 1176, 300, "Financial"), + new SZone(-2274, 744, 0, -1982, 1358, 200, "Calton Heights"), + new SZone(-1982, 744, 0, -1871, 1274, 200, "Downtown"), + new SZone(-1871, 1176, 0, -1620, 1274, 200, "Downtown"), + new SZone(-1700, 744, 0, -1580, 1176, 200, "Downtown"), + new SZone(-1580, 744, 0, -1499, 1025, 200, "Downtown"), + new SZone(-2533, 578, 0, -2274, 968, 200, "Juniper Hill"), + new SZone(-2274, 578, 0, -2078, 744, 200, "Chinatown"), + new SZone(-2078, 578, 0, -1499, 744, 200, "Downtown"), + new SZone(-2329, 458, 0, -1993, 578, 200, "King's"), + new SZone(-2411, 265, 0, -1993, 373, 200, "King's"), + new SZone(-2253, 373, 0, -1993, 458, 200, "King's"), + new SZone(-2411, -222, 0, -2173, 265, 200, "Garcia"), + new SZone(-2270, -324, 0, -1794, -222, 200, "Doherty"), + new SZone(-2173, -222, 0, -1794, 265, 200, "Doherty"), + new SZone(-1993, 265, 0, -1794, 578, 200, "Downtown"), + new SZone(-1499, -50, 0, -1242, 249, 200, "Easter Bay Airport"), + new SZone(-1794, 249, 0, -1242, 578, 200, "Easter Basin"), + new SZone(-1794, -50, 0, -1499, 249, 200, "Easter Basin"), + new SZone(-1620, 1176, 0, -1580, 1274, 200, "Esplanade East"), + new SZone(-1580, 1025, 0, -1499, 1274, 200, "Esplanade East"), + new SZone(-1499, 578, -79, -1339, 1274, 20, "Esplanade East"), + new SZone(-2324, -2584, 0, -1964, -2212, 200, "Angel Pine"), + new SZone(-1632, -2263, 0, -1601, -2231, 200, "Shady Cabin"), + new SZone(-1166, -2641, 0, -321, -1856, 200, "Back o Beyond"), + new SZone(-1166, -1856, 0, -815, -1602, 200, "Leafy Hollow"), + new SZone(-594, -1648, 0, -187, -1276, 200, "Flint Range"), + new SZone(-792, -698, 0, -452, -380, 200, "Fallen Tree"), + new SZone(-1209, -1317, 114, -908, -787, 251, "The Farm"), + new SZone(-1645, 2498, 0, -1372, 2777, 200, "El Quebrados"), + new SZone(-1372, 2498, 0, -1277, 2615, 200, "Aldea Malvada"), + new SZone(-968, 1929, 0, -481, 2155, 200, "The Sherman Dam"), + new SZone(-926, 1398, 0, -719, 1634, 200, "Las Barrancas"), + new SZone(-376, 826, 0, 123, 1220, 200, "Fort Carson"), + new SZone(337, 710, -115, 860, 1031, 203, "Hunter Quarry"), + new SZone(338, 1228, 0, 664, 1655, 200, "Octane Springs"), + new SZone(176, 1305, 0, 338, 1520, 200, "Green Palms"), + new SZone(-405, 1712, 0, -276, 1892, 200, "Regular Tom"), + new SZone(-365, 2123, 0, -208, 2217, 200, "Las Brujas"), + new SZone(37, 2337, 0, 435, 2677, 200, "Verdant Meadows"), + new SZone(-354, 2580, 0, -133, 2816, 200, "Las Payasadas"), + new SZone(-901, 2221, 0, -592, 2571, 200, "Arco del Oeste"), + new SZone(-1794, -730, 0, -1213, -50, 200, "Easter Bay Airport"), + new SZone(2576, 62, 0, 2759, 385, 200, "Hankypanky Point"), + new SZone(2160, -149, 0, 2576, 228, 200, "Palomino Creek"), + new SZone(2285, -768, 0, 2770, -269, 200, "North Rock"), + new SZone(1119, 119, 0, 1451, 493, 200, "Montgomery"), + new SZone(1451, 347, 0, 1582, 420, 200, "Montgomery"), + new SZone(603, 264, 0, 761, 366, 200, "Hampton Barns"), + new SZone(508, -139, 0, 1306, 119, 200, "Fern Ridge"), + new SZone(580, -674, 0, 861, -404, 200, "Dillimore"), + new SZone(967, -450, 0, 1176, -217, 200, "Hilltop Farm"), + new SZone(104, -220, 0, 349, 152, 200, "Blueberry"), + new SZone(19, -404, 0, 349, -220, 200, "Blueberry"), + new SZone(-947, -304, 0, -319, 327, 200, "The Panopticon"), + new SZone(2759, 296, 0, 2774, 594, 200, "Frederick Bridge"), + new SZone(1664, 401, 0, 1785, 567, 200, "The Mako Span"), + new SZone(-319, -220, 0, 104, 293, 200, "Blueberry Acres"), + new SZone(-222, 293, 0, -122, 476, 200, "Martin Bridge"), + new SZone(434, 366, 0, 603, 555, 200, "Fallow Bridge"), + new SZone(-1820, -2643, 0, -1226, -1771, 200, "Shady Creeks"), + new SZone(-2030, -2174, 0, -1820, -1771, 200, "Shady Creeks"), + new SZone(-2533, 458, 0, -2329, 578, 200, "Queens"), + new SZone(-2593, 54, 0, -2411, 458, 200, "Queens"), + new SZone(-2411, 373, 0, -2253, 458, 200, "Queens"), + new SZone(44, -2892, -242, 2997, -768, 900, "Los Santos"), + new SZone(869, 596, -242, 2997, 2993, 900, "Las Venturas"), + new SZone(-480, 596, -242, 869, 2993, 900, "Bone County"), + new SZone(-2997, 1659, -242, -480, 2993, 900, "Tierra Robada"), + new SZone(-2741, 1659, 0, -2616, 2175, 200, "Gant Bridge"), + new SZone(-2741, 1490, 0, -2616, 1659, 200, "Gant Bridge"), + new SZone(-2997, -1115, -242, -1213, 1659, 900, "San Fierro"), + new SZone(-1213, 596, -242, -480, 1659, 900, "Tierra Robada"), + new SZone(-1213, -768, -242, 2997, 596, 900, "Red County"), + new SZone(-1213, -2892, -242, 44, -768, 900, "Flint County"), + new SZone(-1132, -768, 0, -956, -578, 200, "Easter Bay Chemicals"), + new SZone(-1132, -787, 0, -956, -768, 200, "Easter Bay Chemicals"), + new SZone(-1213, -730, 0, -1132, -50, 200, "Easter Bay Airport"), + new SZone(-2178, -1115, 0, -1794, -599, 200, "Foster Valley"), + new SZone(-2178, -1250, 0, -1794, -1115, 200, "Foster Valley"), + new SZone(-1242, -50, 0, -1213, 578, 200, "Easter Bay Airport"), + new SZone(-1213, -50, 0, -947, 578, 200, "Easter Bay Airport"), + new SZone(-2997, -2892, -242, -1213, -1115, 900, "Whetstone"), + new SZone(1249, -2394, -89, 1852, -2179, 110, "Los Santos International"), + new SZone(1852, -2394, -89, 2089, -2179, 110, "Los Santos International"), + new SZone(930, -2488, -89, 1249, -2006, 110, "Verdant Bluffs"), + new SZone(1812, -2179, -89, 1970, -1852, 110, "El Corona"), + new SZone(1970, -2179, -89, 2089, -1852, 110, "Willowfield"), + new SZone(2089, -2235, -89, 2201, -1989, 110, "Willowfield"), + new SZone(2089, -1989, -89, 2324, -1852, 110, "Willowfield"), + new SZone(2201, -2095, -89, 2324, -1989, 110, "Willowfield"), + new SZone(2373, -2697, -89, 2809, -2330, 110, "Ocean Docks"), + new SZone(2201, -2418, -89, 2324, -2095, 110, "Ocean Docks"), + new SZone(647, -1804, -89, 851, -1577, 110, "Marina"), + new SZone(647, -2173, -89, 930, -1804, 110, "Verona Beach"), + new SZone(930, -2006, -89, 1073, -1804, 110, "Verona Beach"), + new SZone(1073, -2006, -89, 1249, -1842, 110, "Verdant Bluffs"), + new SZone(1249, -2179, -89, 1692, -1842, 110, "Verdant Bluffs"), + new SZone(1692, -2179, -89, 1812, -1842, 110, "El Corona"), + new SZone(851, -1804, -89, 1046, -1577, 110, "Verona Beach"), + new SZone(647, -1577, -89, 807, -1416, 110, "Marina"), + new SZone(807, -1577, -89, 926, -1416, 110, "Marina"), + new SZone(1161, -1722, -89, 1323, -1577, 110, "Verona Beach"), + new SZone(1046, -1722, -89, 1161, -1577, 110, "Verona Beach"), + new SZone(1046, -1804, -89, 1323, -1722, 110, "Conference Center"), + new SZone(1073, -1842, -89, 1323, -1804, 110, "Conference Center"), + new SZone(1323, -1842, -89, 1701, -1722, 110, "Commerce"), + new SZone(1323, -1722, -89, 1440, -1577, 110, "Commerce"), + new SZone(1370, -1577, -89, 1463, -1384, 110, "Commerce"), + new SZone(1463, -1577, -89, 1667, -1430, 110, "Commerce"), + new SZone(1440, -1722, -89, 1583, -1577, 110, "Pershing Square"), + new SZone(1583, -1722, -89, 1758, -1577, 110, "Commerce"), + new SZone(1701, -1842, -89, 1812, -1722, 110, "Little Mexico"), + new SZone(1758, -1722, -89, 1812, -1577, 110, "Little Mexico"), + new SZone(1667, -1577, -89, 1812, -1430, 110, "Commerce"), + new SZone(1812, -1852, -89, 1971, -1742, 110, "Idlewood"), + new SZone(1812, -1742, -89, 1951, -1602, 110, "Idlewood"), + new SZone(1951, -1742, -89, 2124, -1602, 110, "Idlewood"), + new SZone(1812, -1602, -89, 2124, -1449, 110, "Idlewood"), + new SZone(2124, -1742, -89, 2222, -1494, 110, "Idlewood"), + new SZone(1812, -1449, -89, 1996, -1350, 110, "Glen Park"), + new SZone(1812, -1100, -89, 1994, -973, 110, "Glen Park"), + new SZone(1996, -1449, -89, 2056, -1350, 110, "Jefferson"), + new SZone(2124, -1494, -89, 2266, -1449, 110, "Jefferson"), + new SZone(2056, -1372, -89, 2281, -1210, 110, "Jefferson"), + new SZone(2056, -1210, -89, 2185, -1126, 110, "Jefferson"), + new SZone(2185, -1210, -89, 2281, -1154, 110, "Jefferson"), + new SZone(1994, -1100, -89, 2056, -920, 110, "Las Colinas"), + new SZone(2056, -1126, -89, 2126, -920, 110, "Las Colinas"), + new SZone(2185, -1154, -89, 2281, -934, 110, "Las Colinas"), + new SZone(2126, -1126, -89, 2185, -934, 110, "Las Colinas"), + new SZone(1971, -1852, -89, 2222, -1742, 110, "Idlewood"), + new SZone(2222, -1852, -89, 2632, -1722, 110, "Ganton"), + new SZone(2222, -1722, -89, 2632, -1628, 110, "Ganton"), + new SZone(2541, -1941, -89, 2703, -1852, 110, "Willowfield"), + new SZone(2632, -1852, -89, 2959, -1668, 110, "East Beach"), + new SZone(2632, -1668, -89, 2747, -1393, 110, "East Beach"), + new SZone(2747, -1668, -89, 2959, -1498, 110, "East Beach"), + new SZone(2421, -1628, -89, 2632, -1454, 110, "East Los Santos"), + new SZone(2222, -1628, -89, 2421, -1494, 110, "East Los Santos"), + new SZone(2056, -1449, -89, 2266, -1372, 110, "Jefferson"), + new SZone(2266, -1494, -89, 2381, -1372, 110, "East Los Santos"), + new SZone(2381, -1494, -89, 2421, -1454, 110, "East Los Santos"), + new SZone(2281, -1372, -89, 2381, -1135, 110, "East Los Santos"), + new SZone(2381, -1454, -89, 2462, -1135, 110, "East Los Santos"), + new SZone(2462, -1454, -89, 2581, -1135, 110, "East Los Santos"), + new SZone(2581, -1454, -89, 2632, -1393, 110, "Los Flores"), + new SZone(2581, -1393, -89, 2747, -1135, 110, "Los Flores"), + new SZone(2747, -1498, -89, 2959, -1120, 110, "East Beach"), + new SZone(2747, -1120, -89, 2959, -945, 110, "Las Colinas"), + new SZone(2632, -1135, -89, 2747, -945, 110, "Las Colinas"), + new SZone(2281, -1135, -89, 2632, -945, 110, "Las Colinas"), + new SZone(1463, -1430, -89, 1724, -1290, 110, "Downtown Los Santos"), + new SZone(1724, -1430, -89, 1812, -1250, 110, "Downtown Los Santos"), + new SZone(1463, -1290, -89, 1724, -1150, 110, "Downtown Los Santos"), + new SZone(1370, -1384, -89, 1463, -1170, 110, "Downtown Los Santos"), + new SZone(1724, -1250, -89, 1812, -1150, 110, "Downtown Los Santos"), + new SZone(1463, -1150, -89, 1812, -768, 110, "Mulholland Intersection"), + new SZone(1414, -768, -89, 1667, -452, 110, "Mulholland"), + new SZone(1281, -452, -89, 1641, -290, 110, "Mulholland"), + new SZone(1269, -768, -89, 1414, -452, 110, "Mulholland"), + new SZone(787, -1416, -89, 1072, -1310, 110, "Market"), + new SZone(787, -1310, -89, 952, -1130, 110, "Vinewood"), + new SZone(952, -1310, -89, 1072, -1130, 110, "Market"), + new SZone(1370, -1170, -89, 1463, -1130, 110, "Downtown Los Santos"), + new SZone(1378, -1130, -89, 1463, -1026, 110, "Downtown Los Santos"), + new SZone(1391, -1026, -89, 1463, -926, 110, "Downtown Los Santos"), + new SZone(1252, -1130, -89, 1378, -1026, 110, "Temple"), + new SZone(1252, -1026, -89, 1391, -926, 110, "Temple"), + new SZone(1252, -926, -89, 1357, -910, 110, "Temple"), + new SZone(1357, -926, -89, 1463, -768, 110, "Mulholland"), + new SZone(1318, -910, -89, 1357, -768, 110, "Mulholland"), + new SZone(1169, -910, -89, 1318, -768, 110, "Mulholland"), + new SZone(787, -1130, -89, 952, -954, 110, "Vinewood"), + new SZone(952, -1130, -89, 1096, -937, 110, "Temple"), + new SZone(1096, -1130, -89, 1252, -1026, 110, "Temple"), + new SZone(1096, -1026, -89, 1252, -910, 110, "Temple"), + new SZone(768, -954, -89, 952, -860, 110, "Mulholland"), + new SZone(687, -860, -89, 911, -768, 110, "Mulholland"), + new SZone(737, -768, -89, 1142, -674, 110, "Mulholland"), + new SZone(1096, -910, -89, 1169, -768, 110, "Mulholland"), + new SZone(952, -937, -89, 1096, -860, 110, "Mulholland"), + new SZone(911, -860, -89, 1096, -768, 110, "Mulholland"), + new SZone(861, -674, -89, 1156, -600, 110, "Mulholland"), + new SZone(342, -2173, -89, 647, -1684, 110, "Santa Maria Beach"), + new SZone(72, -2173, -89, 342, -1684, 110, "Santa Maria Beach"), + new SZone(72, -1684, -89, 225, -1544, 110, "Rodeo"), + new SZone(72, -1544, -89, 225, -1404, 110, "Rodeo"), + new SZone(225, -1684, -89, 312, -1501, 110, "Rodeo"), + new SZone(225, -1501, -89, 334, -1369, 110, "Rodeo"), + new SZone(334, -1501, -89, 422, -1406, 110, "Rodeo"), + new SZone(312, -1684, -89, 422, -1501, 110, "Rodeo"), + new SZone(422, -1684, -89, 558, -1570, 110, "Rodeo"), + new SZone(558, -1684, -89, 647, -1384, 110, "Rodeo"), + new SZone(466, -1570, -89, 558, -1385, 110, "Rodeo"), + new SZone(422, -1570, -89, 466, -1406, 110, "Rodeo"), + new SZone(647, -1227, -89, 787, -1118, 110, "Vinewood"), + new SZone(647, -1118, -89, 787, -954, 110, "Richman"), + new SZone(647, -954, -89, 768, -860, 110, "Richman"), + new SZone(466, -1385, -89, 647, -1235, 110, "Rodeo"), + new SZone(334, -1406, -89, 466, -1292, 110, "Rodeo"), + new SZone(225, -1369, -89, 334, -1292, 110, "Richman"), + new SZone(225, -1292, -89, 466, -1235, 110, "Richman"), + new SZone(72, -1404, -89, 225, -1235, 110, "Richman"), + new SZone(72, -1235, -89, 321, -1008, 110, "Richman"), + new SZone(321, -1235, -89, 647, -1044, 110, "Richman"), + new SZone(321, -1044, -89, 647, -860, 110, "Richman"), + new SZone(321, -860, -89, 687, -768, 110, "Richman"), + new SZone(321, -768, -89, 700, -674, 110, "Richman"), + new SZone(2027, 863, -89, 2087, 1703, 110, "The Strip"), + new SZone(2106, 1863, -89, 2162, 2202, 110, "The Strip"), + new SZone(1817, 863, -89, 2027, 1083, 110, "The Four Dragons Casino"), + new SZone(1817, 1083, -89, 2027, 1283, 110, "The Pink Swan"), + new SZone(1817, 1283, -89, 2027, 1469, 110, "The High Roller"), + new SZone(1817, 1469, -89, 2027, 1703, 110, "Pirates in Men's Pants"), + new SZone(1817, 1863, -89, 2106, 2011, 110, "The Visage"), + new SZone(1817, 1703, -89, 2027, 1863, 110, "The Visage"), + new SZone(1457, 823, -89, 2377, 863, 110, "Julius Thruway South"), + new SZone(1197, 1163, -89, 1236, 2243, 110, "Julius Thruway West"), + new SZone(2377, 788, -89, 2537, 897, 110, "Julius Thruway South"), + new SZone(2537, 676, -89, 2902, 943, 110, "Rockshore East"), + new SZone(2087, 943, -89, 2623, 1203, 110, "Come-A-Lot"), + new SZone(2087, 1203, -89, 2640, 1383, 110, "The Camel's Toe"), + new SZone(2087, 1383, -89, 2437, 1543, 110, "Royal Casino"), + new SZone(2087, 1543, -89, 2437, 1703, 110, "Caligula's Palace"), + new SZone(2137, 1703, -89, 2437, 1783, 110, "Caligula's Palace"), + new SZone(2437, 1383, -89, 2624, 1783, 110, "Pilgrim"), + new SZone(2437, 1783, -89, 2685, 2012, 110, "Starfish Casino"), + new SZone(2027, 1783, -89, 2162, 1863, 110, "The Strip"), + new SZone(2027, 1703, -89, 2137, 1783, 110, "The Strip"), + new SZone(2011, 2202, -89, 2237, 2508, 110, "The Emerald Isle"), + new SZone(2162, 2012, -89, 2685, 2202, 110, "Old Venturas Strip"), + new SZone(2498, 2626, -89, 2749, 2861, 110, "K.A.C.C. Military Fuels"), + new SZone(2749, 1937, -89, 2921, 2669, 110, "Creek"), + new SZone(2749, 1548, -89, 2923, 1937, 110, "Sobell Rail Yards"), + new SZone(2749, 1198, -89, 2923, 1548, 110, "Linden Station"), + new SZone(2623, 943, -89, 2749, 1055, 110, "Julius Thruway East"), + new SZone(2749, 943, -89, 2923, 1198, 110, "Linden Side"), + new SZone(2685, 1055, -89, 2749, 2626, 110, "Julius Thruway East"), + new SZone(2498, 2542, -89, 2685, 2626, 110, "Julius Thruway North"), + new SZone(2536, 2442, -89, 2685, 2542, 110, "Julius Thruway East"), + new SZone(2625, 2202, -89, 2685, 2442, 110, "Julius Thruway East"), + new SZone(2237, 2542, -89, 2498, 2663, 110, "Julius Thruway North"), + new SZone(2121, 2508, -89, 2237, 2663, 110, "Julius Thruway North"), + new SZone(1938, 2508, -89, 2121, 2624, 110, "Julius Thruway North"), + new SZone(1534, 2433, -89, 1848, 2583, 110, "Julius Thruway North"), + new SZone(1236, 2142, -89, 1297, 2243, 110, "Julius Thruway West"), + new SZone(1848, 2478, -89, 1938, 2553, 110, "Julius Thruway North"), + new SZone(1777, 863, -89, 1817, 2342, 110, "Harry Gold Parkway"), + new SZone(1817, 2011, -89, 2106, 2202, 110, "Redsands East"), + new SZone(1817, 2202, -89, 2011, 2342, 110, "Redsands East"), + new SZone(1848, 2342, -89, 2011, 2478, 110, "Redsands East"), + new SZone(1704, 2342, -89, 1848, 2433, 110, "Julius Thruway North"), + new SZone(1236, 1883, -89, 1777, 2142, 110, "Redsands West"), + new SZone(1297, 2142, -89, 1777, 2243, 110, "Redsands West"), + new SZone(1377, 2243, -89, 1704, 2433, 110, "Redsands West"), + new SZone(1704, 2243, -89, 1777, 2342, 110, "Redsands West"), + new SZone(1236, 1203, -89, 1457, 1883, 110, "Las Venturas Airport"), + new SZone(1457, 1203, -89, 1777, 1883, 110, "Las Venturas Airport"), + new SZone(1457, 1143, -89, 1777, 1203, 110, "Las Venturas Airport"), + new SZone(1457, 863, -89, 1777, 1143, 110, "LVA Freight Depot"), + new SZone(1197, 1044, -89, 1277, 1163, 110, "Blackfield Intersection"), + new SZone(1166, 795, -89, 1375, 1044, 110, "Blackfield Intersection"), + new SZone(1277, 1044, -89, 1315, 1087, 110, "Blackfield Intersection"), + new SZone(1375, 823, -89, 1457, 919, 110, "Blackfield Intersection"), + new SZone(1375, 919, -89, 1457, 1203, 110, "LVA Freight Depot"), + new SZone(1277, 1087, -89, 1375, 1203, 110, "LVA Freight Depot"), + new SZone(1315, 1044, -89, 1375, 1087, 110, "LVA Freight Depot"), + new SZone(1236, 1163, -89, 1277, 1203, 110, "LVA Freight Depot"), + new SZone(964, 1044, -89, 1197, 1203, 110, "Greenglass College"), + new SZone(964, 930, -89, 1166, 1044, 110, "Greenglass College"), + new SZone(964, 1203, -89, 1197, 1403, 110, "Blackfield"), + new SZone(964, 1403, -89, 1197, 1726, 110, "Blackfield"), + new SZone(2237, 2202, -89, 2536, 2542, 110, "Roca Escalante"), + new SZone(2536, 2202, -89, 2625, 2442, 110, "Roca Escalante"), + new SZone(1823, 596, -89, 1997, 823, 110, "Last Dime Motel"), + new SZone(1997, 596, -89, 2377, 823, 110, "Rockshore West"), + new SZone(2377, 596, -89, 2537, 788, 110, "Rockshore West"), + new SZone(1558, 596, -89, 1823, 823, 110, "Randolph Industrial Estate"), + new SZone(1375, 596, -89, 1558, 823, 110, "Blackfield Chapel"), + new SZone(1325, 596, -89, 1375, 795, 110, "Blackfield Chapel"), + new SZone(1377, 2433, -89, 1534, 2507, 110, "Julius Thruway North"), + new SZone(1098, 2243, -89, 1377, 2507, 110, "Pilson Intersection"), + new SZone(883, 1726, -89, 1098, 2507, 110, "Whitewood Estates"), + new SZone(1534, 2583, -89, 1848, 2863, 110, "Prickle Pine"), + new SZone(1117, 2507, -89, 1534, 2723, 110, "Prickle Pine"), + new SZone(1848, 2553, -89, 1938, 2863, 110, "Prickle Pine"), + new SZone(2121, 2663, -89, 2498, 2861, 110, "Spinybed"), + new SZone(1938, 2624, -89, 2121, 2861, 110, "Prickle Pine"), + new SZone(2624, 1383, -89, 2685, 1783, 110, "Pilgrim"), + new SZone(2450, 385, -100, 2759, 562, 200, "San Andreas Sound"), + new SZone(1916, -233, -100, 2131, 13, 200, "Fisher's Lagoon"), + new SZone(-1339, 828, -89, -1213, 1057, 110, "Garver Bridge"), + new SZone(-1213, 950, -89, -1087, 1178, 110, "Garver Bridge"), + new SZone(-1499, 696, -179, -1339, 925, 20, "Garver Bridge"), + new SZone(-1339, 599, -89, -1213, 828, 110, "Kincaid Bridge"), + new SZone(-1213, 721, -89, -1087, 950, 110, "Kincaid Bridge"), + new SZone(-1087, 855, -89, -961, 986, 110, "Kincaid Bridge"), + new SZone(-321, -2224, -89, 44, -1724, 110, "Los Santos Inlet"), + new SZone(-789, 1659, -89, -599, 1929, 110, "Sherman Reservoir"), + new SZone(-314, -753, -89, -106, -463, 110, "Flint Water"), + new SZone(-1709, -833, 0, -1446, -730, 200, "Easter Tunnel"), + new SZone(-2290, 2548, -89, -1950, 2723, 110, "Bayside Tunnel"), + new SZone(-410, 1403, 0, -137, 1681, 200, "'The Big Ear'"), + new SZone(-90, 1286, 0, 153, 1554, 200, "Lil' Probe Inn"), + new SZone(-936, 2611, 0, -715, 2847, 200, "Valle Ocultado"), + new SZone(1812, -1350, -89, 2056, -1100, 110, "Glen Park"), + new SZone(2324, -2302, -89, 2703, -2145, 110, "Ocean Docks"), + new SZone(2811, 1229, -39, 2861, 1407, 60, "Linden Station"), + new SZone(1692, -1971, -20, 1812, -1932, 79, "Unity Station"), + new SZone(647, -1416, -89, 787, -1227, 110, "Vinewood"), + new SZone(787, -1410, -34, 866, -1310, 65, "Market Station"), + new SZone(-2007, 56, 0, -1922, 224, 100, "Cranberry Station"), + new SZone(1377, 2600, -21, 1492, 2687, 78, "Yellow Bell Station"), + new SZone(-2616, 1501, 0, -1996, 1659, 200, "San Fierro Bay"), + new SZone(-2616, 1659, 0, -1996, 2175, 200, "San Fierro Bay"), + new SZone(-464, 2217, 0, -208, 2580, 200, "El Castillo del Diablo"), + new SZone(-208, 2123, 0, 114, 2337, 200, "El Castillo del Diablo"), + new SZone(-208, 2337, 0, 8, 2487, 200, "El Castillo del Diablo"), + new SZone(-91, 1655, -50, 421, 2123, 250, "Restricted Area"), + new SZone(1546, 208, 0, 1745, 347, 200, "Montgomery Intersection"), + new SZone(1582, 347, 0, 1664, 401, 200, "Montgomery Intersection"), + new SZone(-1119, 1178, -89, -862, 1351, 110, "Robada Intersection"), + new SZone(-187, -1596, -89, 17, -1276, 110, "Flint Intersection"), + new SZone(-1315, -405, 15, -1264, -209, 25, "Easter Bay Airport"), + new SZone(-1354, -287, 15, -1315, -209, 25, "Easter Bay Airport"), + new SZone(-1490, -209, 15, -1264, -148, 25, "Easter Bay Airport"), + new SZone(1072, -1416, -89, 1370, -1130, 110, "Market"), + new SZone(926, -1577, -89, 1370, -1416, 110, "Market"), + new SZone(-2646, -355, 0, -2270, -222, 200, "Avispa Country Club"), + new SZone(-2831, -430, 0, -2646, -222, 200, "Avispa Country Club"), + new SZone(-2994, -811, 0, -2178, -430, 200, "Missionary Hill"), + new SZone(-2178, -1771, -47, -1936, -1250, 576, "Mount Chiliad"), + new SZone(-2997, -1115, -47, -2178, -971, 576, "Mount Chiliad"), + new SZone(-2994, -2189, -47, -2178, -1115, 576, "Mount Chiliad"), + new SZone(-2178, -2189, -47, -2030, -1771, 576, "Mount Chiliad"), + new SZone(1117, 2723, -89, 1457, 2863, 110, "Yellow Bell Golf Course"), + new SZone(1457, 2723, -89, 1534, 2863, 110, "Yellow Bell Golf Course"), + new SZone(1515, 1586, -12, 1729, 1714, 87, "Las Venturas Airport"), + new SZone(2089, -2394, -89, 2201, -2235, 110, "Ocean Docks"), + new SZone(1382, -2730, -89, 2201, -2394, 110, "Los Santos International"), + new SZone(2201, -2730, -89, 2324, -2418, 110, "Ocean Docks"), + new SZone(1974, -2394, -39, 2089, -2256, 60, "Los Santos International"), + new SZone(1400, -2669, -39, 2189, -2597, 60, "Los Santos International"), + new SZone(2051, -2597, -39, 2152, -2394, 60, "Los Santos International"), + new SZone(2437, 1858, -39, 2495, 1970, 60, "Starfish Casino"), + new SZone(-399, -1075, -1, -319, -977, 198, "Beacon Hill"), + new SZone(-2361, -417, 0, -2270, -355, 200, "Avispa Country Club"), + new SZone(-2667, -302, -28, -2646, -262, 71, "Avispa Country Club"), + new SZone(-2395, -222, 0, -2354, -204, 200, "Garcia"), + new SZone(-2470, -355, 0, -2270, -318, 46, "Avispa Country Club"), + new SZone(-2550, -355, 0, -2470, -318, 39, "Avispa Country Club"), + new SZone(2703, -2126, -89, 2959, -1852, 110, "Playa del Seville"), + new SZone(2703, -2302, -89, 2959, -2126, 110, "Ocean Docks"), + new SZone(2162, 1883, -89, 2437, 2012, 110, "Starfish Casino"), + new SZone(2162, 1783, -89, 2437, 1883, 110, "The Clown's Pocket"), + new SZone(2324, -2145, -89, 2703, -2059, 110, "Ocean Docks"), + new SZone(2324, -2059, -89, 2541, -1852, 110, "Willowfield"), + new SZone(2541, -2059, -89, 2703, -1941, 110, "Willowfield"), + new SZone(1098, 1726, -89, 1197, 2243, 110, "Whitewood Estates") + }; +} + +public class SZone +{ + public Vector3 vmin, vmax; + + public Vector2 minPos2D { get { return new Vector2 (this.vmin.x, this.vmin.z); } } + public Vector2 maxPos2D { get { return new Vector2 (this.vmax.x, this.vmax.z); } } + public Vector3 centerPos { get { return (this.vmin + this.vmax) * 0.5f; } } + + public float volume { get { Vector3 size = this.vmax - this.vmin; return size.x * size.y * size.z; } } + public float squaredSize { get { Vector2 size = this.maxPos2D - this.minPos2D; return size.x * size.y; } } + + public string name; + + public const string defaultZoneName = "San Andreas"; + + public static SZone[] AllZones { get { return ZoneHelpers.zoneInfoList; } } + + + public SZone (int x1, int z1, int y1, int x2, int z2, int y2, string n) + { + vmin = new Vector3 (x1, y1, z1); + vmax = new Vector3 (x2, y2, z2); + name = n; + } + + public static string GetZoneName (SZone[] sZones, Vector3 worldPos) + { + try { + return sZones.Where (x => worldPos.IsInside (x.vmin, x.vmax)) + // .Select (x => new { Center = x.centerPos, Zone = x }) + // .OrderBy (x => Vector3.Distance (worldPos, x.Center)) + .OrderBy(x => x.volume) + // .Select (x => x.Zone) + .FirstOrDefault () + .name; + } catch { + return defaultZoneName; + } + } + + public static string GetZoneName (SZone[] sZones, Vector2 worldPos2D) + { + try { + return sZones.Where (x => IsInside( worldPos2D, x )) + // .Select (x => new { Center = (x.minPos2D + x.maxPos2D) * 0.5f, Zone = x }) + // .OrderBy (x => Vector2.Distance (worldPos2D, x.Center)) + .OrderBy( x => x.squaredSize ) + // .Select (x => x.Zone) + .FirstOrDefault () + .name; + } catch { + return defaultZoneName; + } + } + + public static string GetZoneName( Vector3 worldPos, bool use2DPos = false ) { + if (use2DPos) + return GetZoneName (worldPos.ToVec2WithXAndZ ()); + return GetZoneName (ZoneHelpers.zoneInfoList, worldPos); + } + + public static string GetZoneName( Vector2 worldPos2D ) { + return GetZoneName (ZoneHelpers.zoneInfoList, worldPos2D); + } + + public static bool IsInside(Vector2 pos, SZone zone) { + return pos.x >= zone.vmin.x && pos.x <= zone.vmax.x && pos.y >= zone.vmin.z && pos.y <= zone.vmax.z; + } + +} + +public static class ZHelpers +{ + public static bool IsInside(this Vector3 p, Vector3 vmin, Vector3 vmax) + { + return p.x >= vmin.x && p.x <= vmax.x && p.y >= vmin.y && p.y <= vmax.y && p.z >= vmin.z && p.z <= vmax.z; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Utilities/ZoneHelpers.cs.meta b/Assets/Scripts/Utilities/ZoneHelpers.cs.meta new file mode 100644 index 00000000..8f991704 --- /dev/null +++ b/Assets/Scripts/Utilities/ZoneHelpers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1297dd9d446de2746a5c223b13373686 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Shaders.meta b/Assets/Shaders.meta new file mode 100644 index 00000000..a93d6d3f --- /dev/null +++ b/Assets/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e7118434e39534ffbb1668174d9549f2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Shaders/GLlineZOff.shader b/Assets/Shaders/GLlineZOff.shader new file mode 100644 index 00000000..24a058c2 --- /dev/null +++ b/Assets/Shaders/GLlineZOff.shader @@ -0,0 +1,14 @@ +Shader "Debug/GLlineZOff" { + SubShader { + Pass { + Blend SrcAlpha OneMinusSrcAlpha + ZWrite Off + ZTest Always + Cull Off + BindChannels { + Bind "vertex", vertex + Bind "color", color + } + } + } +} diff --git a/Assets/Shaders/GLlineZOff.shader.meta b/Assets/Shaders/GLlineZOff.shader.meta new file mode 100644 index 00000000..996ac73a --- /dev/null +++ b/Assets/Shaders/GLlineZOff.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 12cb60961770c4d7e8cc1662ca101fec +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Shaders/GLlineZOn.shader b/Assets/Shaders/GLlineZOn.shader new file mode 100644 index 00000000..ca093ddf --- /dev/null +++ b/Assets/Shaders/GLlineZOn.shader @@ -0,0 +1,13 @@ +Shader "Debug/GLlineZOn" { + SubShader { + Pass { + Blend SrcAlpha OneMinusSrcAlpha + ZWrite Off + Cull Off + BindChannels { + Bind "vertex", vertex + Bind "color", color + } + } + } +} diff --git a/Assets/Shaders/GLlineZOn.shader.meta b/Assets/Shaders/GLlineZOn.shader.meta new file mode 100644 index 00000000..711a08de --- /dev/null +++ b/Assets/Shaders/GLlineZOn.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6602491fb85d04f7facf2932f1831720 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Standard Assets.meta b/Assets/Standard Assets.meta new file mode 100644 index 00000000..1514038e --- /dev/null +++ b/Assets/Standard Assets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 25b13f8614139ab48bd9f6e501fa21d6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Standard Assets/Environment.meta b/Assets/Standard Assets/Environment.meta new file mode 100644 index 00000000..784bb5b0 --- /dev/null +++ b/Assets/Standard Assets/Environment.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 6ca8c4e270f964e0da9f731d7d34b123 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic).meta b/Assets/Standard Assets/Environment/Water (Basic).meta new file mode 100644 index 00000000..6e23919a --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic).meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: dc7abfa0435174ded902b073322d67cc +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Materials.meta b/Assets/Standard Assets/Environment/Water (Basic)/Materials.meta new file mode 100644 index 00000000..75cf9237 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Materials.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 706eadfad28bc4c1c9bb137b31052b14 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicDaytime.mat b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicDaytime.mat new file mode 100644 index 00000000..2fd465af --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicDaytime.mat @@ -0,0 +1,188 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: WaterBasicDaytime + m_Shader: {fileID: 4800000, guid: 9dccc8e8f0da4494991c26ef59019551, type: 3} + m_ShaderKeywords: [] + m_CustomRenderQueue: -1 + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + data: + first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: c2ef94ff9d11915d1100a04b44295342, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: a53cf5449d11a15d1100a04b44295342, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ReflectionTex + second: + m_Texture: {fileID: 8400000, guid: 21bb33409d118354d000dcabe39e7c39, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ColorControlCube + second: + m_Texture: {fileID: 8900000, guid: 98c330f39d11745ad0004adb8d76c639, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ColorControl + second: + m_Texture: {fileID: 2800000, guid: 047330f39d11745ad0004adb8d76c639, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _WavesTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _BumpMap2 + second: + m_Texture: {fileID: 2800000, guid: 279fb0a19d11d4a6d00051fa8d76c639, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ColorGradient + second: + m_Texture: {fileID: 2800000, guid: 8403d3349d112ba4d000be1be39e7c39, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _Shininess + second: 1 + data: + first: + name: _WaveScale + second: .0702830181 + data: + first: + name: _Highlight + second: 33.2075462 + data: + first: + name: _bScale + second: .0700000003 + data: + first: + name: _BumpPeturb + second: 82.07547 + data: + first: + name: _BumpPeturb2 + second: .745283008 + data: + first: + name: _bTwirl + second: .0500000007 + data: + first: + name: _distort + second: .100000001 + m_Colors: + data: + first: + name: _Color + second: {r: 0, g: 0, b: 0, a: 1} + data: + first: + name: _MainTex_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _SpecColor + second: {r: 0, g: 0, b: 0, a: .400000006} + data: + first: + name: _BumpMap_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: WaveSpeed + second: {r: 9, g: 4.5, b: -8, a: -3.5} + data: + first: + name: _horizonColor + second: {r: 0, g: .125133663, b: .191176474, a: 0} + data: + first: + name: _ColorControl_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _ColorControlCube_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: BumpParm + second: {r: 1, g: 1, b: 1, a: 1} + data: + first: + name: _EdgeColor + second: {r: 0, g: .100000001, b: 0, a: .100000001} + data: + first: + name: _RefTex_0 + second: {r: -1517.37024, g: -23.9408531, b: -3154.91675, a: 2715.94165} + data: + first: + name: _RefTex_1 + second: {r: 356.584351, g: -313.125671, b: -962.84906, a: 2791.50659} + data: + first: + name: _RefTex_2 + second: {r: 4.95644999, g: -.187056601, b: -13.3834057, a: 20.1233597} + data: + first: + name: _RefTex_3 + second: {r: 4.95595503, g: -.18703793, b: -13.3820696, a: 20.2213535} + data: + first: + name: horizonColor + second: {r: .61500001, g: .796000004, b: .875999987, a: 1} + data: + first: + name: uvParams + second: {r: 10, g: .0199999996, b: .0299999993, a: 0} + data: + first: + name: waveDirX + second: {r: -2.5, g: 0, b: 7, a: 8} + data: + first: + name: waveDirY + second: {r: 0, g: 1.5, b: -7, a: 1} + data: + first: + name: waveHeights + second: {r: .800000012, g: 1, b: .100000001, a: .0500000007} + data: + first: + name: _WaveSpeed + second: {r: 1, g: -1, b: -1, a: 1} +--- !u!1002 &2100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicDaytime.mat.meta b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicDaytime.mat.meta new file mode 100644 index 00000000..47f559a2 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicDaytime.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 52b7d70b1de7c4ce09662b77c14d9fda +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicNighttime.mat b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicNighttime.mat new file mode 100644 index 00000000..6a8d8c7a --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicNighttime.mat @@ -0,0 +1,192 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: WaterBasicNighttime + m_Shader: {fileID: 4800000, guid: 9dccc8e8f0da4494991c26ef59019551, type: 3} + m_ShaderKeywords: [] + m_CustomRenderQueue: -1 + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + data: + first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: c2ef94ff9d11915d1100a04b44295342, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: a53cf5449d11a15d1100a04b44295342, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ReflectionTex + second: + m_Texture: {fileID: 8400000, guid: 21bb33409d118354d000dcabe39e7c39, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _WavesTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ColorControlCube + second: + m_Texture: {fileID: 8900000, guid: 006a5f739d1105f6a000538a2aef8c59, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ColorControl + second: + m_Texture: {fileID: 2800000, guid: 8403d3349d112ba4d000be1be39e7c39, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _BumpMap2 + second: + m_Texture: {fileID: 2800000, guid: 279fb0a19d11d4a6d00051fa8d76c639, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ColorGradient + second: + m_Texture: {fileID: 2800000, guid: 8403d3349d112ba4d000be1be39e7c39, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _Shininess + second: 1 + data: + first: + name: _WaveScale + second: .0702830181 + data: + first: + name: _Highlight + second: 33.2075462 + data: + first: + name: _bScale + second: .0629245341 + data: + first: + name: _BumpPeturb + second: 82.07547 + data: + first: + name: _BumpPeturb2 + second: .745283008 + data: + first: + name: _bTwirl + second: .0500000007 + data: + first: + name: _distort + second: .100000001 + data: + first: + name: _BumpStrength + second: .100000001 + m_Colors: + data: + first: + name: _Color + second: {r: .700785816, g: .481223762, b: .474296182, a: 1} + data: + first: + name: _MainTex_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _SpecColor + second: {r: 0, g: 0, b: 0, a: .400000006} + data: + first: + name: _BumpMap_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: WaveSpeed + second: {r: 9.68770027, g: 4.81898165, b: -7.91322803, a: 2.87029743} + data: + first: + name: _horizonColor + second: {r: .148485541, g: .282429248, b: .379949659, a: 0} + data: + first: + name: _ColorControl_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _ColorControlCube_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: BumpParm + second: {r: 1, g: 1, b: -1, a: -1} + data: + first: + name: _EdgeColor + second: {r: 0, g: .100000001, b: 0, a: .100000001} + data: + first: + name: _RefTex_0 + second: {r: -1517.37024, g: -23.9408531, b: -3154.91675, a: 2715.94165} + data: + first: + name: _RefTex_1 + second: {r: 356.584351, g: -313.125671, b: -962.84906, a: 2791.50659} + data: + first: + name: _RefTex_2 + second: {r: 4.95644999, g: -.187056601, b: -13.3834057, a: 20.1233597} + data: + first: + name: _RefTex_3 + second: {r: 4.95595503, g: -.18703793, b: -13.3820696, a: 20.2213535} + data: + first: + name: horizonColor + second: {r: .61500001, g: .796000004, b: .875999987, a: 1} + data: + first: + name: uvParams + second: {r: 10, g: .0199999996, b: .0299999993, a: 0} + data: + first: + name: waveDirX + second: {r: -2.5, g: 0, b: 7, a: 8} + data: + first: + name: waveDirY + second: {r: 0, g: 1.5, b: -7, a: 1} + data: + first: + name: waveHeights + second: {r: .800000012, g: 1, b: .100000001, a: .0500000007} + data: + first: + name: _WaveSpeed + second: {r: 1, g: -1, b: -1, a: 1} +--- !u!1002 &2100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicNighttime.mat.meta b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicNighttime.mat.meta new file mode 100644 index 00000000..edcaad1c --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterBasicNighttime.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: c55afdc4a8a3b4890b07cc7d176510bb +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterDefault.mat b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterDefault.mat new file mode 100644 index 00000000..04969758 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterDefault.mat @@ -0,0 +1,31 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: WaterDefault + m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: [] + m_CustomRenderQueue: -1 + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + data: + first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: c2ef94ff9d11915d1100a04b44295342, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: {} + m_Colors: + data: + first: + name: _Color + second: {r: .5, g: .5, b: .5, a: 1} +--- !u!1002 &2100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterDefault.mat.meta b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterDefault.mat.meta new file mode 100644 index 00000000..7c8d6cdb --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Materials/WaterDefault.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 30abebfd9bf1c49d8a2d26e61e66bc15 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Models.meta b/Assets/Standard Assets/Environment/Water (Basic)/Models.meta new file mode 100644 index 00000000..b63ac275 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Models.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 5ca387966638baf478f257729f7d9ffd +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Models/WaterBasicPlane.fbx b/Assets/Standard Assets/Environment/Water (Basic)/Models/WaterBasicPlane.fbx new file mode 100644 index 00000000..95966340 Binary files /dev/null and b/Assets/Standard Assets/Environment/Water (Basic)/Models/WaterBasicPlane.fbx differ diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Models/WaterBasicPlane.fbx.meta b/Assets/Standard Assets/Environment/Water (Basic)/Models/WaterBasicPlane.fbx.meta new file mode 100644 index 00000000..76314e09 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Models/WaterBasicPlane.fbx.meta @@ -0,0 +1,73 @@ +fileFormatVersion: 2 +guid: ce8d79c79d11b8f9d00076e98d76c639 +ModelImporter: + serializedVersion: 18 + fileIDToRecycleName: + 100000: //RootNode + 400000: //RootNode + 2300000: //RootNode + 3300000: //RootNode + 4300000: pPlane1 + 4300002: nurbsToPoly1 + 4300004: pCylinder1 + 4300006: waterPlaneMesh + 4300008: WaterBasicPlane + 4300010: WaterSimplePlane + 11100000: //RootNode + materials: + importMaterials: 0 + materialName: 1 + materialSearch: 2 + animations: + legacyGenerateAnimations: 0 + bakeSimulation: 0 + optimizeGameObjects: 0 + motionNodeName: + pivotNodeName: + animationCompression: 1 + animationRotationError: .5 + animationPositionError: .5 + animationScaleError: .5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + importBlendShapes: 1 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 0 + optimizeMeshForGPU: 1 + weldVertices: 1 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 0 + tangentSpace: + normalSmoothAngle: 60 + splitTangentsAcrossUV: 0 + normalImportMode: 0 + tangentImportMode: 1 + importAnimation: 1 + copyAvatar: 0 + humanDescription: + human: [] + skeleton: [] + armTwist: .5 + foreArmTwist: .5 + upperLegTwist: .5 + legTwist: .5 + armStretch: .0500000007 + legStretch: .0500000007 + feetSpacing: 0 + rootMotionBoneName: + lastHumanDescriptionAvatarSource: {instanceID: 0} + animationType: 1 + additionalBone: 0 + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Prefabs.meta b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs.meta new file mode 100644 index 00000000..2920f073 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 50d95e01ce44ff842949168ffec200cf +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicDaytime.prefab b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicDaytime.prefab new file mode 100644 index 00000000..a503df07 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicDaytime.prefab @@ -0,0 +1,104 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &100000 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400000} + - 33: {fileID: 3300000} + - 23: {fileID: 2300000} + - 114: {fileID: 11400000} + m_Layer: 4 + m_Name: WaterBasicDaytime + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400000 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + 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 +--- !u!1002 &400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300000 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 255 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: 52b7d70b1de7c4ce09662b77c14d9fda, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 0 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300000 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Mesh: {fileID: 4300008, guid: ce8d79c79d11b8f9d00076e98d76c639, type: 3} +--- !u!1002 &3300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0d2f50a8e0bb841a5aaa90ae55db8849, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1002 &11400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 100000} + m_IsPrefabParent: 1 +--- !u!1002 &100100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicDaytime.prefab.meta b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicDaytime.prefab.meta new file mode 100644 index 00000000..0923f289 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicDaytime.prefab.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 9485b0c79d11e2e4d0007da98d76c639 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicNightime.prefab b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicNightime.prefab new file mode 100644 index 00000000..20948bd4 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicNightime.prefab @@ -0,0 +1,104 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &100000 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400000} + - 33: {fileID: 3300000} + - 23: {fileID: 2300000} + - 114: {fileID: 11400000} + m_Layer: 4 + m_Name: WaterBasicNightime + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400000 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -3.10330009, y: 10.3140001, z: -40.5900002} + m_LocalScale: {x: 16, y: 1, z: 16} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!1002 &400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300000 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 255 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: c55afdc4a8a3b4890b07cc7d176510bb, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 0 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300000 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Mesh: {fileID: 4300008, guid: ce8d79c79d11b8f9d00076e98d76c639, type: 3} +--- !u!1002 &3300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0d2f50a8e0bb841a5aaa90ae55db8849, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1002 &11400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 100000} + m_IsPrefabParent: 1 +--- !u!1002 &100100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicNightime.prefab.meta b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicNightime.prefab.meta new file mode 100644 index 00000000..b54cc3d5 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Prefabs/WaterBasicNightime.prefab.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 6b436d069d11415d1100ab9b44295342 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Scripts.meta b/Assets/Standard Assets/Environment/Water (Basic)/Scripts.meta new file mode 100644 index 00000000..c58647bd --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Scripts.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: ac85670a1b2274f22905d6a43940371a +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Scripts/WaterBasic.cs b/Assets/Standard Assets/Environment/Water (Basic)/Scripts/WaterBasic.cs new file mode 100644 index 00000000..4edb0d1b --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Scripts/WaterBasic.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + [ExecuteInEditMode] + public class WaterBasic : MonoBehaviour + { + private void Update() + { + Renderer r = GetComponent(); + if (!r) + { + return; + } + Material mat = r.sharedMaterial; + if (!mat) + { + return; + } + + Vector4 waveSpeed = mat.GetVector("WaveSpeed"); + float waveScale = mat.GetFloat("_WaveScale"); + float t = Time.time / 20.0f; + + Vector4 offset4 = waveSpeed * (t * waveScale); + Vector4 offsetClamped = new Vector4(Mathf.Repeat(offset4.x, 1.0f), Mathf.Repeat(offset4.y, 1.0f), + Mathf.Repeat(offset4.z, 1.0f), Mathf.Repeat(offset4.w, 1.0f)); + mat.SetVector("_WaveOffset", offsetClamped); + } + } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Scripts/WaterBasic.cs.meta b/Assets/Standard Assets/Environment/Water (Basic)/Scripts/WaterBasic.cs.meta new file mode 100644 index 00000000..04190181 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Scripts/WaterBasic.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0d2f50a8e0bb841a5aaa90ae55db8849 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Shaders.meta b/Assets/Standard Assets/Environment/Water (Basic)/Shaders.meta new file mode 100644 index 00000000..f570f155 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Shaders.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: c8e96a067d1ef4982b454cf5a686f648 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Shaders/FXWaterBasic.shader b/Assets/Standard Assets/Environment/Water (Basic)/Shaders/FXWaterBasic.shader new file mode 100644 index 00000000..447a2797 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Shaders/FXWaterBasic.shader @@ -0,0 +1,90 @@ +// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' + +Shader "FX/Water (Basic)" { +Properties { + _horizonColor ("Horizon color", COLOR) = ( .172 , .463 , .435 , 0) + _WaveScale ("Wave scale", Range (0.02,0.15)) = .07 + [NoScaleOffset] _ColorControl ("Reflective color (RGB) fresnel (A) ", 2D) = "" { } + [NoScaleOffset] _BumpMap ("Waves Normalmap ", 2D) = "" { } + WaveSpeed ("Wave speed (map1 x,y; map2 x,y)", Vector) = (19,9,-16,-7) + } + +CGINCLUDE + +#include "UnityCG.cginc" + +uniform float4 _horizonColor; + +uniform float4 WaveSpeed; +uniform float _WaveScale; +uniform float4 _WaveOffset; + +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; +}; + +struct v2f { + float4 pos : SV_POSITION; + float2 bumpuv[2] : TEXCOORD0; + float3 viewDir : TEXCOORD2; + UNITY_FOG_COORDS(3) +}; + +v2f vert(appdata v) +{ + v2f o; + float4 s; + + o.pos = UnityObjectToClipPos(v.vertex); + + // scroll bump waves + float4 temp; + float4 wpos = mul (unity_ObjectToWorld, v.vertex); + temp.xyzw = wpos.xzxz * _WaveScale + _WaveOffset; + o.bumpuv[0] = temp.xy * float2(.4, .45); + o.bumpuv[1] = temp.wz; + + // object space view direction + o.viewDir.xzy = normalize( WorldSpaceViewDir(v.vertex) ); + + UNITY_TRANSFER_FOG(o,o.pos); + return o; +} + +ENDCG + + +Subshader { + Tags { "RenderType"="Opaque" } + Pass { + +CGPROGRAM +#pragma vertex vert +#pragma fragment frag +#pragma multi_compile_fog + +sampler2D _BumpMap; +sampler2D _ColorControl; + +half4 frag( v2f i ) : COLOR +{ + half3 bump1 = UnpackNormal(tex2D( _BumpMap, i.bumpuv[0] )).rgb; + half3 bump2 = UnpackNormal(tex2D( _BumpMap, i.bumpuv[1] )).rgb; + half3 bump = (bump1 + bump2) * 0.5; + + half fresnel = dot( i.viewDir, bump ); + half4 water = tex2D( _ColorControl, float2(fresnel,fresnel) ); + + half4 col; + col.rgb = lerp( water.rgb, _horizonColor.rgb, water.a ); + col.a = _horizonColor.a; + + UNITY_APPLY_FOG(i.fogCoord, col); + return col; +} +ENDCG + } +} + +} diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Shaders/FXWaterBasic.shader.meta b/Assets/Standard Assets/Environment/Water (Basic)/Shaders/FXWaterBasic.shader.meta new file mode 100644 index 00000000..99b59b90 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Shaders/FXWaterBasic.shader.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 9dccc8e8f0da4494991c26ef59019551 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Textures.meta b/Assets/Standard Assets/Environment/Water (Basic)/Textures.meta new file mode 100644 index 00000000..18d2ee91 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Textures.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 33850b67ffcaa4b6c9a7146e4be0b917 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicDaytimeGradient.psd b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicDaytimeGradient.psd new file mode 100644 index 00000000..afed36b5 Binary files /dev/null and b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicDaytimeGradient.psd differ diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicDaytimeGradient.psd.meta b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicDaytimeGradient.psd.meta new file mode 100644 index 00000000..de311855 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicDaytimeGradient.psd.meta @@ -0,0 +1,52 @@ +fileFormatVersion: 2 +guid: 047330f39d11745ad0004adb8d76c639 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 2 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .100000001 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 32 + textureSettings: + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 0 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNighttimeGradient.psd b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNighttimeGradient.psd new file mode 100644 index 00000000..d853a2bc Binary files /dev/null and b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNighttimeGradient.psd differ diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNighttimeGradient.psd.meta b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNighttimeGradient.psd.meta new file mode 100644 index 00000000..e6a5ac2d --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNighttimeGradient.psd.meta @@ -0,0 +1,52 @@ +fileFormatVersion: 2 +guid: 8403d3349d112ba4d000be1be39e7c39 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 2 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .100000001 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 32 + textureSettings: + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 0 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNormals.jpg b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNormals.jpg new file mode 100644 index 00000000..9cbd3dec Binary files /dev/null and b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNormals.jpg differ diff --git a/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNormals.jpg.meta b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNormals.jpg.meta new file mode 100644 index 00000000..5551f25d --- /dev/null +++ b/Assets/Standard Assets/Environment/Water (Basic)/Textures/WaterBasicNormals.jpg.meta @@ -0,0 +1,68 @@ +fileFormatVersion: 2 +guid: a53cf5449d11a15d1100a04b44295342 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 2 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 1 + externalNormalMap: 1 + heightScale: .0164516103 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 512 + textureSettings: + filterMode: 2 + aniso: 1 + mipBias: 0 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 1 + buildTargetSettings: + - buildTarget: iPhone + maxTextureSize: 256 + textureFormat: -1 + compressionQuality: 50 + - buildTarget: Android + maxTextureSize: 256 + textureFormat: -1 + compressionQuality: 50 + - buildTarget: BlackBerry + maxTextureSize: 256 + textureFormat: -1 + compressionQuality: 50 + - buildTarget: WP8 + maxTextureSize: 256 + textureFormat: -1 + compressionQuality: 50 + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water.meta b/Assets/Standard Assets/Environment/Water.meta new file mode 100644 index 00000000..00efa6af --- /dev/null +++ b/Assets/Standard Assets/Environment/Water.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 4f65f58f1750429468db4bef75317815 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water.meta b/Assets/Standard Assets/Environment/Water/Water.meta new file mode 100644 index 00000000..d8d45c08 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: e2e84b28786ce854391d79fb76df820b +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Materials.meta b/Assets/Standard Assets/Environment/Water/Water/Materials.meta new file mode 100644 index 00000000..e56ac81c --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Materials.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 8269a010592f549af8f11b1683d9e794 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Materials/WaterPlaneMaterial.mat b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterPlaneMaterial.mat new file mode 100644 index 00000000..cb5e8d21 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterPlaneMaterial.mat @@ -0,0 +1,154 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: WaterPlaneMaterial + m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + - _LIGHTMAPPING_STATIC_LIGHTMAPS + - _UVSEC_UV1 + m_CustomRenderQueue: -1 + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + data: + first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _Occlusion + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _SpecGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _Lightmapping + second: 0 + data: + first: + name: _SrcBlend + second: 1 + data: + first: + name: _DstBlend + second: 0 + data: + first: + name: _Parallax + second: .0199999996 + data: + first: + name: _ZWrite + second: 1 + data: + first: + name: _AlphaTestRef + second: .5 + data: + first: + name: _Glossiness + second: 0 + data: + first: + name: _BumpScale + second: 1 + data: + first: + name: _OcclusionStrength + second: 1 + data: + first: + name: _DetailNormalMapScale + second: 1 + data: + first: + name: _UVSec + second: 0 + data: + first: + name: _Mode + second: 0 + data: + first: + name: _EmissionScaleUI + second: 1 + m_Colors: + data: + first: + name: _Color + second: {r: .5, g: .5, b: .5, a: 1} + data: + first: + name: _EmissionColor + second: {r: 0, g: 0, b: 0, a: 1} + data: + first: + name: _SpecularColor + second: {r: .200000003, g: .200000003, b: .200000003, a: 1} + data: + first: + name: _EmissionColorUI + second: {r: 0, g: 0, b: 0, a: 1} + data: + first: + name: _EmissionColorWithMapUI + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/Standard Assets/Environment/Water/Water/Materials/WaterPlaneMaterial.mat.meta b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterPlaneMaterial.mat.meta new file mode 100644 index 00000000..93cb3570 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterPlaneMaterial.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: f1bc741ea0e69a241896582ddb633d55 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProDaytime.mat b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProDaytime.mat new file mode 100644 index 00000000..81d118dd --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProDaytime.mat @@ -0,0 +1,66 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: WaterProDaytime + m_Shader: {fileID: 4800000, guid: 1cac2e0bcc34e4b3cbb4bd85982eba83, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 2800000, guid: 2dd3788f8589b40bf82a92d76ffc5091, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Fresnel: + m_Texture: {fileID: 2800000, guid: 5b5c5575fd4c74abd9f7b30862fb76a3, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: e6f8288974c664a309d6c66de636978c, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectiveColor: + m_Texture: {fileID: 2800000, guid: ab97f9ab7c2ce724ebc9446060a819a4, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectiveColorCube: + m_Texture: {fileID: 8900000, guid: 9cda328e4b6954d70841a8a66f42ec08, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RefractionTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _ReflDistort: 0.44 + - _RefrDistort: 0.4 + - _WaveScale: 0.118 + m_Colors: + - WaveSpeed: {r: 9, g: 4.5, b: -8, a: -3.5} + - _BumpMap_ST: {r: 1, g: 1, b: 0, a: 0} + - _Fresnel_ST: {r: 1, g: 1, b: 0, a: 0} + - _HorizonColor: {r: 0.13575952, g: 0.22810712, b: 0.3810788, a: 0} + - _MainTex_ST: {r: 1, g: 1, b: 0, a: 0} + - _ReflectionTex_ST: {r: 1, g: 1, b: 0, a: 0} + - _ReflectiveColorCube_ST: {r: 1, g: 1, b: 0, a: 0} + - _ReflectiveColor_ST: {r: 1, g: 1, b: 0, a: 0} + - _RefrColor: {r: 0.9372549, g: 0.9372549, b: 0.9372549, a: 1} + - _RefractionTex_ST: {r: 1, g: 1, b: 0, a: 0} +--- !u!1002 &2100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProDaytime.mat.meta b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProDaytime.mat.meta new file mode 100644 index 00000000..b05600fe --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProDaytime.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 7350b65a6431f604a8496c39db1ac9c5 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProNighttime.mat b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProNighttime.mat new file mode 100644 index 00000000..397e9017 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProNighttime.mat @@ -0,0 +1,125 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: WaterProNighttime + m_Shader: {fileID: 4800000, guid: 1cac2e0bcc34e4b3cbb4bd85982eba83, type: 3} + m_ShaderKeywords: [] + m_CustomRenderQueue: -1 + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + data: + first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: e6f8288974c664a309d6c66de636978c, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: 2dd3788f8589b40bf82a92d76ffc5091, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _Fresnel + second: + m_Texture: {fileID: 2800000, guid: 5b5c5575fd4c74abd9f7b30862fb76a3, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ReflectiveColor + second: + m_Texture: {fileID: 2800000, guid: b725b62cfc9d04e4886735ab2a8107d1, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ReflectionTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _RefractionTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ReflectiveColorCube + second: + m_Texture: {fileID: 8900000, guid: 15c6acc4f11254a04b03849245d80574, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _WaveScale + second: .063000001 + data: + first: + name: _ReflDistort + second: .439999998 + data: + first: + name: _RefrDistort + second: .400000006 + m_Colors: + data: + first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + data: + first: + name: _RefrColor + second: {r: 1, g: 1, b: 1, a: 1} + data: + first: + name: _Fresnel_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _BumpMap_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: WaveSpeed + second: {r: 9, g: 4.5, b: -8, a: -3.5} + data: + first: + name: _ReflectiveColor_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _HorizonColor + second: {r: .149019614, g: .282352954, b: .380392164, a: 0} + data: + first: + name: _ReflectionTex_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _RefractionTex_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _MainTex_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _ReflectiveColorCube_ST + second: {r: 1, g: 1, b: 0, a: 0} +--- !u!1002 &2100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProNighttime.mat.meta b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProNighttime.mat.meta new file mode 100644 index 00000000..295eaaa2 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Materials/WaterProNighttime.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: e633a20421c47426aa04444234225b69 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Models.meta b/Assets/Standard Assets/Environment/Water/Water/Models.meta new file mode 100644 index 00000000..ae0f659d --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Models.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: fe5d00245bc1d42a7927f4b2879026b8 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Models/WaterPlane.fbx b/Assets/Standard Assets/Environment/Water/Water/Models/WaterPlane.fbx new file mode 100644 index 00000000..fafb032e Binary files /dev/null and b/Assets/Standard Assets/Environment/Water/Water/Models/WaterPlane.fbx differ diff --git a/Assets/Standard Assets/Environment/Water/Water/Models/WaterPlane.fbx.meta b/Assets/Standard Assets/Environment/Water/Water/Models/WaterPlane.fbx.meta new file mode 100644 index 00000000..bb50109f --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Models/WaterPlane.fbx.meta @@ -0,0 +1,71 @@ +fileFormatVersion: 2 +guid: ba6a41dc489914734857bb5924eb70ad +ModelImporter: + serializedVersion: 18 + fileIDToRecycleName: + 100000: //RootNode + 400000: //RootNode + 2300000: //RootNode + 3300000: //RootNode + 4300000: pPlane1 + 4300002: nurbsToPoly1 + 4300004: pCylinder1 + 4300006: waterPlaneMesh + 11100000: //RootNode + materials: + importMaterials: 1 + materialName: 1 + materialSearch: 1 + animations: + legacyGenerateAnimations: 0 + bakeSimulation: 0 + optimizeGameObjects: 0 + motionNodeName: + pivotNodeName: + animationCompression: 1 + animationRotationError: .5 + animationPositionError: .5 + animationScaleError: .5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + importBlendShapes: 1 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 0 + optimizeMeshForGPU: 1 + weldVertices: 1 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 0 + tangentSpace: + normalSmoothAngle: 60 + splitTangentsAcrossUV: 0 + normalImportMode: 0 + tangentImportMode: 1 + importAnimation: 1 + copyAvatar: 0 + humanDescription: + human: [] + skeleton: [] + armTwist: .5 + foreArmTwist: .5 + upperLegTwist: .5 + legTwist: .5 + armStretch: .0500000007 + legStretch: .0500000007 + feetSpacing: 0 + rootMotionBoneName: + lastHumanDescriptionAvatarSource: {instanceID: 0} + animationType: 1 + additionalBone: 1 + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Prefabs.meta b/Assets/Standard Assets/Environment/Water/Water/Prefabs.meta new file mode 100644 index 00000000..78e202d8 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Prefabs.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 2dc67c8fe799ae845add403087340bd1 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProDaytime.prefab b/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProDaytime.prefab new file mode 100644 index 00000000..85016f8f --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProDaytime.prefab @@ -0,0 +1,114 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &100000 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400000} + - 33: {fileID: 3300000} + - 23: {fileID: 2300000} + - 114: {fileID: 11400000} + m_Layer: 4 + m_Name: WaterProDaytime + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400000 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 16, y: 1, z: 16} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!1002 &400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300000 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 255 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: 7350b65a6431f604a8496c39db1ac9c5, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300000 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Mesh: {fileID: 4300006, guid: ba6a41dc489914734857bb5924eb70ad, type: 3} +--- !u!1002 &3300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a3d3ef1a5bbfb4e0a910fbbe5830b1f9, type: 3} + m_Name: + m_EditorClassIdentifier: + m_WaterMode: 2 + m_DisablePixelLights: 1 + m_TextureSize: 256 + m_ClipPlaneOffset: .0700000003 + m_ReflectLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_RefractLayers: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!1002 &11400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 100000} + m_IsPrefabParent: 1 +--- !u!1002 &100100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProDaytime.prefab.meta b/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProDaytime.prefab.meta new file mode 100644 index 00000000..70f211a9 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProDaytime.prefab.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 780611a67e8e941a2b3aa96e5915a793 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProNighttime.prefab b/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProNighttime.prefab new file mode 100644 index 00000000..2cac43e4 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProNighttime.prefab @@ -0,0 +1,114 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &100000 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400000} + - 33: {fileID: 3300000} + - 23: {fileID: 2300000} + - 114: {fileID: 11400000} + m_Layer: 4 + m_Name: WaterProNighttime + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400000 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 16, y: 1, z: 16} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!1002 &400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300000 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 255 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: e633a20421c47426aa04444234225b69, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300000 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Mesh: {fileID: 4300006, guid: ba6a41dc489914734857bb5924eb70ad, type: 3} +--- !u!1002 &3300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a3d3ef1a5bbfb4e0a910fbbe5830b1f9, type: 3} + m_Name: + m_EditorClassIdentifier: + m_WaterMode: 2 + m_DisablePixelLights: 1 + m_TextureSize: 256 + m_ClipPlaneOffset: .0700000003 + m_ReflectLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_RefractLayers: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!1002 &11400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 100000} + m_IsPrefabParent: 1 +--- !u!1002 &100100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProNighttime.prefab.meta b/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProNighttime.prefab.meta new file mode 100644 index 00000000..a59e814b --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Prefabs/WaterProNighttime.prefab.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: bcae914220acd4907840a029bb9d9aec +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts.meta new file mode 100644 index 00000000..a3b7325c --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: b5b8c0f9acc2944f086c02cb83f4ae76 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/Displace.cs b/Assets/Standard Assets/Environment/Water/Water/Scripts/Displace.cs new file mode 100644 index 00000000..5e4ccf85 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/Displace.cs @@ -0,0 +1,33 @@ +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + [ExecuteInEditMode] + [RequireComponent(typeof(WaterBase))] + public class Displace : MonoBehaviour + { + public void Awake() + { + if (enabled) + { + OnEnable(); + } + else + { + OnDisable(); + } + } + + public void OnEnable() + { + Shader.EnableKeyword("WATER_VERTEX_DISPLACEMENT_ON"); + Shader.DisableKeyword("WATER_VERTEX_DISPLACEMENT_OFF"); + } + + public void OnDisable() + { + Shader.EnableKeyword("WATER_VERTEX_DISPLACEMENT_OFF"); + Shader.DisableKeyword("WATER_VERTEX_DISPLACEMENT_ON"); + } + } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/Displace.cs.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts/Displace.cs.meta new file mode 100644 index 00000000..2eaaef37 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/Displace.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c62b7d87755b447919138e67f8e22e0c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/GerstnerDisplace.cs b/Assets/Standard Assets/Environment/Water/Water/Scripts/GerstnerDisplace.cs new file mode 100644 index 00000000..b07eb5c4 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/GerstnerDisplace.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + [ExecuteInEditMode] + [RequireComponent(typeof(WaterBase))] + public class GerstnerDisplace : Displace { } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/GerstnerDisplace.cs.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts/GerstnerDisplace.cs.meta new file mode 100644 index 00000000..dbaa174a --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/GerstnerDisplace.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 42e7f46d0e5a84171a3909479c1646ba +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/MeshContainer.cs b/Assets/Standard Assets/Environment/Water/Water/Scripts/MeshContainer.cs new file mode 100644 index 00000000..58b50184 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/MeshContainer.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + public class MeshContainer + { + public Mesh mesh; + public Vector3[] vertices; + public Vector3[] normals; + + public MeshContainer(Mesh m) + { + mesh = m; + vertices = m.vertices; + normals = m.normals; + } + + public void Update() + { + mesh.vertices = vertices; + mesh.normals = normals; + } + } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/MeshContainer.cs.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts/MeshContainer.cs.meta new file mode 100644 index 00000000..9a16e3e8 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/MeshContainer.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 951d74f7d57bed84cb623c62436bd064 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/PlanarReflection.cs b/Assets/Standard Assets/Environment/Water/Water/Scripts/PlanarReflection.cs new file mode 100644 index 00000000..d7fdc5e2 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/PlanarReflection.cs @@ -0,0 +1,268 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + [ExecuteInEditMode] + [RequireComponent(typeof(WaterBase))] + public class PlanarReflection : MonoBehaviour + { + public LayerMask reflectionMask; + public bool reflectSkybox = false; + public Color clearColor = Color.grey; + public String reflectionSampler = "_ReflectionTex"; + public float clipPlaneOffset = 0.07F; + + private Vector3 m_Oldpos; + private Camera m_ReflectionCamera; + private Material m_SharedMaterial; + private Dictionary m_HelperCameras; + + public void Start() + { + m_SharedMaterial = ((WaterBase)gameObject.GetComponent(typeof(WaterBase))).sharedMaterial; + } + + private Camera CreateReflectionCameraFor(Camera cam) + { + String reflName = gameObject.name + "Reflection" + cam.name; + GameObject go = GameObject.Find(reflName); + + if (!go) + { + go = new GameObject(reflName, typeof(Camera)); + } + if (!go.GetComponent(typeof(Camera))) + { + go.AddComponent(typeof(Camera)); + } + Camera reflectCamera = go.GetComponent(); + + reflectCamera.backgroundColor = clearColor; + reflectCamera.clearFlags = reflectSkybox ? CameraClearFlags.Skybox : CameraClearFlags.SolidColor; + + SetStandardCameraParameter(reflectCamera, reflectionMask); + + if (!reflectCamera.targetTexture) + { + reflectCamera.targetTexture = CreateTextureFor(cam); + } + + return reflectCamera; + } + + private void SetStandardCameraParameter(Camera cam, LayerMask mask) + { + cam.cullingMask = mask & ~(1 << LayerMask.NameToLayer("Water")); + cam.backgroundColor = Color.black; + cam.enabled = false; + } + + private RenderTexture CreateTextureFor(Camera cam) + { + RenderTexture rt = new RenderTexture(Mathf.FloorToInt(cam.pixelWidth * 0.5F), + Mathf.FloorToInt(cam.pixelHeight * 0.5F), 24); + rt.hideFlags = HideFlags.DontSave; + return rt; + } + + public void RenderHelpCameras(Camera currentCam) + { + if (null == m_HelperCameras) + { + m_HelperCameras = new Dictionary(); + } + + if (!m_HelperCameras.ContainsKey(currentCam)) + { + m_HelperCameras.Add(currentCam, false); + } + if (m_HelperCameras[currentCam]) + { + return; + } + + if (!m_ReflectionCamera) + { + m_ReflectionCamera = CreateReflectionCameraFor(currentCam); + } + + RenderReflectionFor(currentCam, m_ReflectionCamera); + + m_HelperCameras[currentCam] = true; + } + + public void LateUpdate() + { + if (null != m_HelperCameras) + { + m_HelperCameras.Clear(); + } + } + + public void WaterTileBeingRendered(Transform tr, Camera currentCam) + { + RenderHelpCameras(currentCam); + + if (m_ReflectionCamera && m_SharedMaterial) + { + m_SharedMaterial.SetTexture(reflectionSampler, m_ReflectionCamera.targetTexture); + } + } + + public void OnEnable() + { + Shader.EnableKeyword("WATER_REFLECTIVE"); + Shader.DisableKeyword("WATER_SIMPLE"); + } + + public void OnDisable() + { + Shader.EnableKeyword("WATER_SIMPLE"); + Shader.DisableKeyword("WATER_REFLECTIVE"); + } + + private void RenderReflectionFor(Camera cam, Camera reflectCamera) + { + if (!reflectCamera) + { + return; + } + + if (m_SharedMaterial && !m_SharedMaterial.HasProperty(reflectionSampler)) + { + return; + } + + reflectCamera.cullingMask = reflectionMask & ~(1 << LayerMask.NameToLayer("Water")); + + SaneCameraSettings(reflectCamera); + + reflectCamera.backgroundColor = clearColor; + reflectCamera.clearFlags = reflectSkybox ? CameraClearFlags.Skybox : CameraClearFlags.SolidColor; + if (reflectSkybox) + { + if (cam.gameObject.GetComponent(typeof(Skybox))) + { + Skybox sb = (Skybox)reflectCamera.gameObject.GetComponent(typeof(Skybox)); + if (!sb) + { + sb = (Skybox)reflectCamera.gameObject.AddComponent(typeof(Skybox)); + } + sb.material = ((Skybox)cam.GetComponent(typeof(Skybox))).material; + } + } + + GL.invertCulling = true; + + Transform reflectiveSurface = transform; //waterHeight; + + Vector3 eulerA = cam.transform.eulerAngles; + + reflectCamera.transform.eulerAngles = new Vector3(-eulerA.x, eulerA.y, eulerA.z); + reflectCamera.transform.position = cam.transform.position; + + Vector3 pos = reflectiveSurface.transform.position; + pos.y = reflectiveSurface.position.y; + Vector3 normal = reflectiveSurface.transform.up; + float d = -Vector3.Dot(normal, pos) - clipPlaneOffset; + Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); + + Matrix4x4 reflection = Matrix4x4.zero; + reflection = CalculateReflectionMatrix(reflection, reflectionPlane); + m_Oldpos = cam.transform.position; + Vector3 newpos = reflection.MultiplyPoint(m_Oldpos); + + reflectCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection; + + Vector4 clipPlane = CameraSpacePlane(reflectCamera, pos, normal, 1.0f); + + Matrix4x4 projection = cam.projectionMatrix; + projection = CalculateObliqueMatrix(projection, clipPlane); + reflectCamera.projectionMatrix = projection; + + reflectCamera.transform.position = newpos; + Vector3 euler = cam.transform.eulerAngles; + reflectCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); + + reflectCamera.Render(); + + GL.invertCulling = false; + } + + private void SaneCameraSettings(Camera helperCam) + { + helperCam.depthTextureMode = DepthTextureMode.None; + helperCam.backgroundColor = Color.black; + helperCam.clearFlags = CameraClearFlags.SolidColor; + helperCam.renderingPath = RenderingPath.Forward; + } + + private static Matrix4x4 CalculateObliqueMatrix(Matrix4x4 projection, Vector4 clipPlane) + { + Vector4 q = projection.inverse * new Vector4( + Sgn(clipPlane.x), + Sgn(clipPlane.y), + 1.0F, + 1.0F + ); + Vector4 c = clipPlane * (2.0F / (Vector4.Dot(clipPlane, q))); + // third row = clip plane - fourth row + projection[2] = c.x - projection[3]; + projection[6] = c.y - projection[7]; + projection[10] = c.z - projection[11]; + projection[14] = c.w - projection[15]; + + return projection; + } + + private static Matrix4x4 CalculateReflectionMatrix(Matrix4x4 reflectionMat, Vector4 plane) + { + reflectionMat.m00 = (1.0F - 2.0F * plane[0] * plane[0]); + reflectionMat.m01 = (-2.0F * plane[0] * plane[1]); + reflectionMat.m02 = (-2.0F * plane[0] * plane[2]); + reflectionMat.m03 = (-2.0F * plane[3] * plane[0]); + + reflectionMat.m10 = (-2.0F * plane[1] * plane[0]); + reflectionMat.m11 = (1.0F - 2.0F * plane[1] * plane[1]); + reflectionMat.m12 = (-2.0F * plane[1] * plane[2]); + reflectionMat.m13 = (-2.0F * plane[3] * plane[1]); + + reflectionMat.m20 = (-2.0F * plane[2] * plane[0]); + reflectionMat.m21 = (-2.0F * plane[2] * plane[1]); + reflectionMat.m22 = (1.0F - 2.0F * plane[2] * plane[2]); + reflectionMat.m23 = (-2.0F * plane[3] * plane[2]); + + reflectionMat.m30 = 0.0F; + reflectionMat.m31 = 0.0F; + reflectionMat.m32 = 0.0F; + reflectionMat.m33 = 1.0F; + + return reflectionMat; + } + + private static float Sgn(float a) + { + if (a > 0.0F) + { + return 1.0F; + } + if (a < 0.0F) + { + return -1.0F; + } + return 0.0F; + } + + private Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign) + { + Vector3 offsetPos = pos + normal * clipPlaneOffset; + Matrix4x4 m = cam.worldToCameraMatrix; + Vector3 cpos = m.MultiplyPoint(offsetPos); + Vector3 cnormal = m.MultiplyVector(normal).normalized * sideSign; + + return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal)); + } + } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/PlanarReflection.cs.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts/PlanarReflection.cs.meta new file mode 100644 index 00000000..f1b5a126 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/PlanarReflection.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4185bc77c7194462ca3b1097ef4a5de0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/SpecularLighting.cs b/Assets/Standard Assets/Environment/Water/Water/Scripts/SpecularLighting.cs new file mode 100644 index 00000000..64a0b834 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/SpecularLighting.cs @@ -0,0 +1,30 @@ +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + [RequireComponent(typeof(WaterBase))] + [ExecuteInEditMode] + public class SpecularLighting : MonoBehaviour + { + public Transform specularLight; + private WaterBase m_WaterBase; + + public void Start() + { + m_WaterBase = (WaterBase)gameObject.GetComponent(typeof(WaterBase)); + } + + public void Update() + { + if (!m_WaterBase) + { + m_WaterBase = (WaterBase)gameObject.GetComponent(typeof(WaterBase)); + } + + if (specularLight && m_WaterBase.sharedMaterial) + { + m_WaterBase.sharedMaterial.SetVector("_WorldLightDir", specularLight.transform.forward); + } + } + } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/SpecularLighting.cs.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts/SpecularLighting.cs.meta new file mode 100644 index 00000000..4db1a365 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/SpecularLighting.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: de2ab2b9ac93bb544b9552e49030371b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/Water.cs b/Assets/Standard Assets/Environment/Water/Water/Scripts/Water.cs new file mode 100644 index 00000000..9d4ab776 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/Water.cs @@ -0,0 +1,399 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + [ExecuteInEditMode] // Make water live-update even when not in play mode + public class Water : MonoBehaviour + { + public enum WaterMode + { + Simple = 0, + Reflective = 1, + Refractive = 2, + }; + + public WaterMode waterMode = WaterMode.Refractive; + public bool disablePixelLights = true; + public int textureSize = 256; + public float clipPlaneOffset = 0.07f; + public LayerMask reflectLayers = -1; + public LayerMask refractLayers = -1; + + private Dictionary m_ReflectionCameras = new Dictionary(); // Camera -> Camera table + private Dictionary m_RefractionCameras = new Dictionary(); // Camera -> Camera table + private RenderTexture m_ReflectionTexture; + private RenderTexture m_RefractionTexture; + private WaterMode m_HardwareWaterSupport = WaterMode.Refractive; + private int m_OldReflectionTextureSize; + private int m_OldRefractionTextureSize; + private static bool s_InsideWater; + + // This is called when it's known that the object will be rendered by some + // camera. We render reflections / refractions and do other updates here. + // Because the script executes in edit mode, reflections for the scene view + // camera will just work! + public void OnWillRenderObject() + { + if (!enabled || !GetComponent() || !GetComponent().sharedMaterial || + !GetComponent().enabled) + { + return; + } + + Camera cam = Camera.current; + if (!cam) + { + return; + } + + // Safeguard from recursive water reflections. + if (s_InsideWater) + { + return; + } + s_InsideWater = true; + + // Actual water rendering mode depends on both the current setting AND + // the hardware support. There's no point in rendering refraction textures + // if they won't be visible in the end. + m_HardwareWaterSupport = FindHardwareWaterSupport(); + WaterMode mode = GetWaterMode(); + + Camera reflectionCamera, refractionCamera; + CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); + + // find out the reflection plane: position and normal in world space + Vector3 pos = transform.position; + Vector3 normal = transform.up; + + // Optionally disable pixel lights for reflection/refraction + int oldPixelLightCount = QualitySettings.pixelLightCount; + if (disablePixelLights) + { + QualitySettings.pixelLightCount = 0; + } + + UpdateCameraModes(cam, reflectionCamera); + UpdateCameraModes(cam, refractionCamera); + + // Render reflection if needed + if (mode >= WaterMode.Reflective) + { + // Reflect camera around reflection plane + float d = -Vector3.Dot(normal, pos) - clipPlaneOffset; + Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); + + Matrix4x4 reflection = Matrix4x4.zero; + CalculateReflectionMatrix(ref reflection, reflectionPlane); + Vector3 oldpos = cam.transform.position; + Vector3 newpos = reflection.MultiplyPoint(oldpos); + reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection; + + // Setup oblique projection matrix so that near plane is our reflection + // plane. This way we clip everything below/above it for free. + Vector4 clipPlane = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); + reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); + + // Set custom culling matrix from the current camera + reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; + + reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer + reflectionCamera.targetTexture = m_ReflectionTexture; + bool oldCulling = GL.invertCulling; + GL.invertCulling = !oldCulling; + reflectionCamera.transform.position = newpos; + Vector3 euler = cam.transform.eulerAngles; + reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); + reflectionCamera.Render(); + reflectionCamera.transform.position = oldpos; + GL.invertCulling = oldCulling; + GetComponent().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); + } + + // Render refraction + if (mode >= WaterMode.Refractive) + { + refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; + + // Setup oblique projection matrix so that near plane is our reflection + // plane. This way we clip everything below/above it for free. + Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); + refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); + + // Set custom culling matrix from the current camera + refractionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; + + refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer + refractionCamera.targetTexture = m_RefractionTexture; + refractionCamera.transform.position = cam.transform.position; + refractionCamera.transform.rotation = cam.transform.rotation; + refractionCamera.Render(); + GetComponent().sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); + } + + // Restore pixel light count + if (disablePixelLights) + { + QualitySettings.pixelLightCount = oldPixelLightCount; + } + + // Setup shader keywords based on water mode + switch (mode) + { + case WaterMode.Simple: + Shader.EnableKeyword("WATER_SIMPLE"); + Shader.DisableKeyword("WATER_REFLECTIVE"); + Shader.DisableKeyword("WATER_REFRACTIVE"); + break; + + case WaterMode.Reflective: + Shader.DisableKeyword("WATER_SIMPLE"); + Shader.EnableKeyword("WATER_REFLECTIVE"); + Shader.DisableKeyword("WATER_REFRACTIVE"); + break; + + case WaterMode.Refractive: + Shader.DisableKeyword("WATER_SIMPLE"); + Shader.DisableKeyword("WATER_REFLECTIVE"); + Shader.EnableKeyword("WATER_REFRACTIVE"); + break; + } + + s_InsideWater = false; + } + + // Cleanup all the objects we possibly have created + private void OnDisable() + { + if (m_ReflectionTexture) + { + DestroyImmediate(m_ReflectionTexture); + m_ReflectionTexture = null; + } + if (m_RefractionTexture) + { + DestroyImmediate(m_RefractionTexture); + m_RefractionTexture = null; + } + foreach (var kvp in m_ReflectionCameras) + { + DestroyImmediate((kvp.Value).gameObject); + } + m_ReflectionCameras.Clear(); + foreach (var kvp in m_RefractionCameras) + { + DestroyImmediate((kvp.Value).gameObject); + } + m_RefractionCameras.Clear(); + } + + // This just sets up some matrices in the material; for really + // old cards to make water texture scroll. + private void Update() + { + if (!GetComponent()) + { + return; + } + Material mat = GetComponent().sharedMaterial; + if (!mat) + { + return; + } + + Vector4 waveSpeed = mat.GetVector("WaveSpeed"); + float waveScale = mat.GetFloat("_WaveScale"); + Vector4 waveScale4 = new Vector4(waveScale, waveScale, waveScale * 0.4f, waveScale * 0.45f); + + // Time since level load, and do intermediate calculations with doubles + double t = Time.timeSinceLevelLoad / 20.0; + Vector4 offsetClamped = new Vector4( + (float)Math.IEEERemainder(waveSpeed.x * waveScale4.x * t, 1.0), + (float)Math.IEEERemainder(waveSpeed.y * waveScale4.y * t, 1.0), + (float)Math.IEEERemainder(waveSpeed.z * waveScale4.z * t, 1.0), + (float)Math.IEEERemainder(waveSpeed.w * waveScale4.w * t, 1.0) + ); + + mat.SetVector("_WaveOffset", offsetClamped); + mat.SetVector("_WaveScale4", waveScale4); + } + + private void UpdateCameraModes(Camera src, Camera dest) + { + if (dest == null) + { + return; + } + // set water camera to clear the same way as current camera + dest.clearFlags = src.clearFlags; + dest.backgroundColor = src.backgroundColor; + if (src.clearFlags == CameraClearFlags.Skybox) + { + Skybox sky = src.GetComponent(); + Skybox mysky = dest.GetComponent(); + if (!sky || !sky.material) + { + mysky.enabled = false; + } + else + { + mysky.enabled = true; + mysky.material = sky.material; + } + } + // update other values to match current camera. + // even if we are supplying custom camera&projection matrices, + // some of values are used elsewhere (e.g. skybox uses far plane) + dest.farClipPlane = src.farClipPlane; + dest.nearClipPlane = src.nearClipPlane; + dest.orthographic = src.orthographic; + dest.fieldOfView = src.fieldOfView; + dest.aspect = src.aspect; + dest.orthographicSize = src.orthographicSize; + } + + // On-demand create any objects we need for water + private void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera) + { + WaterMode mode = GetWaterMode(); + + reflectionCamera = null; + refractionCamera = null; + + if (mode >= WaterMode.Reflective) + { + // Reflection render texture + if (!m_ReflectionTexture || m_OldReflectionTextureSize != textureSize) + { + if (m_ReflectionTexture) + { + DestroyImmediate(m_ReflectionTexture); + } + m_ReflectionTexture = new RenderTexture(textureSize, textureSize, 16); + m_ReflectionTexture.name = "__WaterReflection" + GetInstanceID(); + m_ReflectionTexture.isPowerOfTwo = true; + m_ReflectionTexture.hideFlags = HideFlags.DontSave; + m_OldReflectionTextureSize = textureSize; + } + + // Camera for reflection + m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera); + if (!reflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO + { + GameObject go = new GameObject("Water Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); + reflectionCamera = go.GetComponent(); + reflectionCamera.enabled = false; + reflectionCamera.transform.position = transform.position; + reflectionCamera.transform.rotation = transform.rotation; + reflectionCamera.gameObject.AddComponent(); + go.hideFlags = HideFlags.HideAndDontSave; + m_ReflectionCameras[currentCamera] = reflectionCamera; + } + } + + if (mode >= WaterMode.Refractive) + { + // Refraction render texture + if (!m_RefractionTexture || m_OldRefractionTextureSize != textureSize) + { + if (m_RefractionTexture) + { + DestroyImmediate(m_RefractionTexture); + } + m_RefractionTexture = new RenderTexture(textureSize, textureSize, 16); + m_RefractionTexture.name = "__WaterRefraction" + GetInstanceID(); + m_RefractionTexture.isPowerOfTwo = true; + m_RefractionTexture.hideFlags = HideFlags.DontSave; + m_OldRefractionTextureSize = textureSize; + } + + // Camera for refraction + m_RefractionCameras.TryGetValue(currentCamera, out refractionCamera); + if (!refractionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO + { + GameObject go = + new GameObject("Water Refr Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), + typeof(Camera), typeof(Skybox)); + refractionCamera = go.GetComponent(); + refractionCamera.enabled = false; + refractionCamera.transform.position = transform.position; + refractionCamera.transform.rotation = transform.rotation; + refractionCamera.gameObject.AddComponent(); + go.hideFlags = HideFlags.HideAndDontSave; + m_RefractionCameras[currentCamera] = refractionCamera; + } + } + } + + private WaterMode GetWaterMode() + { + if (m_HardwareWaterSupport < waterMode) + { + return m_HardwareWaterSupport; + } + return waterMode; + } + + private WaterMode FindHardwareWaterSupport() + { + if (!GetComponent()) + { + return WaterMode.Simple; + } + + Material mat = GetComponent().sharedMaterial; + if (!mat) + { + return WaterMode.Simple; + } + + string mode = mat.GetTag("WATERMODE", false); + if (mode == "Refractive") + { + return WaterMode.Refractive; + } + if (mode == "Reflective") + { + return WaterMode.Reflective; + } + + return WaterMode.Simple; + } + + // Given position/normal of the plane, calculates plane in camera space. + private Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign) + { + Vector3 offsetPos = pos + normal * clipPlaneOffset; + Matrix4x4 m = cam.worldToCameraMatrix; + Vector3 cpos = m.MultiplyPoint(offsetPos); + Vector3 cnormal = m.MultiplyVector(normal).normalized * sideSign; + return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal)); + } + + // Calculates reflection matrix around the given plane + private static void CalculateReflectionMatrix(ref Matrix4x4 reflectionMat, Vector4 plane) + { + reflectionMat.m00 = (1F - 2F * plane[0] * plane[0]); + reflectionMat.m01 = (-2F * plane[0] * plane[1]); + reflectionMat.m02 = (-2F * plane[0] * plane[2]); + reflectionMat.m03 = (-2F * plane[3] * plane[0]); + + reflectionMat.m10 = (-2F * plane[1] * plane[0]); + reflectionMat.m11 = (1F - 2F * plane[1] * plane[1]); + reflectionMat.m12 = (-2F * plane[1] * plane[2]); + reflectionMat.m13 = (-2F * plane[3] * plane[1]); + + reflectionMat.m20 = (-2F * plane[2] * plane[0]); + reflectionMat.m21 = (-2F * plane[2] * plane[1]); + reflectionMat.m22 = (1F - 2F * plane[2] * plane[2]); + reflectionMat.m23 = (-2F * plane[3] * plane[2]); + + reflectionMat.m30 = 0F; + reflectionMat.m31 = 0F; + reflectionMat.m32 = 0F; + reflectionMat.m33 = 1F; + } + } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/Water.cs.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts/Water.cs.meta new file mode 100644 index 00000000..f353f103 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/Water.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a3d3ef1a5bbfb4e0a910fbbe5830b1f9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterBase.cs b/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterBase.cs new file mode 100644 index 00000000..9c13121b --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterBase.cs @@ -0,0 +1,74 @@ +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + public enum WaterQuality + { + High = 2, + Medium = 1, + Low = 0, + } + + [ExecuteInEditMode] + public class WaterBase : MonoBehaviour + { + public Material sharedMaterial; + public WaterQuality waterQuality = WaterQuality.High; + public bool edgeBlend = true; + + public void UpdateShader() + { + if (waterQuality > WaterQuality.Medium) + { + sharedMaterial.shader.maximumLOD = 501; + } + else if (waterQuality > WaterQuality.Low) + { + sharedMaterial.shader.maximumLOD = 301; + } + else + { + sharedMaterial.shader.maximumLOD = 201; + } + + // If the system does not support depth textures (ie. NaCl), turn off edge bleeding, + // as the shader will render everything as transparent if the depth texture is not valid. + if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.Depth)) + { + edgeBlend = false; + } + + if (edgeBlend) + { + Shader.EnableKeyword("WATER_EDGEBLEND_ON"); + Shader.DisableKeyword("WATER_EDGEBLEND_OFF"); + // just to make sure (some peeps might forget to add a water tile to the patches) + if (Camera.main) + { + Camera.main.depthTextureMode |= DepthTextureMode.Depth; + } + } + else + { + Shader.EnableKeyword("WATER_EDGEBLEND_OFF"); + Shader.DisableKeyword("WATER_EDGEBLEND_ON"); + } + } + + public void WaterTileBeingRendered(Transform tr, Camera currentCam) + { + if (currentCam && edgeBlend) + { + currentCam.depthTextureMode |= DepthTextureMode.Depth; + } + } + + public void Update() + { + if (sharedMaterial) + { + UpdateShader(); + } + } + } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterBase.cs.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterBase.cs.meta new file mode 100644 index 00000000..2cc09198 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterBase.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a1da353243062479a9b31c85074a796b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterTile.cs b/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterTile.cs new file mode 100644 index 00000000..40b4575a --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterTile.cs @@ -0,0 +1,64 @@ +using UnityEngine; + +namespace UnityStandardAssets.Water +{ + [ExecuteInEditMode] + public class WaterTile : MonoBehaviour + { + public PlanarReflection reflection; + public WaterBase waterBase; + + public void Start() + { + AcquireComponents(); + } + + private void AcquireComponents() + { + if (!reflection) + { + if (transform.parent) + { + reflection = transform.parent.GetComponent(); + } + else + { + reflection = transform.GetComponent(); + } + } + + if (!waterBase) + { + if (transform.parent) + { + waterBase = transform.parent.GetComponent(); + } + else + { + waterBase = transform.GetComponent(); + } + } + } + +#if UNITY_EDITOR + + public void Update() + { + AcquireComponents(); + } + +#endif + + public void OnWillRenderObject() + { + if (reflection) + { + reflection.WaterTileBeingRendered(transform, Camera.current); + } + if (waterBase) + { + waterBase.WaterTileBeingRendered(transform, Camera.current); + } + } + } +} \ No newline at end of file diff --git a/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterTile.cs.meta b/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterTile.cs.meta new file mode 100644 index 00000000..62454033 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Scripts/WaterTile.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2a91e8dd37cdd41efb4859b65aced7a2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Shaders.meta b/Assets/Standard Assets/Environment/Water/Water/Shaders.meta new file mode 100644 index 00000000..4756dabc --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Shaders.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: e70b47c0cfc1d4b12a3c663d7582a523 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Shaders/FXWaterPro.shader b/Assets/Standard Assets/Environment/Water/Water/Shaders/FXWaterPro.shader new file mode 100644 index 00000000..3addae12 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Shaders/FXWaterPro.shader @@ -0,0 +1,163 @@ +// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' + +Shader "FX/Water" { +Properties { + _WaveScale ("Wave scale", Range (0.02,0.15)) = 0.063 + _ReflDistort ("Reflection distort", Range (0,1.5)) = 0.44 + _RefrDistort ("Refraction distort", Range (0,1.5)) = 0.40 + _RefrColor ("Refraction color", COLOR) = ( .34, .85, .92, 1) + [NoScaleOffset] _Fresnel ("Fresnel (A) ", 2D) = "gray" {} + [NoScaleOffset] _BumpMap ("Normalmap ", 2D) = "bump" {} + WaveSpeed ("Wave speed (map1 x,y; map2 x,y)", Vector) = (19,9,-16,-7) + [NoScaleOffset] _ReflectiveColor ("Reflective color (RGB) fresnel (A) ", 2D) = "" {} + _HorizonColor ("Simple water horizon color", COLOR) = ( .172, .463, .435, 1) + [HideInInspector] _ReflectionTex ("Internal Reflection", 2D) = "" {} + [HideInInspector] _RefractionTex ("Internal Refraction", 2D) = "" {} +} + + +// ----------------------------------------------------------- +// Fragment program cards + + +Subshader { + Tags { "WaterMode"="Refractive" "RenderType"="Opaque" } + Pass { +CGPROGRAM +#pragma vertex vert +#pragma fragment frag +#pragma multi_compile_fog +#pragma multi_compile WATER_REFRACTIVE WATER_REFLECTIVE WATER_SIMPLE + +#if defined (WATER_REFLECTIVE) || defined (WATER_REFRACTIVE) +#define HAS_REFLECTION 1 +#endif +#if defined (WATER_REFRACTIVE) +#define HAS_REFRACTION 1 +#endif + + +#include "UnityCG.cginc" + +uniform float4 _WaveScale4; +uniform float4 _WaveOffset; + +#if HAS_REFLECTION +uniform float _ReflDistort; +#endif +#if HAS_REFRACTION +uniform float _RefrDistort; +#endif + +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; +}; + +struct v2f { + float4 pos : SV_POSITION; + #if defined(HAS_REFLECTION) || defined(HAS_REFRACTION) + float4 ref : TEXCOORD0; + float2 bumpuv0 : TEXCOORD1; + float2 bumpuv1 : TEXCOORD2; + float3 viewDir : TEXCOORD3; + #else + float2 bumpuv0 : TEXCOORD0; + float2 bumpuv1 : TEXCOORD1; + float3 viewDir : TEXCOORD2; + #endif + UNITY_FOG_COORDS(4) +}; + +v2f vert(appdata v) +{ + v2f o; + o.pos = UnityObjectToClipPos(v.vertex); + + + // scroll bump waves + float4 temp; + float4 wpos = mul (unity_ObjectToWorld, v.vertex); + temp.xyzw = wpos.xzxz * _WaveScale4 + _WaveOffset; + o.bumpuv0 = temp.xy; + o.bumpuv1 = temp.wz; + + // object space view direction (will normalize per pixel) + o.viewDir.xzy = WorldSpaceViewDir(v.vertex); + + #if defined(HAS_REFLECTION) || defined(HAS_REFRACTION) + o.ref = ComputeNonStereoScreenPos(o.pos); + #endif + + UNITY_TRANSFER_FOG(o,o.pos); + return o; +} + +#if defined (WATER_REFLECTIVE) || defined (WATER_REFRACTIVE) +sampler2D _ReflectionTex; +#endif +#if defined (WATER_REFLECTIVE) || defined (WATER_SIMPLE) +sampler2D _ReflectiveColor; +#endif +#if defined (WATER_REFRACTIVE) +sampler2D _Fresnel; +sampler2D _RefractionTex; +uniform float4 _RefrColor; +#endif +#if defined (WATER_SIMPLE) +uniform float4 _HorizonColor; +#endif +sampler2D _BumpMap; + +half4 frag( v2f i ) : SV_Target +{ + i.viewDir = normalize(i.viewDir); + + // combine two scrolling bumpmaps into one + half3 bump1 = UnpackNormal(tex2D( _BumpMap, i.bumpuv0 )).rgb; + half3 bump2 = UnpackNormal(tex2D( _BumpMap, i.bumpuv1 )).rgb; + half3 bump = (bump1 + bump2) * 0.5; + + // fresnel factor + half fresnelFac = dot( i.viewDir, bump ); + + // perturb reflection/refraction UVs by bumpmap, and lookup colors + + #if HAS_REFLECTION + float4 uv1 = i.ref; uv1.xy += bump * _ReflDistort; + half4 refl = tex2Dproj( _ReflectionTex, UNITY_PROJ_COORD(uv1) ); + #endif + #if HAS_REFRACTION + float4 uv2 = i.ref; uv2.xy -= bump * _RefrDistort; + half4 refr = tex2Dproj( _RefractionTex, UNITY_PROJ_COORD(uv2) ) * _RefrColor; + #endif + + // final color is between refracted and reflected based on fresnel + half4 color; + + #if defined(WATER_REFRACTIVE) + half fresnel = UNITY_SAMPLE_1CHANNEL( _Fresnel, float2(fresnelFac,fresnelFac) ); + color = lerp( refr, refl, fresnel ); + #endif + + #if defined(WATER_REFLECTIVE) + half4 water = tex2D( _ReflectiveColor, float2(fresnelFac,fresnelFac) ); + color.rgb = lerp( water.rgb, refl.rgb, water.a ); + color.a = refl.a * water.a; + #endif + + #if defined(WATER_SIMPLE) + half4 water = tex2D( _ReflectiveColor, float2(fresnelFac,fresnelFac) ); + color.rgb = lerp( water.rgb, _HorizonColor.rgb, water.a ); + color.a = _HorizonColor.a; + #endif + + UNITY_APPLY_FOG(i.fogCoord, color); + return color; +} +ENDCG + + } +} + +} diff --git a/Assets/Standard Assets/Environment/Water/Water/Shaders/FXWaterPro.shader.meta b/Assets/Standard Assets/Environment/Water/Water/Shaders/FXWaterPro.shader.meta new file mode 100644 index 00000000..5321fd16 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Shaders/FXWaterPro.shader.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 1cac2e0bcc34e4b3cbb4bd85982eba83 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures.meta b/Assets/Standard Assets/Environment/Water/Water/Textures.meta new file mode 100644 index 00000000..0b7c1b75 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Textures.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: c22094bc116524b2a95c9aae09278b22 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures/WaterBump.jpg b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterBump.jpg new file mode 100644 index 00000000..9cbd3dec Binary files /dev/null and b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterBump.jpg differ diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures/WaterBump.jpg.meta b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterBump.jpg.meta new file mode 100644 index 00000000..8c6b3b33 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterBump.jpg.meta @@ -0,0 +1,52 @@ +fileFormatVersion: 2 +guid: 2dd3788f8589b40bf82a92d76ffc5091 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 2 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 1 + externalNormalMap: 1 + heightScale: .0164516103 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 512 + textureSettings: + filterMode: 1 + aniso: 3 + mipBias: 0 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures/WaterFresnel.psd b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterFresnel.psd new file mode 100644 index 00000000..3ddb2258 Binary files /dev/null and b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterFresnel.psd differ diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures/WaterFresnel.psd.meta b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterFresnel.psd.meta new file mode 100644 index 00000000..591d541c --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterFresnel.psd.meta @@ -0,0 +1,52 @@ +fileFormatVersion: 2 +guid: 5b5c5575fd4c74abd9f7b30862fb76a3 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 2 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 1024 + textureSettings: + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapMode: 0 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProDaytimeGradient.psd b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProDaytimeGradient.psd new file mode 100644 index 00000000..afed36b5 Binary files /dev/null and b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProDaytimeGradient.psd differ diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProDaytimeGradient.psd.meta b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProDaytimeGradient.psd.meta new file mode 100644 index 00000000..1eb0f89c --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProDaytimeGradient.psd.meta @@ -0,0 +1,52 @@ +fileFormatVersion: 2 +guid: ab97f9ab7c2ce724ebc9446060a819a4 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 2 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .100000001 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 32 + textureSettings: + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 0 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProNighttimeGradient.psd b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProNighttimeGradient.psd new file mode 100644 index 00000000..d853a2bc Binary files /dev/null and b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProNighttimeGradient.psd differ diff --git a/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProNighttimeGradient.psd.meta b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProNighttimeGradient.psd.meta new file mode 100644 index 00000000..338d29b9 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water/Textures/WaterProNighttimeGradient.psd.meta @@ -0,0 +1,52 @@ +fileFormatVersion: 2 +guid: b725b62cfc9d04e4886735ab2a8107d1 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 2 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .100000001 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 32 + textureSettings: + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 0 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4.meta b/Assets/Standard Assets/Environment/Water/Water4.meta new file mode 100644 index 00000000..119d7661 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 17e234879cb994b7f93d7437c10d23d6 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Materials.meta b/Assets/Standard Assets/Environment/Water/Water4/Materials.meta new file mode 100644 index 00000000..080fb2ae --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Materials.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: a771af3b1958445078af5fe2e9ec726c +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Materials/OceanPlaneMaterial.mat b/Assets/Standard Assets/Environment/Water/Water4/Materials/OceanPlaneMaterial.mat new file mode 100644 index 00000000..1fbe9f27 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Materials/OceanPlaneMaterial.mat @@ -0,0 +1,142 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: OceanPlaneMaterial + m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + - _LIGHTMAPPING_STATIC_LIGHTMAPS + - _UVSEC_UV1 + m_CustomRenderQueue: -1 + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + data: + first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _Occlusion + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _SpecGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _SrcBlend + second: 1 + data: + first: + name: _DstBlend + second: 0 + data: + first: + name: _Parallax + second: .0199999996 + data: + first: + name: _ZWrite + second: 1 + data: + first: + name: _AlphaTestRef + second: .5 + data: + first: + name: _Glossiness + second: 0 + data: + first: + name: _BumpScale + second: 1 + data: + first: + name: _OcclusionStrength + second: 1 + data: + first: + name: _EmissionScale + second: 1 + data: + first: + name: _Lightmapping + second: 0 + data: + first: + name: _DetailNormalMapScale + second: 1 + data: + first: + name: _UVSec + second: 0 + data: + first: + name: _Mode + second: 0 + m_Colors: + data: + first: + name: _Color + second: {r: .5, g: .5, b: .5, a: 1} + data: + first: + name: _SpecularColor + second: {r: .200000003, g: .200000003, b: .200000003, a: 1} diff --git a/Assets/Standard Assets/Environment/Water/Water4/Materials/OceanPlaneMaterial.mat.meta b/Assets/Standard Assets/Environment/Water/Water4/Materials/OceanPlaneMaterial.mat.meta new file mode 100644 index 00000000..9cc7fd55 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Materials/OceanPlaneMaterial.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: a437a9b380909fa4d98f929428f70388 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Advanced.mat b/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Advanced.mat new file mode 100644 index 00000000..3c32d689 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Advanced.mat @@ -0,0 +1,416 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: Water4Advanced + m_Shader: {fileID: 4800000, guid: 475c4a4e617a8401b84ca7b32c7cc460, type: 3} + m_ShaderKeywords: [] + m_CustomRenderQueue: -1 + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + data: + first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: e6f8288974c664a309d6c66de636978c, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 1, y: 1} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: fb6566c21f717904f83743a5a76dd0b0, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DecalTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _Fresnel + second: + m_Texture: {fileID: 2800000, guid: 5b5c5575fd4c74abd9f7b30862fb76a3, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ReflectiveColor + second: + m_Texture: {fileID: 2800000, guid: 17680dc3bf8f74b498b01cf1481e2593, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ReflectionTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _RefractionTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ShoreTex + second: + m_Texture: {fileID: 2800000, guid: 36dd0b22da8874ed38075789055ca664, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 1, y: 1} + data: + first: + name: _ReflectiveColorCube + second: + m_Texture: {fileID: 8900000, guid: 0620bdf0302d84423be4aa15b82a0e11, type: 2} + m_Scale: {x: .150000006, y: .100000001} + m_Offset: {x: 0, y: 0} + data: + first: + name: _WavesTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DisplacementHeightMap + second: + m_Texture: {fileID: 2800000, guid: a782b26d6436b48d9882906b9f8ca31a, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _SecondDisplacementHeightMap + second: + m_Texture: {fileID: 2800000, guid: 4facc21e08e3a43ed97c930f7dae6e7b, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ThirdDisplacementHeightMap + second: + m_Texture: {fileID: 2800000, guid: dc30b984e8e3c4cdfb38d5fceb411602, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _SpecialWavesTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DepthMap + second: + m_Texture: {fileID: 2800000, guid: ff6e0fbcfc24e4f95a2711ea0e73dd6a, type: 3} + m_Scale: {x: .0140000004, y: .0140000004} + m_Offset: {x: 0, y: 0} + data: + first: + name: _WaterHolesTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _Caustics + second: + m_Texture: {fileID: 2800000, guid: eb9e91ee4c264b942a46baeec92ca0a4, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: m_DisplacementHeightMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: m_SecondDisplacementHeightMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _HeightMask + second: + m_Texture: {fileID: 2800000, guid: cff6f2c02e93742c095cd0c69d3d92ce, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _Shininess + second: 313.218384 + data: + first: + name: _WaveScale + second: .0462896563 + data: + first: + name: _ReflDistort + second: .926769614 + data: + first: + name: _RefrDistort + second: 1.43932855 + data: + first: + name: _FresnelScale + second: .657142818 + data: + first: + name: _GerstnerIntensity + second: 1.67142856 + data: + first: + name: _InvFade + second: .628782988 + data: + first: + name: _HeightDisplacement + second: 3.27225137 + data: + first: + name: _NormalsDisplacement + second: 0 + data: + first: + name: _Displacement + second: .278633773 + data: + first: + name: _ShoreTiling + second: 56.8627434 + data: + first: + name: _FresnelPower + second: 1.79310346 + data: + first: + name: _FadeExp + second: .915032744 + data: + first: + name: _InvFadeFoam + second: .121699996 + data: + first: + name: _WaveFoamDistort + second: .279310346 + data: + first: + name: _InvFadeDepthFade + second: .0719775632 + data: + first: + name: _FoamWaveDependency + second: .10205479 + data: + first: + name: _WaveCapsAmount + second: .182758614 + data: + first: + name: _Speed + second: .413793087 + data: + first: + name: _DisplacementTiling + second: 18.5868073 + data: + first: + name: _Ambient + second: 1 + data: + first: + name: _WaterDepth + second: 40.9807701 + m_Colors: + data: + first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + data: + first: + name: _RefrColor + second: {r: .523390472, g: .947761178, b: .912149608, a: 1} + data: + first: + name: _Fresnel_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _BumpMap_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: WaveSpeed + second: {r: 1.08616495, g: 4.44057512, b: 12.1051464, a: -3.02064466} + data: + first: + name: _ReflectiveColor_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _HorizonColor + second: {r: .052907113, g: .244867355, b: .283582091, a: 1} + data: + first: + name: _ReflectionTex_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _RefractionTex_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _MainTex_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _DistortParams + second: {r: 1.43999994, g: .242857143, b: 1.85306406, a: -.531428456} + data: + first: + name: _InvFadeParemeter + second: {r: .218965515, g: .159448281, b: .043103449, a: 0} + data: + first: + name: _AnimationTiling + second: {r: .0458255298, g: .0182000007, b: .0457144678, a: .0271296911} + data: + first: + name: _AnimationDirection + second: {r: 2, g: 4, b: 2, a: -1} + data: + first: + name: _BumpTiling + second: {r: .119999997, g: .0700000003, b: .0799999982, a: .0599999987} + data: + first: + name: _BumpDirection + second: {r: 40, g: 40, b: 40, a: -40} + data: + first: + name: _BaseColor + second: {r: .153709054, g: .268130153, b: .298507452, a: .819999993} + data: + first: + name: _ReflectionColor + second: {r: .579416394, g: .684923828, b: .76119405, a: .431372553} + data: + first: + name: _SpecularColor + second: {r: .917910457, g: .917910457, b: .917910457, a: 1} + data: + first: + name: _WorldLightDir + second: {r: -.0303751379, g: -.201390833, b: -.979039967, a: 0} + data: + first: + name: _Foam + second: {r: .426666677, g: .486666679, b: 0, a: 0} + data: + first: + name: _GAmplitude + second: {r: .140000001, g: .75999999, b: .174999997, a: .224999994} + data: + first: + name: _GFrequency + second: {r: .5, g: .379999995, b: .589999974, a: .600000024} + data: + first: + name: _GSteepness + second: {r: 7, g: 2, b: 6, a: 2} + data: + first: + name: _GSpeed + second: {r: -3, g: 2, b: 1, a: 3} + data: + first: + name: _GDirectionAB + second: {r: .469143569, g: .354051262, b: -.200000003, a: .100000001} + data: + first: + name: _GDirectionCD + second: {r: .70338881, g: -.679999888, b: .717573524, a: -.200000003} + data: + first: + name: _ReflectiveColorCube_ST + second: {r: 1, g: 1, b: 0, a: 0} + data: + first: + name: _WaveScale4 + second: {r: .100000001, g: .100000001, b: .00999999978, a: .00999999978} + data: + first: + name: _WaveOffset + second: {r: 1, g: 1, b: -.00999999978, a: -.00999999978} + data: + first: + name: _DepthColor + second: {r: .0275116973, g: .141791046, b: .132267773, a: .4627451} + data: + first: + name: _RefractionFog + second: {r: .505434752, g: .505434752, b: .505434752, a: .5} + data: + first: + name: _Displacement + second: {r: 6.6371665, g: 20.3539829, b: -1, a: -.681415975} + data: + first: + name: _ShoreTiling + second: {r: 1, g: 1, b: .100000001, a: .100000001} + data: + first: + name: _DisplacementXz + second: {r: .649999917, g: -2.92037153, b: 1.65999985, a: -3.93630457} + data: + first: + name: _RefrColorDepth + second: {r: .050066825, g: .231343269, b: .170495242, a: 1} + data: + first: + name: _UnderwaterColor + second: {r: .695032299, g: .895522356, b: .75023967, a: 1} + data: + first: + name: _FoamWaveParams + second: {r: 0, g: .24918434, b: 3.33957815, a: 1} + data: + first: + name: _ShoreColor + second: {r: 1, g: 1, b: 1, a: 1} + data: + first: + name: _ShorePerturbation + second: {r: 0, g: 0, b: 0, a: 0} + data: + first: + name: _DepthColorFade + second: {r: .888059676, g: .278347045, b: .444632441, a: .223529413} + data: + first: + name: _Extinction + second: {r: 4.5, g: 75, b: 300, a: 1} +--- !u!1002 &2100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Advanced.mat.meta b/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Advanced.mat.meta new file mode 100644 index 00000000..e1f026da --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Advanced.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: a5f2339f242f6cc41a982ec55ea3c201 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Simple.mat b/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Simple.mat new file mode 100644 index 00000000..f3f26d77 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Simple.mat @@ -0,0 +1,190 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: Water4Simple + m_Shader: {fileID: 4800000, guid: 8aaff0751054e4a9cb4642d01eaf5be9, type: 3} + m_ShaderKeywords: [] + m_CustomRenderQueue: -1 + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + data: + first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: e6f8288974c664a309d6c66de636978c, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: fb6566c21f717904f83743a5a76dd0b0, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ReflectionTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _RefractionTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ShoreTex + second: + m_Texture: {fileID: 2800000, guid: 36dd0b22da8874ed38075789055ca664, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _WavesTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DisplacementHeightMap + second: + m_Texture: {fileID: 2800000, guid: a782b26d6436b48d9882906b9f8ca31a, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _SecondDisplacementHeightMap + second: + m_Texture: {fileID: 2800000, guid: 4facc21e08e3a43ed97c930f7dae6e7b, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ThirdDisplacementHeightMap + second: + m_Texture: {fileID: 2800000, guid: dc30b984e8e3c4cdfb38d5fceb411602, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _CubeTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _Shininess + second: 349.137939 + data: + first: + name: _FresnelScale + second: .389714301 + data: + first: + name: _GerstnerIntensity + second: 1 + data: + first: + name: _HeightDisplacement + second: 2.33703184 + data: + first: + name: _NormalsDisplacement + second: 72.7272797 + m_Colors: + data: + first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + data: + first: + name: _DistortParams + second: {r: 1.02857149, g: .201872215, b: 2.76662493, a: -.417142838} + data: + first: + name: _InvFadeParemeter + second: {r: .275081277, g: .0856210217, b: .0941423923, a: .480310023} + data: + first: + name: _AnimationTiling + second: {r: .400000006, g: .390999973, b: .560000002, a: .699999988} + data: + first: + name: _AnimationDirection + second: {r: 2, g: 1, b: -1, a: 1} + data: + first: + name: _BumpTiling + second: {r: .0399999991, g: .0399999991, b: .0399999991, a: .0799999982} + data: + first: + name: _BumpDirection + second: {r: 1, g: 30, b: 20, a: -20} + data: + first: + name: _BaseColor + second: {r: .172755614, g: .224076003, b: .24626863, a: .505882382} + data: + first: + name: _ReflectionColor + second: {r: .47582978, g: .606486499, b: .664179087, a: .470588237} + data: + first: + name: _SpecularColor + second: {r: .820895553, g: .805815935, b: .771886885, a: 1} + data: + first: + name: _WorldLightDir + second: {r: .0139923692, g: -.173590809, b: -.984718621, a: 0} + data: + first: + name: _Foam + second: {r: .327586204, g: .7471264, b: 0, a: 0} + data: + first: + name: _GAmplitude + second: {r: .300000012, g: .200000003, b: .25, a: .25} + data: + first: + name: _GFrequency + second: {r: .5, g: .25, b: .600000024, a: .245000005} + data: + first: + name: _GSteepness + second: {r: 3.03013062, g: 1, b: 1, a: 1} + data: + first: + name: _GSpeed + second: {r: 4, g: 2, b: 1, a: 1} + data: + first: + name: _GDirectionAB + second: {r: .850000024, g: .300000012, b: .25, a: .25} + data: + first: + name: _GDirectionCD + second: {r: -.300000012, g: -.899999976, b: .5, a: .5} + data: + first: + name: _DepthColor + second: {r: .298117638, g: .366117179, b: .395522416, a: .345098048} + data: + first: + name: _RefractionFog + second: {r: .868177772, g: .879717588, b: .888059676, a: 1} +--- !u!1002 &2100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Simple.mat.meta b/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Simple.mat.meta new file mode 100644 index 00000000..04e28b7f --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Materials/Water4Simple.mat.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 656fde119942645aa8e062e04c119aa1 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Models.meta b/Assets/Standard Assets/Environment/Water/Water4/Models.meta new file mode 100644 index 00000000..62bdffe5 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Models.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 6aa58ee2f84094af2846e1a7bb0c23f9 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Models/OceanPlane.FBX b/Assets/Standard Assets/Environment/Water/Water4/Models/OceanPlane.FBX new file mode 100644 index 00000000..86cd6dd8 Binary files /dev/null and b/Assets/Standard Assets/Environment/Water/Water4/Models/OceanPlane.FBX differ diff --git a/Assets/Standard Assets/Environment/Water/Water4/Models/OceanPlane.FBX.meta b/Assets/Standard Assets/Environment/Water/Water4/Models/OceanPlane.FBX.meta new file mode 100644 index 00000000..7a0b4ea3 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Models/OceanPlane.FBX.meta @@ -0,0 +1,69 @@ +fileFormatVersion: 2 +guid: 681e41ee1260343b395ca58745c94870 +ModelImporter: + serializedVersion: 18 + fileIDToRecycleName: + 100000: //RootNode + 400000: //RootNode + 2300000: //RootNode + 3300000: //RootNode + 4300000: kraut_plane + 4300002: OceanPlane + 11100000: //RootNode + materials: + importMaterials: 1 + materialName: 1 + materialSearch: 1 + animations: + legacyGenerateAnimations: 3 + bakeSimulation: 0 + optimizeGameObjects: 0 + motionNodeName: + pivotNodeName: + animationCompression: 1 + animationRotationError: .5 + animationPositionError: .5 + animationScaleError: .5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + importBlendShapes: 1 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 0 + optimizeMeshForGPU: 1 + weldVertices: 1 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 0 + tangentSpace: + normalSmoothAngle: 60 + splitTangentsAcrossUV: 1 + normalImportMode: 0 + tangentImportMode: 1 + importAnimation: 1 + copyAvatar: 0 + humanDescription: + human: [] + skeleton: [] + armTwist: .5 + foreArmTwist: .5 + upperLegTwist: .5 + legTwist: .5 + armStretch: .0500000007 + legStretch: .0500000007 + feetSpacing: 0 + rootMotionBoneName: + lastHumanDescriptionAvatarSource: {instanceID: 0} + animationType: 1 + additionalBone: 0 + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Prefabs.meta b/Assets/Standard Assets/Environment/Water/Water4/Prefabs.meta new file mode 100644 index 00000000..d97c13c5 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Prefabs.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: d25c4f81e90442d4bbda4d5285669c95 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Advanced.prefab b/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Advanced.prefab new file mode 100644 index 00000000..f90d050e --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Advanced.prefab @@ -0,0 +1,518 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &100000 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400000} + - 33: {fileID: 3300000} + - 23: {fileID: 2300000} + - 114: {fileID: 11400010} + m_Layer: 4 + m_Name: Tile + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1 &100002 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400002} + - 33: {fileID: 3300002} + - 23: {fileID: 2300002} + - 114: {fileID: 11400012} + m_Layer: 4 + m_Name: Tile + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100003 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1 &100004 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400004} + - 33: {fileID: 3300004} + - 23: {fileID: 2300004} + - 114: {fileID: 11400014} + m_Layer: 4 + m_Name: Tile + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1 &100006 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400006} + - 114: {fileID: 11400008} + - 114: {fileID: 11400002} + - 114: {fileID: 11400004} + - 114: {fileID: 11400000} + m_Layer: 0 + m_Name: Water4Advanced + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100007 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1 &100012 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400012} + m_Layer: 0 + m_Name: Specular + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100013 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1 &100014 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400014} + - 33: {fileID: 3300006} + - 23: {fileID: 2300006} + - 114: {fileID: 11400016} + m_Layer: 4 + m_Name: Tile + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100015 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400000 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 25, y: 0, z: -25} + m_LocalScale: {x: .5, y: .5, z: .5} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 3 +--- !u!1002 &400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400002 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -25, y: 0, z: -25} + m_LocalScale: {x: .5, y: .5, z: .5} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 2 +--- !u!1002 &400003 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400004 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -25, y: 0, z: 25} + m_LocalScale: {x: .5, y: .5, z: .5} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 1 +--- !u!1002 &400005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400006 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + 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: 400014} + - {fileID: 400004} + - {fileID: 400002} + - {fileID: 400000} + - {fileID: 400012} + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!1002 &400007 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400012 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100012} + m_LocalRotation: {x: -.00156955631, y: .994744956, z: -.101203032, w: -.0154274851} + m_LocalPosition: {x: 0, y: 10, z: 10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 4 +--- !u!1002 &400013 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400014 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100014} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 25, y: 0, z: 25} + m_LocalScale: {x: .5, y: .5, z: .5} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 0 +--- !u!1002 &400015 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300000 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 8 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 2, y: -2, z: -.5, w: 1.5} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: a5f2339f242f6cc41a982ec55ea3c201, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300002 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 8 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 2, y: -2, z: -.5, w: 1.5} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: a5f2339f242f6cc41a982ec55ea3c201, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300003 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300004 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 8 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 2, y: -2, z: -.5, w: 1.5} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: a5f2339f242f6cc41a982ec55ea3c201, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300006 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100014} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 8 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 2, y: -2, z: -.5, w: 1.5} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: a5f2339f242f6cc41a982ec55ea3c201, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300007 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300000 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Mesh: {fileID: 4300002, guid: 681e41ee1260343b395ca58745c94870, type: 3} +--- !u!1002 &3300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300002 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + m_Mesh: {fileID: 4300002, guid: 681e41ee1260343b395ca58745c94870, type: 3} +--- !u!1002 &3300003 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300004 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_Mesh: {fileID: 4300002, guid: 681e41ee1260343b395ca58745c94870, type: 3} +--- !u!1002 &3300005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300006 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100014} + m_Mesh: {fileID: 4300002, guid: 681e41ee1260343b395ca58745c94870, type: 3} +--- !u!1002 &3300007 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 42e7f46d0e5a84171a3909479c1646ba, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1002 &11400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400002 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: de2ab2b9ac93bb544b9552e49030371b, type: 3} + m_Name: + m_EditorClassIdentifier: + specularLight: {fileID: 400012} +--- !u!1002 &11400003 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400004 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4185bc77c7194462ca3b1097ef4a5de0, type: 3} + m_Name: + m_EditorClassIdentifier: + reflectionMask: + serializedVersion: 2 + m_Bits: 4294967295 + reflectSkybox: 1 + clearColor: {r: 1, g: 1, b: 1, a: 1} + reflectionSampler: _ReflectionTex + clipPlaneOffset: .0700000003 +--- !u!1002 &11400005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400008 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a1da353243062479a9b31c85074a796b, type: 3} + m_Name: + m_EditorClassIdentifier: + sharedMaterial: {fileID: 2100000, guid: a5f2339f242f6cc41a982ec55ea3c201, type: 2} + waterQuality: 2 + edgeBlend: 1 +--- !u!1002 &11400009 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400010 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a91e8dd37cdd41efb4859b65aced7a2, type: 3} + m_Name: + m_EditorClassIdentifier: + reflection: {fileID: 11400004} + waterBase: {fileID: 11400008} +--- !u!1002 &11400011 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400012 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a91e8dd37cdd41efb4859b65aced7a2, type: 3} + m_Name: + m_EditorClassIdentifier: + reflection: {fileID: 11400004} + waterBase: {fileID: 11400008} +--- !u!1002 &11400013 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400014 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a91e8dd37cdd41efb4859b65aced7a2, type: 3} + m_Name: + m_EditorClassIdentifier: + reflection: {fileID: 11400004} + waterBase: {fileID: 11400008} +--- !u!1002 &11400015 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400016 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100014} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a91e8dd37cdd41efb4859b65aced7a2, type: 3} + m_Name: + m_EditorClassIdentifier: + reflection: {fileID: 11400004} + waterBase: {fileID: 11400008} +--- !u!1002 &11400017 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 100006} + m_IsPrefabParent: 1 +--- !u!1002 &100100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Advanced.prefab.meta b/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Advanced.prefab.meta new file mode 100644 index 00000000..dc352e6c --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Advanced.prefab.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: b544816461f324e56a39767fdeb5b114 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Simple.prefab b/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Simple.prefab new file mode 100644 index 00000000..5ed97565 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Simple.prefab @@ -0,0 +1,336 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &100000 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400000} + - 33: {fileID: 3300000} + - 23: {fileID: 2300000} + - 114: {fileID: 11400010} + m_Layer: 4 + m_Name: Tile + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1 &100004 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400004} + - 33: {fileID: 3300004} + - 23: {fileID: 2300004} + - 114: {fileID: 11400014} + m_Layer: 4 + m_Name: Tile + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1 &100006 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400006} + - 114: {fileID: 11400008} + - 114: {fileID: 11400004} + - 114: {fileID: 11400002} + - 114: {fileID: 11400000} + m_Layer: 0 + m_Name: Water4Simple + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100007 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1 &100012 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400012} + m_Layer: 0 + m_Name: Specular + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1002 &100013 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400000 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -25} + m_LocalScale: {x: .5, y: .5, z: .5} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 2 +--- !u!1002 &400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400004 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 25} + m_LocalScale: {x: .5, y: .5, z: .5} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 0 +--- !u!1002 &400005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400006 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + 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: 400004} + - {fileID: 400012} + - {fileID: 400000} + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!1002 &400007 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!4 &400012 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100012} + m_LocalRotation: {x: -.726843357, y: .681218088, z: -.0647061244, w: -.05876977} + m_LocalPosition: {x: -.699409485, y: 16.8292236, z: 52.0728149} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 1 +--- !u!1002 &400013 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300000 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 8 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 2, y: -2, z: -.5, w: 1.5} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: 656fde119942645aa8e062e04c119aa1, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!23 &2300004 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_LightmapIndex: 8 + m_LightmapIndexDynamic: 255 + m_LightmapTilingOffset: {x: 2, y: -2, z: -.5, w: 1.5} + m_LightmapTilingOffsetDynamic: {x: 1, y: 1, z: 0, w: 0} + m_Materials: + - {fileID: 2100000, guid: 656fde119942645aa8e062e04c119aa1, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_UseReflectionProbes: 1 + m_ProbeAnchor: {fileID: 0} + m_ScaleInLightmap: 1 + m_EnlightenSystemBuildParameters: {fileID: 0} + m_GIBackfaceCull: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!1002 &2300005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300000 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Mesh: {fileID: 4300002, guid: 681e41ee1260343b395ca58745c94870, type: 3} +--- !u!1002 &3300001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!33 &3300004 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_Mesh: {fileID: 4300002, guid: 681e41ee1260343b395ca58745c94870, type: 3} +--- !u!1002 &3300005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 42e7f46d0e5a84171a3909479c1646ba, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1002 &11400001 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400002 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: de2ab2b9ac93bb544b9552e49030371b, type: 3} + m_Name: + m_EditorClassIdentifier: + specularLight: {fileID: 400012} +--- !u!1002 &11400003 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400004 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4185bc77c7194462ca3b1097ef4a5de0, type: 3} + m_Name: + m_EditorClassIdentifier: + reflectionMask: + serializedVersion: 2 + m_Bits: 4294967295 + reflectSkybox: 1 + clearColor: {r: 1, g: 1, b: 1, a: 1} + reflectionSampler: _ReflectionTex + clipPlaneOffset: .0700000003 +--- !u!1002 &11400005 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400008 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a1da353243062479a9b31c85074a796b, type: 3} + m_Name: + m_EditorClassIdentifier: + sharedMaterial: {fileID: 2100000, guid: 656fde119942645aa8e062e04c119aa1, type: 2} + waterQuality: 2 + edgeBlend: 1 +--- !u!1002 &11400009 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400010 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a91e8dd37cdd41efb4859b65aced7a2, type: 3} + m_Name: + m_EditorClassIdentifier: + reflection: {fileID: 11400004} + waterBase: {fileID: 11400008} +--- !u!1002 &11400011 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!114 &11400014 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a91e8dd37cdd41efb4859b65aced7a2, type: 3} + m_Name: + m_EditorClassIdentifier: + reflection: {fileID: 11400004} + waterBase: {fileID: 11400008} +--- !u!1002 &11400015 +EditorExtensionImpl: + serializedVersion: 6 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 100006} + m_IsPrefabParent: 1 +--- !u!1002 &100100001 +EditorExtensionImpl: + serializedVersion: 6 diff --git a/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Simple.prefab.meta b/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Simple.prefab.meta new file mode 100644 index 00000000..2a687a26 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Prefabs/Water4Simple.prefab.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 843740dbe549a4a6ba9556d1b80001f5 +NativeFormatImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Shaders.meta b/Assets/Standard Assets/Environment/Water/Water4/Shaders.meta new file mode 100644 index 00000000..16f8845a --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Shaders.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 2c538784885b34a5987ed9f6651d9ecd +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Advanced.shader b/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Advanced.shader new file mode 100644 index 00000000..19ca8988 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Advanced.shader @@ -0,0 +1,450 @@ +// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' + +Shader "FX/Water4" { +Properties { + _ReflectionTex ("Internal reflection", 2D) = "white" {} + + _MainTex ("Fallback texture", 2D) = "black" {} + _ShoreTex ("Shore & Foam texture ", 2D) = "black" {} + _BumpMap ("Normals ", 2D) = "bump" {} + + _DistortParams ("Distortions (Bump waves, Reflection, Fresnel power, Fresnel bias)", Vector) = (1.0 ,1.0, 2.0, 1.15) + _InvFadeParemeter ("Auto blend parameter (Edge, Shore, Distance scale)", Vector) = (0.15 ,0.15, 0.5, 1.0) + + _AnimationTiling ("Animation Tiling (Displacement)", Vector) = (2.2 ,2.2, -1.1, -1.1) + _AnimationDirection ("Animation Direction (displacement)", Vector) = (1.0 ,1.0, 1.0, 1.0) + + _BumpTiling ("Bump Tiling", Vector) = (1.0 ,1.0, -2.0, 3.0) + _BumpDirection ("Bump Direction & Speed", Vector) = (1.0 ,1.0, -1.0, 1.0) + + _FresnelScale ("FresnelScale", Range (0.15, 4.0)) = 0.75 + + _BaseColor ("Base color", COLOR) = ( .54, .95, .99, 0.5) + _ReflectionColor ("Reflection color", COLOR) = ( .54, .95, .99, 0.5) + _SpecularColor ("Specular color", COLOR) = ( .72, .72, .72, 1) + + _WorldLightDir ("Specular light direction", Vector) = (0.0, 0.1, -0.5, 0.0) + _Shininess ("Shininess", Range (2.0, 500.0)) = 200.0 + + _Foam ("Foam (intensity, cutoff)", Vector) = (0.1, 0.375, 0.0, 0.0) + + _GerstnerIntensity("Per vertex displacement", Float) = 1.0 + _GAmplitude ("Wave Amplitude", Vector) = (0.3 ,0.35, 0.25, 0.25) + _GFrequency ("Wave Frequency", Vector) = (1.3, 1.35, 1.25, 1.25) + _GSteepness ("Wave Steepness", Vector) = (1.0, 1.0, 1.0, 1.0) + _GSpeed ("Wave Speed", Vector) = (1.2, 1.375, 1.1, 1.5) + _GDirectionAB ("Wave Direction", Vector) = (0.3 ,0.85, 0.85, 0.25) + _GDirectionCD ("Wave Direction", Vector) = (0.1 ,0.9, 0.5, 0.5) +} + + +CGINCLUDE + + #include "UnityCG.cginc" + #include "WaterInclude.cginc" + + struct appdata + { + float4 vertex : POSITION; + float3 normal : NORMAL; + }; + + // interpolator structs + + struct v2f + { + float4 pos : SV_POSITION; + float4 normalInterpolator : TEXCOORD0; + float4 viewInterpolator : TEXCOORD1; + float4 bumpCoords : TEXCOORD2; + float4 screenPos : TEXCOORD3; + float4 grabPassPos : TEXCOORD4; + UNITY_FOG_COORDS(5) + }; + + struct v2f_noGrab + { + float4 pos : SV_POSITION; + float4 normalInterpolator : TEXCOORD0; + float3 viewInterpolator : TEXCOORD1; + float4 bumpCoords : TEXCOORD2; + float4 screenPos : TEXCOORD3; + UNITY_FOG_COORDS(4) + }; + + struct v2f_simple + { + float4 pos : SV_POSITION; + float4 viewInterpolator : TEXCOORD0; + float4 bumpCoords : TEXCOORD1; + UNITY_FOG_COORDS(2) + }; + + // textures + sampler2D _BumpMap; + sampler2D _ReflectionTex; + sampler2D _RefractionTex; + sampler2D _ShoreTex; + sampler2D_float _CameraDepthTexture; + + // colors in use + uniform float4 _RefrColorDepth; + uniform float4 _SpecularColor; + uniform float4 _BaseColor; + uniform float4 _ReflectionColor; + + // edge & shore fading + uniform float4 _InvFadeParemeter; + + // specularity + uniform float _Shininess; + uniform float4 _WorldLightDir; + + // fresnel, vertex & bump displacements & strength + uniform float4 _DistortParams; + uniform float _FresnelScale; + uniform float4 _BumpTiling; + uniform float4 _BumpDirection; + + uniform float4 _GAmplitude; + uniform float4 _GFrequency; + uniform float4 _GSteepness; + uniform float4 _GSpeed; + uniform float4 _GDirectionAB; + uniform float4 _GDirectionCD; + + // foam + uniform float4 _Foam; + + // shortcuts + #define PER_PIXEL_DISPLACE _DistortParams.x + #define REALTIME_DISTORTION _DistortParams.y + #define FRESNEL_POWER _DistortParams.z + #define VERTEX_WORLD_NORMAL i.normalInterpolator.xyz + #define FRESNEL_BIAS _DistortParams.w + #define NORMAL_DISPLACEMENT_PER_VERTEX _InvFadeParemeter.z + + // + // HQ VERSION + // + + v2f vert(appdata_full v) + { + v2f o; + + half3 worldSpaceVertex = mul(unity_ObjectToWorld,(v.vertex)).xyz; + half3 vtxForAni = (worldSpaceVertex).xzz; + + half3 nrml; + half3 offsets; + Gerstner ( + offsets, nrml, v.vertex.xyz, vtxForAni, // offsets, nrml will be written + _GAmplitude, // amplitude + _GFrequency, // frequency + _GSteepness, // steepness + _GSpeed, // speed + _GDirectionAB, // direction # 1, 2 + _GDirectionCD // direction # 3, 4 + ); + + v.vertex.xyz += offsets; + + // one can also use worldSpaceVertex.xz here (speed!), albeit it'll end up a little skewed + half2 tileableUv = mul(unity_ObjectToWorld,(v.vertex)).xz; + + o.bumpCoords.xyzw = (tileableUv.xyxy + _Time.xxxx * _BumpDirection.xyzw) * _BumpTiling.xyzw; + + o.viewInterpolator.xyz = worldSpaceVertex - _WorldSpaceCameraPos; + + o.pos = UnityObjectToClipPos(v.vertex); + + ComputeScreenAndGrabPassPos(o.pos, o.screenPos, o.grabPassPos); + + o.normalInterpolator.xyz = nrml; + + o.viewInterpolator.w = saturate(offsets.y); + o.normalInterpolator.w = 1; //GetDistanceFadeout(o.screenPos.w, DISTANCE_SCALE); + + UNITY_TRANSFER_FOG(o,o.pos); + return o; + } + + half4 frag( v2f i ) : SV_Target + { + half3 worldNormal = PerPixelNormal(_BumpMap, i.bumpCoords, VERTEX_WORLD_NORMAL, PER_PIXEL_DISPLACE); + half3 viewVector = normalize(i.viewInterpolator.xyz); + + half4 distortOffset = half4(worldNormal.xz * REALTIME_DISTORTION * 10.0, 0, 0); + half4 screenWithOffset = i.screenPos + distortOffset; + half4 grabWithOffset = i.grabPassPos + distortOffset; + + half4 rtRefractionsNoDistort = tex2Dproj(_RefractionTex, UNITY_PROJ_COORD(i.grabPassPos)); + half refrFix = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(grabWithOffset)); + half4 rtRefractions = tex2Dproj(_RefractionTex, UNITY_PROJ_COORD(grabWithOffset)); + + #ifdef WATER_REFLECTIVE + half4 rtReflections = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(screenWithOffset)); + #endif + + #ifdef WATER_EDGEBLEND_ON + if (LinearEyeDepth(refrFix) < i.screenPos.z) + rtRefractions = rtRefractionsNoDistort; + #endif + + half3 reflectVector = normalize(reflect(viewVector, worldNormal)); + half3 h = normalize ((_WorldLightDir.xyz) + viewVector.xyz); + float nh = max (0, dot (worldNormal, -h)); + float spec = max(0.0,pow (nh, _Shininess)); + + half4 edgeBlendFactors = half4(1.0, 0.0, 0.0, 0.0); + + #ifdef WATER_EDGEBLEND_ON + float depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos)); + depth = LinearEyeDepth(depth); + edgeBlendFactors = saturate(_InvFadeParemeter * (depth-i.screenPos.w)); + edgeBlendFactors.y = 1.0-edgeBlendFactors.y; + #endif + + // shading for fresnel term + worldNormal.xz *= _FresnelScale; + half refl2Refr = Fresnel(viewVector, worldNormal, FRESNEL_BIAS, FRESNEL_POWER); + + // base, depth & reflection colors + half4 baseColor = ExtinctColor (_BaseColor, i.viewInterpolator.w * _InvFadeParemeter.w); + #ifdef WATER_REFLECTIVE + half4 reflectionColor = lerp (rtReflections,_ReflectionColor,_ReflectionColor.a); + #else + half4 reflectionColor = _ReflectionColor; + #endif + + baseColor = lerp (lerp (rtRefractions, baseColor, baseColor.a), reflectionColor, refl2Refr); + baseColor = baseColor + spec * _SpecularColor; + + // handle foam + half4 foam = Foam(_ShoreTex, i.bumpCoords * 2.0); + baseColor.rgb += foam.rgb * _Foam.x * (edgeBlendFactors.y + saturate(i.viewInterpolator.w - _Foam.y)); + + baseColor.a = edgeBlendFactors.x; + UNITY_APPLY_FOG(i.fogCoord, baseColor); + return baseColor; + } + + // + // MQ VERSION + // + + v2f_noGrab vert300(appdata_full v) + { + v2f_noGrab o; + + half3 worldSpaceVertex = mul(unity_ObjectToWorld,(v.vertex)).xyz; + half3 vtxForAni = (worldSpaceVertex).xzz; + + half3 nrml; + half3 offsets; + Gerstner ( + offsets, nrml, v.vertex.xyz, vtxForAni, // offsets, nrml will be written + _GAmplitude, // amplitude + _GFrequency, // frequency + _GSteepness, // steepness + _GSpeed, // speed + _GDirectionAB, // direction # 1, 2 + _GDirectionCD // direction # 3, 4 + ); + + v.vertex.xyz += offsets; + + // one can also use worldSpaceVertex.xz here (speed!), albeit it'll end up a little skewed + half2 tileableUv = mul(unity_ObjectToWorld,v.vertex).xz; + o.bumpCoords.xyzw = (tileableUv.xyxy + _Time.xxxx * _BumpDirection.xyzw) * _BumpTiling.xyzw; + + o.viewInterpolator.xyz = worldSpaceVertex - _WorldSpaceCameraPos; + + o.pos = UnityObjectToClipPos(v.vertex); + + o.screenPos = ComputeNonStereoScreenPos(o.pos); + + o.normalInterpolator.xyz = nrml; + o.normalInterpolator.w = 1; //GetDistanceFadeout(o.screenPos.w, DISTANCE_SCALE); + + UNITY_TRANSFER_FOG(o,o.pos); + return o; + } + + half4 frag300( v2f_noGrab i ) : SV_Target + { + half3 worldNormal = PerPixelNormal(_BumpMap, i.bumpCoords, normalize(VERTEX_WORLD_NORMAL), PER_PIXEL_DISPLACE); + + half3 viewVector = normalize(i.viewInterpolator.xyz); + + half4 distortOffset = half4(worldNormal.xz * REALTIME_DISTORTION * 10.0, 0, 0); + half4 screenWithOffset = i.screenPos + distortOffset; + + #ifdef WATER_REFLECTIVE + half4 rtReflections = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(screenWithOffset)); + #endif + + half3 reflectVector = normalize(reflect(viewVector, worldNormal)); + half3 h = normalize (_WorldLightDir.xyz + viewVector.xyz); + float nh = max (0, dot (worldNormal, -h)); + float spec = max(0.0,pow (nh, _Shininess)); + + half4 edgeBlendFactors = half4(1.0, 0.0, 0.0, 0.0); + + #ifdef WATER_EDGEBLEND_ON + half depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos)); + depth = LinearEyeDepth(depth); + edgeBlendFactors = saturate(_InvFadeParemeter * (depth-i.screenPos.z)); + edgeBlendFactors.y = 1.0-edgeBlendFactors.y; + #endif + + worldNormal.xz *= _FresnelScale; + half refl2Refr = Fresnel(viewVector, worldNormal, FRESNEL_BIAS, FRESNEL_POWER); + + half4 baseColor = _BaseColor; + #ifdef WATER_REFLECTIVE + baseColor = lerp (baseColor, lerp (rtReflections,_ReflectionColor,_ReflectionColor.a), saturate(refl2Refr * 2.0)); + #else + baseColor = lerp (baseColor, _ReflectionColor, saturate(refl2Refr * 2.0)); + #endif + + baseColor = baseColor + spec * _SpecularColor; + + baseColor.a = edgeBlendFactors.x * saturate(0.5 + refl2Refr * 1.0); + UNITY_APPLY_FOG(i.fogCoord, baseColor); + return baseColor; + } + + // + // LQ VERSION + // + + v2f_simple vert200(appdata_full v) + { + v2f_simple o; + + half3 worldSpaceVertex = mul(unity_ObjectToWorld, v.vertex).xyz; + half2 tileableUv = worldSpaceVertex.xz; + + o.bumpCoords.xyzw = (tileableUv.xyxy + _Time.xxxx * _BumpDirection.xyzw) * _BumpTiling.xyzw; + + o.viewInterpolator.xyz = worldSpaceVertex-_WorldSpaceCameraPos; + + o.pos = UnityObjectToClipPos( v.vertex); + + o.viewInterpolator.w = 1; //GetDistanceFadeout(ComputeNonStereoScreenPos(o.pos).w, DISTANCE_SCALE); + + UNITY_TRANSFER_FOG(o,o.pos); + return o; + + } + + half4 frag200( v2f_simple i ) : SV_Target + { + half3 worldNormal = PerPixelNormal(_BumpMap, i.bumpCoords, half3(0,1,0), PER_PIXEL_DISPLACE); + half3 viewVector = normalize(i.viewInterpolator.xyz); + + half3 reflectVector = normalize(reflect(viewVector, worldNormal)); + half3 h = normalize ((_WorldLightDir.xyz) + viewVector.xyz); + float nh = max (0, dot (worldNormal, -h)); + float spec = max(0.0,pow (nh, _Shininess)); + + worldNormal.xz *= _FresnelScale; + half refl2Refr = Fresnel(viewVector, worldNormal, FRESNEL_BIAS, FRESNEL_POWER); + + half4 baseColor = _BaseColor; + baseColor = lerp(baseColor, _ReflectionColor, saturate(refl2Refr * 2.0)); + baseColor.a = saturate(2.0 * refl2Refr + 0.5); + + baseColor.rgb += spec * _SpecularColor.rgb; + UNITY_APPLY_FOG(i.fogCoord, baseColor); + return baseColor; + } + +ENDCG + +Subshader +{ + Tags {"RenderType"="Transparent" "Queue"="Transparent"} + + Lod 500 + ColorMask RGB + + GrabPass { "_RefractionTex" } + + Pass { + Blend SrcAlpha OneMinusSrcAlpha + ZTest LEqual + ZWrite Off + Cull Off + + CGPROGRAM + + #pragma target 3.0 + + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_fog + + #pragma multi_compile WATER_VERTEX_DISPLACEMENT_ON WATER_VERTEX_DISPLACEMENT_OFF + #pragma multi_compile WATER_EDGEBLEND_ON WATER_EDGEBLEND_OFF + #pragma multi_compile WATER_REFLECTIVE WATER_SIMPLE + + ENDCG + } +} + +Subshader +{ + Tags {"RenderType"="Transparent" "Queue"="Transparent"} + + Lod 300 + ColorMask RGB + + Pass { + Blend SrcAlpha OneMinusSrcAlpha + ZTest LEqual + ZWrite Off + Cull Off + + CGPROGRAM + + #pragma target 3.0 + + #pragma vertex vert300 + #pragma fragment frag300 + #pragma multi_compile_fog + + #pragma multi_compile WATER_VERTEX_DISPLACEMENT_ON WATER_VERTEX_DISPLACEMENT_OFF + #pragma multi_compile WATER_EDGEBLEND_ON WATER_EDGEBLEND_OFF + #pragma multi_compile WATER_REFLECTIVE WATER_SIMPLE + + ENDCG + } +} + +Subshader +{ + Tags {"RenderType"="Transparent" "Queue"="Transparent"} + + Lod 200 + ColorMask RGB + + Pass { + Blend SrcAlpha OneMinusSrcAlpha + ZTest LEqual + ZWrite Off + Cull Off + + CGPROGRAM + + #pragma vertex vert200 + #pragma fragment frag200 + #pragma multi_compile_fog + + ENDCG + } +} + +Fallback "Transparent/Diffuse" +} diff --git a/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Advanced.shader.meta b/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Advanced.shader.meta new file mode 100644 index 00000000..44952fb2 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Advanced.shader.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 475c4a4e617a8401b84ca7b32c7cc460 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Simple.shader b/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Simple.shader new file mode 100644 index 00000000..cb58c6e0 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Simple.shader @@ -0,0 +1,435 @@ +// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' + +Shader "FX/SimpleWater4" { +Properties { + _ReflectionTex ("Internal reflection", 2D) = "white" {} + + _MainTex ("Fallback texture", 2D) = "black" {} + _BumpMap ("Normals ", 2D) = "bump" {} + + _DistortParams ("Distortions (Bump waves, Reflection, Fresnel power, Fresnel bias)", Vector) = (1.0 ,1.0, 2.0, 1.15) + _InvFadeParemeter ("Auto blend parameter (Edge, Shore, Distance scale)", Vector) = (0.15 ,0.15, 0.5, 1.0) + + _AnimationTiling ("Animation Tiling (Displacement)", Vector) = (2.2 ,2.2, -1.1, -1.1) + _AnimationDirection ("Animation Direction (displacement)", Vector) = (1.0 ,1.0, 1.0, 1.0) + + _BumpTiling ("Bump Tiling", Vector) = (1.0 ,1.0, -2.0, 3.0) + _BumpDirection ("Bump Direction & Speed", Vector) = (1.0 ,1.0, -1.0, 1.0) + + _FresnelScale ("FresnelScale", Range (0.15, 4.0)) = 0.75 + + _BaseColor ("Base color", COLOR) = ( .54, .95, .99, 0.5) + _ReflectionColor ("Reflection color", COLOR) = ( .54, .95, .99, 0.5) + _SpecularColor ("Specular color", COLOR) = ( .72, .72, .72, 1) + + _WorldLightDir ("Specular light direction", Vector) = (0.0, 0.1, -0.5, 0.0) + _Shininess ("Shininess", Range (2.0, 500.0)) = 200.0 + + _GerstnerIntensity("Per vertex displacement", Float) = 1.0 + _GAmplitude ("Wave Amplitude", Vector) = (0.3 ,0.35, 0.25, 0.25) + _GFrequency ("Wave Frequency", Vector) = (1.3, 1.35, 1.25, 1.25) + _GSteepness ("Wave Steepness", Vector) = (1.0, 1.0, 1.0, 1.0) + _GSpeed ("Wave Speed", Vector) = (1.2, 1.375, 1.1, 1.5) + _GDirectionAB ("Wave Direction", Vector) = (0.3 ,0.85, 0.85, 0.25) + _GDirectionCD ("Wave Direction", Vector) = (0.1 ,0.9, 0.5, 0.5) +} + + +CGINCLUDE + + #include "UnityCG.cginc" + #include "WaterInclude.cginc" + + struct appdata + { + float4 vertex : POSITION; + float3 normal : NORMAL; + }; + + // interpolator structs + + struct v2f + { + float4 pos : SV_POSITION; + float4 normalInterpolator : TEXCOORD0; + float3 viewInterpolator : TEXCOORD1; + float4 bumpCoords : TEXCOORD2; + float4 screenPos : TEXCOORD3; + float4 grabPassPos : TEXCOORD4; + UNITY_FOG_COORDS(5) + }; + + struct v2f_noGrab + { + float4 pos : SV_POSITION; + float4 normalInterpolator : TEXCOORD0; + float3 viewInterpolator : TEXCOORD1; + float4 bumpCoords : TEXCOORD2; + float4 screenPos : TEXCOORD3; + UNITY_FOG_COORDS(4) + }; + + struct v2f_simple + { + float4 pos : SV_POSITION; + float3 viewInterpolator : TEXCOORD0; + float4 bumpCoords : TEXCOORD1; + UNITY_FOG_COORDS(2) + }; + + // textures + sampler2D _BumpMap; + sampler2D _ReflectionTex; + sampler2D _RefractionTex; + sampler2D _ShoreTex; + sampler2D_float _CameraDepthTexture; + + // colors in use + uniform float4 _RefrColorDepth; + uniform float4 _SpecularColor; + uniform float4 _BaseColor; + uniform float4 _ReflectionColor; + + // edge & shore fading + uniform float4 _InvFadeParemeter; + + // specularity + uniform float _Shininess; + uniform float4 _WorldLightDir; + + // fresnel, vertex & bump displacements & strength + uniform float4 _DistortParams; + uniform float _FresnelScale; + uniform float4 _BumpTiling; + uniform float4 _BumpDirection; + + uniform float4 _GAmplitude; + uniform float4 _GFrequency; + uniform float4 _GSteepness; + uniform float4 _GSpeed; + uniform float4 _GDirectionAB; + uniform float4 _GDirectionCD; + + // shortcuts + #define PER_PIXEL_DISPLACE _DistortParams.x + #define REALTIME_DISTORTION _DistortParams.y + #define FRESNEL_POWER _DistortParams.z + #define VERTEX_WORLD_NORMAL i.normalInterpolator.xyz + #define DISTANCE_SCALE _InvFadeParemeter.z + #define FRESNEL_BIAS _DistortParams.w + + // + // HQ VERSION + // + + v2f vert(appdata_full v) + { + v2f o; + + half3 worldSpaceVertex = mul(unity_ObjectToWorld,(v.vertex)).xyz; + half3 vtxForAni = (worldSpaceVertex).xzz; + + half3 nrml; + half3 offsets; + + Gerstner ( + offsets, nrml, v.vertex.xyz, vtxForAni, // offsets, nrml will be written + _GAmplitude, // amplitude + _GFrequency, // frequency + _GSteepness, // steepness + _GSpeed, // speed + _GDirectionAB, // direction # 1, 2 + _GDirectionCD // direction # 3, 4 + ); + + v.vertex.xyz += offsets; + + half2 tileableUv = worldSpaceVertex.xz; + + o.bumpCoords.xyzw = (tileableUv.xyxy + _Time.xxxx * _BumpDirection.xyzw) * _BumpTiling.xyzw; + + o.viewInterpolator.xyz = worldSpaceVertex - _WorldSpaceCameraPos; + + o.pos = UnityObjectToClipPos(v.vertex); + + ComputeScreenAndGrabPassPos(o.pos, o.screenPos, o.grabPassPos); + + o.normalInterpolator.xyz = nrml; + + o.normalInterpolator.w = 1; //GetDistanceFadeout(o.screenPos.w, DISTANCE_SCALE); + + UNITY_TRANSFER_FOG(o,o.pos); + return o; + } + + half4 frag( v2f i ) : SV_Target + { + half3 worldNormal = PerPixelNormal(_BumpMap, i.bumpCoords, VERTEX_WORLD_NORMAL, PER_PIXEL_DISPLACE); + half3 viewVector = normalize(i.viewInterpolator.xyz); + + half4 distortOffset = half4(worldNormal.xz * REALTIME_DISTORTION * 10.0, 0, 0); + half4 screenWithOffset = i.screenPos + distortOffset; + half4 grabWithOffset = i.grabPassPos + distortOffset; + + half4 rtRefractionsNoDistort = tex2Dproj(_RefractionTex, UNITY_PROJ_COORD(i.grabPassPos)); + half refrFix = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(grabWithOffset)); + half4 rtRefractions = tex2Dproj(_RefractionTex, UNITY_PROJ_COORD(grabWithOffset)); + + #ifdef WATER_REFLECTIVE + half4 rtReflections = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(screenWithOffset)); + #endif + + #ifdef WATER_EDGEBLEND_ON + if (LinearEyeDepth(refrFix) < i.screenPos.z) + rtRefractions = rtRefractionsNoDistort; + #endif + + half3 reflectVector = normalize(reflect(viewVector, worldNormal)); + half3 h = normalize ((_WorldLightDir.xyz) + viewVector.xyz); + float nh = max (0, dot (worldNormal, -h)); + float spec = max(0.0,pow (nh, _Shininess)); + + half4 edgeBlendFactors = half4(1.0, 0.0, 0.0, 0.0); + + #ifdef WATER_EDGEBLEND_ON + half depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos)); + depth = LinearEyeDepth(depth); + edgeBlendFactors = saturate(_InvFadeParemeter * (depth-i.screenPos.w)); + #endif + + // shading for fresnel term + worldNormal.xz *= _FresnelScale; + half refl2Refr = Fresnel(viewVector, worldNormal, FRESNEL_BIAS, FRESNEL_POWER); + + // base, depth & reflection colors + half4 baseColor = _BaseColor; + #ifdef WATER_REFLECTIVE + half4 reflectionColor = lerp (rtReflections,_ReflectionColor,_ReflectionColor.a); + #else + half4 reflectionColor = _ReflectionColor; + #endif + + baseColor = lerp (lerp (rtRefractions, baseColor, baseColor.a), reflectionColor, refl2Refr); + baseColor = baseColor + spec * _SpecularColor; + + baseColor.a = edgeBlendFactors.x; + UNITY_APPLY_FOG(i.fogCoord, baseColor); + return baseColor; + } + + // + // MQ VERSION + // + + v2f_noGrab vert300(appdata_full v) + { + v2f_noGrab o; + + half3 worldSpaceVertex = mul(unity_ObjectToWorld,(v.vertex)).xyz; + half3 vtxForAni = (worldSpaceVertex).xzz; + + half3 nrml; + half3 offsets; + Gerstner ( + offsets, nrml, v.vertex.xyz, vtxForAni, // offsets, nrml will be written + _GAmplitude, // amplitude + _GFrequency, // frequency + _GSteepness, // steepness + _GSpeed, // speed + _GDirectionAB, // direction # 1, 2 + _GDirectionCD // direction # 3, 4 + ); + + v.vertex.xyz += offsets; + + half2 tileableUv = worldSpaceVertex.xz; + + o.bumpCoords.xyzw = (tileableUv.xyxy + _Time.xxxx * _BumpDirection.xyzw) * _BumpTiling.xyzw; + + o.viewInterpolator.xyz = worldSpaceVertex - _WorldSpaceCameraPos; + + o.pos = UnityObjectToClipPos(v.vertex); + + o.screenPos = ComputeNonStereoScreenPos(o.pos); + + o.normalInterpolator.xyz = nrml; + + o.normalInterpolator.w = 1; //GetDistanceFadeout(o.screenPos.w, DISTANCE_SCALE); + + UNITY_TRANSFER_FOG(o,o.pos); + return o; + } + + half4 frag300( v2f_noGrab i ) : SV_Target + { + half3 worldNormal = PerPixelNormal(_BumpMap, i.bumpCoords, VERTEX_WORLD_NORMAL, PER_PIXEL_DISPLACE); + half3 viewVector = normalize(i.viewInterpolator.xyz); + + half4 distortOffset = half4(worldNormal.xz * REALTIME_DISTORTION * 10.0, 0, 0); + half4 screenWithOffset = i.screenPos + distortOffset; + + #ifdef WATER_REFLECTIVE + half4 rtReflections = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(screenWithOffset)); + #endif + + half3 reflectVector = normalize(reflect(viewVector, worldNormal)); + half3 h = normalize (_WorldLightDir.xyz + viewVector.xyz); + float nh = max (0, dot (worldNormal, -h)); + float spec = max(0.0,pow (nh, _Shininess)); + + half4 edgeBlendFactors = half4(1.0, 0.0, 0.0, 0.0); + + #ifdef WATER_EDGEBLEND_ON + half depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos)); + depth = LinearEyeDepth(depth); + edgeBlendFactors = saturate(_InvFadeParemeter * (depth-i.screenPos.z)); + #endif + + worldNormal.xz *= _FresnelScale; + half refl2Refr = Fresnel(viewVector, worldNormal, FRESNEL_BIAS, FRESNEL_POWER); + + half4 baseColor = _BaseColor; + #ifdef WATER_REFLECTIVE + baseColor = lerp (baseColor, lerp (rtReflections,_ReflectionColor,_ReflectionColor.a), saturate(refl2Refr * 1.0)); + #else + baseColor = _ReflectionColor; //lerp (baseColor, _ReflectionColor, saturate(refl2Refr * 2.0)); + #endif + + baseColor = baseColor + spec * _SpecularColor; + + baseColor.a = edgeBlendFactors.x * saturate(0.5 + refl2Refr * 1.0); + UNITY_APPLY_FOG(i.fogCoord, baseColor); + return baseColor; + } + + // + // LQ VERSION + // + + v2f_simple vert200(appdata_full v) + { + v2f_simple o; + + half3 worldSpaceVertex = mul(unity_ObjectToWorld, v.vertex).xyz; + half2 tileableUv = worldSpaceVertex.xz; + + o.bumpCoords.xyzw = (tileableUv.xyxy + _Time.xxxx * _BumpDirection.xyzw) * _BumpTiling.xyzw; + + o.viewInterpolator.xyz = worldSpaceVertex-_WorldSpaceCameraPos; + + o.pos = UnityObjectToClipPos( v.vertex); + + UNITY_TRANSFER_FOG(o,o.pos); + return o; + + } + + half4 frag200( v2f_simple i ) : SV_Target + { + half3 worldNormal = PerPixelNormal(_BumpMap, i.bumpCoords, half3(0,1,0), PER_PIXEL_DISPLACE); + half3 viewVector = normalize(i.viewInterpolator.xyz); + + half3 reflectVector = normalize(reflect(viewVector, worldNormal)); + half3 h = normalize ((_WorldLightDir.xyz) + viewVector.xyz); + float nh = max (0, dot (worldNormal, -h)); + float spec = max(0.0,pow (nh, _Shininess)); + + worldNormal.xz *= _FresnelScale; + half refl2Refr = Fresnel(viewVector, worldNormal, FRESNEL_BIAS, FRESNEL_POWER); + + half4 baseColor = _BaseColor; + baseColor = lerp(baseColor, _ReflectionColor, saturate(refl2Refr * 2.0)); + baseColor.a = saturate(2.0 * refl2Refr + 0.5); + + baseColor.rgb += spec * _SpecularColor.rgb; + UNITY_APPLY_FOG(i.fogCoord, baseColor); + return baseColor; + } + +ENDCG + +Subshader +{ + Tags {"RenderType"="Transparent" "Queue"="Transparent"} + + Lod 500 + ColorMask RGB + + GrabPass { "_RefractionTex" } + + Pass { + Blend SrcAlpha OneMinusSrcAlpha + ZTest LEqual + ZWrite Off + Cull Off + + CGPROGRAM + + #pragma target 3.0 + + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_fog + + #pragma multi_compile WATER_VERTEX_DISPLACEMENT_ON WATER_VERTEX_DISPLACEMENT_OFF + #pragma multi_compile WATER_EDGEBLEND_ON WATER_EDGEBLEND_OFF + #pragma multi_compile WATER_REFLECTIVE WATER_SIMPLE + + ENDCG + } +} + +Subshader +{ + Tags {"RenderType"="Transparent" "Queue"="Transparent"} + + Lod 300 + ColorMask RGB + + Pass { + Blend SrcAlpha OneMinusSrcAlpha + ZTest LEqual + ZWrite Off + Cull Off + + CGPROGRAM + + #pragma target 3.0 + + #pragma vertex vert300 + #pragma fragment frag300 + #pragma multi_compile_fog + + #pragma multi_compile WATER_VERTEX_DISPLACEMENT_ON WATER_VERTEX_DISPLACEMENT_OFF + #pragma multi_compile WATER_EDGEBLEND_ON WATER_EDGEBLEND_OFF + #pragma multi_compile WATER_REFLECTIVE WATER_SIMPLE + + ENDCG + } +} + +Subshader +{ + Tags {"RenderType"="Transparent" "Queue"="Transparent"} + + Lod 200 + ColorMask RGB + + Pass { + Blend SrcAlpha OneMinusSrcAlpha + ZTest LEqual + ZWrite Off + Cull Off + + CGPROGRAM + + #pragma vertex vert200 + #pragma fragment frag200 + #pragma multi_compile_fog + + ENDCG + } +} + +Fallback "Transparent/Diffuse" +} diff --git a/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Simple.shader.meta b/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Simple.shader.meta new file mode 100644 index 00000000..8b60e33e --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Shaders/FXWater4Simple.shader.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 8aaff0751054e4a9cb4642d01eaf5be9 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Shaders/WaterInclude.cginc b/Assets/Standard Assets/Environment/Water/Water4/Shaders/WaterInclude.cginc new file mode 100644 index 00000000..961d4389 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Shaders/WaterInclude.cginc @@ -0,0 +1,257 @@ + +#ifndef WATER_CG_INCLUDED +#define WATER_CG_INCLUDED + +#include "UnityCG.cginc" + +half _GerstnerIntensity; + +inline half3 PerPixelNormal(sampler2D bumpMap, half4 coords, half3 vertexNormal, half bumpStrength) +{ + half3 bump = (UnpackNormal(tex2D(bumpMap, coords.xy)) + UnpackNormal(tex2D(bumpMap, coords.zw))) * 0.5; + half3 worldNormal = vertexNormal + bump.xxy * bumpStrength * half3(1,0,1); + return normalize(worldNormal); +} + +inline half3 PerPixelNormalUnpacked(sampler2D bumpMap, half4 coords, half bumpStrength) +{ + half4 bump = tex2D(bumpMap, coords.xy) + tex2D(bumpMap, coords.zw); + bump = bump * 0.5; + half3 normal = UnpackNormal(bump); + normal.xy *= bumpStrength; + return normalize(normal); +} + +inline half3 GetNormal(half4 tf) { + #ifdef WATER_VERTEX_DISPLACEMENT_ON + return half3(2,1,2) * tf.rbg - half3(1,0,1); + #else + return half3(0,1,0); + #endif +} + +inline half GetDistanceFadeout(half screenW, half speed) { + return 1.0f / abs(0.5f + screenW * speed); +} + +half4 GetDisplacement3(half4 tileableUv, half4 tiling, half4 directionSpeed, sampler2D mapA, sampler2D mapB, sampler2D mapC) +{ + half4 displacementUv = tileableUv * tiling + _Time.xxxx * directionSpeed; + #ifdef WATER_VERTEX_DISPLACEMENT_ON + half4 tf = tex2Dlod(mapA, half4(displacementUv.xy, 0.0,0.0)); + tf += tex2Dlod(mapB, half4(displacementUv.zw, 0.0,0.0)); + tf += tex2Dlod(mapC, half4(displacementUv.xw, 0.0,0.0)); + tf *= 0.333333; + #else + half4 tf = half4(0.5,0.5,0.5,0.0); + #endif + + return tf; +} + +half4 GetDisplacement2(half4 tileableUv, half4 tiling, half4 directionSpeed, sampler2D mapA, sampler2D mapB) +{ + half4 displacementUv = tileableUv * tiling + _Time.xxxx * directionSpeed; + #ifdef WATER_VERTEX_DISPLACEMENT_ON + half4 tf = tex2Dlod(mapA, half4(displacementUv.xy, 0.0,0.0)); + tf += tex2Dlod(mapB, half4(displacementUv.zw, 0.0,0.0)); + tf *= 0.5; + #else + half4 tf = half4(0.5,0.5,0.5,0.0); + #endif + + return tf; +} + +inline void ComputeScreenAndGrabPassPos (float4 pos, out float4 screenPos, out float4 grabPassPos) +{ + #if UNITY_UV_STARTS_AT_TOP + float scale = -1.0; + #else + float scale = 1.0f; + #endif + + screenPos = ComputeNonStereoScreenPos(pos); + grabPassPos.xy = ( float2( pos.x, pos.y*scale ) + pos.w ) * 0.5; + grabPassPos.zw = pos.zw; +} + + +inline half3 PerPixelNormalUnpacked(sampler2D bumpMap, half4 coords, half bumpStrength, half2 perVertxOffset) +{ + half4 bump = tex2D(bumpMap, coords.xy) + tex2D(bumpMap, coords.zw); + bump = bump * 0.5; + half3 normal = UnpackNormal(bump); + normal.xy *= bumpStrength; + normal.xy += perVertxOffset; + return normalize(normal); +} + +inline half3 PerPixelNormalLite(sampler2D bumpMap, half4 coords, half3 vertexNormal, half bumpStrength) +{ + half4 bump = tex2D(bumpMap, coords.xy); + bump.xy = bump.wy - half2(0.5, 0.5); + half3 worldNormal = vertexNormal + bump.xxy * bumpStrength * half3(1,0,1); + return normalize(worldNormal); +} + +inline half4 Foam(sampler2D shoreTex, half4 coords, half amount) +{ + half4 foam = ( tex2D(shoreTex, coords.xy) * tex2D(shoreTex,coords.zw) ) - 0.125; + foam.a = amount; + return foam; +} + +inline half4 Foam(sampler2D shoreTex, half4 coords) +{ + half4 foam = (tex2D(shoreTex, coords.xy) * tex2D(shoreTex,coords.zw)) - 0.125; + return foam; +} + +inline half Fresnel(half3 viewVector, half3 worldNormal, half bias, half power) +{ + half facing = clamp(1.0-max(dot(-viewVector, worldNormal), 0.0), 0.0,1.0); + half refl2Refr = saturate(bias+(1.0-bias) * pow(facing,power)); + return refl2Refr; +} + +inline half FresnelViaTexture(half3 viewVector, half3 worldNormal, sampler2D fresnel) +{ + half facing = saturate(dot(-viewVector, worldNormal)); + half fresn = tex2D(fresnel, half2(facing, 0.5f)).b; + return fresn; +} + +inline void VertexDisplacementHQ( sampler2D mapA, sampler2D mapB, + sampler2D mapC, half4 uv, + half vertexStrength, half3 normal, + out half4 vertexOffset, out half2 normalOffset) +{ + half4 tf = tex2Dlod(mapA, half4(uv.xy, 0.0,0.0)); + tf += tex2Dlod(mapB, half4(uv.zw, 0.0,0.0)); + tf += tex2Dlod(mapC, half4(uv.xw, 0.0,0.0)); + tf /= 3.0; + + tf.rga = tf.rga-half3(0.5,0.5,0.0); + + // height displacement in alpha channel, normals info in rgb + + vertexOffset = tf.a * half4(normal.xyz, 0.0) * vertexStrength; + normalOffset = tf.rg; +} + +inline void VertexDisplacementLQ( sampler2D mapA, sampler2D mapB, + sampler2D mapC, half4 uv, + half vertexStrength, half normalsStrength, + out half4 vertexOffset, out half2 normalOffset) +{ + // @NOTE: for best performance, this should really be properly packed! + + half4 tf = tex2Dlod(mapA, half4(uv.xy, 0.0,0.0)); + tf += tex2Dlod(mapB, half4(uv.zw, 0.0,0.0)); + tf *= 0.5; + + tf.rga = tf.rga-half3(0.5,0.5,0.0); + + // height displacement in alpha channel, normals info in rgb + + vertexOffset = tf.a * half4(0,1,0,0) * vertexStrength; + normalOffset = tf.rg * normalsStrength; +} + +half4 ExtinctColor (half4 baseColor, half extinctionAmount) +{ + // tweak the extinction coefficient for different coloring + return baseColor - extinctionAmount * half4(0.15, 0.03, 0.01, 0.0); +} + + half3 GerstnerOffsets (half2 xzVtx, half steepness, half amp, half freq, half speed, half2 dir) + { + half3 offsets; + + offsets.x = + steepness * amp * dir.x * + cos( freq * dot( dir, xzVtx ) + speed * _Time.x); + + offsets.z = + steepness * amp * dir.y * + cos( freq * dot( dir, xzVtx ) + speed * _Time.x); + + offsets.y = + amp * sin ( freq * dot( dir, xzVtx ) + speed * _Time.x); + + return offsets; + } + + half3 GerstnerOffset4 (half2 xzVtx, half4 steepness, half4 amp, half4 freq, half4 speed, half4 dirAB, half4 dirCD) + { + half3 offsets; + + half4 AB = steepness.xxyy * amp.xxyy * dirAB.xyzw; + half4 CD = steepness.zzww * amp.zzww * dirCD.xyzw; + + half4 dotABCD = freq.xyzw * half4(dot(dirAB.xy, xzVtx), dot(dirAB.zw, xzVtx), dot(dirCD.xy, xzVtx), dot(dirCD.zw, xzVtx)); + half4 TIME = _Time.yyyy * speed; + + half4 COS = cos (dotABCD + TIME); + half4 SIN = sin (dotABCD + TIME); + + offsets.x = dot(COS, half4(AB.xz, CD.xz)); + offsets.z = dot(COS, half4(AB.yw, CD.yw)); + offsets.y = dot(SIN, amp); + + return offsets; + } + + half3 GerstnerNormal (half2 xzVtx, half steepness, half amp, half freq, half speed, half2 dir) + { + half3 nrml = half3(0,0,0); + + nrml.x -= + dir.x * (amp * freq) * + cos(freq * dot( dir, xzVtx ) + speed * _Time.x); + + nrml.z -= + dir.y * (amp * freq) * + cos(freq * dot( dir, xzVtx ) + speed * _Time.x); + + return nrml; + } + + half3 GerstnerNormal4 (half2 xzVtx, half4 amp, half4 freq, half4 speed, half4 dirAB, half4 dirCD) + { + half3 nrml = half3(0,2.0,0); + + half4 AB = freq.xxyy * amp.xxyy * dirAB.xyzw; + half4 CD = freq.zzww * amp.zzww * dirCD.xyzw; + + half4 dotABCD = freq.xyzw * half4(dot(dirAB.xy, xzVtx), dot(dirAB.zw, xzVtx), dot(dirCD.xy, xzVtx), dot(dirCD.zw, xzVtx)); + half4 TIME = _Time.yyyy * speed; + + half4 COS = cos (dotABCD + TIME); + + nrml.x -= dot(COS, half4(AB.xz, CD.xz)); + nrml.z -= dot(COS, half4(AB.yw, CD.yw)); + + nrml.xz *= _GerstnerIntensity; + nrml = normalize (nrml); + + return nrml; + } + + void Gerstner ( out half3 offs, out half3 nrml, + half3 vtx, half3 tileableVtx, + half4 amplitude, half4 frequency, half4 steepness, + half4 speed, half4 directionAB, half4 directionCD ) + { + #ifdef WATER_VERTEX_DISPLACEMENT_ON + offs = GerstnerOffset4(tileableVtx.xz, steepness, amplitude, frequency, speed, directionAB, directionCD); + nrml = GerstnerNormal4(tileableVtx.xz + offs.xz, amplitude, frequency, speed, directionAB, directionCD); + #else + offs = half3(0,0,0); + nrml = half3(0,1,0); + #endif + } + + +#endif diff --git a/Assets/Standard Assets/Environment/Water/Water4/Shaders/WaterInclude.cginc.meta b/Assets/Standard Assets/Environment/Water/Water4/Shaders/WaterInclude.cginc.meta new file mode 100644 index 00000000..6d8dcf23 --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Shaders/WaterInclude.cginc.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 34e1452e07a0b40c295c5b10aa679465 +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Textures.meta b/Assets/Standard Assets/Environment/Water/Water4/Textures.meta new file mode 100644 index 00000000..ef29949b --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Textures.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 3cc8ac37e0da341db819af6143a07b03 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Textures/SimpleFoam.png b/Assets/Standard Assets/Environment/Water/Water4/Textures/SimpleFoam.png new file mode 100644 index 00000000..e83c171e Binary files /dev/null and b/Assets/Standard Assets/Environment/Water/Water4/Textures/SimpleFoam.png differ diff --git a/Assets/Standard Assets/Environment/Water/Water4/Textures/SimpleFoam.png.meta b/Assets/Standard Assets/Environment/Water/Water4/Textures/SimpleFoam.png.meta new file mode 100644 index 00000000..ccbd4ded --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Textures/SimpleFoam.png.meta @@ -0,0 +1,52 @@ +fileFormatVersion: 2 +guid: 36dd0b22da8874ed38075789055ca664 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Standard Assets/Environment/Water/Water4/Textures/SmallWaves.png b/Assets/Standard Assets/Environment/Water/Water4/Textures/SmallWaves.png new file mode 100644 index 00000000..477d61ca Binary files /dev/null and b/Assets/Standard Assets/Environment/Water/Water4/Textures/SmallWaves.png differ diff --git a/Assets/Standard Assets/Environment/Water/Water4/Textures/SmallWaves.png.meta b/Assets/Standard Assets/Environment/Water/Water4/Textures/SmallWaves.png.meta new file mode 100644 index 00000000..94b3ef7c --- /dev/null +++ b/Assets/Standard Assets/Environment/Water/Water4/Textures/SmallWaves.png.meta @@ -0,0 +1,52 @@ +fileFormatVersion: 2 +guid: fb6566c21f717904f83743a5a76dd0b0 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 1 + externalNormalMap: 1 + heightScale: .131052643 + normalMapFilter: 1 + isReadable: 1 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 256 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: diff --git a/Assets/Textures.meta b/Assets/Textures.meta new file mode 100644 index 00000000..2c758825 --- /dev/null +++ b/Assets/Textures.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec8805b280ed949faabc86dd45fef677 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Textures/logo.png b/Assets/Textures/logo.png new file mode 100644 index 00000000..38fdae49 Binary files /dev/null and b/Assets/Textures/logo.png differ diff --git a/Assets/Textures/logo.png.meta b/Assets/Textures/logo.png.meta new file mode 100644 index 00000000..32a27dfc --- /dev/null +++ b/Assets/Textures/logo.png.meta @@ -0,0 +1,84 @@ +fileFormatVersion: 2 +guid: 7ba03d38f2c9d483eb98097a1990d3ec +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Data/SFX_GENRL_137.txt b/Data/SFX_GENRL_137.txt new file mode 100644 index 00000000..b7b5c47c --- /dev/null +++ b/Data/SFX_GENRL_137.txt @@ -0,0 +1,89 @@ +0 6148 25600 +6148 6186 25600 +12334 28580 12800 +40914 4286 22000 +45200 4286 22000 +49486 43376 20000 +92862 7884 26600 +100746 7884 26600 +108630 32602 16000 +141232 19486 22050 +160718 28448 15000 +189166 4086 14364 +193252 4086 14364 +197338 4086 14364 +201424 5992 18569 +207416 4368 24000 +211784 2276 8000 +214060 3998 23000 +218058 4328 23000 +222386 21112 8000 +243498 26824 8000 +270322 9816 26000 +280138 9816 26000 +289954 80834 19200 +370788 4924 17600 +375712 4916 17600 +380628 12630 24000 +393258 12630 24000 +405888 25424 28000 +431312 2276 26400 +433588 1502 8000 +435090 17388 23000 +452478 8550 23000 +461028 8816 24000 +469844 2980 22050 +472824 6366 10000 +479190 7492 22050 +486682 8898 22050 +495580 7774 22050 +503354 7712 22050 +511066 6824 22050 +517890 9328 22050 +527218 11506 22050 +538724 11744 22050 +550468 1246 18000 +551714 21264 18000 +572978 5440 22050 +578418 4762 24000 +583180 3314 22050 +586494 2130 8000 +588624 3178 16000 +591802 10676 24600 +602478 7868 28000 +610346 1416 8000 +611762 17546 23000 +629308 2072 19700 +631380 7406 18000 +638786 12396 18000 +651182 404 16500 +651586 12256 22050 +663842 14976 22050 +678818 8792 22050 +687610 12608 22050 +700218 62472 21600 +762690 39288 16600 +801978 17926 16000 +819904 4182 23000 +824086 4102 18000 +828188 24790 22050 +852978 13678 21000 +866656 8640 22400 +875296 3422 17600 +878718 14654 22000 +893372 5394 26000 +898766 5152 8000 +903918 11284 18000 +915202 2604 44100 +917806 5648 44100 +923454 9218 22050 +932672 8704 22050 +941376 9078 22050 +950454 17368 21000 +967822 10322 22050 +978144 12254 32000 +990398 5950 22400 +996348 5584 24000 +1001932 6198 18000 +1008130 10256 21000 +1018386 3516 17800 diff --git a/Data/auxanimgrp.dat b/Data/auxanimgrp.dat new file mode 100644 index 00000000..fb13d357 --- /dev/null +++ b/Data/auxanimgrp.dat @@ -0,0 +1,162 @@ +# +# filename: auxanimgrp.dat +# description: This file describes additional anim association groups. +# +#format is +# name, filename, animtype, numanims +# animlist.... +#end +# +# name: name of animation definition group +# filename: name of file in which these animations occur (minus the IFP extension) +# animtype: type of animations +# numanims: number of animations in groups +# + +default, ped, car, 12 + CAR_sit + CAR_sitp + Drive_L + Drive_R + CAR_getin_LHS + CAR_getin_RHS + CAR_getout_LHS + CAR_getout_RHS + CAR_closedoor_LHS + CAR_closedoor_RHS + CAR_close_LHS + CAR_close_RHS +end + +default, ped, mywalkcycle, 4 + IDLE_ARMED + FUCKU + GUN_STAND + sprint_civi +end + +default, ped, gun, 23 + GunCrouchBwd + GunCrouchFwd + GunMove_BWD + GunMove_FWD + GunMove_L + GunMove_R + Gun_2_IDLE + GUN_BUTT + GUN_BUTT_crouch + Gun_stand + IDLE_armed + run_1armed + run_armed + run_left + run_right + run_player + sprint_civi + WALK_armed + WALK_start_armed + SHOT_leftP + SHOT_partial + SHOT_partial_B + SHOT_rightP +end + +default, weapons, weapons, 17 + SHP_1H_Lift + SHP_1H_Lift_End + SHP_1H_Ret + SHP_1H_Ret_S + SHP_2H_Lift + SHP_2H_Lift_End + SHP_2H_Ret + SHP_2H_Ret_S + SHP_Ar_Lift + SHP_Ar_Lift_End + SHP_Ar_Ret + SHP_Ar_Ret_S + SHP_G_Lift_In + SHP_G_Lift_Out + SHP_Tray_In + SHP_Tray_Out + SHP_Tray_Pose +end + +default, colt45, colt45, 7 + colt45_fire + COLT45_RELOAD + colt45_crouchfire + colt45_fire_2hands + 2guns_crouchfire + colt45_crouchreload + sawnoff_reload +end + +default, silenced, silenced, 4 + CrouchReload + SilenceCrouchfire + Silence_fire + Silence_reload +end + +default, python, python, 5 + python_crouchfire + python_crouchreload + python_fire + python_fire_poor + python_reload +end + +default, shotgun, shotgun, 3 + shotgun_crouchfire + shotgun_fire + shotgun_fire_poor +end + +default, buddy, buddy, 5 + buddy_crouchfire + buddy_crouchreload + buddy_fire + buddy_fire_poor + buddy_fire_reload +end + +default, tec, tec, 4 + TEC_crouchfire + TEC_crouchreload + TEC_fire + TEC_reload +end + +default, uzi, uzi, 5 + UZI_crouchfire + UZI_crouchreload + UZI_fire + UZI_fire_poor + UZI_reload +end + +default, rifle, rifle, 5 + RIFLE_crouchfire + RIFLE_crouchload + RIFLE_fire + RIFLE_fire_poor + RIFLE_load +end + +default, rocket, rocket, 5 + idle_rocket + RocketFire + run_rocket + walk_rocket + WALK_start_rocket +end + +default, flame, flame, 1 + FLAME_fire +end + +default, grenade, grenade, 3 + WEAPON_start_throw + WEAPON_throw + WEAPON_throwu +end diff --git a/Docs/AddingNewAnims.md b/Docs/AddingNewAnims.md new file mode 100644 index 00000000..822ef6ef --- /dev/null +++ b/Docs/AddingNewAnims.md @@ -0,0 +1,42 @@ + +## Adding/playing new anims + + +There are 2 ways to play anim: + +- using it's anim group and index + +- using it's ifp file name and anim name (needs testing) + +
+### Anim groups + +Anims can be placed in groups. The idea is that peds' anims can be grouped, so that using the same index, you can play different anims for different ped groups. + +For example, if you use AnimGroup.WalkCycle as anim group, and AnimIndex.Walk as index, then when ped is a man, 'walk_civi' will be player, and when ped is a woman, 'woman_walknorm' will be played. + +Anim groups are defined inside /Data/auxanimgrp.dat file. You can read more about file structure in that file. + +If you want to add new anims, you can add them to existing group, or create new group. After you added them to a file, you will need to update AnimGroup and AnimIndex enumerations, so that you can play those anims. + +Example for playing walk anim: + + Pedestrian.PlayAnim (AnimGroup.WalkCycle, AnimIndex.Walk) + +
+### Ifp file name and anim name + +This method is not tested, but in the future, it will be the main method for playing anims. + +All you have to do when you want to play anim, is to call: + + Pedestrian.PlayAnim (animId) + +where 'animId' is the anim you want to play. + +For example: + + Pedestrian.PlayAnim (new AnimId('ped', 'roadcross')) + +this will play anim which is located in *ped.ifp*, and which is called *roadcross* + diff --git a/Docs/AsyncAssetLoading.md b/Docs/AsyncAssetLoading.md new file mode 100644 index 00000000..26f5bcc8 --- /dev/null +++ b/Docs/AsyncAssetLoading.md @@ -0,0 +1,45 @@ + + +All geometry and some other assets should be loaded async-ly. + +We need a background thread which loads assets from disk. It will have a queue, where any script can register it's file for loading. + +We need a way to wait until specific asset is loaded. + + +*** + +First identify what is taking time using Profiler. Maybe not all time goes on loading from disk. Some of it may be spent on converting the mesh. + +Identified what is taking time: + +- loading from disk (mostly takes around 20 ms, and goes up to 70 ms, but for some txds it goes to 100 ms) + +- creating mesh (mostly around 10 ms, but can go up to 100 ms) + +- attach collision model (mostly below the time to create mesh, but in some cases it goes to more than 100 ms) + +- updating divisions - runs almost every frame (especially when loading something), even though you invoke it with 100 ms interval - takes around 30 ms + + +*** + +## TODO + +- order in which Async functions will return is not equal to order of call to those functions - because some of loading objects may be cached - adjust Geometry.LoadAsync() when loading multiple textures + +- create meshes asyncly (this means converting mesh and it's textures) + +- attach collision model asyncly + +- update divisions in separate thread ? or optimize division system ? + +- unload map objects which are not visible to any focus point for given amount of time - this means destroying meshes, materials, textures, and removing references to loaded data in RAM + + +## TIPS + +- attaching collision model takes a lot of memory - why ? - because it reads archive file + +- dedicated server doesn't need textures - we can detect if we are running as dedicated server, and skip loading textures + diff --git a/Docs/Map.md b/Docs/Map.md new file mode 100644 index 00000000..58002a23 --- /dev/null +++ b/Docs/Map.md @@ -0,0 +1,26 @@ + +We'll have to convert map to use new unity UI system, because clipping doesn't work well with rotated objects in imGUI. + +No big deal, all calculations are done, just change the way the map items are drawn. + +Instead of drawing them every frame, we'll add/remove items from map. + +AddMapItem (MapItem), RemoveMapItem (MapItem) + +class MapItem { + + // use position from transform, or otherwise obtain it from delegates (this is useful if map item doesn't have it's game object) + bool usePositionFromTransform; + Transform transform; + bool applyRotation; // is map item rotated ? + System.Action getPosition; + System.Action getRotation; + bool isVisible; // is it currently visible ? + bool isClampedToEdge; // if item is not visible, is it clamped to edge of map ? + +} + +Then, for every map item create sprite, position it and optionally rotate it every frame, and enable/disable it based on whether it is in visible part of the map. + +We can still draw info area and some parts of the map using imGUI. + diff --git a/Docs/Multiplayer.md b/Docs/Multiplayer.md new file mode 100644 index 00000000..92ca33e3 --- /dev/null +++ b/Docs/Multiplayer.md @@ -0,0 +1,69 @@ + + +# What needs to be done before starting work on multiplayer + +- create windows for: start new game ; join game ; + +- all scripts should work when Camera.main is null + +- killing local ped + + + +# Potential problems + +- server will have multiple Cell focus points - the game can lag too much, so server has to run on a dedicated machine + + + +# Scripts that need to be synced across network + + +## Ped + +variables: + +- id +- transform +- is walking / running / sprinting +- heading +- is aiming +- is firing +- current weapon +- current vehicle - not needed - synced in Vehicle +- aim direction + +events: + +- fire +- enter/exit vehicle +- jump + + + +## Vehicle + +variables: + +- id +- transform +- car colors +- linear velocity +- angular velocity +- steering angle +- acceleration +- brake +- peds which occupy seats + + + +## Weapon + +variables: + +- id +- ammo in clip +- ammo outside of clip +- ped owner + + diff --git a/Docs/Performance.md b/Docs/Performance.md new file mode 100644 index 00000000..b86714eb --- /dev/null +++ b/Docs/Performance.md @@ -0,0 +1,24 @@ + + +## Rendering + +with max draw distance 500, on Fastest quality setting, in the center of Las Venturas: + +- around 50K vertices and triangles +- up to 600 setpass calls + +*** + +When shadows are turned on (with decent quality), frame time is increased by 1.5x (somewhere in Las Venturas) + + +## Loading + +- map loading speed can be increased by not using SetPixel() + + +## Vehicles + +- vehicles take too much frame time - their physics should be disabled when they stand in place + + diff --git a/Docs/TODO.md b/Docs/TODO.md new file mode 100644 index 00000000..b31f25ce --- /dev/null +++ b/Docs/TODO.md @@ -0,0 +1,72 @@ + +## TODO + + +- Weapons - see [weapons.md](weapons.md) + +- **Rigid body character** + +- Load map in editor ? + +- **Async geometry loading** - currently, geometry is loaded synchronously, which seems like the main performance bottleneck + +- Make everything networked + +- Map - better info area ; input mouse position is not always correct ; see [Map.md](Map.md) ; + +- Teleport : when ground is too far away (like on mountains), geometry around it will not be loaded, and raycast will not succeed ; when position is too low, player gets constantly respawned ; adapt all other teleport code ; + +- Crouching: adjust camera aim offset ? ; + +- don't fade high LOD meshes + +- Validate path to GTA ? + +- Anims must be played by their name + +- Vehicles window: it's too slow - use pages ; display additional info ; + +- Non-working ped model ids: WMYST, 0, special peds at the end, + +- Create custom inspector for ped - it will display info from ped definition + +- Pin windows - pinned windows are visible even when pause menu is not + +- Remove unneeded assets: files from Resources, + +- Bug when ped gets down to low heights (trying to move him back to starting location, and causing shaking) + +- Minimap size should depend on screen resolution + +- Limit number of messages in console to 200 + + +- Navigation: build navmesh from static geometry at runtime + +- Import: AI paths, ped spawn info, item pickups, + +- Implement other vehicles: airplanes, helicopters, bikes, boats + +- In-game input settings + +- Update audio library ; Don't use separate file for weapon sound timings ; + + +#### Vehicles + +- Adapt to damage system (so that they can be damaged and destroyed) + +- Wheels should be excluded from damage effects + +- Remove car blinkers and associated shaders + +- Some cars have its suspension too low to allow them to move + +- Car lights can't be turned off + +- Blinkers are not working correctly + +- In some cases damage to vehicles isn't performed at first collision + +- Repair cars with key + diff --git a/Docs/weapons.md b/Docs/weapons.md new file mode 100644 index 00000000..3f32e4ca --- /dev/null +++ b/Docs/weapons.md @@ -0,0 +1,83 @@ + +## About weapons implementation +
+ + +Loading weapons is easy, just load weapons.dat, and their models, and that's pretty much it. +
+ + +*** +
+ + +What is difficult, is to integrate weapons with animations. + +We need the following functionality: + +- When player aims, he needs to switch to another anim, and he needs to **lean his head** (how to do this, is there a separate anim for this ?). - Found the anims that were needed. + +- When player aims, his head and hands should rotate in that direction (including up and down), so we would need to somehow **rotate spine** or something + +- When player has a weapon in his hand, the **weapon should be attached to fingers** (maybe with a little adjustment for fingers) - this way player can do all anims (jump, run, etc), and weapon will remain on the proper place. This should only be done for specific anims. + +- There are cases when we need to **play 2 anims at the same time**. Examples: reloading a weapon, aim and move at the same time. How to do this ? Tried with anim blending, but it looked ugly. Try avatar mask ? + + +*** + +Each weapon has it's own anim group. So, anims will be played based on what weapon is held. + +But **how to determine position of weapon ?** Each weapon has firing offset, and aiming offset (maybe this is actually the position of weapon). - This can be done by testing. + +**Where to place hands ?** There is nothing in weapons.dat saying about this. Is it hardcoded ? Or shall we just play weaponaim anim, and somehow adjust hands/fingers based on type of the weapon (or his aim offset) ? - Looks like that this is handled by anim. + +*** + +These are the useful parameters in weapons.dat : + +- fire offset (this could be just the location of bullet when it's fired ?) +- aim offset (this could be position of weapon when it's held, or position of where the other hand should be ?) +- anim group + +*** + +### TODO + +- play separate anim for tec9 ? + +- let aim anim to control head (or spine ?), in order to better simulate bullet firing ? + +- improve aiming with AIMWITHARM weapons - upper arm should follow right vector of aiming, when aiming to side + +- reloading + +- when lerping upper arm transform toward player forward vector, arm is going on the opposite side - it seems that it depends on world rotation of player + +- spine should be rotated locally, not globally ? - some models have different rotation of spine in the idle anim, which means that their spine will not look at the same place - possible solution would be to play the same idle anim on all models + +- right after the model is loaded, reset model state - it's already done ? + +- rotate the pelvis instead of spine (because thighs look ugly) + +- rotate neck instead of spine, when following direction of aiming + +- play separate anim for: minigun and flame thrower, + + +#### Damage system + +- particles on place of hit + +- display inflicted damage as on-screen message + +- die animation ; ped needs to have IsDead bool variable - code has to be adapted ; + +- we need to raycast against ped mesh, not capsule collider ; also need to detect which part of body was hit + +- adapt vehicles to damage system + +- decals + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..f82e3b89 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 James King + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Packages/manifest.json b/Packages/manifest.json new file mode 100644 index 00000000..526aca60 --- /dev/null +++ b/Packages/manifest.json @@ -0,0 +1,4 @@ +{ + "dependencies": { + } +} diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 00000000..4f31e744 --- /dev/null +++ b/ProjectSettings/AudioManager.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 00000000..e7886b26 --- /dev/null +++ b/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 00000000..32d4c2c5 --- /dev/null +++ b/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,29 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 00000000..cff9991e --- /dev/null +++ b/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: + - enabled: 1 + path: Assets/Scenes/Startup.unity + guid: 025dece97687f439e94a9fe8c3b1b3fe + - enabled: 1 + path: Assets/Scenes/Main.unity + guid: d0dd0b2b82e7ac84c92f1fffb0a83854 + - enabled: 1 + path: Assets/Scenes/ModelViewer.unity + guid: 4d342ee4081345b4fa59c038c306616d + m_configObjects: {} diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset new file mode 100644 index 00000000..7b426952 --- /dev/null +++ b/ProjectSettings/EditorSettings.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_ExternalVersionControlSupport: Hidden Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 0 + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp + m_ProjectGenerationRootNamespace: + m_UserGeneratedProjectSuffix: + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 00000000..8fdf51c2 --- /dev/null +++ b/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10782, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 4800000, guid: 49fd1db3df113024cbd126e6512e1a72, type: 3} + - {fileID: 4800000, guid: 4b35cae85d16f8944bece3d3f097382f, type: 3} + - {fileID: 4800000, guid: d0ef1746d4f9edb4ea29696a672cdbd8, type: 3} + - {fileID: 4800000, guid: bb103097da716f9429c3e6f1bd163ec1, type: 3} + - {fileID: 4800000, guid: 1dfc503a7a71189419ce3bd16bd7fe8c, type: 3} + - {fileID: 4800000, guid: a30271b9e70d2e1449126ba4eace3155, type: 3} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: + - serializedVersion: 5 + m_BuildTarget: 1 + m_Tier: 0 + m_Settings: + standardShaderQuality: 0 + renderingPath: 1 + hdrMode: 1 + realtimeGICPUUsage: 25 + useReflectionProbeBoxProjection: 0 + useReflectionProbeBlending: 0 + useHDR: 0 + useDetailNormalMap: 0 + useCascadedShadowMaps: 0 + prefer32BitShadowMaps: 0 + enableLPPV: 0 + useDitherMaskForAlphaBlendedShadows: 0 + m_Automatic: 0 + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 00000000..b92ec836 --- /dev/null +++ b/ProjectSettings/InputManager.asset @@ -0,0 +1,343 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: mouse 0 + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Walk + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: joystick button 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Sprint + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: joystick button 3 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Joystick X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.2 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 3 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Joystick Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.2 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 4 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: RightClick + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: mouse 1 + altNegativeButton: + altPositiveButton: joystick button 4 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: LeftClick + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: mouse 0 + altNegativeButton: + altPositiveButton: joystick button 5 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Use + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Start + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 7 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Brake + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: joystick button 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 00000000..3b0b7c3d --- /dev/null +++ b/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/ProjectSettings/NetworkManager.asset b/ProjectSettings/NetworkManager.asset new file mode 100644 index 00000000..5dc6a831 --- /dev/null +++ b/ProjectSettings/NetworkManager.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!149 &1 +NetworkManager: + m_ObjectHideFlags: 0 + m_DebugLevel: 0 + m_Sendrate: 15 + m_AssetToPrefab: {} diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 00000000..8e9e0210 --- /dev/null +++ b/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,55 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 3 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_AutoSyncTransforms: 1 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/ProjectSettings/PresetManager.asset b/ProjectSettings/PresetManager.asset new file mode 100644 index 00000000..636a595b --- /dev/null +++ b/ProjectSettings/PresetManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + m_DefaultList: [] diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset new file mode 100644 index 00000000..2c8bae58 --- /dev/null +++ b/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,652 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 15 + productGUID: 64ef0b23aa281494eb7adceec137df80 + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: SanAndreasUnity + productName: SanAndreasUnity + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + tizenShowActivityIndicatorOnLoading: -1 + iosAppInBackgroundBehavior: 0 + displayResolutionDialog: 1 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidBlitType: 0 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 0 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 0 + graphicsJobs: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + graphicsJobMode: 0 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + n3dsDisableStereoscopicView: 0 + n3dsEnableSharedListOpt: 1 + n3dsEnableVSync: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + videoMemoryForVertexBuffers: 0 + psp2PowerMode: 0 + psp2AcquireBGM: 1 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 1.0 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 0 + xboxOneEnable7thCore: 0 + vrSettings: + cardboard: + depthFormat: 0 + enableTransitionView: 0 + daydream: + depthFormat: 0 + useSustainedPerformanceMode: 0 + enableVideoLayer: 0 + useProtectedVideoMemory: 0 + minimumSupportedHeadTracking: 0 + maximumSupportedHeadTracking: 1 + hololens: + depthFormat: 1 + depthBufferSharingEnabled: 0 + enable360StereoCapture: 0 + oculus: + sharedDepthBuffer: 0 + dashSupport: 0 + protectGraphicsMemory: 0 + useHDRDisplay: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: {} + buildNumber: {} + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 16 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 0 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 8.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + iPhoneSplashScreen: {fileID: 0} + iPhoneHighResSplashScreen: {fileID: 0} + iPhoneTallHighResSplashScreen: {fileID: 0} + iPhone47inSplashScreen: {fileID: 0} + iPhone55inPortraitSplashScreen: {fileID: 0} + iPhone55inLandscapeSplashScreen: {fileID: 0} + iPhone58inPortraitSplashScreen: {fileID: 0} + iPhone58inLandscapeSplashScreen: {fileID: 0} + iPadPortraitSplashScreen: {fileID: 0} + iPadHighResPortraitSplashScreen: {fileID: 0} + iPadLandscapeSplashScreen: {fileID: 0} + iPadHighResLandscapeSplashScreen: {fileID: 0} + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSUseLaunchScreenStoryboard: 0 + iOSLaunchScreenCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + appleEnableProMotion: 0 + clonedFromGUID: 00000000000000000000000000000000 + templatePackageId: + templateDefaultScene: + AndroidTargetArchitectures: 1 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidTVCompatibility: 1 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + resolutionDialogBanner: {fileID: 0} + m_BuildTargetIcons: + - m_BuildTarget: + m_Icons: + - serializedVersion: 2 + m_Icon: {fileID: 2800000, guid: 7ba03d38f2c9d483eb98097a1990d3ec, type: 3} + m_Width: 128 + m_Height: 128 + m_Kind: 0 + m_BuildTargetPlatformIcons: [] + m_BuildTargetBatching: [] + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: WindowsStandaloneSupport + m_APIs: 0200000011000000 + m_Automatic: 1 + m_BuildTargetVRSettings: [] + m_BuildTargetEnableVuforiaSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: + - m_BuildTarget: Standalone + m_EncodingQuality: 2 + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchSupportedNpadStyles: 3 + switchNativeFsCacheSize: 32 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 2 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + monoEnv: + psp2Splashimage: {fileID: 0} + psp2NPTrophyPackPath: + psp2NPSupportGBMorGJP: 0 + psp2NPAgeRating: 12 + psp2NPTitleDatPath: + psp2NPCommsID: + psp2NPCommunicationsID: + psp2NPCommsPassphrase: + psp2NPCommsSig: + psp2ParamSfxPath: + psp2ManualPath: + psp2LiveAreaGatePath: + psp2LiveAreaBackroundPath: + psp2LiveAreaPath: + psp2LiveAreaTrialPath: + psp2PatchChangeInfoPath: + psp2PatchOriginalPackage: + psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui + psp2KeystoneFile: + psp2MemoryExpansionMode: 3 + psp2DRMType: 0 + psp2StorageType: 0 + psp2MediaCapacity: 0 + psp2DLCConfigPath: + psp2ThumbnailPath: + psp2BackgroundPath: + psp2SoundPath: + psp2TrophyCommId: + psp2TrophyPackagePath: + psp2PackagedResourcesPath: + psp2SaveDataQuota: 10240 + psp2ParentalLevel: 1 + psp2ShortTitle: SanAndreasUnity + psp2ContentID: IV1984-UNSA19844_00-0123456789UNISAN + psp2Category: 0 + psp2MasterVersion: 01.00 + psp2AppVersion: 01.00 + psp2TVBootMode: 0 + psp2EnterButtonAssignment: 2 + psp2TVDisableEmu: 0 + psp2AllowTwitterDialog: 1 + psp2Upgradable: 0 + psp2HealthWarning: 0 + psp2UseLibLocation: 0 + psp2InfoBarOnStartup: 0 + psp2InfoBarColor: 0 + psp2ScriptOptimizationLevel: 2 + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + spritePackerPolicy: + webGLMemorySize: 256 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 0 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLLinkerTarget: 0 + scriptingDefineSymbols: + 1: CLIENT1;UNITY_POST_PROCESSING_STACK_V2 + 4: UNITY_POST_PROCESSING_STACK_V2 + 7: UNITY_POST_PROCESSING_STACK_V2 + 13: UNITY_POST_PROCESSING_STACK_V2 + 17: UNITY_POST_PROCESSING_STACK_V2 + 18: UNITY_POST_PROCESSING_STACK_V2 + 19: UNITY_POST_PROCESSING_STACK_V2 + 21: UNITY_POST_PROCESSING_STACK_V2 + 23: UNITY_POST_PROCESSING_STACK_V2 + 25: UNITY_POST_PROCESSING_STACK_V2 + 26: UNITY_POST_PROCESSING_STACK_V2 + 27: UNITY_POST_PROCESSING_STACK_V2 + platformArchitecture: {} + scriptingBackend: + PSP2: 1 + Standalone: 0 + il2cppCompilerConfiguration: {} + incrementalIl2cppBuild: {} + allowUnsafeCode: 0 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + apiCompatibilityLevelPerPlatform: + Standalone: 3 + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: SanAndreasUnity + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: SanAndreasUnity + wsaImages: {} + metroTileShortName: + metroCommandLineArgsFile: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + metroCompilationOverrides: 1 + tizenProductDescription: + tizenProductURL: + tizenSigningProfileName: + tizenGPSPermissions: 0 + tizenMicrophonePermissions: 0 + tizenDeploymentTarget: + tizenDeploymentTargetType: -1 + tizenMinOSVersion: 1 + n3dsUseExtSaveData: 0 + n3dsCompressStaticMem: 1 + n3dsExtSaveDataNumber: 0x12345 + n3dsStackSize: 131072 + n3dsTargetPlatform: 2 + n3dsRegion: 7 + n3dsMediaSize: 0 + n3dsLogoStyle: 3 + n3dsTitle: GameName + n3dsProductCode: + n3dsApplicationId: 0xFF3FF + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnableGPUVariability: 0 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + xboxOneScriptCompiler: 0 + vrEditorSettings: + daydream: + daydreamIconForeground: {fileID: 0} + daydreamIconBackground: {fileID: 0} + cloudServicesEnabled: {} + facebookSdkVersion: 7.9.4 + apiCompatibilityLevel: 3 + cloudProjectId: + projectName: + organizationId: + cloudEnabled: 0 + enableNativePlatformBackendsForNewInputSystem: 0 + disableOldInputManagerSupport: 0 diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt new file mode 100644 index 00000000..b171987b --- /dev/null +++ b/ProjectSettings/ProjectVersion.txt @@ -0,0 +1 @@ +m_EditorVersion: 2018.1.3f1 diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset new file mode 100644 index 00000000..bb2d890d --- /dev/null +++ b/ProjectSettings/QualitySettings.asset @@ -0,0 +1,177 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 0 + m_QualitySettings: + - serializedVersion: 2 + name: Fastest + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 2 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Fast + pixelLightCount: 1 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 2 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Simple + pixelLightCount: 2 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 2 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.7 + maximumLODLevel: 0 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Good + pixelLightCount: 3 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 2 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Beautiful + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 2 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Fantastic + pixelLightCount: 4 + shadows: 1 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 2 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.19999999, z: 0.46666664} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: {} diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset new file mode 100644 index 00000000..72595ddc --- /dev/null +++ b/ProjectSettings/TagManager.asset @@ -0,0 +1,54 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: + - Minimap + - UI + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - Breakable + - Vehicle + - World + - Player + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 + - name: Map + uniqueID: 401442191 + locked: 0 + - name: MapIcons + uniqueID: 3495189807 + locked: 0 + - name: MapPlayer + uniqueID: 3677193385 + locked: 0 diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset new file mode 100644 index 00000000..558a017e --- /dev/null +++ b/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 00000000..3da14d5b --- /dev/null +++ b/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + m_Enabled: 0 + m_TestMode: 0 + m_TestEventUrl: + m_TestConfigUrl: + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes + m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate + m_Enabled: 0 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_TestEventUrl: + m_TestConfigUrl: + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/README.md b/README.md new file mode 100644 index 00000000..624800c7 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ + +# San Andreas Unity + +
+ +
+ +
+ +   + +   + +
+ +
+ +San Andreas Unity is an open source recreation of [GTA San Andreas](http://www.rockstargames.com/sanandreas/) in Unity. + +This won't be a complete recreation, but the focus is on gameplay features, mutliplayer, and creating a framework which will allow easy game extending and unlimited modding possibilities. + +For more information about the project, read this [wiki page](https://github.com/GTA-ASM/SanAndreasUnity/wiki/About-project). + + +## Setup Instructions + +- open the project +- open startup scene located at Assets/Scenes/Startup.unity +- press Play button + +When running for the first time, the game will ask you for path to GTA installation, and will store that path in config.user.json. If you ever need to change the path, you can just edit this file. + + +## Download + +Download it from [here](https://github.com/GTA-ASM/SanAndreasUnity/releases/download/v1.2/SanAndreasUnity.7z) (for windows). + +The game is tested on linux, windows, mac, android and ps vita. It supports both Mono and IL2CPP scripting backends, so it can be built for any platform that Unity supports, provided that you can copy PC version of GTASA to target device. + + +## In-game controls + +Press Escape while in game to open pause menu. You'll see there a lot of utilities, and among them, there is a window which shows all controls. + +## TODO List + +Here is an extensive list of [what should be implemented](/Docs/TODO.md). + +Can help us to develop this ? In that case, join us on discord so we can discuss about it. + +## Screenshots + +![](https://cloud.githubusercontent.com/assets/557828/24571348/d964f098-1670-11e7-8759-0160dbf5bcb5.png) + +![](https://cloud.githubusercontent.com/assets/557828/24571349/d96b7c24-1670-11e7-997d-ae15913481f8.png) + +![](https://i.imgur.com/HX978mr.png) + +## Videos + +### + +[![](http://files.facepunch.com/ziks/2015/April/12/vidthumb1.png)](http://files.facepunch.com/ziks/2015/April/12/2015-04-12-2011-02.mp4) + +### + +[![](http://files.facepunch.com/ziks/2015/April/12/vidthumb2.png)](http://files.facepunch.com/layla/2015/April/06/2015-04-06_04-32-12.mp4) + +### + +[![](http://img.youtube.com/vi/8YaVLwE9UXw/0.jpg)](https://www.youtube.com/watch?v=8YaVLwE9UXw) + +### + +[![](http://img.youtube.com/vi/4DpdcawFjG4/0.jpg)](https://www.youtube.com/watch?v=4DpdcawFjG4) + + diff --git a/config.json b/config.json new file mode 100644 index 00000000..56761c04 --- /dev/null +++ b/config.json @@ -0,0 +1,43 @@ +{ + "cl_name": "Unnamed Busta", + "cl_connect": true, + "cl_remote_hostname": "localhost", + "cl_remote_port": 14242, + "cl_model_id": 167, + "cl_drawdist_scale": 1.0, + "sv_listen": true, + "sv_name": "San Anreas Unity Server", + "sv_max_connections": 32, + "sv_port": 14242, + + "game_dir" : "", + + "archive_paths": [ + "${game_dir}", + "${game_dir}/models/gta3.img", + "${game_dir}/models/gta_int.img", + "${game_dir}/models/player.img", + "${game_dir}/anim/anim.img", + "${game_dir}/anim/cuts.img", + "${game_dir}/models/cutscene.img", + "${game_dir}/data/paths/carrec.img", + "${game_dir}/data/script/script.img" + ], + + "item_paths": [ + "${game_dir}/data/gta.dat", + "${game_dir}/data/vehicles.ide", + "${game_dir}/data/peds.ide", + "${game_dir}/data/default.ide" + ], + + "handling_path": "${game_dir}/data/handling.cfg", + "water_path": "${game_dir}/data/water.dat", + "car_colors_path": "${game_dir}/data/carcols.dat", + "anim_groups_paths": [ + "${game_dir}/data/animgrp.dat", + "${data_dir}/auxanimgrp.dat" + ], + "weapons_path": "${game_dir}/data/weapon.dat" + +} \ No newline at end of file