diff --git a/.gitattributes b/.gitattributes index e5c5394e6..d530ed421 100644 --- a/.gitattributes +++ b/.gitattributes @@ -54,6 +54,9 @@ *.sbsar filter=lfs diff=lfs merge=lfs -text *.msgpack filter=lfs diff=lfs merge=lfs -text GameData/*.cc filter=lfs diff=lfs merge=lfs -text +GameData/Mods/**/*.cc filter=lfs diff=lfs merge=lfs -text +GameData/Mods/**/*.glb filter=lfs diff=lfs merge=lfs -text +tools/blender/tests/fixtures/*.glb filter=lfs diff=lfs merge=lfs -text *.a filter=lfs diff=lfs merge=lfs -text *AkSoundEngine filter=lfs diff=lfs merge=lfs -text *AkWaapiClient filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index 2cbd223f9..811814afa 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ GameData/*.lock /Aetheria.Shared/obj/ /tools/**/bin/ /tools/**/obj/ +/ModTools/ /tests/**/bin/ /tests/**/obj/ diff --git a/Aetheria.Shared/Aetheria.Shared.csproj b/Aetheria.Shared/Aetheria.Shared.csproj index 43d1c257d..a8a4c97bc 100644 --- a/Aetheria.Shared/Aetheria.Shared.csproj +++ b/Aetheria.Shared/Aetheria.Shared.csproj @@ -23,6 +23,10 @@ + + + + diff --git a/Asset Sources/PBR Materials.blend b/Asset Sources/PBR Materials.blend new file mode 100644 index 000000000..cbe7a475b --- /dev/null +++ b/Asset Sources/PBR Materials.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c88c4c5380c3553182a545e04ffcc0776a54f7cbde4fa80de95f5e569b931de +size 359499 diff --git a/Asset Sources/blender_assets.cats.txt b/Asset Sources/blender_assets.cats.txt new file mode 100644 index 000000000..7fc29fe08 --- /dev/null +++ b/Asset Sources/blender_assets.cats.txt @@ -0,0 +1,10 @@ +# This is an Asset Catalog Definition file for Blender. +# +# Empty lines and lines starting with `#` will be ignored. +# The first non-ignored line should be the version indicator. +# Other lines are of the format "UUID:catalog/path/for/assets:simple catalog name" + +VERSION 1 + +2c70f9d2-3a69-4004-8f42-4712b3e6c439:Aetheria:Aetheria +a71be0dc-105e-4c66-8ff3-acb25522e9cd:Aetheria/PBR:Aetheria-PBR diff --git a/Assets/Content/Prefabs/Mine.prefab b/Assets/Content/Prefabs/Mine.prefab new file mode 100644 index 000000000..912986ee7 --- /dev/null +++ b/Assets/Content/Prefabs/Mine.prefab @@ -0,0 +1,150 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3437702659452284539 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3879893384158149147} + - component: {fileID: 8643339631069775210} + - component: {fileID: 7703217095432408775} + - component: {fileID: 7283754118921506074} + m_Layer: 0 + m_Name: Mine + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3879893384158149147 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3437702659452284539} + serializedVersion: 2 + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &8643339631069775210 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3437702659452284539} + m_Mesh: {fileID: -5495902117074765545, guid: dab8e1a18a1b825458e8e6356cf00cd2, type: 3} +--- !u!23 &7703217095432408775 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3437702659452284539} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 38f8ba6b169127249b6532be2b3926ee, type: 2} + - {fileID: 2100000, guid: 71e1f3613633dfa488fff097aaf97660, type: 2} + - {fileID: 2100000, guid: e879c37f3520bf14a8a6075581faf7b2, type: 2} + - {fileID: 2100000, guid: 33a2546b27ff92d4fb43d5a76a9693c0, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &7283754118921506074 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3437702659452284539} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 35c62f5e26769f645b1a1614a70422e1, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::MineInstance + MeshRenderer: {fileID: 7703217095432408775} + EmissionSubmesh: 2 + EmissionCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0.051179443 + outSlope: 0.051179443 + tangentMode: 0 + weightedMode: 3 + inWeight: 0 + outWeight: 0.24423963 + - serializedVersion: 3 + time: 0.5 + value: 0.1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 3 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 3 + inWeight: 0.22580647 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + ActiveCycleDuration: 1 + ArmedCycleDuration: 0.25 + ActiveEmission: 100 + ArmedEmission: 1000 + RotationSpeed: 1 + HitEffect: {fileID: 1121192042590650, guid: e1b08032bec16ba4eb1ae23cbd572664, type: 3} + HitEffectScale: 10 diff --git a/Assets/Content/Prefabs/Thrusters/Aether Drive.prefab.meta b/Assets/Content/Prefabs/Mine.prefab.meta similarity index 74% rename from Assets/Content/Prefabs/Thrusters/Aether Drive.prefab.meta rename to Assets/Content/Prefabs/Mine.prefab.meta index e33810938..01e11b0eb 100644 --- a/Assets/Content/Prefabs/Thrusters/Aether Drive.prefab.meta +++ b/Assets/Content/Prefabs/Mine.prefab.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 151cf0ff54a22274caf671ece149fa6e +guid: b04728b2b65e057429eb6e8529299c8a PrefabImporter: externalObjects: {} userData: diff --git a/Assets/Content/Prefabs/Stations/PlanetOutpost.prefab b/Assets/Content/Prefabs/Stations/PlanetOutpost.prefab index 6ce31f34f..e3d20ceb7 100644 --- a/Assets/Content/Prefabs/Stations/PlanetOutpost.prefab +++ b/Assets/Content/Prefabs/Stations/PlanetOutpost.prefab @@ -81,87 +81,6 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &7783244517717541194 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 7783244517717541195} - - component: {fileID: 7783244517717541175} - - component: {fileID: 7783244517717541174} - m_Layer: 9 - m_Name: Gravity Well - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &7783244517717541195 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7783244517717541194} - m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 7783244518521719148} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &7783244517717541175 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7783244517717541194} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &7783244517717541174 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7783244517717541194} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &7783244518317531027 GameObject: m_ObjectHideFlags: 0 @@ -289,7 +208,6 @@ Transform: m_Children: - {fileID: 589192530128514016} - {fileID: 7783244518317531036} - - {fileID: 7783244517717541195} - {fileID: 7783244516809707565} m_Father: {fileID: 0} m_RootOrder: 0 @@ -307,7 +225,6 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Body: {fileID: 7783244518317531038} - GravityWell: {fileID: 7783244517717541174} Icon: {fileID: 7783244516809707566} Generator: {fileID: 741236912059895623} --- !u!114 &741236912059895623 diff --git a/Assets/Content/Prefabs/Thrusters/Aether Drive.prefab b/Assets/Content/Prefabs/Thrusters/Aether Drive.prefab deleted file mode 100644 index 4a566b534..000000000 --- a/Assets/Content/Prefabs/Thrusters/Aether Drive.prefab +++ /dev/null @@ -1,4819 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &3270076511764283730 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 5152310125488819541} - - component: {fileID: 8928170315538518364} - - component: {fileID: 8974554360790158463} - m_Layer: 0 - m_Name: Aether Drive - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &5152310125488819541 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3270076511764283730} - 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!198 &8928170315538518364 -ParticleSystem: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3270076511764283730} - serializedVersion: 7 - lengthInSec: 5 - simulationSpeed: 2 - stopAction: 0 - cullingMode: 0 - ringBufferMode: 0 - ringBufferLoopRange: {x: 0, y: 1} - looping: 1 - prewarm: 0 - playOnAwake: 1 - useUnscaledTime: 0 - autoRandomSeed: 1 - useRigidbodyForVelocity: 0 - startDelay: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - moveWithTransform: 2 - moveWithCustomTransform: {fileID: 0} - scalingMode: 2 - randomSeed: 0 - InitialModule: - serializedVersion: 3 - enabled: 1 - startLifetime: - serializedVersion: 2 - minMaxState: 0 - scalar: 0.5 - minScalar: 5 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - startSpeed: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 5 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - startColor: - serializedVersion: 2 - minMaxState: 0 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - maxGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - startSize: - serializedVersion: 2 - minMaxState: 0 - scalar: 0.25 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - startSizeY: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - startSizeZ: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - startRotationX: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - startRotationY: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - startRotation: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - randomizeRotationDirection: 0 - maxNumParticles: 1000 - size3D: 0 - rotation3D: 0 - gravityModifier: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - ShapeModule: - serializedVersion: 6 - enabled: 1 - type: 0 - angle: 25 - length: 5 - boxThickness: {x: 0, y: 0, z: 0} - radiusThickness: 1 - donutRadius: 0.2 - m_Position: {x: 0, y: 0, z: 0} - m_Rotation: {x: 0, y: 0, z: 0} - m_Scale: {x: 1, y: 1, z: 1} - placementMode: 2 - m_MeshMaterialIndex: 0 - m_MeshNormalOffset: 0 - m_MeshSpawn: - mode: 0 - spread: 0 - speed: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - m_Mesh: {fileID: 0} - m_MeshRenderer: {fileID: 0} - m_SkinnedMeshRenderer: {fileID: 0} - m_Sprite: {fileID: 0} - m_SpriteRenderer: {fileID: 0} - m_UseMeshMaterialIndex: 0 - m_UseMeshColors: 0 - alignToDirection: 0 - m_Texture: {fileID: 0} - m_TextureClipChannel: 3 - m_TextureClipThreshold: 0 - m_TextureUVChannel: 0 - m_TextureColorAffectsParticles: 1 - m_TextureAlphaAffectsParticles: 1 - m_TextureBilinearFiltering: 0 - randomDirectionAmount: 0 - sphericalDirectionAmount: 0 - randomPositionAmount: 0 - radius: - value: 10 - mode: 0 - spread: 0 - speed: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - arc: - value: 360 - mode: 0 - spread: 0 - speed: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - EmissionModule: - enabled: 1 - serializedVersion: 4 - rateOverTime: - serializedVersion: 2 - minMaxState: 0 - scalar: 75 - minScalar: 10 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - rateOverDistance: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - m_BurstCount: 0 - m_Bursts: [] - SizeModule: - enabled: 1 - curve: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 1 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 1 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - y: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 1 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 1 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - z: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 1 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 1 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - separateAxes: 0 - RotationModule: - enabled: 0 - x: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - y: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - curve: - serializedVersion: 2 - minMaxState: 0 - scalar: 0.7853982 - minScalar: 0.7853982 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - separateAxes: 0 - ColorModule: - enabled: 1 - gradient: - serializedVersion: 2 - minMaxState: 1 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - maxGradient: - serializedVersion: 2 - key0: {r: 0, g: 0.54509807, b: 1, a: 1} - key1: {r: 0.122641504, g: 0, b: 0.121027805, a: 0.45490196} - key2: {r: 0.122641504, g: 0, b: 0.121027805, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 65535 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - UVModule: - serializedVersion: 2 - enabled: 0 - mode: 0 - timeMode: 0 - fps: 30 - frameOverTime: - serializedVersion: 2 - minMaxState: 1 - scalar: 0.9999 - minScalar: 0.9999 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 1 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 1 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - startFrame: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - speedRange: {x: 0, y: 1} - tilesX: 1 - tilesY: 1 - animationType: 0 - rowIndex: 0 - cycles: 1 - uvChannelMask: -1 - rowMode: 1 - sprites: - - sprite: {fileID: 0} - flipU: 0 - flipV: 0 - VelocityModule: - enabled: 0 - x: - serializedVersion: 2 - minMaxState: 1 - scalar: 99.9 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - y: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - z: - serializedVersion: 2 - minMaxState: 1 - scalar: 50 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: -1 - inSlope: 2 - outSlope: 2 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - - serializedVersion: 3 - time: 1 - value: -0.013513565 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - orbitalX: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - orbitalY: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - orbitalZ: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - orbitalOffsetX: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - orbitalOffsetY: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - orbitalOffsetZ: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - radial: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - speedModifier: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - inWorldSpace: 0 - InheritVelocityModule: - enabled: 0 - m_Mode: 0 - m_Curve: - serializedVersion: 2 - minMaxState: 0 - scalar: 2 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - LifetimeByEmitterSpeedModule: - enabled: 0 - m_Curve: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: -0.8 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0.2 - inSlope: -0.8 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - m_Range: {x: 0, y: 1} - ForceModule: - enabled: 1 - x: - serializedVersion: 2 - minMaxState: 1 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: -1 - inSlope: 3.072868 - outSlope: 3.072868 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.11519607 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - y: - serializedVersion: 2 - minMaxState: 1 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: -1 - inSlope: 3.0251138 - outSlope: 3.0251138 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0.09068627 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.12531352 - outWeight: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - z: - serializedVersion: 2 - minMaxState: 1 - scalar: 50 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: -1 - inSlope: 3.0335512 - outSlope: 3.0335512 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0.09354838 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - inWorldSpace: 1 - randomizePerFrame: 0 - ExternalForcesModule: - serializedVersion: 2 - enabled: 0 - multiplierCurve: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - influenceFilter: 0 - influenceMask: - serializedVersion: 2 - m_Bits: 4294967295 - influenceList: [] - ClampVelocityModule: - enabled: 0 - x: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - y: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - z: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - magnitude: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - separateAxis: 0 - inWorldSpace: 0 - multiplyDragByParticleSize: 1 - multiplyDragByParticleVelocity: 1 - dampen: 0 - drag: - serializedVersion: 2 - minMaxState: 0 - scalar: 33.08 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - NoiseModule: - enabled: 1 - strength: - serializedVersion: 2 - minMaxState: 0 - scalar: 25 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: -2 - outSlope: -2 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - strengthY: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - strengthZ: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - separateAxes: 0 - frequency: 0.1 - damping: 0 - octaves: 3 - octaveMultiplier: 0.5 - octaveScale: 2 - quality: 2 - scrollSpeed: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - remap: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: -1 - inSlope: 0 - outSlope: 2 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 2 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - remapY: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: -1 - inSlope: 0 - outSlope: 2 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 2 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - remapZ: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: -1 - inSlope: 0 - outSlope: 2 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 2 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - remapEnabled: 0 - positionAmount: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - rotationAmount: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - sizeAmount: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - SizeBySpeedModule: - enabled: 0 - curve: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 1 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 1 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - y: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 1 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 1 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - z: - serializedVersion: 2 - minMaxState: 1 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 1 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 1 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - range: {x: 0, y: 1} - separateAxes: 0 - RotationBySpeedModule: - enabled: 0 - x: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - y: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - curve: - serializedVersion: 2 - minMaxState: 0 - scalar: 0.7853982 - minScalar: 0.7853982 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - separateAxes: 0 - range: {x: 0, y: 1} - ColorBySpeedModule: - enabled: 0 - gradient: - serializedVersion: 2 - minMaxState: 1 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - maxGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - range: {x: 0, y: 1} - CollisionModule: - enabled: 0 - serializedVersion: 4 - type: 0 - collisionMode: 0 - colliderForce: 0 - multiplyColliderForceByParticleSize: 0 - multiplyColliderForceByParticleSpeed: 0 - multiplyColliderForceByCollisionAngle: 1 - m_Planes: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - m_Dampen: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - m_Bounce: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - m_EnergyLossOnCollision: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minKillSpeed: 0 - maxKillSpeed: 10000 - radiusScale: 1 - collidesWith: - serializedVersion: 2 - m_Bits: 4294967295 - maxCollisionShapes: 256 - quality: 0 - voxelSize: 0.5 - collisionMessages: 0 - collidesWithDynamic: 1 - interiorCollisions: 0 - TriggerModule: - enabled: 0 - serializedVersion: 2 - inside: 1 - outside: 0 - enter: 0 - exit: 0 - colliderQueryMode: 0 - radiusScale: 1 - primitives: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - SubModule: - serializedVersion: 2 - enabled: 0 - subEmitters: - - serializedVersion: 3 - emitter: {fileID: 0} - type: 0 - properties: 0 - emitProbability: 1 - LightsModule: - enabled: 0 - ratio: 0 - light: {fileID: 0} - randomDistribution: 1 - color: 1 - range: 1 - intensity: 1 - rangeCurve: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - intensityCurve: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - maxLights: 20 - TrailModule: - enabled: 1 - mode: 0 - ratio: 1 - lifetime: - serializedVersion: 2 - minMaxState: 0 - scalar: 1 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minVertexDistance: 0.5 - textureMode: 0 - ribbonCount: 1 - shadowBias: 0.5 - worldSpace: 0 - dieWithParticles: 0 - sizeAffectsWidth: 0 - sizeAffectsLifetime: 0 - inheritParticleColor: 0 - generateLightingData: 0 - splitSubEmitterRibbons: 0 - attachRibbonsToTransform: 0 - colorOverLifetime: - serializedVersion: 2 - minMaxState: 0 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - maxGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - widthOverTrail: - serializedVersion: 2 - minMaxState: 1 - scalar: 0.25 - minScalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 6.705435 - outSlope: 6.705435 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0.034313723 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - colorOverTrail: - serializedVersion: 2 - minMaxState: 1 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - maxGradient: - serializedVersion: 2 - key0: {r: 0.2830189, g: 0, b: 0, a: 0} - key1: {r: 0.12415449, g: 0.26510748, b: 0.8490566, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 129 - atime1: 31802 - atime2: 65535 - atime3: 65535 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 3 - minGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - CustomDataModule: - enabled: 1 - mode0: 1 - vectorComponentCount0: 2 - color0: - serializedVersion: 2 - minMaxState: 0 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - maxGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - colorLabel0: Color - vector0_0: - serializedVersion: 2 - minMaxState: 3 - scalar: 1 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - vectorLabel0_0: X - vector0_1: - serializedVersion: 2 - minMaxState: 3 - scalar: 1 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - vectorLabel0_1: Y - vector0_2: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - vectorLabel0_2: Z - vector0_3: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - vectorLabel0_3: W - mode1: 0 - vectorComponentCount1: 4 - color1: - serializedVersion: 2 - minMaxState: 0 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - maxGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minGradient: - serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} - key2: {r: 0, g: 0, b: 0, a: 0} - key3: {r: 0, g: 0, b: 0, a: 0} - key4: {r: 0, g: 0, b: 0, a: 0} - key5: {r: 0, g: 0, b: 0, a: 0} - key6: {r: 0, g: 0, b: 0, a: 0} - key7: {r: 0, g: 0, b: 0, a: 0} - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_Mode: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - colorLabel1: Color - vector1_0: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - vectorLabel1_0: X - vector1_1: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - vectorLabel1_1: Y - vector1_2: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - vectorLabel1_2: Z - vector1_3: - serializedVersion: 2 - minMaxState: 0 - scalar: 0 - minScalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - vectorLabel1_3: W ---- !u!199 &8974554360790158463 -ParticleSystemRenderer: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3270076511764283730} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 0 - m_RayTracingMode: 0 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 6af0f423a2567be43b16d152d2b60e0c, type: 2} - - {fileID: 2100000, guid: 555ada90c0f01654a9387483bd95a688, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_RenderMode: 5 - m_SortMode: 0 - m_MinParticleSize: 0 - m_MaxParticleSize: 0.5 - m_CameraVelocityScale: 0 - m_VelocityScale: 0 - m_LengthScale: 2 - m_SortingFudge: 0 - m_NormalDirection: 1 - m_ShadowBias: 0 - m_RenderAlignment: 0 - m_Pivot: {x: 0, y: 0, z: 0} - m_Flip: {x: 0, y: 0, z: 0} - m_UseCustomVertexStreams: 1 - m_EnableGPUInstancing: 1 - m_ApplyActiveColorSpace: 1 - m_AllowRoll: 1 - m_FreeformStretching: 0 - m_RotateWithStretchDirection: 1 - m_VertexStreams: 0001030420 - m_Mesh: {fileID: 0} - m_Mesh1: {fileID: 0} - m_Mesh2: {fileID: 0} - m_Mesh3: {fileID: 0} - m_MaskInteraction: 0 diff --git a/Assets/Content/Prefabs/Tractor Beam.prefab b/Assets/Content/Prefabs/Tractor Beam.prefab index 9ce0d7760..c98d252a3 100644 --- a/Assets/Content/Prefabs/Tractor Beam.prefab +++ b/Assets/Content/Prefabs/Tractor Beam.prefab @@ -4818,6 +4818,3 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: ParticleSystem: {fileID: 5087162364086924483} - Radius: 25 - Traction: 25 - Distance: 75 diff --git a/Assets/Editor/AetheriaBuild.cs b/Assets/Editor/AetheriaBuild.cs new file mode 100644 index 000000000..7d3c891d2 --- /dev/null +++ b/Assets/Editor/AetheriaBuild.cs @@ -0,0 +1,106 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEditor.AddressableAssets.Settings; +using UnityEditor.Build.Reporting; +using Debug = UnityEngine.Debug; + +// The one way to make a Win64 player directory. Owns what the directory contains: Aetheria.exe and its data, +// GameData/Aetheria.cc, GameData/Narrative/**, GameData/Mods/** and ModTools/AetherDb. Manual builds, smokes and +// release cuts all call this and stage nothing themselves. +// +// Unity -batchmode -quit -projectPath -executeMethod AetheriaBuild.Build +// -aetheriaVersion -aetheriaOut -logFile +// +// AetherDb is published from tools/AetherDb, so the headless build's CULTLIB_ROOT / CULTMATH_ROOT (Directory.Build.props) +// must be set for dotnet when the defaults do not hold the pinned revisions. +// Any failure logs "AetheriaBuild FAILED at " and exits 1. +public static class AetheriaBuild +{ + private static readonly Regex SemVer = new Regex(@"^\d+\.\d+\.\d+([-+][0-9A-Za-z.-]+)?$"); + + public static void Build() + { + var step = "arguments"; + try + { + var version = Argument("-aetheriaVersion"); + if (!SemVer.IsMatch(version)) throw new InvalidOperationException("-aetheriaVersion is not a semver"); + var output = Path.GetFullPath(Argument("-aetheriaOut")); + var repoRoot = Directory.GetParent(UnityEngine.Application.dataPath).FullName; + + step = "version"; + UnityEditor.PlayerSettings.bundleVersion = version; // the game has its own global PlayerSettings + + step = "addressables"; + AddressableAssetSettings.BuildPlayerContent(out var content); + if (!string.IsNullOrEmpty(content.Error)) throw new InvalidOperationException("Addressables build reported an error: " + content.Error); + + step = "player"; + Directory.CreateDirectory(output); + var scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(scene => scene.path).ToArray(); + if (scenes.Length == 0) throw new InvalidOperationException("EditorBuildSettings has no enabled scene"); + var report = BuildPipeline.BuildPlayer(new BuildPlayerOptions + { + scenes = scenes, + locationPathName = Path.Combine(output, "Aetheria.exe"), + target = BuildTarget.StandaloneWindows64, + options = BuildOptions.None, + }); + if (report.summary.result != BuildResult.Succeeded || report.summary.totalErrors != 0) + throw new InvalidOperationException($"BuildPlayer ended {report.summary.result} with {report.summary.totalErrors} errors"); + + step = "gamedata"; + PlayerStaging.Stage(repoRoot, output); + + step = "aetherdb"; + Publish(repoRoot, Path.Combine(output, "ModTools")); + + step = "burst"; + var burst = Path.Combine(output, "Aetheria_BurstDebugInformation_DoNotShip"); + if (Directory.Exists(burst)) Directory.Delete(burst, true); + + Debug.Log($"AetheriaBuild OK {version} {output}"); + } + catch (Exception error) + { + Debug.LogError($"AetheriaBuild FAILED at {step}: {error.GetType().Name}: {error.Message}"); + EditorApplication.Exit(1); + return; + } + EditorApplication.Exit(0); + } + + private static void Publish(string repoRoot, string modTools) + { + var info = new ProcessStartInfo("dotnet") + { + Arguments = $"publish tools/AetherDb -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -o \"{modTools}\"", + WorkingDirectory = repoRoot, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + }; + using (var process = Process.Start(info)) + { + var errors = process.StandardError.ReadToEndAsync(); + var text = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + if (process.ExitCode != 0) + throw new InvalidOperationException($"dotnet publish exited {process.ExitCode}:\n{text}\n{errors.Result}"); + } + if (!File.Exists(Path.Combine(modTools, "AetherDb.exe"))) + throw new InvalidOperationException("dotnet publish produced no ModTools/AetherDb.exe"); + } + + private static string Argument(string name) + { + var args = Environment.GetCommandLineArgs(); + var at = Array.IndexOf(args, name); + if (at < 0 || at + 1 >= args.Length) throw new InvalidOperationException(name + " is required"); + return args[at + 1]; + } +} diff --git a/Assets/Editor/AetheriaBuild.cs.meta b/Assets/Editor/AetheriaBuild.cs.meta new file mode 100644 index 000000000..833ad46ac --- /dev/null +++ b/Assets/Editor/AetheriaBuild.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d38caad223051494ba36c734ce79950d \ No newline at end of file diff --git a/Assets/Editor/PlayerStaging.cs b/Assets/Editor/PlayerStaging.cs new file mode 100644 index 000000000..6f48daaa0 --- /dev/null +++ b/Assets/Editor/PlayerStaging.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; + +// What a player directory holds beside the executable's data: GameData/Aetheria.cc, GameData/Narrative/** and, when +// the repo has one, GameData/Mods/**. Nothing else under GameData ships (run.cc and player.cc are the player's own). +// Unity-free so the headless suite can prove the rules; AetheriaBuild is the only caller. +internal static class PlayerStaging +{ + public const string Catalog = "Aetheria.cc"; + public const string Narrative = "Narrative"; + public const string Mods = "Mods"; + + // Replaces /GameData with a copy of the three shipped entries of /GameData. + // Throws InvalidOperationException naming the entry when the catalog or Narrative is absent. + public static void Stage(string repoRoot, string playerDir) + { + var source = Path.Combine(repoRoot, "GameData"); + var destination = Path.Combine(playerDir, "GameData"); + var catalog = Path.Combine(source, Catalog); + var narrative = Path.Combine(source, Narrative); + var mods = Path.Combine(source, Mods); + + if (!File.Exists(catalog)) throw new InvalidOperationException($"GameData/{Catalog} is missing; a player never ships without its catalog."); + if (!Directory.Exists(narrative)) throw new InvalidOperationException($"GameData/{Narrative} is missing."); + + if (Directory.Exists(destination)) Directory.Delete(destination, true); + Directory.CreateDirectory(destination); + File.Copy(catalog, Path.Combine(destination, Catalog)); + CopyTree(narrative, Path.Combine(destination, Narrative)); + if (Directory.Exists(mods)) CopyTree(mods, Path.Combine(destination, Mods)); + } + + private static void CopyTree(string from, string to) + { + Directory.CreateDirectory(to); + foreach (var directory in Directory.GetDirectories(from, "*", SearchOption.AllDirectories)) + Directory.CreateDirectory(Path.Combine(to, directory.Substring(from.Length + 1))); + foreach (var file in Directory.GetFiles(from, "*", SearchOption.AllDirectories)) + File.Copy(file, Path.Combine(to, file.Substring(from.Length + 1))); + } +} diff --git a/Assets/Editor/PlayerStaging.cs.meta b/Assets/Editor/PlayerStaging.cs.meta new file mode 100644 index 000000000..71743d471 --- /dev/null +++ b/Assets/Editor/PlayerStaging.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 16dce8087f9149b44b6e294cb0851dd8 \ No newline at end of file diff --git a/Assets/TextMesh Pro/Sprites.meta b/Assets/Fonts/Emoji.meta similarity index 77% rename from Assets/TextMesh Pro/Sprites.meta rename to Assets/Fonts/Emoji.meta index 8b699e5fc..442fb19cd 100644 --- a/Assets/TextMesh Pro/Sprites.meta +++ b/Assets/Fonts/Emoji.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d0603b6d5186471b96c778c3949c7ce2 +guid: 5e0ef88f85924e146855ca7bb57bbdb6 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Fonts/Emoji/Emoji.asset b/Assets/Fonts/Emoji/Emoji.asset new file mode 100644 index 000000000..b37478ebd --- /dev/null +++ b/Assets/Fonts/Emoji/Emoji.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0da0ff045c78def703de64f1c79a0f6c0842985e21c261b165ada948dc726b1e +size 5791 diff --git a/Assets/Fonts/Emoji/Emoji.asset.meta b/Assets/Fonts/Emoji/Emoji.asset.meta new file mode 100644 index 000000000..f89bc04be --- /dev/null +++ b/Assets/Fonts/Emoji/Emoji.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4cbb1005dc560d54ba85c3d091dbe30b +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fonts/Emoji/LICENSE.txt b/Assets/Fonts/Emoji/LICENSE.txt new file mode 100644 index 000000000..db961e007 --- /dev/null +++ b/Assets/Fonts/Emoji/LICENSE.txt @@ -0,0 +1,410 @@ +Twemoji v17.0.3: https://github.com/jdecked/twemoji/archive/refs/tags/v17.0.3.tar.gz +Copyright (c) 2022–present Jason Sofonia & Justine De Caires +Copyright (c) 2014–2021 Twitter +Graphics licensed under CC-BY 4.0: + +Change notice (CC BY 4.0 section 3(a)(1)(B)): the SVG graphics are converted to a COLRv0 colour +font (Twemoji.ttf) by tools/emoji/fetch_emoji_font.py using nanoemoji. No artwork is edited. + +Attribution Requirements (upstream README) + +As an open source project, attribution is critical from a legal, practical and motivational perspective in our opinion. The graphics are licensed under the CC-BY 4.0 which has a pretty good guide on [best practices for attribution](https://wiki.creativecommons.org/Best_practices_for_attribution). + +However, we consider the guide a bit onerous and as a project, will accept a mention in a project README or an 'About' section or footer on a website. In mobile applications, a common place would be in the Settings/About section (for example, see the mobile Twitter application Settings->About->Legal section). We would consider a mention in the HTML/JS source sufficient also. + +LICENSE-GRAPHICS (upstream, verbatim) +======================================================================= + +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public licenses. +Notwithstanding, Creative Commons may elect to apply one of its public +licenses to material it publishes and in those instances will be +considered the "Licensor." Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the public +licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/Assets/TextMesh Pro/Sprites/EmojiOne Attribution.txt.meta b/Assets/Fonts/Emoji/LICENSE.txt.meta similarity index 75% rename from Assets/TextMesh Pro/Sprites/EmojiOne Attribution.txt.meta rename to Assets/Fonts/Emoji/LICENSE.txt.meta index 0d30e6532..8dabd4444 100644 --- a/Assets/TextMesh Pro/Sprites/EmojiOne Attribution.txt.meta +++ b/Assets/Fonts/Emoji/LICENSE.txt.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 381dcb09d5029d14897e55f98031fca5 +guid: db23d2e6bc295794888af02d32cbae60 TextScriptImporter: externalObjects: {} userData: diff --git a/Assets/Fonts/Emoji/Twemoji.ttf b/Assets/Fonts/Emoji/Twemoji.ttf new file mode 100644 index 000000000..60d816cf2 --- /dev/null +++ b/Assets/Fonts/Emoji/Twemoji.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:283b775ce3715a84065212985ebbdecb8fa0c457b7ccf2c9c15c99b5a83ef702 +size 1805956 diff --git a/Assets/Fonts/Emoji/Twemoji.ttf.meta b/Assets/Fonts/Emoji/Twemoji.ttf.meta new file mode 100644 index 000000000..5cc7ab440 --- /dev/null +++ b/Assets/Fonts/Emoji/Twemoji.ttf.meta @@ -0,0 +1,21 @@ +fileFormatVersion: 2 +guid: bde541f3fd3b82b4aa6aa068e4a205a7 +TrueTypeFontImporter: + externalObjects: {} + serializedVersion: 4 + fontSize: 16 + forceTextureCase: -2 + characterSpacing: 0 + characterPadding: 1 + includeFontData: 1 + fontNames: + - Aetheria Emoji + fallbackFontReferences: [] + customCharacters: + fontRenderingMode: 0 + ascentCalculationMode: 1 + useLegacyBoundsCalculation: 0 + shouldRoundAdvanceValue: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fonts/Emoji/emoji-font.lock b/Assets/Fonts/Emoji/emoji-font.lock new file mode 100644 index 000000000..cc54beafa --- /dev/null +++ b/Assets/Fonts/Emoji/emoji-font.lock @@ -0,0 +1,25 @@ +source_url=https://github.com/jdecked/twemoji/archive/refs/tags/v17.0.3.tar.gz +source_version=v17.0.3 +source_sha256=a0855654b633045ae2337537e77f1bb4361162f7fcd910e613eaab1d6d9c5fca +emoji_test_version=17.0 +emoji_test_url=https://unicode.org/Public/17.0.0/emoji/emoji-test.txt +emoji_test_sha256=1d8a944f88d7952f7ef7c5167fef3c67995bcae24543949710231b03a201acda +svg_count=4009 +single_codepoint_count=1400 +unsupported_count=0 +sequence_count=2760 +tool_nanoemoji=0.16.0 +tool_fonttools=4.66.1 +tool_picosvg=0.23.0 +tool_ninja=1.13.2 +source_date_epoch=1780352497 +color_format=glyf_colr_0 +python_version=3.13.15 +platform=linux +container_image=python:3.13-slim +fe0f_less_twins=15 +font_file=Twemoji.ttf +font_sha256=283b775ce3715a84065212985ebbdecb8fa0c457b7ccf2c9c15c99b5a83ef702 +singles_sha256=7ad887a16ef5386df040e1e8988e9bdc55ae5cab461ffc9df4613d0cb5770b4e +unsupported_sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sequences_sha256=18529154b14f75f54db5dedd72910de35af9ca05aef284b7d121be249b3c3bb2 diff --git a/Assets/Materials/Fog Marching.mat.meta b/Assets/Fonts/Emoji/emoji-font.lock.meta similarity index 54% rename from Assets/Materials/Fog Marching.mat.meta rename to Assets/Fonts/Emoji/emoji-font.lock.meta index 04c6076f8..d59e8a3eb 100644 --- a/Assets/Materials/Fog Marching.mat.meta +++ b/Assets/Fonts/Emoji/emoji-font.lock.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 2ff39f5d101241043ba1dcde19d92f77 -NativeFormatImporter: +guid: 6290b5397f6ae1d47a19c6886ebd87e2 +DefaultImporter: externalObjects: {} - mainObjectFileID: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Materials/Brushes/Gravity Well.mat b/Assets/Materials/Brushes/Gravity Field.mat similarity index 92% rename from Assets/Materials/Brushes/Gravity Well.mat rename to Assets/Materials/Brushes/Gravity Field.mat index e0bd9f79d..d912917c9 100644 --- a/Assets/Materials/Brushes/Gravity Well.mat +++ b/Assets/Materials/Brushes/Gravity Field.mat @@ -7,8 +7,8 @@ Material: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: Gravity Well - m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} + m_Name: Gravity Field + m_Shader: {fileID: 4800000, guid: 08d8efa80af84065b54c9bfed784e435, type: 3} m_ShaderKeywords: m_LightmapFlags: 4 m_EnableInstancingVariants: 0 @@ -57,8 +57,6 @@ Material: m_Offset: {x: 0, y: 0} m_Floats: - _BumpScale: 1 - - _Cutoff: 1 - - _Depth: 80 - _DetailNormalMapScale: 1 - _DstBlend: 0 - _GlossMapScale: 1 @@ -68,7 +66,6 @@ Material: - _Mode: 0 - _OcclusionStrength: 1 - _Parallax: 0.02 - - _Power: 16 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 - _SrcBlend: 1 diff --git a/Assets/Materials/Brushes/Gravity Well.mat.meta b/Assets/Materials/Brushes/Gravity Field.mat.meta similarity index 100% rename from Assets/Materials/Brushes/Gravity Well.mat.meta rename to Assets/Materials/Brushes/Gravity Field.mat.meta diff --git a/Assets/Materials/Brushes/Sector Tint.mat b/Assets/Materials/Brushes/Sector Tint.mat index 3e5e00f24..84e252ad3 100644 --- a/Assets/Materials/Brushes/Sector Tint.mat +++ b/Assets/Materials/Brushes/Sector Tint.mat @@ -8,7 +8,7 @@ Material: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: Sector Tint - m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} + m_Shader: {fileID: 4800000, guid: 782740c1a3d7455ea75dc87fafdc8432, type: 3} m_ValidKeywords: [] m_InvalidKeywords: [] m_LightmapFlags: 4 @@ -59,8 +59,8 @@ Material: m_Ints: [] m_Floats: - _BumpScale: 1 - - _Cutoff: 1 - _Depth: 0.025 + - _EdgeBrightness: 0.12 - _DetailNormalMapScale: 1 - _DstBlend: 0 - _Frequency: 6.2832 @@ -72,7 +72,6 @@ Material: - _OcclusionStrength: 1 - _Parallax: 0.02 - _Phase: 0 - - _Power: 2 - _SinePower: 1.25 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 diff --git a/Assets/Materials/Brushes/Wormhole Gravity.mat b/Assets/Materials/Brushes/Wormhole Gravity.mat deleted file mode 100644 index fb6f52b20..000000000 --- a/Assets/Materials/Brushes/Wormhole Gravity.mat +++ /dev/null @@ -1,82 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Wormhole Gravity - m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} - m_ValidKeywords: [] - m_InvalidKeywords: [] - 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_Ints: [] - m_Floats: - - _BumpScale: 1 - - _Cutoff: 0.15 - - _Depth: 2000 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _GlossMapScale: 1 - - _Glossiness: 0.5 - - _GlossyReflections: 1 - - _Metallic: 0 - - _Mode: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.02 - - _Power: 64 - - _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} - m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Wormhole Waves.mat.meta b/Assets/Materials/Brushes/Wormhole Waves.mat.meta deleted file mode 100644 index 1e5f35dd3..000000000 --- a/Assets/Materials/Brushes/Wormhole Waves.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ef2f6090d5cc14a4e9ce38def3bed9ac -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Materials/Fog Marching 1.mat b/Assets/Materials/Fog Marching 1.mat deleted file mode 100644 index 20290c785..000000000 --- a/Assets/Materials/Fog Marching 1.mat +++ /dev/null @@ -1,73 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Fog Marching 1 - m_Shader: {fileID: 4800000, guid: 7a890b6ceccf53c44bfc54b18b5daa58, type: 3} - m_ShaderKeywords: - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _Displacement: - m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} - 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} - - _Patch: - m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _Surface: - m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _TintTexture: - m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: - - _AlphaFloor: 0.01 - - _DepthBlend: 512 - - _DepthCeiling: 4096 - - _FlowSpeed: 2 - - _Gamma: 0.5 - - _GridCeilingBlend: -300 - - _GridCeilingDensity: 0.01 - - _GridCeilingFollow: 0 - - _GridCeilingOffset: 0 - - _GridFillDensity: 0.001 - - _GridFloorBlend: 100 - - _GridFloorDensity: 2 - - _GridFloorOffset: 20 - - _GridPatchBlend: 50 - - _GridPatchDensity: 2 - - _NoiseExponent: 2.25 - - _NoiseFrequency: 0.015 - - _NoiseSpeed: 0 - - _NoiseStrength: 500 - - _SafetyDistance: 20 - - _Scattering: 0 - - _ScatteringDensityExponent: 0.5 - - _ScatteringDistExponent: 0.5 - - _ScatteringMinDist: 500 - - _StepExponent: 2 - - _TintExponent: 0.1 - - _TurbulenceAmplitude: 100 - - _TurbulenceScale: 100 - m_Colors: - - _Tint: {r: 0.0627451, g: 0.0627451, b: 0.0627451, a: 1} - m_BuildTextureStacks: [] diff --git a/Assets/Materials/Fog Marching 1.mat.meta b/Assets/Materials/Fog Marching 1.mat.meta deleted file mode 100644 index 00e039020..000000000 --- a/Assets/Materials/Fog Marching 1.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a72896cb7097bfa46a1a8f4092e47c72 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Materials/Fog Marching Main Menu.mat b/Assets/Materials/Fog Marching Main Menu.mat deleted file mode 100644 index b22522a2d..000000000 --- a/Assets/Materials/Fog Marching Main Menu.mat +++ /dev/null @@ -1,99 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Fog Marching Main Menu - m_Shader: {fileID: 4800000, guid: 7a890b6ceccf53c44bfc54b18b5daa58, type: 3} - m_ShaderKeywords: - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _Displacement: - m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} - 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} - - _NebulaPatch: - m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _NebulaPatchHeight: - m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _NebulaSurfaceHeight: - m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _NebulaTint: - m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _Patch: - m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _Surface: - m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _TintTexture: - m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: - - _AlphaFloor: 0 - - _DepthBlend: 512 - - _DepthCeiling: 1024 - - _Exposure: 100 - - _FlowAmplitude: 1 - - _FlowScale: 1 - - _FlowScroll: 1 - - _FlowSpeed: 5 - - _Gamma: 0.3 - - _GridCeilingBlend: -300 - - _GridCeilingDensity: 0.01 - - _GridCeilingFollow: 0 - - _GridCeilingOffset: 0 - - _GridFillDensity: 0.001 - - _GridFloorBlend: 50 - - _GridFloorDensity: 1 - - _GridFloorOffset: 100 - - _GridPatchBlend: 50 - - _GridPatchDensity: 1 - - _NebulaFillDensity: 0.00075 - - _NebulaFloorBlend: 50 - - _NebulaFloorDensity: 1 - - _NebulaFloorOffset: 80 - - _NebulaPatchBlend: 25 - - _NebulaPatchDensity: 0.1 - - _NoiseExponent: 2 - - _NoiseFrequency: 0.02 - - _NoiseSpeed: 0.00001 - - _NoiseStrength: 200 - - _SafetyDistance: 50 - - _Scattering: 0 - - _ScatteringDensityExponent: 8 - - _ScatteringDistExponent: 0.5 - - _ScatteringMinDist: 1 - - _StepExponent: 2 - - _TintExponent: 1.2 - - _TurbulenceAmplitude: 20 - - _TurbulenceScale: 30 - m_Colors: - - _Tint: {r: 0.09411765, g: 0.09411765, b: 0.09411765, a: 1} - m_BuildTextureStacks: [] diff --git a/Assets/Materials/Fog Marching Main Menu.mat.meta b/Assets/Materials/Fog Marching Main Menu.mat.meta deleted file mode 100644 index 6a5cdb35e..000000000 --- a/Assets/Materials/Fog Marching Main Menu.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e21702a5e6e98b7409d6913663ceab7e -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Materials/Fog Marching Test.mat b/Assets/Materials/Fog Marching Test.mat deleted file mode 100644 index 91b56761e..000000000 --- a/Assets/Materials/Fog Marching Test.mat +++ /dev/null @@ -1,65 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Fog Marching Test - m_Shader: {fileID: 4800000, guid: 7a890b6ceccf53c44bfc54b18b5daa58, type: 3} - m_ShaderKeywords: - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _Displacement: - m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} - 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} - - _Patch: - m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _Surface: - m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _TintTexture: - m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: - - _AlphaFloor: 0 - - _DepthBlend: 512 - - _DepthCeiling: 4096 - - _Gamma: 0.66 - - _GridCeilingBlend: -300 - - _GridCeilingDensity: 0.01 - - _GridCeilingFollow: 0 - - _GridCeilingOffset: 0 - - _GridFillDensity: 0.000025 - - _GridFloorBlend: 100 - - _GridFloorDensity: 4 - - _GridFloorOffset: 0 - - _GridPatchBlend: 5 - - _GridPatchDensity: 0.1 - - _NoiseFrequency: 0.01 - - _NoiseSpeed: 0.02 - - _NoiseStrength: 50 - - _SafetyDistance: 0 - - _StepExponent: 2 - - _TintExponent: 8 - m_Colors: - - _Tint: {r: 2.0078435, g: 2.0078435, b: 2.0078435, a: 1} - m_BuildTextureStacks: [] diff --git a/Assets/Materials/Fog Marching Test.mat.meta b/Assets/Materials/Fog Marching Test.mat.meta deleted file mode 100644 index 9f0e3d586..000000000 --- a/Assets/Materials/Fog Marching Test.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ad63650ae6d6cc542a5aad16694b3c46 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Materials/Fog Marching.mat b/Assets/Materials/Fog Marching.mat deleted file mode 100644 index 52dc13c19..000000000 --- a/Assets/Materials/Fog Marching.mat +++ /dev/null @@ -1,99 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Fog Marching - m_Shader: {fileID: 4800000, guid: 7a890b6ceccf53c44bfc54b18b5daa58, type: 3} - m_ShaderKeywords: - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _Displacement: - m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} - 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} - - _NebulaPatch: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _NebulaPatchHeight: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _NebulaSurfaceHeight: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _NebulaTint: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _Patch: - m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _Surface: - m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _TintTexture: - m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: - - _AlphaFloor: 0.01 - - _DepthBlend: 512 - - _DepthCeiling: 4096 - - _Exposure: 10 - - _FlowAmplitude: 512 - - _FlowScale: 1024 - - _FlowScroll: 0 - - _FlowSpeed: 1 - - _Gamma: 0.3 - - _GridCeilingBlend: -300 - - _GridCeilingDensity: 0.01 - - _GridCeilingFollow: 0 - - _GridCeilingOffset: 0 - - _GridFillDensity: 0.0005 - - _GridFloorBlend: 50 - - _GridFloorDensity: 1 - - _GridFloorOffset: 10 - - _GridPatchBlend: 150 - - _GridPatchDensity: 1 - - _NebulaFillDensity: 0.00075 - - _NebulaFloorBlend: 150 - - _NebulaFloorDensity: 1 - - _NebulaFloorOffset: 0 - - _NebulaPatchBlend: 51.47 - - _NebulaPatchDensity: 0.25 - - _NoiseExponent: 3 - - _NoiseFrequency: 0.005 - - _NoiseSpeed: 0 - - _NoiseStrength: -400 - - _SafetyDistance: 200 - - _Scattering: 50 - - _ScatteringDensityExponent: 1 - - _ScatteringDistExponent: 1.5 - - _ScatteringMinDist: 10 - - _StepExponent: 2 - - _TintExponent: 2 - - _TurbulenceAmplitude: 20 - - _TurbulenceScale: 60 - m_Colors: - - _Tint: {r: 0.01, g: 0.01, b: 0.01, a: 1} - m_BuildTextureStacks: [] diff --git a/Assets/TextMesh Pro/Resources/Sprite Assets.meta b/Assets/Materials/PBR.meta similarity index 58% rename from Assets/TextMesh Pro/Resources/Sprite Assets.meta rename to Assets/Materials/PBR.meta index 5171f1b68..a534b0d5a 100644 --- a/Assets/TextMesh Pro/Resources/Sprite Assets.meta +++ b/Assets/Materials/PBR.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 -guid: 512a49d95c0c4332bdd98131869c23c9 +guid: 5b293e272c024dc999b28fe49925e1d5 folderAsset: yes -timeCreated: 1441876896 -licenseType: Pro DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Materials/PBR/Carbon_Fibre.meta b/Assets/Materials/PBR/Carbon_Fibre.meta new file mode 100644 index 000000000..c4c6f51e4 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 636104c9ca48436da05c3f6003fd3eae +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Brushes/Gravity Waves.mat b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre.mat similarity index 70% rename from Assets/Materials/Brushes/Gravity Waves.mat rename to Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre.mat index a45dfed21..b7f244b60 100644 --- a/Assets/Materials/Brushes/Gravity Waves.mat +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre.mat @@ -7,9 +7,9 @@ Material: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: Gravity Waves - m_Shader: {fileID: 4800000, guid: 8a8e593b17063b54ea02f7ea5363b59d, type: 3} - m_ShaderKeywords: + m_Name: Carbon_Fibre + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 @@ -20,7 +20,7 @@ Material: serializedVersion: 3 m_TexEnvs: - _BumpMap: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: 5723eb533deb4d73a2b015bb75b523b4, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _DetailAlbedoMap: @@ -39,12 +39,16 @@ Material: m_Texture: {fileID: 0} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: 32fc9d1c4304495da5350f8a8b52e14b, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: 15a9bba7a82740718ad2d3913f7297af, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _OcclusionMap: @@ -58,20 +62,18 @@ Material: m_Floats: - _BumpScale: 1 - _Cutoff: 0.5 - - _Depth: 3.5 - _DetailNormalMapScale: 1 - _DstBlend: 0 - - _Frequency: 27.43 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 - _GlossMapScale: 1 - - _Glossiness: 0.5 + - _Glossiness: 1 - _GlossyReflections: 1 - - _Metallic: 0 + - _Metallic: 1 - _Mode: 0 - _OcclusionStrength: 1 - _Parallax: 0.02 - - _Phase: 0 - - _Power: 8 - - _SinePower: 1.25 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 - _SrcBlend: 1 @@ -79,5 +81,6 @@ Material: - _ZWrite: 1 m_Colors: - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Wormhole Gravity 1.mat.meta b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre.mat.meta similarity index 79% rename from Assets/Materials/Brushes/Wormhole Gravity 1.mat.meta rename to Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre.mat.meta index 7d40d0332..b0f1c3097 100644 --- a/Assets/Materials/Brushes/Wormhole Gravity 1.mat.meta +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre.mat.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 244f3e4c0c030a24b8d7aa944895bdcf +guid: 8e5a779dec614c80a12925ba063bb99f NativeFormatImporter: externalObjects: {} mainObjectFileID: 2100000 diff --git a/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Color.jpg b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Color.jpg new file mode 100644 index 000000000..4e3c4a374 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:327e42b2dfc859efd9b4f122cf1adbdb611c75e80dd3cb8a18bc69e83eef9585 +size 566952 diff --git a/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Color.jpg.meta b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Color.jpg.meta new file mode 100644 index 000000000..614f43088 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 32fc9d1c4304495da5350f8a8b52e14b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_MetallicSmoothness.png b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_MetallicSmoothness.png new file mode 100644 index 000000000..31131f1a7 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd50d0187fdf8c05eba5ef982da5217c6adf9f03720a2c8041ef4bebd5a2658d +size 1944562 diff --git a/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_MetallicSmoothness.png.meta new file mode 100644 index 000000000..19a8fae68 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 15a9bba7a82740718ad2d3913f7297af +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_NormalGL.jpg b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_NormalGL.jpg new file mode 100644 index 000000000..c0e1c9aa8 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e76a53fce87086a2346756ef1ef25f6db6153bda3433611a192ac71b32b2ebdc +size 1356999 diff --git a/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_NormalGL.jpg.meta b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_NormalGL.jpg.meta new file mode 100644 index 000000000..072cf13c3 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 5723eb533deb4d73a2b015bb75b523b4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Roughness.jpg b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Roughness.jpg new file mode 100644 index 000000000..fd7a1f7f1 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8005027078e974df48351781ce90885bd6325ac63d0a16b41938fca8fd35a634 +size 1189710 diff --git a/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Roughness.jpg.meta b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Roughness.jpg.meta new file mode 100644 index 000000000..503d1d154 --- /dev/null +++ b/Assets/Materials/PBR/Carbon_Fibre/Carbon_Fibre_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: b8e5cd91353441ebb42296a830fef845 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Gunmetal_Dark.meta b/Assets/Materials/PBR/Gunmetal_Dark.meta new file mode 100644 index 000000000..7680bfe76 --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 22e47659e8e14482b3466711751b01b8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Brushes/Wormhole Gravity 1.mat b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark.mat similarity index 69% rename from Assets/Materials/Brushes/Wormhole Gravity 1.mat rename to Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark.mat index 3ae24d6ee..150f0f72c 100644 --- a/Assets/Materials/Brushes/Wormhole Gravity 1.mat +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark.mat @@ -7,9 +7,9 @@ Material: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: Wormhole Gravity 1 - m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} - m_ShaderKeywords: + m_Name: Gunmetal_Dark + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 @@ -20,7 +20,7 @@ Material: serializedVersion: 3 m_TexEnvs: - _BumpMap: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: dc71e34b4a1f4de7aa826d18b67b5852, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _DetailAlbedoMap: @@ -39,12 +39,16 @@ Material: m_Texture: {fileID: 0} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: 1ed06708491744fe944217d19e450157, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: 31e7d642ff8a49a28390c82626c4b6b9, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _OcclusionMap: @@ -57,18 +61,19 @@ Material: m_Offset: {x: 0, y: 0} m_Floats: - _BumpScale: 1 - - _Cutoff: 1 - - _Depth: 54 + - _Cutoff: 0.5 - _DetailNormalMapScale: 1 - _DstBlend: 0 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 - _GlossMapScale: 1 - - _Glossiness: 0.5 + - _Glossiness: 1 - _GlossyReflections: 1 - - _Metallic: 0 + - _Metallic: 1 - _Mode: 0 - _OcclusionStrength: 1 - _Parallax: 0.02 - - _Power: 4 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 - _SrcBlend: 1 @@ -76,5 +81,6 @@ Material: - _ZWrite: 1 m_Colors: - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Wormhole Gravity.mat.meta b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark.mat.meta similarity index 79% rename from Assets/Materials/Brushes/Wormhole Gravity.mat.meta rename to Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark.mat.meta index 30ec9b01d..24a52eab3 100644 --- a/Assets/Materials/Brushes/Wormhole Gravity.mat.meta +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark.mat.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a9ef17c902709ce41a837c54b809184b +guid: 32199fedf9ce473191d8a734a74f3d5f NativeFormatImporter: externalObjects: {} mainObjectFileID: 2100000 diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Color.jpg b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Color.jpg new file mode 100644 index 000000000..4a0118922 --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28845bf0cc6a1edeed7e9f10f5db4034cae4ba7377bc53633f413de0dbcae5b7 +size 1451112 diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Color.jpg.meta b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Color.jpg.meta new file mode 100644 index 000000000..848791f40 --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 1ed06708491744fe944217d19e450157 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_MetallicSmoothness.png b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_MetallicSmoothness.png new file mode 100644 index 000000000..f3cca5c7f --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c101b3b9d7b3ff0636b6539cc65908dc5cac76e31e951a6a375918bb681076c +size 2899231 diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_MetallicSmoothness.png.meta new file mode 100644 index 000000000..598a3c189 --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 31e7d642ff8a49a28390c82626c4b6b9 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Metalness.jpg b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Metalness.jpg new file mode 100644 index 000000000..afd0fe3a6 --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Metalness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b65d6b9091747bd81ee58adedcb6209d8ee21b2bde9298d7216989ada85ef622 +size 16545 diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Metalness.jpg.meta b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Metalness.jpg.meta new file mode 100644 index 000000000..2eb33ad5e --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Metalness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 51e45f19716b43128ce5d2aac5b5aed4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_NormalGL.jpg b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_NormalGL.jpg new file mode 100644 index 000000000..37f403c32 --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7b4437dca1fe52addbb21e145d3ccc43e8c1780b7930cc9dad1e2b73cb7455b +size 2260227 diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_NormalGL.jpg.meta b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_NormalGL.jpg.meta new file mode 100644 index 000000000..e3fed3ebc --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: dc71e34b4a1f4de7aa826d18b67b5852 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Roughness.jpg b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Roughness.jpg new file mode 100644 index 000000000..1e6edb81f --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f466bcf997694d56cb7bc93526a881a195e2ee63b1e0c8a19da88289596b9f4 +size 1228992 diff --git a/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Roughness.jpg.meta b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Roughness.jpg.meta new file mode 100644 index 000000000..d09d43872 --- /dev/null +++ b/Assets/Materials/PBR/Gunmetal_Dark/Gunmetal_Dark_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 5677a8acff8f49358627841b9be8e2dd +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Metal_Scratched.meta b/Assets/Materials/PBR/Metal_Scratched.meta new file mode 100644 index 000000000..a53ff5c65 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3e9d00e0b2454cc08632c972d2ee499b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched.mat b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched.mat new file mode 100644 index 000000000..fe6463397 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched.mat @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Metal_Scratched + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP + 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: 3a10044baac4438f9fc0930783eccdf7, type: 3} + 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} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 5a9cee903a2d48718aaf6b224126f279, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 2800000, guid: 8b24d7ea11c341408a146fa39f59b7b0, type: 3} + 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 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 + - _GlossMapScale: 1 + - _Glossiness: 1 + - _GlossyReflections: 1 + - _Metallic: 1 + - _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} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Wormhole Gravity 2.mat.meta b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched.mat.meta similarity index 79% rename from Assets/Materials/Brushes/Wormhole Gravity 2.mat.meta rename to Assets/Materials/PBR/Metal_Scratched/Metal_Scratched.mat.meta index fb6f1270d..1d5895d52 100644 --- a/Assets/Materials/Brushes/Wormhole Gravity 2.mat.meta +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched.mat.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0ec0689c58b99c64297b3e429e1d9112 +guid: a5874fba9e2242c79aea6b21ddb63af0 NativeFormatImporter: externalObjects: {} mainObjectFileID: 2100000 diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Color.jpg b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Color.jpg new file mode 100644 index 000000000..cb09761f3 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:934e3f0e21b71cb534442f398b287f70158ba7cc3e11ab829f873ddce9cea7fb +size 4314757 diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Color.jpg.meta b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Color.jpg.meta new file mode 100644 index 000000000..7b34b1c8f --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 5a9cee903a2d48718aaf6b224126f279 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_MetallicSmoothness.png b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_MetallicSmoothness.png new file mode 100644 index 000000000..7b1578437 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ce0400bc23c44f54aa018b195472b99b7c7007bf93166017bfaf05d68bca38d +size 4647897 diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_MetallicSmoothness.png.meta new file mode 100644 index 000000000..b6b4c4b0e --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 8b24d7ea11c341408a146fa39f59b7b0 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Metalness.jpg b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Metalness.jpg new file mode 100644 index 000000000..687e06af5 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Metalness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a4f1124670270e69c5fae2537f2493ab55d6f6264310fa344414eb75026cfde +size 564910 diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Metalness.jpg.meta b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Metalness.jpg.meta new file mode 100644 index 000000000..697296e8c --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Metalness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 2eace05436f24d15944266ed3b841f21 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_NormalGL.jpg b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_NormalGL.jpg new file mode 100644 index 000000000..e772289b2 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb3d7953fb7867f7948b5d7a0dff6044f92a6bba56e6f4a48ad30a94c6096d98 +size 5038957 diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_NormalGL.jpg.meta b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_NormalGL.jpg.meta new file mode 100644 index 000000000..932d93b51 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 3a10044baac4438f9fc0930783eccdf7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Roughness.jpg b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Roughness.jpg new file mode 100644 index 000000000..9dab37dc6 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fbd2281a995ab1185715dae4d7a657c10b338dfcb57a2f2245eac530d5bd7ed +size 2140434 diff --git a/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Roughness.jpg.meta b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Roughness.jpg.meta new file mode 100644 index 000000000..393e3bd91 --- /dev/null +++ b/Assets/Materials/PBR/Metal_Scratched/Metal_Scratched_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 986a2475c1e248d7be5208d88ee17a15 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Clean_Light.meta b/Assets/Materials/PBR/Paint_Clean_Light.meta new file mode 100644 index 000000000..c72ff31ca --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c2497e59922c471b935a06c396acb73e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light.mat b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light.mat new file mode 100644 index 000000000..f76052e2d --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light.mat @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Paint_Clean_Light + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP + 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: f548cd63b5734e04a284018fefc81b30, type: 3} + 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} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 2c82a94e33b64fd481cbfeb7df9516bd, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 2800000, guid: ad8a50784ce04f5d9b3bab2115eeea34, type: 3} + 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 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 + - _GlossMapScale: 1 + - _Glossiness: 1 + - _GlossyReflections: 1 + - _Metallic: 1 + - _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} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Gravity Waves.mat.meta b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light.mat.meta similarity index 79% rename from Assets/Materials/Brushes/Gravity Waves.mat.meta rename to Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light.mat.meta index f4e2f41d4..519f702b0 100644 --- a/Assets/Materials/Brushes/Gravity Waves.mat.meta +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light.mat.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 11fbaa87dcc7a3743a6bd3aa5c86e5ae +guid: 132cb2f99d9f42fe9b05db1c0d653897 NativeFormatImporter: externalObjects: {} mainObjectFileID: 2100000 diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Color.jpg b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Color.jpg new file mode 100644 index 000000000..222b441ba --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e966978debc85c05e1e4834e1ac8406d863f9267c396d1580ec2d94fdce9738 +size 638778 diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Color.jpg.meta b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Color.jpg.meta new file mode 100644 index 000000000..029f71505 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 2c82a94e33b64fd481cbfeb7df9516bd +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_MetallicSmoothness.png b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_MetallicSmoothness.png new file mode 100644 index 000000000..a61363526 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:412547b698a0968ba6f7c4f31e888bd88afb9f24e049f5811ca51c7490510998 +size 3692433 diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_MetallicSmoothness.png.meta new file mode 100644 index 000000000..41ba9a3be --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: ad8a50784ce04f5d9b3bab2115eeea34 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_NormalGL.jpg b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_NormalGL.jpg new file mode 100644 index 000000000..0c74319d3 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70e36c645d2d6bc9ddc79b86d1275147c52947613fed8ed75dc6aec5d9282187 +size 3220864 diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_NormalGL.jpg.meta b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_NormalGL.jpg.meta new file mode 100644 index 000000000..d0c0e745e --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: f548cd63b5734e04a284018fefc81b30 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Roughness.jpg b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Roughness.jpg new file mode 100644 index 000000000..499f33718 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44a1a3eb43252db6c242cd3e777a2e41819e872058e032e3cf8285cc578f35bb +size 2011305 diff --git a/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Roughness.jpg.meta b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Roughness.jpg.meta new file mode 100644 index 000000000..117171aad --- /dev/null +++ b/Assets/Materials/PBR/Paint_Clean_Light/Paint_Clean_Light_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 21721bf50f1f407d8e0f2b5e06bf4ef5 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Dark.meta b/Assets/Materials/PBR/Paint_Worn_Dark.meta new file mode 100644 index 000000000..f6af35502 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 22c55f60ad784e7495f2ddbae1e2799e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark.mat b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark.mat new file mode 100644 index 000000000..11deee75d --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark.mat @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Paint_Worn_Dark + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP _OCCLUSIONMAP + 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: b37cce6dfe8a45d0a7ba4e9a844c68b9, type: 3} + 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} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 8f9bc4377cc4451aae71a877219e700f, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 2800000, guid: b5158bc316ef42bead7fa70b7bc08a7a, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 2800000, guid: e8713adbe3e74ac4a4f431581bb31a4b, type: 3} + 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 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 + - _GlossMapScale: 1 + - _Glossiness: 1 + - _GlossyReflections: 1 + - _Metallic: 1 + - _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} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark.mat.meta b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark.mat.meta new file mode 100644 index 000000000..c70f30afd --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e081b7d98e6d424fa42a6876a8e0bab3 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_AO.jpg b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_AO.jpg new file mode 100644 index 000000000..7c4f50094 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_AO.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2e4af5867078208c00332af23bded29a4ac325b040f5980c2730ff8e551bc9d +size 2924087 diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_AO.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_AO.jpg.meta new file mode 100644 index 000000000..e3c6ca27e --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_AO.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: e8713adbe3e74ac4a4f431581bb31a4b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Color.jpg b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Color.jpg new file mode 100644 index 000000000..de88b6108 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c57d484d39db6704fbcf32184f73472e6a78cfc63027422426fa170d87bdfc4a +size 5177435 diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Color.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Color.jpg.meta new file mode 100644 index 000000000..5cdcca076 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 8f9bc4377cc4451aae71a877219e700f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_MetallicSmoothness.png b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_MetallicSmoothness.png new file mode 100644 index 000000000..ca9d86708 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98cc6442c3952acba81f86ae0210e9e0b171522dec1a80d9177eb942dd295d73 +size 5117887 diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_MetallicSmoothness.png.meta new file mode 100644 index 000000000..28b873752 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: b5158bc316ef42bead7fa70b7bc08a7a +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Metalness.jpg b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Metalness.jpg new file mode 100644 index 000000000..90096ce14 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Metalness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3cdb47576c1085bea1bd3e90d055c7f45b66bda53d3ad03f825e5dc9665b93f +size 1073864 diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Metalness.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Metalness.jpg.meta new file mode 100644 index 000000000..fb46b8a1a --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Metalness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: c6d0917aab0d4442ad102a6088628f53 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_NormalGL.jpg b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_NormalGL.jpg new file mode 100644 index 000000000..9c151b688 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60e7d12d4eefed9f9c763b3095b6db35542ee00c7f076b72bb2718a3ccd649c9 +size 7526970 diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_NormalGL.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_NormalGL.jpg.meta new file mode 100644 index 000000000..bcfcf9af3 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: b37cce6dfe8a45d0a7ba4e9a844c68b9 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Roughness.jpg b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Roughness.jpg new file mode 100644 index 000000000..918bb48c5 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:648bf332066975dad0fc618eda260571e8077a7d418587b8b55a68c7da797541 +size 2083327 diff --git a/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Roughness.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Roughness.jpg.meta new file mode 100644 index 000000000..3607f105d --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Dark/Paint_Worn_Dark_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 46fe06d220b044d1a6bb1a716c6e8705 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Light.meta b/Assets/Materials/PBR/Paint_Worn_Light.meta new file mode 100644 index 000000000..34d26b097 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b660a03d95714359ac68aa01a52064b9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light.mat b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light.mat new file mode 100644 index 000000000..9f6a4ff51 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light.mat @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Paint_Worn_Light + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP _OCCLUSIONMAP + 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: 4ce3c2cc69304068b4a2ddc833b748b9, type: 3} + 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} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 73568a0c02bd4184bcb398c9e3dd7ab6, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 2800000, guid: d9cd336372c244e398532512e3f8f3be, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 2800000, guid: 73e117729c3447e5aa0eb1a30fad7c75, type: 3} + 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 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 + - _GlossMapScale: 1 + - _Glossiness: 1 + - _GlossyReflections: 1 + - _Metallic: 1 + - _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} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light.mat.meta b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light.mat.meta new file mode 100644 index 000000000..1441ced17 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5eb890ad19d44af98f2710f3af280e3c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_AO.jpg b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_AO.jpg new file mode 100644 index 000000000..a9989d282 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_AO.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2560f1aa453ffd2f4374c9ba4d184e1c43456726d8971460062515acef83b76 +size 2764255 diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_AO.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_AO.jpg.meta new file mode 100644 index 000000000..be48781f6 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_AO.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 73e117729c3447e5aa0eb1a30fad7c75 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Color.jpg b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Color.jpg new file mode 100644 index 000000000..d05a21ab2 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:401b7ee4394595110564bcb12a40c0b87ea50acfc3632b7e7237e2d0165d1ded +size 4364255 diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Color.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Color.jpg.meta new file mode 100644 index 000000000..cc5b0e17b --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 73568a0c02bd4184bcb398c9e3dd7ab6 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_MetallicSmoothness.png b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_MetallicSmoothness.png new file mode 100644 index 000000000..08375c3a3 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c59489103f8a5ef438f0f74484cdf5af90b1ee2985a180d690772d1325816bf +size 6990606 diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_MetallicSmoothness.png.meta new file mode 100644 index 000000000..13b040de5 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: d9cd336372c244e398532512e3f8f3be +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Metalness.jpg b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Metalness.jpg new file mode 100644 index 000000000..10a0cd502 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Metalness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8be2891eeff9e521ac8d672edb106830e878ee0b73852a5763c803a8088014f2 +size 2705735 diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Metalness.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Metalness.jpg.meta new file mode 100644 index 000000000..402c2f3f3 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Metalness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 464aecd85593406aa2426215e07b988a +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_NormalGL.jpg b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_NormalGL.jpg new file mode 100644 index 000000000..549164ad2 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2ae51f315549a7d63c7f0290e9f6d35dfcd1bc42df422579ee407c30692599a +size 6857447 diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_NormalGL.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_NormalGL.jpg.meta new file mode 100644 index 000000000..a9aa1c988 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 4ce3c2cc69304068b4a2ddc833b748b9 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Roughness.jpg b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Roughness.jpg new file mode 100644 index 000000000..d0ab06978 --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1207c0c4716229b36290416e4af37ccaf5351a65c8d93237a7802a95f45dfbcf +size 1929057 diff --git a/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Roughness.jpg.meta b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Roughness.jpg.meta new file mode 100644 index 000000000..2b1eeabdb --- /dev/null +++ b/Assets/Materials/PBR/Paint_Worn_Light/Paint_Worn_Light_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 58cb097056b5431e819ca45954ee3b47 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plastic_Matte.meta b/Assets/Materials/PBR/Plastic_Matte.meta new file mode 100644 index 000000000..91fd17d97 --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1126ae7b5bcb4d6b8403e31233638b8d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Brushes/Wormhole Gravity 2.mat b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte.mat similarity index 69% rename from Assets/Materials/Brushes/Wormhole Gravity 2.mat rename to Assets/Materials/PBR/Plastic_Matte/Plastic_Matte.mat index 3ae24d6ee..f5845363d 100644 --- a/Assets/Materials/Brushes/Wormhole Gravity 2.mat +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte.mat @@ -7,9 +7,9 @@ Material: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: Wormhole Gravity 1 - m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} - m_ShaderKeywords: + m_Name: Plastic_Matte + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 @@ -20,7 +20,7 @@ Material: serializedVersion: 3 m_TexEnvs: - _BumpMap: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: d9e9439b6e9f43ed9c47015cafdcd5d3, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _DetailAlbedoMap: @@ -39,12 +39,16 @@ Material: m_Texture: {fileID: 0} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: 053c9b821bf649bab9c8f7b234803809, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: f405c1ca89914831a4366ac1e4d850ee, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _OcclusionMap: @@ -57,18 +61,19 @@ Material: m_Offset: {x: 0, y: 0} m_Floats: - _BumpScale: 1 - - _Cutoff: 1 - - _Depth: 54 + - _Cutoff: 0.5 - _DetailNormalMapScale: 1 - _DstBlend: 0 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 - _GlossMapScale: 1 - - _Glossiness: 0.5 + - _Glossiness: 1 - _GlossyReflections: 1 - - _Metallic: 0 + - _Metallic: 1 - _Mode: 0 - _OcclusionStrength: 1 - _Parallax: 0.02 - - _Power: 4 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 - _SrcBlend: 1 @@ -76,5 +81,6 @@ Material: - _ZWrite: 1 m_Colors: - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} m_BuildTextureStacks: [] diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte.mat.meta b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte.mat.meta new file mode 100644 index 000000000..f92b559c4 --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 636667df941046e79d2417c6b062d995 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Color.jpg b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Color.jpg new file mode 100644 index 000000000..00c2a444a --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cb3a446755c2f868957807195d1e51ff989384da7878e8c0d9f93f391a5b755 +size 905715 diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Color.jpg.meta b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Color.jpg.meta new file mode 100644 index 000000000..e0947dee4 --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 053c9b821bf649bab9c8f7b234803809 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_MetallicSmoothness.png b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_MetallicSmoothness.png new file mode 100644 index 000000000..45e075a5b --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:811b05a5b78048c711f5129d14073bfa1983443553a2b75453f15e46ad6da998 +size 3782071 diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_MetallicSmoothness.png.meta new file mode 100644 index 000000000..c641103a4 --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: f405c1ca89914831a4366ac1e4d850ee +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_NormalGL.jpg b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_NormalGL.jpg new file mode 100644 index 000000000..12b6ad1ff --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e177082ed5027b4bb533e39b0556c7f3ca4701d6ffa3761910dff678d7f43d07 +size 9096346 diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_NormalGL.jpg.meta b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_NormalGL.jpg.meta new file mode 100644 index 000000000..357ce2800 --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: d9e9439b6e9f43ed9c47015cafdcd5d3 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Roughness.jpg b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Roughness.jpg new file mode 100644 index 000000000..c1eb5f150 --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:629c695383835080794b90174ae19a422cb7234870752642afa81f36a28cd9e7 +size 2095946 diff --git a/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Roughness.jpg.meta b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Roughness.jpg.meta new file mode 100644 index 000000000..575bf2428 --- /dev/null +++ b/Assets/Materials/PBR/Plastic_Matte/Plastic_Matte_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 142ed10762d242a9a4ecf63ee0e38b71 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Panels.meta b/Assets/Materials/PBR/Plates_Panels.meta new file mode 100644 index 000000000..99eb09f70 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 086928e6583747e1b14c6767ced082b4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels.mat b/Assets/Materials/PBR/Plates_Panels/Plates_Panels.mat new file mode 100644 index 000000000..babe13ca0 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels.mat @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Plates_Panels + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP + 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: 8bc10cfce8a64defaf9f67d156003f09, type: 3} + 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} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 2195885db9e846999fd10aa7f5c629b1, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 2800000, guid: d91bff887b764847a484d0a9bedce9e9, type: 3} + 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 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 + - _GlossMapScale: 1 + - _Glossiness: 1 + - _GlossyReflections: 1 + - _Metallic: 1 + - _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} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels.mat.meta b/Assets/Materials/PBR/Plates_Panels/Plates_Panels.mat.meta new file mode 100644 index 000000000..a8a703cf0 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c508beb10bbe4c7f88fc9a7c003e51d5 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Color.jpg b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Color.jpg new file mode 100644 index 000000000..9945f16ae --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e69514467f58898537ecc6b3c47e618537406a00b7eb24099d3835ca4ae4c9a +size 2132182 diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Color.jpg.meta b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Color.jpg.meta new file mode 100644 index 000000000..960e6e0e3 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 2195885db9e846999fd10aa7f5c629b1 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_MetallicSmoothness.png b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_MetallicSmoothness.png new file mode 100644 index 000000000..de028ea73 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b5ea65058b4792f97c7f9affd89930342b2306ab5dbd21f930ef153d4f4acf1 +size 3414650 diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_MetallicSmoothness.png.meta new file mode 100644 index 000000000..6b036cb95 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: d91bff887b764847a484d0a9bedce9e9 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Metalness.jpg b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Metalness.jpg new file mode 100644 index 000000000..9edfab941 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Metalness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:736a312c106a791672e1115df51ba0a08be7927f6cfc4aff97fcfb60311e002f +size 171958 diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Metalness.jpg.meta b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Metalness.jpg.meta new file mode 100644 index 000000000..69399ee42 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Metalness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 5df39678e5734f51a29940f2f6a43dda +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_NormalGL.jpg b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_NormalGL.jpg new file mode 100644 index 000000000..127c7888d --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f916040ca388073191224a515def08761a3e136a74f559feb5774ef50527d54 +size 3505435 diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_NormalGL.jpg.meta b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_NormalGL.jpg.meta new file mode 100644 index 000000000..da4e2137e --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 8bc10cfce8a64defaf9f67d156003f09 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Roughness.jpg b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Roughness.jpg new file mode 100644 index 000000000..cf7a6709b --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9fc8550cdb559c16cbd2d43196dcc271653e78c802519bc446684224048ff69 +size 1742286 diff --git a/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Roughness.jpg.meta b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Roughness.jpg.meta new file mode 100644 index 000000000..9d51593f6 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Panels/Plates_Panels_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: e2f6e4f21fd14d6eb65e100b4f012349 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Riveted.meta b/Assets/Materials/PBR/Plates_Riveted.meta new file mode 100644 index 000000000..870fc938a --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 79fbea05234f4b53a53eab2f090d2005 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted.mat b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted.mat new file mode 100644 index 000000000..e8088be9b --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted.mat @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Plates_Riveted + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP + 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: 6fb688a276034675b895c2edeb1b538b, type: 3} + 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} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: f07bacf217654b269eecfabbcc651b2b, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 2800000, guid: 08b45a54ea8c4521b7c4e7b3974f0b42, type: 3} + 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 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 + - _GlossMapScale: 1 + - _Glossiness: 1 + - _GlossyReflections: 1 + - _Metallic: 1 + - _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} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted.mat.meta b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted.mat.meta new file mode 100644 index 000000000..62c10b5e6 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 538d82fdc2de48f4bcf4e93b17407f90 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Color.jpg b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Color.jpg new file mode 100644 index 000000000..fe22d7428 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a72ee2d4e5e6c3d4154e9244ad57f7c6b644b40b356db162c9f2b01e80547eb +size 1602784 diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Color.jpg.meta b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Color.jpg.meta new file mode 100644 index 000000000..dc74b1c54 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: f07bacf217654b269eecfabbcc651b2b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_MetallicSmoothness.png b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_MetallicSmoothness.png new file mode 100644 index 000000000..527fe9f5f --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d678e8bff66b2d3bc703c5d355c47644f135544ac33afd517f1a542195b7e43d +size 5021835 diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_MetallicSmoothness.png.meta new file mode 100644 index 000000000..778892894 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 08b45a54ea8c4521b7c4e7b3974f0b42 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Metalness.jpg b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Metalness.jpg new file mode 100644 index 000000000..05c05f99a --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Metalness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:212258a43acddd1cb67203b3b263721022ae5f22bbf2213842a608fb09dc2b2f +size 1396144 diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Metalness.jpg.meta b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Metalness.jpg.meta new file mode 100644 index 000000000..86f483ff4 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Metalness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 24e3f6b76da9420592e2f21931defae7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_NormalGL.jpg b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_NormalGL.jpg new file mode 100644 index 000000000..4c272122c --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e49f90c003cf728de4892eec7d71f08abec1b2f9cb4780c875d005cb313498ac +size 3616644 diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_NormalGL.jpg.meta b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_NormalGL.jpg.meta new file mode 100644 index 000000000..aa8d94dbe --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 6fb688a276034675b895c2edeb1b538b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Roughness.jpg b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Roughness.jpg new file mode 100644 index 000000000..b96f7460a --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d48b683b55fd5e89c91a0c4bfde3a539fc892abc958387045e7d0786fe5c1fbd +size 1889081 diff --git a/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Roughness.jpg.meta b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Roughness.jpg.meta new file mode 100644 index 000000000..232a09cf3 --- /dev/null +++ b/Assets/Materials/PBR/Plates_Riveted/Plates_Riveted_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 7b50b58679684fc8991f112974a62120 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Rubber.meta b/Assets/Materials/PBR/Rubber.meta new file mode 100644 index 000000000..f4d39fafb --- /dev/null +++ b/Assets/Materials/PBR/Rubber.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 180d9a65c5784b618970824077421002 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Brushes/Wormhole Waves.mat b/Assets/Materials/PBR/Rubber/Rubber.mat similarity index 70% rename from Assets/Materials/Brushes/Wormhole Waves.mat rename to Assets/Materials/PBR/Rubber/Rubber.mat index 7902c5c36..2c10c3488 100644 --- a/Assets/Materials/Brushes/Wormhole Waves.mat +++ b/Assets/Materials/PBR/Rubber/Rubber.mat @@ -7,9 +7,9 @@ Material: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: Wormhole Waves - m_Shader: {fileID: 4800000, guid: 8681ac064d59d15458d16cc9b884262c, type: 3} - m_ShaderKeywords: + m_Name: Rubber + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 @@ -20,7 +20,7 @@ Material: serializedVersion: 3 m_TexEnvs: - _BumpMap: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: 42826f488ae243178be306ada5ee9f41, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _DetailAlbedoMap: @@ -39,12 +39,16 @@ Material: m_Texture: {fileID: 0} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: 83e6c1768e014acfb494fbf007c40c80, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: - m_Texture: {fileID: 0} + m_Texture: {fileID: 2800000, guid: f1d4409638e4452cb1412503ed8526de, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _OcclusionMap: @@ -58,27 +62,25 @@ Material: m_Floats: - _BumpScale: 1 - _Cutoff: 0.5 - - _Depth: 33.9 - _DetailNormalMapScale: 1 - _DstBlend: 0 - - _Frequency: 2 - - _FrequencyDist: 60 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 - _GlossMapScale: 1 - - _Glossiness: 0.5 + - _Glossiness: 1 - _GlossyReflections: 1 - - _Metallic: 0 + - _Metallic: 1 - _Mode: 0 - _OcclusionStrength: 1 - _Parallax: 0.02 - - _Power: 2 - - _SinePower: 1.25 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 - - _Speed: 15 - _SrcBlend: 1 - _UVSec: 0 - _ZWrite: 1 m_Colors: - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} m_BuildTextureStacks: [] diff --git a/Assets/Materials/PBR/Rubber/Rubber.mat.meta b/Assets/Materials/PBR/Rubber/Rubber.mat.meta new file mode 100644 index 000000000..989c2cd22 --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 257d49e9af154d6c9b5ea50a288db1fa +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Rubber/Rubber_Color.jpg b/Assets/Materials/PBR/Rubber/Rubber_Color.jpg new file mode 100644 index 000000000..3a0e09062 --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d712c25987d3e6f40e3f37fae1ce1a4a4155d5e27cff64dadf2bbe140979dd98 +size 4479634 diff --git a/Assets/Materials/PBR/Rubber/Rubber_Color.jpg.meta b/Assets/Materials/PBR/Rubber/Rubber_Color.jpg.meta new file mode 100644 index 000000000..ff443d7b4 --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 83e6c1768e014acfb494fbf007c40c80 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Rubber/Rubber_MetallicSmoothness.png b/Assets/Materials/PBR/Rubber/Rubber_MetallicSmoothness.png new file mode 100644 index 000000000..d194ddc8f --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a5d2c567edceeeec37de50166d325a0b3d29bc6cd90ad891635bf4cf8334376 +size 5044494 diff --git a/Assets/Materials/PBR/Rubber/Rubber_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Rubber/Rubber_MetallicSmoothness.png.meta new file mode 100644 index 000000000..fe4234492 --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: f1d4409638e4452cb1412503ed8526de +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Rubber/Rubber_NormalGL.jpg b/Assets/Materials/PBR/Rubber/Rubber_NormalGL.jpg new file mode 100644 index 000000000..461b856ff --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61bf1b38eae723913275a1de5eb08d4ac543f11e28f4ac6f596a0644169010fc +size 9238212 diff --git a/Assets/Materials/PBR/Rubber/Rubber_NormalGL.jpg.meta b/Assets/Materials/PBR/Rubber/Rubber_NormalGL.jpg.meta new file mode 100644 index 000000000..16144739a --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 42826f488ae243178be306ada5ee9f41 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Rubber/Rubber_Roughness.jpg b/Assets/Materials/PBR/Rubber/Rubber_Roughness.jpg new file mode 100644 index 000000000..7c59cbb40 --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc137f95179a4ae42d67819750d78c3fe878d438b789cf96b33947618305a275 +size 3042709 diff --git a/Assets/Materials/PBR/Rubber/Rubber_Roughness.jpg.meta b/Assets/Materials/PBR/Rubber/Rubber_Roughness.jpg.meta new file mode 100644 index 000000000..feca8c0c2 --- /dev/null +++ b/Assets/Materials/PBR/Rubber/Rubber_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 834b5a5e1e1a49559f9fdeffd947e0a0 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/SOURCES.md b/Assets/Materials/PBR/SOURCES.md new file mode 100644 index 000000000..baebd4022 --- /dev/null +++ b/Assets/Materials/PBR/SOURCES.md @@ -0,0 +1,22 @@ +# PBR material sources + +All texture sets are from ambientCG (https://ambientcg.com), licensed CC0 1.0 Universal (public domain, https://creativecommons.org/publicdomain/zero/1.0/). 2K-JPG downloads; displacement and NormalDX dropped; NormalGL kept (OpenGL convention, used by Blender and Unity). + +| Material | ambientCG id | URL | Metallic source | +|---|---|---|---| +| Paint_Clean_Light | Plastic010 | https://ambientcg.com/view?id=Plastic010 | none in set: constant 0 | +| Paint_Worn_Light | PaintedMetal012 | https://ambientcg.com/view?id=PaintedMetal012 | ambientCG Metalness map | +| Paint_Worn_Dark | PaintedMetal007 | https://ambientcg.com/view?id=PaintedMetal007 | ambientCG Metalness map | +| Steel_Brushed | Metal009 | https://ambientcg.com/view?id=Metal009 | ambientCG Metalness map | +| Metal_Scratched | Metal002 | https://ambientcg.com/view?id=Metal002 | ambientCG Metalness map | +| Gunmetal_Dark | Metal030 | https://ambientcg.com/view?id=Metal030 | ambientCG Metalness map | +| Plates_Riveted | MetalPlates002 | https://ambientcg.com/view?id=MetalPlates002 | ambientCG Metalness map | +| Plates_Panels | MetalPlates006 | https://ambientcg.com/view?id=MetalPlates006 | ambientCG Metalness map | +| Tread_Diamond | DiamondPlate001 | https://ambientcg.com/view?id=DiamondPlate001 | ambientCG Metalness map | +| Rubber | Rubber001 | https://ambientcg.com/view?id=Rubber001 | none in set: constant 0 | +| Plastic_Matte | Plastic004 | https://ambientcg.com/view?id=Plastic004 | none in set: constant 0 | +| Carbon_Fibre | Fabric004 | https://ambientcg.com/view?id=Fabric004 | set map is all 1.0; dielectric, so constant 0 | + +Files per material: `_Color`, `_Roughness`, `_NormalGL`, `_Metalness` and `_AO` (where the set has them), plus `_MetallicSmoothness.png` generated here for Unity (Metallic in R, Smoothness = 1 - Roughness in A). AO exists only for Paint_Worn_Light and Paint_Worn_Dark. + +Blender library: `Asset Sources/PBR Materials.blend` (catalog Aetheria/PBR, images linked by relative path to this folder). Unity materials use Aetheria/GlowFade. diff --git a/Assets/TextMesh Pro/Sprites/EmojiOne.json.meta b/Assets/Materials/PBR/SOURCES.md.meta similarity index 54% rename from Assets/TextMesh Pro/Sprites/EmojiOne.json.meta rename to Assets/Materials/PBR/SOURCES.md.meta index 762cf15c9..4c16a4a62 100644 --- a/Assets/TextMesh Pro/Sprites/EmojiOne.json.meta +++ b/Assets/Materials/PBR/SOURCES.md.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 8f05276190cf498a8153f6cbe761d4e6 -timeCreated: 1480316860 -licenseType: Pro +guid: a29568b9a0cf46babc43fe6045d6e10a TextScriptImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Materials/PBR/Steel_Brushed.meta b/Assets/Materials/PBR/Steel_Brushed.meta new file mode 100644 index 000000000..0a76b67a2 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 76edddc4bbd74a8d80e7cc29729b334e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed.mat b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed.mat new file mode 100644 index 000000000..7147c9aa2 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed.mat @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Steel_Brushed + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP + 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: c3ef09438e3e46d18a4c267810aeb285, type: 3} + 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} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: f70b6df0395b4752b4ec80cb7bfd8f42, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 2800000, guid: 40f5e915d2734d43bc01f984772e9d29, type: 3} + 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 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 + - _GlossMapScale: 1 + - _Glossiness: 1 + - _GlossyReflections: 1 + - _Metallic: 1 + - _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} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed.mat.meta b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed.mat.meta new file mode 100644 index 000000000..6a17f81b3 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 65c607f056d64708bb493dd31b39e79e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Color.jpg b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Color.jpg new file mode 100644 index 000000000..c3406774a --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:209d3bb050be9f58c5af179d9712fa7799567a4cd50afd338d37674bdcff765b +size 2439272 diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Color.jpg.meta b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Color.jpg.meta new file mode 100644 index 000000000..d6973f061 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: f70b6df0395b4752b4ec80cb7bfd8f42 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_MetallicSmoothness.png b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_MetallicSmoothness.png new file mode 100644 index 000000000..8142b06f2 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2b84e6acb67eb71fb263546ba5fe2ddd5f6e00517addb3c96c0f226becab3bb +size 3309438 diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_MetallicSmoothness.png.meta new file mode 100644 index 000000000..130146909 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 40f5e915d2734d43bc01f984772e9d29 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Metalness.jpg b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Metalness.jpg new file mode 100644 index 000000000..afd0fe3a6 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Metalness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b65d6b9091747bd81ee58adedcb6209d8ee21b2bde9298d7216989ada85ef622 +size 16545 diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Metalness.jpg.meta b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Metalness.jpg.meta new file mode 100644 index 000000000..1aa819912 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Metalness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 415d2498454d4d419948b2aa11eac78c +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_NormalGL.jpg b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_NormalGL.jpg new file mode 100644 index 000000000..2c9942542 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8773d9e97a4b057ced3e538d8ecc6069d27c8948191d61daf79b9ad93d93e3b3 +size 4120356 diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_NormalGL.jpg.meta b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_NormalGL.jpg.meta new file mode 100644 index 000000000..e223398fa --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: c3ef09438e3e46d18a4c267810aeb285 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Roughness.jpg b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Roughness.jpg new file mode 100644 index 000000000..a1d7edd1f --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e802f013b93cb1bd4b55cd91f02a1863233475a7f8bd0e6755cfaa447a729674 +size 1891607 diff --git a/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Roughness.jpg.meta b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Roughness.jpg.meta new file mode 100644 index 000000000..726ff5549 --- /dev/null +++ b/Assets/Materials/PBR/Steel_Brushed/Steel_Brushed_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 158c7794c28740d0a16fa2dc22e93d8c +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Tread_Diamond.meta b/Assets/Materials/PBR/Tread_Diamond.meta new file mode 100644 index 000000000..6a3445907 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 78b78bf7d2f84a8d85daaf75d21fa56f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond.mat b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond.mat new file mode 100644 index 000000000..5b9542d0f --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond.mat @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Tread_Diamond + m_Shader: {fileID: 4800000, guid: ddff0b48b92c991499817d2a0f5d5059, type: 3} + m_ShaderKeywords: _MAINTEX _METALLICGLOSSMAP _NORMALMAP + 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: 043636050ee1492697e5bebb7603bf12, type: 3} + 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} + - _FadeTex: + m_Texture: {fileID: 2800000, guid: df0632a08c5f1a1498fa325c755dc459, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: f04f0c584e824d81b7d7a91b969efef8, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 2800000, guid: 28456bc0a3c045e394e0937b6fe0231c, type: 3} + 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 + - _Fade: 0 + - _FadeEdge: 0.05 + - _FadeSharpness: 16 + - _GlossMapScale: 1 + - _Glossiness: 1 + - _GlossyReflections: 1 + - _Metallic: 1 + - _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} + - _EdgeColor: {r: 3.0117648, g: 3.0117648, b: 11.984314, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond.mat.meta b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond.mat.meta new file mode 100644 index 000000000..dd3e8ee22 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd8a08731d8c4a4d8961c92fe318f1bb +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Color.jpg b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Color.jpg new file mode 100644 index 000000000..c4aae91a2 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a1de0119ef8592c3054949b6a9608a5a814156f661ed54541b390feb6fb87cd +size 2675454 diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Color.jpg.meta b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Color.jpg.meta new file mode 100644 index 000000000..f02278e36 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Color.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: f04f0c584e824d81b7d7a91b969efef8 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_MetallicSmoothness.png b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_MetallicSmoothness.png new file mode 100644 index 000000000..8c48d3028 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_MetallicSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6131476bdbc8b6e910a5537a0aaadc977584f22c2a76d97f4cab4aa2b2b7ec0 +size 7151369 diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_MetallicSmoothness.png.meta b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_MetallicSmoothness.png.meta new file mode 100644 index 000000000..8804c2d58 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_MetallicSmoothness.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 28456bc0a3c045e394e0937b6fe0231c +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Metalness.jpg b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Metalness.jpg new file mode 100644 index 000000000..d65027465 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Metalness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6925202668aae7828b0a4765ca8854c539d94c4cd0f945b5195b5576272cdc7a +size 2420905 diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Metalness.jpg.meta b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Metalness.jpg.meta new file mode 100644 index 000000000..c786edbd3 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Metalness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 5086225cf1bf485597fe191f1b9ca912 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_NormalGL.jpg b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_NormalGL.jpg new file mode 100644 index 000000000..7411d45d0 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_NormalGL.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:317627265f2587cdfb00e06ea80415333b0ff2597321c79a77c2fd55448e5ec5 +size 7454546 diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_NormalGL.jpg.meta b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_NormalGL.jpg.meta new file mode 100644 index 000000000..747097254 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_NormalGL.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 043636050ee1492697e5bebb7603bf12 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 1 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Roughness.jpg b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Roughness.jpg new file mode 100644 index 000000000..2a2b7c7f8 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6aa2c8bd6044829215771cb1c3d82fcd3845565ff1a9416f4a10403dc2dfbc1b +size 2395648 diff --git a/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Roughness.jpg.meta b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Roughness.jpg.meta new file mode 100644 index 000000000..cc15cc441 --- /dev/null +++ b/Assets/Materials/PBR/Tread_Diamond/Tread_Diamond_Roughness.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 1d942e92edc64885ae82ceb88af83104 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 4 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Particles/Dithered Particle Trail AetherDrive.mat b/Assets/Materials/Particles/Dithered Particle Trail AetherDrive.mat deleted file mode 100644 index d4224d262..000000000 --- a/Assets/Materials/Particles/Dithered Particle Trail AetherDrive.mat +++ /dev/null @@ -1,78 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Dithered Particle Trail AetherDrive - m_Shader: {fileID: 4800000, guid: 46776b9fa35a437448f683f31b04d68d, 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: 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: 2800000, guid: 1d6eba2a167939a468c00fda35723dd0, type: 3} - m_Scale: {x: 0, y: 1} - m_Offset: {x: 0.5, 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 - - _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.216786, g: 1.216786, b: 1.216786, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - m_BuildTextureStacks: [] diff --git a/Assets/Materials/Particles/Dithered Particle Trail AetherDrive.mat.meta b/Assets/Materials/Particles/Dithered Particle Trail AetherDrive.mat.meta deleted file mode 100644 index 292027b73..000000000 --- a/Assets/Materials/Particles/Dithered Particle Trail AetherDrive.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 555ada90c0f01654a9387483bd95a688 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Prefabs/RPG/Fog Patch.prefab b/Assets/Prefabs/RPG/Fog Patch.prefab index 64769c721..52cdefc65 100644 --- a/Assets/Prefabs/RPG/Fog Patch.prefab +++ b/Assets/Prefabs/RPG/Fog Patch.prefab @@ -11,6 +11,7 @@ GameObject: - component: {fileID: 3040023561780424834} - component: {fileID: 8539532519029615782} - component: {fileID: 4655154266675363797} + - component: {fileID: 2914522964471179774} m_Layer: 11 m_Name: Fog Patch m_TagString: Untagged @@ -25,13 +26,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 791530951415938407} + serializedVersion: 2 m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: -3148.4, y: -253.6, z: -1108.1} - m_LocalScale: {x: 1513.8295, y: 1513.8295, z: 1513.8295} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} --- !u!33 &8539532519029615782 MeshFilter: @@ -58,6 +59,11 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -79,7 +85,22 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &2914522964471179774 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 791530951415938407} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a792b8f456004d04997a26557b338d1c, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::VapourCloudInstance + PatchHeight: -5 diff --git a/Assets/Prefabs/RPG/Pickups/Dodecahedron.prefab b/Assets/Prefabs/RPG/Pickups/Dodecahedron.prefab index 431b3c1a2..7a65a0864 100644 --- a/Assets/Prefabs/RPG/Pickups/Dodecahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Dodecahedron.prefab @@ -23,6 +23,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 4094535758000554889} + serializedVersion: 2 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} @@ -30,7 +31,6 @@ Transform: m_Children: - {fileID: 9133920759869389018} m_Father: {fileID: 8489385781787202308} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &5284461483464579928 GameObject: @@ -44,7 +44,6 @@ GameObject: - component: {fileID: 2667259809042191123} - component: {fileID: 2093307059618178533} - component: {fileID: 8815906420840494942} - - component: {fileID: 8842807112802394818} - component: {fileID: 8689774408369415534} - component: {fileID: 5705448000916375656} - component: {fileID: -5496574226213385675} @@ -62,6 +61,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5284461483464579928} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 2.76403, y: 0, z: 0} m_LocalScale: {x: 3, y: 3, z: 3} @@ -69,7 +69,6 @@ Transform: m_Children: - {fileID: 6463386671854692106} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &2667259809042191123 MeshFilter: @@ -96,6 +95,11 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -118,9 +122,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!135 &8815906420840494942 SphereCollider: @@ -130,29 +136,19 @@ SphereCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5284461483464579928} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 2 + serializedVersion: 3 m_Radius: 0.91187096 m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &8842807112802394818 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5284461483464579928} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 737f47c158214f0995ba2835f040ed96, type: 3} - m_Name: - m_EditorClassIdentifier: - RotationSpeed: 1 - GridOffset: 0 - GridAttraction: 10 - Gravity: 1 - Drag: 0.05 - LaunchDrag: 0.2 --- !u!54 &8689774408369415534 Rigidbody: m_ObjectHideFlags: 0 @@ -160,10 +156,21 @@ Rigidbody: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5284461483464579928} - serializedVersion: 2 + serializedVersion: 5 m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 + m_LinearDamping: 0 + m_AngularDamping: 0.05 + m_CenterOfMass: {x: 0, y: 0, z: 0} + m_InertiaTensor: {x: 1, y: 1, z: 1} + m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ImplicitCom: 1 + m_ImplicitTensor: 1 m_UseGravity: 0 m_IsKinematic: 1 m_Interpolate: 0 @@ -181,6 +188,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0c18f67d85af44c2b5afc8ecd15ce960, type: 3} m_Name: m_EditorClassIdentifier: + RotationSpeed: 1 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 @@ -204,6 +212,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 6463386671854692106} m_Modifications: - target: {fileID: 2945231343692618236, guid: e7877477dc889804ea9d04f7ffd08e9b, @@ -327,6 +336,9 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: e7877477dc889804ea9d04f7ffd08e9b, type: 3} --- !u!114 &3355762817961458026 stripped MonoBehaviour: diff --git a/Assets/Prefabs/RPG/Pickups/Hexahedron.prefab b/Assets/Prefabs/RPG/Pickups/Hexahedron.prefab index fea9f67a9..f9a477cda 100644 --- a/Assets/Prefabs/RPG/Pickups/Hexahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Hexahedron.prefab @@ -23,6 +23,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3193517496555256095} + serializedVersion: 2 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} @@ -30,7 +31,6 @@ Transform: m_Children: - {fileID: 7638477100053754924} m_Father: {fileID: 3419130779256825702} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &7643266616531142933 GameObject: @@ -44,7 +44,6 @@ GameObject: - component: {fileID: 3269639735116279291} - component: {fileID: 7427774873968414741} - component: {fileID: 674324171579366365} - - component: {fileID: 7449398549621940518} - component: {fileID: 4507103896627202189} - component: {fileID: 648083621841515580} - component: {fileID: -5443764149998352794} @@ -62,6 +61,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7643266616531142933} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 3, y: 3, z: 3} @@ -69,7 +69,6 @@ Transform: m_Children: - {fileID: 3601651121922051457} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &3269639735116279291 MeshFilter: @@ -96,6 +95,11 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -118,9 +122,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!135 &674324171579366365 SphereCollider: @@ -130,29 +136,19 @@ SphereCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7643266616531142933} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 2 + serializedVersion: 3 m_Radius: 0.8 m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &7449398549621940518 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7643266616531142933} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 737f47c158214f0995ba2835f040ed96, type: 3} - m_Name: - m_EditorClassIdentifier: - RotationSpeed: 1 - GridOffset: 0 - GridAttraction: 10 - Gravity: 1 - Drag: 0.05 - LaunchDrag: 0.2 --- !u!114 &4507103896627202189 MonoBehaviour: m_ObjectHideFlags: 0 @@ -165,6 +161,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0c18f67d85af44c2b5afc8ecd15ce960, type: 3} m_Name: m_EditorClassIdentifier: + RotationSpeed: 1 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 @@ -178,10 +175,21 @@ Rigidbody: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7643266616531142933} - serializedVersion: 2 + serializedVersion: 5 m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 + m_LinearDamping: 0 + m_AngularDamping: 0.05 + m_CenterOfMass: {x: 0, y: 0, z: 0} + m_InertiaTensor: {x: 1, y: 1, z: 1} + m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ImplicitCom: 1 + m_ImplicitTensor: 1 m_UseGravity: 0 m_IsKinematic: 1 m_Interpolate: 0 @@ -204,6 +212,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 3601651121922051457} m_Modifications: - target: {fileID: 2945231343692618236, guid: e7877477dc889804ea9d04f7ffd08e9b, @@ -327,6 +336,9 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: e7877477dc889804ea9d04f7ffd08e9b, type: 3} --- !u!114 &4202270197902620060 stripped MonoBehaviour: diff --git a/Assets/Prefabs/RPG/Pickups/Icosahedron.prefab b/Assets/Prefabs/RPG/Pickups/Icosahedron.prefab index e99ae3392..4252e74cc 100644 --- a/Assets/Prefabs/RPG/Pickups/Icosahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Icosahedron.prefab @@ -23,6 +23,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6430764275721745537} + serializedVersion: 2 m_LocalRotation: {x: 0.7069834, y: -0, z: -0, w: 0.7072302} m_LocalPosition: {x: 0, y: -0.9858858, z: 0.000344038} m_LocalScale: {x: 1, y: 1, z: 1} @@ -30,7 +31,6 @@ Transform: m_Children: - {fileID: 5373456011921669618} m_Father: {fileID: 7548484292876150345} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &7167547457198401877 GameObject: @@ -44,7 +44,6 @@ GameObject: - component: {fileID: 7390838957595368880} - component: {fileID: 6960669510133879758} - component: {fileID: 3507902894264904200} - - component: {fileID: 8747099621875196907} - component: {fileID: 1545255963217739444} - component: {fileID: -5409019571952974707} - component: {fileID: -2501508196100734606} @@ -62,6 +61,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7167547457198401877} + serializedVersion: 2 m_LocalRotation: {x: -0.7069834, y: 0, z: 0, w: 0.7072302} m_LocalPosition: {x: -0, y: 0, z: -2.9576573} m_LocalScale: {x: 3, y: 3, z: 3} @@ -69,7 +69,6 @@ Transform: m_Children: - {fileID: 4002800527770282731} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: -89.98, y: 0, z: 0} --- !u!33 &7390838957595368880 MeshFilter: @@ -96,6 +95,11 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -118,9 +122,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!135 &3507902894264904200 SphereCollider: @@ -130,29 +136,19 @@ SphereCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7167547457198401877} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 2 + serializedVersion: 3 m_Radius: 0.8303433 m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &8747099621875196907 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7167547457198401877} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 737f47c158214f0995ba2835f040ed96, type: 3} - m_Name: - m_EditorClassIdentifier: - RotationSpeed: 1 - GridOffset: 0 - GridAttraction: 10 - Gravity: 1 - Drag: 0.05 - LaunchDrag: 0.2 --- !u!114 &1545255963217739444 MonoBehaviour: m_ObjectHideFlags: 0 @@ -165,6 +161,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0c18f67d85af44c2b5afc8ecd15ce960, type: 3} m_Name: m_EditorClassIdentifier: + RotationSpeed: 1 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 @@ -178,10 +175,21 @@ Rigidbody: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7167547457198401877} - serializedVersion: 2 + serializedVersion: 5 m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 + m_LinearDamping: 0 + m_AngularDamping: 0.05 + m_CenterOfMass: {x: 0, y: 0, z: 0} + m_InertiaTensor: {x: 1, y: 1, z: 1} + m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ImplicitCom: 1 + m_ImplicitTensor: 1 m_UseGravity: 0 m_IsKinematic: 1 m_Interpolate: 0 @@ -204,6 +212,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 4002800527770282731} m_Modifications: - target: {fileID: 2945231343692618236, guid: e7877477dc889804ea9d04f7ffd08e9b, @@ -327,6 +336,9 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: e7877477dc889804ea9d04f7ffd08e9b, type: 3} --- !u!114 &1928241908402748482 stripped MonoBehaviour: diff --git a/Assets/Prefabs/RPG/Pickups/Octahedron.prefab b/Assets/Prefabs/RPG/Pickups/Octahedron.prefab index 7ba7910d2..099083195 100644 --- a/Assets/Prefabs/RPG/Pickups/Octahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Octahedron.prefab @@ -23,6 +23,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3932408193141279893} + serializedVersion: 2 m_LocalRotation: {x: 0.7069834, y: -0, z: -0, w: 0.7072302} m_LocalPosition: {x: 0, y: 0.9264834, z: -0.0003232956} m_LocalScale: {x: 1, y: 1, z: 1} @@ -30,7 +31,6 @@ Transform: m_Children: - {fileID: 7372978312502119311} m_Father: {fileID: 5807113421007930924} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &8555821447211356933 GameObject: @@ -44,7 +44,6 @@ GameObject: - component: {fileID: 4899765339662518078} - component: {fileID: 1691511938472729356} - component: {fileID: 3657818610818556929} - - component: {fileID: 946329779588188460} - component: {fileID: 7390748043139687254} - component: {fileID: -4611973708976329780} - component: {fileID: -8908388773057984787} @@ -62,6 +61,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 8555821447211356933} + serializedVersion: 2 m_LocalRotation: {x: -0.7069834, y: 0, z: 0, w: 0.7072302} m_LocalPosition: {x: -0, y: 0, z: 2.7794502} m_LocalScale: {x: 3, y: 3, z: 3} @@ -69,7 +69,6 @@ Transform: m_Children: - {fileID: 2388751103296260666} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: -89.98, y: 0, z: 0} --- !u!33 &4899765339662518078 MeshFilter: @@ -96,6 +95,11 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -118,9 +122,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!135 &3657818610818556929 SphereCollider: @@ -130,29 +136,19 @@ SphereCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 8555821447211356933} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 2 + serializedVersion: 3 m_Radius: 0.75 m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &946329779588188460 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8555821447211356933} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 737f47c158214f0995ba2835f040ed96, type: 3} - m_Name: - m_EditorClassIdentifier: - RotationSpeed: 1 - GridOffset: 0 - GridAttraction: 10 - Gravity: 1 - Drag: 0.05 - LaunchDrag: 0.2 --- !u!114 &7390748043139687254 MonoBehaviour: m_ObjectHideFlags: 0 @@ -165,6 +161,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0c18f67d85af44c2b5afc8ecd15ce960, type: 3} m_Name: m_EditorClassIdentifier: + RotationSpeed: 1 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 @@ -178,10 +175,21 @@ Rigidbody: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 8555821447211356933} - serializedVersion: 2 + serializedVersion: 5 m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 + m_LinearDamping: 0 + m_AngularDamping: 0.05 + m_CenterOfMass: {x: 0, y: 0, z: 0} + m_InertiaTensor: {x: 1, y: 1, z: 1} + m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ImplicitCom: 1 + m_ImplicitTensor: 1 m_UseGravity: 0 m_IsKinematic: 1 m_Interpolate: 0 @@ -204,6 +212,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 2388751103296260666} m_Modifications: - target: {fileID: 2945231343692618236, guid: e7877477dc889804ea9d04f7ffd08e9b, @@ -327,6 +336,9 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: e7877477dc889804ea9d04f7ffd08e9b, type: 3} --- !u!114 &3891726626588969535 stripped MonoBehaviour: diff --git a/Assets/Prefabs/RPG/Pickups/Scan Label.prefab b/Assets/Prefabs/RPG/Pickups/Scan Label.prefab index dff141f55..62c129c2b 100644 --- a/Assets/Prefabs/RPG/Pickups/Scan Label.prefab +++ b/Assets/Prefabs/RPG/Pickups/Scan Label.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -48,11 +48,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -74,9 +80,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!114 &3085702413493447743 MonoBehaviour: @@ -136,20 +144,23 @@ MonoBehaviour: m_VerticalAlignment: 1024 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 0 m_isCullingEnabled: 0 @@ -164,8 +175,9 @@ MonoBehaviour: m_margin: {x: 0, y: 0, z: 0, w: 0} m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 m_hasFontAssetChanged: 0 m_renderer: {fileID: 2000937249754104238} m_maskType: 0 - _SortingLayerID: 0 - _SortingOrder: 0 diff --git a/Assets/Prefabs/RPG/Pickups/Tetrahedron.prefab b/Assets/Prefabs/RPG/Pickups/Tetrahedron.prefab index 26c2b96dd..6dad19967 100644 --- a/Assets/Prefabs/RPG/Pickups/Tetrahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Tetrahedron.prefab @@ -23,6 +23,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2238948151922859802} + serializedVersion: 2 m_LocalRotation: {x: 0.7069834, y: -0, z: -0, w: 0.7072302} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} @@ -30,7 +31,6 @@ Transform: m_Children: - {fileID: 3300919539099916088} m_Father: {fileID: 8414659055235772867} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &7767746557817481743 GameObject: @@ -44,7 +44,6 @@ GameObject: - component: {fileID: 2868629223358676395} - component: {fileID: 6959931328227918623} - component: {fileID: 4540815661693075899} - - component: {fileID: 4008709970769624704} - component: {fileID: 7436534270673427838} - component: {fileID: -6589342969031261525} - component: {fileID: 5724758014884646323} @@ -62,6 +61,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7767746557817481743} + serializedVersion: 2 m_LocalRotation: {x: -0.7069834, y: 0, z: 0, w: 0.7072302} m_LocalPosition: {x: -0, y: 0, z: 0} m_LocalScale: {x: 3, y: 3, z: 3} @@ -69,7 +69,6 @@ Transform: m_Children: - {fileID: 7682789761269032435} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: -89.98, y: 0, z: 0} --- !u!33 &2868629223358676395 MeshFilter: @@ -96,6 +95,11 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -118,9 +122,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!135 &4540815661693075899 SphereCollider: @@ -130,29 +136,19 @@ SphereCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7767746557817481743} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 2 + serializedVersion: 3 m_Radius: 0.60371214 m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &4008709970769624704 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7767746557817481743} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 737f47c158214f0995ba2835f040ed96, type: 3} - m_Name: - m_EditorClassIdentifier: - RotationSpeed: 1 - GridOffset: 0 - GridAttraction: 10 - Gravity: 1 - Drag: 0.05 - LaunchDrag: 0.2 --- !u!114 &7436534270673427838 MonoBehaviour: m_ObjectHideFlags: 0 @@ -165,6 +161,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0c18f67d85af44c2b5afc8ecd15ce960, type: 3} m_Name: m_EditorClassIdentifier: + RotationSpeed: 1 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 @@ -178,10 +175,21 @@ Rigidbody: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7767746557817481743} - serializedVersion: 2 + serializedVersion: 5 m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 + m_LinearDamping: 0 + m_AngularDamping: 0.05 + m_CenterOfMass: {x: 0, y: 0, z: 0} + m_InertiaTensor: {x: 1, y: 1, z: 1} + m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ImplicitCom: 1 + m_ImplicitTensor: 1 m_UseGravity: 0 m_IsKinematic: 1 m_Interpolate: 0 @@ -204,6 +212,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 7682789761269032435} m_Modifications: - target: {fileID: 2945231343692618236, guid: e7877477dc889804ea9d04f7ffd08e9b, @@ -327,6 +336,9 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: e7877477dc889804ea9d04f7ffd08e9b, type: 3} --- !u!224 &3300919539099916088 stripped RectTransform: diff --git a/Assets/Prefabs/RPG/Planets/Gas Giant.prefab b/Assets/Prefabs/RPG/Planets/Gas Giant.prefab index 46ae7a3b1..de87b2a13 100644 --- a/Assets/Prefabs/RPG/Planets/Gas Giant.prefab +++ b/Assets/Prefabs/RPG/Planets/Gas Giant.prefab @@ -30,8 +30,6 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3973935122748960680} - - {fileID: 3973935121058605868} - - {fileID: 3973935122114073483} - {fileID: 3973935121358855036} m_Father: {fileID: 0} m_RootOrder: 0 @@ -49,94 +47,9 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Body: {fileID: 3973935122748960683} - GravityWell: {fileID: 3973935121058605871} Icon: {fileID: 3973935121358855037} Generator: {fileID: 0} SunMaterial: {fileID: 3973935122748960685} - GravityWaves: {fileID: 3973935122114073485} ---- !u!1 &3973935121058605867 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 3973935121058605868} - - component: {fileID: 3973935121058605856} - - component: {fileID: 3973935121058605871} - m_Layer: 9 - m_Name: Gravity Well - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &3973935121058605868 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3973935121058605867} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 3973935120991099173} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &3973935121058605856 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3973935121058605867} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &3973935121058605871 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3973935121058605867} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &3973935121358855035 GameObject: m_ObjectHideFlags: 0 @@ -220,89 +133,6 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &3973935122114073482 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 3973935122114073483} - - component: {fileID: 3973935122114073486} - - component: {fileID: 3973935122114073485} - m_Layer: 10 - m_Name: Gravity Waves - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &3973935122114073483 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3973935122114073482} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 3973935120991099173} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &3973935122114073486 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3973935122114073482} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &3973935122114073485 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3973935122114073482} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 11fbaa87dcc7a3743a6bd3aa5c86e5ae, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &3973935122748960663 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Prefabs/RPG/Planets/Planet.prefab b/Assets/Prefabs/RPG/Planets/Planet.prefab index 336b3430b..afffe73c4 100644 --- a/Assets/Prefabs/RPG/Planets/Planet.prefab +++ b/Assets/Prefabs/RPG/Planets/Planet.prefab @@ -83,89 +83,6 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &8859079004671924238 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 8859079004671924239} - - component: {fileID: 8859079004671924339} - - component: {fileID: 8859079004671924338} - m_Layer: 9 - m_Name: Gravity Well - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &8859079004671924239 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8859079004671924238} - m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 8859079004937162792} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &8859079004671924339 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8859079004671924238} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &8859079004671924338 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8859079004671924238} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &8859079004937162791 GameObject: m_ObjectHideFlags: 0 @@ -197,7 +114,6 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 8859079005270853336} - - {fileID: 8859079004671924239} - {fileID: 8859079003226229097} m_Father: {fileID: 0} m_RootOrder: 0 @@ -215,7 +131,6 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Body: {fileID: 8859079005270853338} - GravityWell: {fileID: 8859079004671924338} Icon: {fileID: 8859079003226229098} Generator: {fileID: -7153121627769399805} --- !u!114 &-7153121627769399805 diff --git a/Assets/Prefabs/RPG/Planets/Sun.prefab b/Assets/Prefabs/RPG/Planets/Sun.prefab index a7950f448..ebe0fa72f 100644 --- a/Assets/Prefabs/RPG/Planets/Sun.prefab +++ b/Assets/Prefabs/RPG/Planets/Sun.prefab @@ -30,8 +30,6 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 7852221720971737233} - - {fileID: 7852221720969441490} - - {fileID: 7852221720741322892} - {fileID: 7852221720816817928} - {fileID: 7852221720964551245} m_Father: {fileID: 0} @@ -50,96 +48,11 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Body: {fileID: 7852221720971737229} - GravityWell: {fileID: 7852221720969441484} Icon: {fileID: 7852221720964551246} Generator: {fileID: 0} SunMaterial: {fileID: 7852221720971737234} - GravityWaves: {fileID: 7852221720741322894} FogTint: {fileID: 7852221720816817929} Light: {fileID: 8064377225639657765} ---- !u!1 &7852221720741322899 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 7852221720741322892} - - component: {fileID: 7852221720741322895} - - component: {fileID: 7852221720741322894} - m_Layer: 10 - m_Name: Gravity Waves - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &7852221720741322892 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7852221720741322899} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 7852221720480299767} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &7852221720741322895 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7852221720741322899} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &7852221720741322894 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7852221720741322899} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 11fbaa87dcc7a3743a6bd3aa5c86e5ae, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &7852221720816817935 GameObject: m_ObjectHideFlags: 0 @@ -306,89 +219,6 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &7852221720969441489 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 7852221720969441490} - - component: {fileID: 7852221720969441485} - - component: {fileID: 7852221720969441484} - m_Layer: 9 - m_Name: Gravity Well - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &7852221720969441490 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7852221720969441489} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 7852221720480299767} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &7852221720969441485 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7852221720969441489} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &7852221720969441484 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7852221720969441489} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &7852221720971737232 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Prefabs/RPG/Wormhole 1.prefab b/Assets/Prefabs/RPG/Wormhole 1.prefab index b03d01009..e1ca93be7 100644 --- a/Assets/Prefabs/RPG/Wormhole 1.prefab +++ b/Assets/Prefabs/RPG/Wormhole 1.prefab @@ -1,167 +1,5 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: ---- !u!1 &1826894967093516808 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1030590306481442051} - - component: {fileID: 3216580199816124320} - - component: {fileID: 3211969211988968959} - m_Layer: 9 - m_Name: Gravity Well - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1030590306481442051 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1826894967093516808} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1024, y: 1024, z: 1024} - m_Children: [] - m_Father: {fileID: 463084220523011477} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &3216580199816124320 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1826894967093516808} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &3211969211988968959 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1826894967093516808} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 244f3e4c0c030a24b8d7aa944895bdcf, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &3908760799087214860 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 581261949390603689} - - component: {fileID: 987447324816385543} - - component: {fileID: 3959510878930752720} - m_Layer: 9 - m_Name: Gravity Waves - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &581261949390603689 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3908760799087214860} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 512, y: 512, z: 512} - m_Children: [] - m_Father: {fileID: 463084220523011477} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &987447324816385543 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3908760799087214860} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &3959510878930752720 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3908760799087214860} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: ef2f6090d5cc14a4e9ce38def3bed9ac, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &4837153162502999620 GameObject: m_ObjectHideFlags: 0 @@ -189,9 +27,6 @@ Transform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - - {fileID: 8222188360457572195} - - {fileID: 1030590306481442051} - - {fileID: 581261949390603689} - {fileID: 8249320701965103923} m_Father: {fileID: 0} m_RootOrder: 0 @@ -277,84 +112,3 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &7647029665738834910 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 8222188360457572195} - - component: {fileID: 2468954688819198096} - - component: {fileID: 8290522694236574882} - m_Layer: 9 - m_Name: Gravity Pit - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &8222188360457572195 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7647029665738834910} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 512, y: 512, z: 512} - m_Children: [] - m_Father: {fileID: 463084220523011477} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!33 &2468954688819198096 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7647029665738834910} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &8290522694236574882 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7647029665738834910} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a9ef17c902709ce41a837c54b809184b, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/Prefabs/RTS/Entity.prefab b/Assets/Prefabs/RTS/Entity.prefab index c981cb3fb..61a1a8eb7 100644 --- a/Assets/Prefabs/RTS/Entity.prefab +++ b/Assets/Prefabs/RTS/Entity.prefab @@ -10,7 +10,6 @@ GameObject: m_Component: - component: {fileID: 4644834953993757301} - component: {fileID: 1859458984701215649} - - component: {fileID: 3439515216706641237} - component: {fileID: 3170441533209407059} - component: {fileID: 3150651635148382191} m_Layer: 0 @@ -30,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7667578565413050542} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -50,13 +49,21 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -64,6 +71,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -73,17 +81,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 ---- !u!33 &3439515216706641237 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 235155884317602032} - m_Mesh: {fileID: 0} + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!222 &3170441533209407059 CanvasRenderer: m_ObjectHideFlags: 0 @@ -107,16 +110,18 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] m_text: 'Something just happened, now I''m telling you about it. - Something just happened, now I''m telling you about it.' + Something + just happened, now I''m telling you about it.' m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} - m_sharedMaterial: {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, - type: 2} + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -134,13 +139,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 2.5 m_fontSizeBase: 2.5 m_fontWeight: 400 @@ -148,62 +152,46 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 1026 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 1024 + m_textAlignment: 65535 m_characterSpacing: 1.38 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 7.09 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: 0 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 0 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 3150651635148382191} - characterCount: 109 - spriteCount: 0 - spaceCount: 17 - wordCount: 18 - linkCount: 0 - lineCount: 2 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 m_hasFontAssetChanged: 0 m_renderer: {fileID: 1859458984701215649} - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_maskType: 0 --- !u!1 &7667578565016065614 GameObject: @@ -232,12 +220,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7667578565016065614} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0.05} m_LocalScale: {x: 0.75, y: 0.75, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7667578565413050542} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &7667578565016065611 MeshFilter: @@ -258,9 +247,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -272,6 +269,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -281,9 +279,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!64 &7667578565016065609 MeshCollider: m_ObjectHideFlags: 0 @@ -292,11 +293,19 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7667578565016065614} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 3 + serializedVersion: 5 m_Convex: 0 - m_CookingOptions: 14 + m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} --- !u!114 &7667578565016065610 MonoBehaviour: @@ -334,15 +343,16 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7667578565413050543} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 5.38, y: 0.81, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 7667578565016065613} - {fileID: 7667578566386612334} - {fileID: 4644834953993757301} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &5800314421439145179 MonoBehaviour: @@ -370,7 +380,6 @@ GameObject: m_Component: - component: {fileID: 7667578566386612334} - component: {fileID: 7667578566386612330} - - component: {fileID: 7667578566386612331} - component: {fileID: 7667578566386612332} - component: {fileID: 7667578566386612333} m_Layer: 0 @@ -390,9 +399,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7667578565413050542} - 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} @@ -410,13 +419,21 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -424,6 +441,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -433,17 +451,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 ---- !u!33 &7667578566386612331 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7667578566386612335} - m_Mesh: {fileID: 0} + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!222 &7667578566386612332 CanvasRenderer: m_ObjectHideFlags: 0 @@ -467,6 +480,8 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -474,9 +489,8 @@ MonoBehaviour: ' m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} - m_sharedMaterial: {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, - type: 2} + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -494,13 +508,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 2 m_fontSizeBase: 2 m_fontWeight: 400 @@ -508,60 +521,44 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 258 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 256 + m_textAlignment: 65535 m_characterSpacing: 1.38 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: -1 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 0 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 7667578566386612333} - characterCount: 13 - spriteCount: 0 - spaceCount: 2 - wordCount: 2 - linkCount: 0 - lineCount: 1 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 m_hasFontAssetChanged: 0 m_renderer: {fileID: 7667578566386612330} - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_maskType: 0 diff --git a/Assets/Prefabs/RTS/Planet.prefab b/Assets/Prefabs/RTS/Planet.prefab index 09c80e995..b288f30c5 100644 --- a/Assets/Prefabs/RTS/Planet.prefab +++ b/Assets/Prefabs/RTS/Planet.prefab @@ -10,7 +10,6 @@ GameObject: m_Component: - component: {fileID: 1093865191529778971} - component: {fileID: 956320758189013213} - - component: {fileID: 6189203536709783203} - component: {fileID: 688008198251117811} - component: {fileID: 6196070888394201391} m_Layer: 0 @@ -30,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5321404118521994135} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -50,13 +49,21 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -64,6 +71,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -73,17 +81,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 ---- !u!33 &6189203536709783203 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4176311944753611310} - m_Mesh: {fileID: 0} + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!222 &688008198251117811 CanvasRenderer: m_ObjectHideFlags: 0 @@ -107,16 +110,18 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] m_text: 'Something just happened, now I''m telling you about it. - Something just happened, now I''m telling you about it.' + Something + just happened, now I''m telling you about it.' m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} - m_sharedMaterial: {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, - type: 2} + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -134,13 +139,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 2.5 m_fontSizeBase: 2.5 m_fontWeight: 400 @@ -148,62 +152,46 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 1026 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 1024 + m_textAlignment: 65535 m_characterSpacing: 1.38 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 7.09 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: 0 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 0 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 6196070888394201391} - characterCount: 109 - spriteCount: 0 - spaceCount: 17 - wordCount: 18 - linkCount: 0 - lineCount: 2 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 m_hasFontAssetChanged: 0 m_renderer: {fileID: 956320758189013213} - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_maskType: 0 --- !u!1 &5321404118521994134 GameObject: @@ -229,16 +217,16 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5321404118521994134} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 5.38, y: 0.81, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - - {fileID: 5321404120083801960} - {fileID: 5321404118931821940} - {fileID: 5321404119494867799} - {fileID: 1093865191529778971} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &5321404118521994133 MonoBehaviour: @@ -256,7 +244,7 @@ MonoBehaviour: Label: {fileID: 5321404119494867796} Message: {fileID: 6196070888394201391} Children: [] - GravityMesh: {fileID: 5321404120083801962} + GravityMesh: {fileID: 0} --- !u!1 &5321404118931821943 GameObject: m_ObjectHideFlags: 0 @@ -284,12 +272,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5321404118931821943} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0.05} m_LocalScale: {x: 0.75, y: 0.75, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5321404118521994135} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &5321404118931821938 MeshFilter: @@ -310,9 +299,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -324,6 +321,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -333,9 +331,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!64 &5321404118931821936 MeshCollider: m_ObjectHideFlags: 0 @@ -344,11 +345,19 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5321404118931821943} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 3 + serializedVersion: 5 m_Convex: 0 - m_CookingOptions: 14 + m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} --- !u!114 &5321404118931821939 MonoBehaviour: @@ -372,7 +381,6 @@ GameObject: m_Component: - component: {fileID: 5321404119494867799} - component: {fileID: 5321404119494867795} - - component: {fileID: 5321404119494867794} - component: {fileID: 5321404119494867797} - component: {fileID: 5321404119494867796} m_Layer: 0 @@ -392,9 +400,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5321404118521994135} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -412,13 +420,21 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -426,6 +442,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -435,17 +452,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 ---- !u!33 &5321404119494867794 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5321404119494867798} - m_Mesh: {fileID: 0} + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!222 &5321404119494867797 CanvasRenderer: m_ObjectHideFlags: 0 @@ -469,6 +481,8 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -476,9 +490,8 @@ MonoBehaviour: ' m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} - m_sharedMaterial: {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, - type: 2} + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -496,13 +509,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 2 m_fontSizeBase: 2 m_fontWeight: 400 @@ -510,137 +522,44 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 258 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 256 + m_textAlignment: 65535 m_characterSpacing: 1.38 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: -1 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 0 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 5321404119494867796} - characterCount: 13 - spriteCount: 0 - spaceCount: 2 - wordCount: 2 - linkCount: 0 - lineCount: 1 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 m_hasFontAssetChanged: 0 m_renderer: {fileID: 5321404119494867795} - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_maskType: 0 ---- !u!1 &5321404120083801964 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 5321404120083801960} - - component: {fileID: 5321404120083801963} - - component: {fileID: 5321404120083801962} - m_Layer: 8 - m_Name: Gravity Well - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &5321404120083801960 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5321404120083801964} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 10, y: 10, z: 1} - m_Children: [] - m_Father: {fileID: 5321404118521994135} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &5321404120083801963 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5321404120083801964} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &5321404120083801962 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5321404120083801964} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, 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 diff --git a/Assets/Prefabs/RTS/Ship.prefab b/Assets/Prefabs/RTS/Ship.prefab index 34867f7bf..9bfde2c33 100644 --- a/Assets/Prefabs/RTS/Ship.prefab +++ b/Assets/Prefabs/RTS/Ship.prefab @@ -23,13 +23,14 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 717230718983664133} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0.7071068, w: 0.7071068} m_LocalPosition: {x: 0, y: -0.396, z: 0.025000002} m_LocalScale: {x: 1, y: 1.5, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 6370514743660505460} m_Father: {fileID: 752969731239391542} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &752969730562965460 GameObject: @@ -55,15 +56,16 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 752969730562965460} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 5.38, y: 0.81, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 752969731239391542} - {fileID: 752969731603226389} - {fileID: 2376444423840420930} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &795352744099449573 MonoBehaviour: @@ -109,13 +111,14 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 752969731239391541} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0.05} m_LocalScale: {x: 0.75, y: 0.75, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 6634195572313526987} m_Father: {fileID: 752969730562965461} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &752969731239391536 MeshFilter: @@ -136,9 +139,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -150,6 +161,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -159,9 +171,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!64 &752969731239391538 MeshCollider: m_ObjectHideFlags: 0 @@ -170,11 +185,19 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 752969731239391541} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 3 + serializedVersion: 5 m_Convex: 0 - m_CookingOptions: 14 + m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} --- !u!114 &752969731239391537 MonoBehaviour: @@ -198,7 +221,6 @@ GameObject: m_Component: - component: {fileID: 752969731603226389} - component: {fileID: 752969731603226385} - - component: {fileID: 752969731603226384} - component: {fileID: 752969731603226391} - component: {fileID: 752969731603226390} m_Layer: 0 @@ -218,9 +240,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 752969730562965461} - 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} @@ -238,13 +260,21 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -252,6 +282,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -261,17 +292,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 ---- !u!33 &752969731603226384 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 752969731603226388} - m_Mesh: {fileID: 0} + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!222 &752969731603226391 CanvasRenderer: m_ObjectHideFlags: 0 @@ -295,6 +321,8 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -302,9 +330,8 @@ MonoBehaviour: ' m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} - m_sharedMaterial: {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, - type: 2} + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -322,13 +349,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 2 m_fontSizeBase: 2 m_fontWeight: 400 @@ -336,62 +362,46 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 258 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 256 + m_textAlignment: 65535 m_characterSpacing: 1.38 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: -1 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 0 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 752969731603226390} - characterCount: 13 - spriteCount: 0 - spaceCount: 2 - wordCount: 2 - linkCount: 0 - lineCount: 1 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 m_hasFontAssetChanged: 0 m_renderer: {fileID: 752969731603226385} - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_maskType: 0 --- !u!1 &1383583254418650531 GameObject: @@ -418,12 +428,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1383583254418650531} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0.114, y: 0, z: 0} m_LocalScale: {x: 0.3, y: 0.3, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6634195572313526987} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} --- !u!33 &2644584120131549798 MeshFilter: @@ -444,9 +455,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -458,6 +477,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -467,9 +487,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &8284500064616352456 GameObject: m_ObjectHideFlags: 0 @@ -480,7 +503,6 @@ GameObject: m_Component: - component: {fileID: 2376444423840420930} - component: {fileID: 9122382316357193139} - - component: {fileID: 2978801183465297864} - component: {fileID: 7740350830631187417} - component: {fileID: 2269191731601446379} m_Layer: 0 @@ -500,9 +522,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 752969730562965461} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -520,13 +542,21 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -534,6 +564,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -543,17 +574,12 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 ---- !u!33 &2978801183465297864 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8284500064616352456} - m_Mesh: {fileID: 0} + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!222 &7740350830631187417 CanvasRenderer: m_ObjectHideFlags: 0 @@ -577,16 +603,18 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] m_text: 'Something just happened, now I''m telling you about it. - Something just happened, now I''m telling you about it.' + Something + just happened, now I''m telling you about it.' m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} - m_sharedMaterial: {fileID: 21677577810600300, guid: ef74c4c30ca5ced4489f28b914006aad, - type: 2} + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -604,13 +632,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 2.5 m_fontSizeBase: 2.5 m_fontWeight: 400 @@ -618,60 +645,44 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 1026 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 1024 + m_textAlignment: 65535 m_characterSpacing: 1.38 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 7.09 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: 0 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 0 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 2269191731601446379} - characterCount: 109 - spriteCount: 0 - spaceCount: 17 - wordCount: 18 - linkCount: 0 - lineCount: 2 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 m_hasFontAssetChanged: 0 m_renderer: {fileID: 9122382316357193139} - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_maskType: 0 diff --git a/Assets/Prefabs/UI/Action Slot.prefab b/Assets/Prefabs/UI/Action Slot.prefab index 6ecf19406..acfc2f263 100644 --- a/Assets/Prefabs/UI/Action Slot.prefab +++ b/Assets/Prefabs/UI/Action Slot.prefab @@ -31,7 +31,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8334150340270499360} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -105,20 +104,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -181,7 +183,6 @@ RectTransform: - {fileID: 8334150341178146430} - {fileID: 8334150340826609675} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -350,7 +351,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8334150340270499360} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -426,7 +426,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8334150340270499360} - m_RootOrder: 7 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -502,7 +501,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8334150340270499360} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -578,7 +576,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8334150340270499360} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -654,7 +651,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8334150340270499360} - m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -728,20 +724,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -790,7 +789,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8334150340270499360} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -864,20 +862,23 @@ MonoBehaviour: m_VerticalAlignment: 1024 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -926,7 +927,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8334150340270499360} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} diff --git a/Assets/Prefabs/UI/Choice.prefab b/Assets/Prefabs/UI/Choice.prefab index 7aff99027..5624bd6ff 100644 --- a/Assets/Prefabs/UI/Choice.prefab +++ b/Assets/Prefabs/UI/Choice.prefab @@ -11,7 +11,7 @@ GameObject: - component: {fileID: 1388299342124750210} - component: {fileID: 7958013063086106696} m_Layer: 5 - m_Name: TMP SubMeshUI [UbuntuMono-R SDF + LiberationSans SDF Atlas] + m_Name: 'TMP SubMeshUI [UbuntuMono-R SDF + LiberationSans SDF Atlas]' m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -27,9 +27,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3385051013345111086} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -76,10 +76,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1388299342124750210} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -152,20 +152,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Context Menu Option.prefab b/Assets/Prefabs/UI/Context Menu Option.prefab index 77cbd95e0..ccaca26d5 100644 --- a/Assets/Prefabs/UI/Context Menu Option.prefab +++ b/Assets/Prefabs/UI/Context Menu Option.prefab @@ -32,11 +32,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2147126713793274338} - {fileID: 1944744018361081348} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -202,9 +202,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2147126713262799480} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -278,20 +278,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -357,9 +360,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2147126713262799480} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} diff --git a/Assets/Prefabs/UI/Corporation Selection.prefab b/Assets/Prefabs/UI/Corporation Selection.prefab index 0e983e9be..b9dda795c 100644 --- a/Assets/Prefabs/UI/Corporation Selection.prefab +++ b/Assets/Prefabs/UI/Corporation Selection.prefab @@ -29,10 +29,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3643881634033459408} m_Father: {fileID: 3643881633437836137} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -62,6 +62,8 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -89,13 +91,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 12 m_fontSizeBase: 16 m_fontWeight: 400 @@ -103,61 +104,42 @@ MonoBehaviour: m_fontSizeMin: 12 m_fontSizeMax: 20 m_fontStyle: 0 - m_textAlignment: 514 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: 0 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 3643881633221182914} - characterCount: 212 - spriteCount: 0 - spaceCount: 31 - wordCount: 32 - linkCount: 0 - lineCount: 181 - pageCount: 1 - materialCount: 2 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} m_hasFontAssetChanged: 0 - m_subTextObjects: - - {fileID: 0} - - {fileID: 3643881634033459409} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &3643881633221182915 @@ -169,7 +151,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881633221182924} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} m_Name: m_EditorClassIdentifier: m_IgnoreLayout: 0 @@ -212,6 +194,7 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3643881633927103020} - {fileID: 3643881634854544289} @@ -219,7 +202,6 @@ RectTransform: - {fileID: 3643881634695350169} - {fileID: 3643881634325817956} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -235,7 +217,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881633437836136} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} m_Name: m_EditorClassIdentifier: m_IgnoreLayout: 0 @@ -255,7 +237,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881633437836136} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} m_Name: m_EditorClassIdentifier: m_Padding: @@ -269,6 +251,9 @@ MonoBehaviour: m_ChildForceExpandHeight: 0 m_ChildControlWidth: 1 m_ChildControlHeight: 1 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 --- !u!222 &3643881633437836141 CanvasRenderer: m_ObjectHideFlags: 0 @@ -286,12 +271,14 @@ MonoBehaviour: m_GameObject: {fileID: 3643881633437836136} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0, g: 0.29125005, b: 0.699, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -304,6 +291,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!114 &6925424662664426412 MonoBehaviour: m_ObjectHideFlags: 0 @@ -313,11 +301,12 @@ MonoBehaviour: m_GameObject: {fileID: 3643881633437836136} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} m_Name: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -327,17 +316,20 @@ MonoBehaviour: m_NormalColor: {r: 0.3962264, g: 0.3962264, b: 0.3962264, a: 1} m_HighlightedColor: {r: 0.8018868, g: 0.8018868, b: 0.8018868, a: 1} m_PressedColor: {r: 1, g: 1, b: 1, a: 1} + m_SelectedColor: {r: 0.8018868, g: 0.8018868, b: 0.8018868, a: 1} m_DisabledColor: {r: 0.301, g: 0.301, b: 0.301, a: 0.5019608} m_ColorMultiplier: 1 m_FadeDuration: 0.1 m_SpriteState: m_HighlightedSprite: {fileID: 0} m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} m_DisabledSprite: {fileID: 0} m_AnimationTriggers: m_NormalTrigger: Normal m_HighlightedTrigger: Highlighted m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted m_DisabledTrigger: Disabled m_Interactable: 1 m_TargetGraphic: {fileID: 3643881633437836140} @@ -390,9 +382,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3643881633437836137} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -422,6 +414,8 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -447,13 +441,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 18 m_fontSizeBase: 48 m_fontWeight: 400 @@ -461,61 +454,42 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 514 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: 0 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 3643881633927103010} - characterCount: 17 - spriteCount: 0 - spaceCount: 1 - wordCount: 2 - linkCount: 0 - lineCount: 16 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} m_hasFontAssetChanged: 0 - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &3643881633927103021 @@ -527,7 +501,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881633927103023} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} m_Name: m_EditorClassIdentifier: m_IgnoreLayout: 0 @@ -548,9 +522,8 @@ GameObject: m_Component: - component: {fileID: 3643881634033459408} - component: {fileID: 3643881634033459414} - - component: {fileID: 3643881634033459409} m_Layer: 5 - m_Name: TMP SubMeshUI [Ubuntu-R SDF Material + LiberationSans SDF Atlas] + m_Name: 'TMP SubMeshUI [Ubuntu-R SDF Material + LiberationSans SDF Atlas]' m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -566,9 +539,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3643881633221182925} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -583,33 +556,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3643881634033459411} m_CullTransparentMesh: 0 ---- !u!114 &3643881634033459409 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3643881634033459411} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 058cba836c1846c3aa1c5fd2e28aea77, 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_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} - m_spriteAsset: {fileID: 0} - m_material: {fileID: 0} - m_sharedMaterial: {fileID: 0} - m_isDefaultMaterial: 0 - m_padding: 8.5625 - m_canvasRenderer: {fileID: 3643881634033459414} - m_TextComponent: {fileID: 3643881633221182914} - m_materialReferenceIndex: 1 --- !u!1 &3643881634325817959 GameObject: m_ObjectHideFlags: 0 @@ -639,9 +585,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3643881633437836137} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -665,12 +611,14 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634325817959} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.8, g: 0.9333333, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -683,6 +631,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!114 &3643881634325817957 MonoBehaviour: m_ObjectHideFlags: 0 @@ -692,7 +641,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634325817959} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} m_Name: m_EditorClassIdentifier: m_IgnoreLayout: 1 @@ -733,9 +682,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3643881634854544289} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -759,12 +708,14 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634576849061} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -777,6 +728,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!114 &3643881634576849048 MonoBehaviour: m_ObjectHideFlags: 0 @@ -786,7 +738,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634576849061} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -1254083943, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3} m_Name: m_EditorClassIdentifier: m_AspectMode: 1 @@ -800,7 +752,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634576849061} m_Enabled: 0 m_EditorHideFlags: 0 - m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} m_Name: m_EditorClassIdentifier: m_HorizontalFit: 0 @@ -834,9 +786,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3643881633437836137} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -860,12 +812,14 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634695350168} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.8, g: 0.9333333, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -878,6 +832,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!114 &3643881634695350174 MonoBehaviour: m_ObjectHideFlags: 0 @@ -887,7 +842,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634695350168} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} m_Name: m_EditorClassIdentifier: m_IgnoreLayout: 1 @@ -926,10 +881,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3643881634576849050} m_Father: {fileID: 3643881633437836137} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -945,7 +900,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634854544288} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} m_Name: m_EditorClassIdentifier: m_IgnoreLayout: 0 @@ -965,7 +920,7 @@ MonoBehaviour: m_GameObject: {fileID: 3643881634854544288} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -405508275, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} m_Name: m_EditorClassIdentifier: m_Padding: @@ -979,3 +934,6 @@ MonoBehaviour: m_ChildForceExpandHeight: 0 m_ChildControlWidth: 1 m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 diff --git a/Assets/Prefabs/UI/Dropdown Option.prefab b/Assets/Prefabs/UI/Dropdown Option.prefab index 0f99f8b8a..a93c5f568 100644 --- a/Assets/Prefabs/UI/Dropdown Option.prefab +++ b/Assets/Prefabs/UI/Dropdown Option.prefab @@ -30,11 +30,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 5288995275525413887} - {fileID: 4420144871448733516} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -103,6 +103,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -161,9 +162,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4420144871272692262} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -237,20 +238,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -317,9 +321,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4420144871272692262} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} diff --git a/Assets/Prefabs/UI/Flat InputField.prefab b/Assets/Prefabs/UI/Flat InputField.prefab index f5748ed7b..9e59ba224 100644 --- a/Assets/Prefabs/UI/Flat InputField.prefab +++ b/Assets/Prefabs/UI/Flat InputField.prefab @@ -28,11 +28,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4451361955953725104} - {fileID: 4451361956030022757} m_Father: {fileID: 4451361956630297310} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -89,9 +89,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4451361954557856253} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -164,20 +164,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 1 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -223,9 +226,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4451361954557856253} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -298,20 +301,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 3 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 1 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -358,10 +364,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4451361954557856253} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -470,10 +476,13 @@ MonoBehaviour: m_GlobalFontAsset: {fileID: 11400000, guid: 3fb7d873bb5a7944bb9a7c73c430c44b, type: 2} m_OnFocusSelectAll: 1 m_ResetOnDeActivation: 1 + m_KeepTextSelectionVisible: 0 m_RestoreOriginalTextOnEscape: 1 m_isRichTextEditingAllowed: 0 m_LineLimit: 0 + isAlert: 0 m_InputValidator: {fileID: 0} + m_ShouldActivateOnSelect: 1 --- !u!114 &3109909670730689337 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/Prefabs/UI/Input Display Container.prefab b/Assets/Prefabs/UI/Input Display Container.prefab index 20f1b6c1a..e0fe5c833 100644 --- a/Assets/Prefabs/UI/Input Display Container.prefab +++ b/Assets/Prefabs/UI/Input Display Container.prefab @@ -26,10 +26,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543201409287275} m_Father: {fileID: 3575543199475698844} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -64,9 +64,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543201164511461} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -138,13 +138,13 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543199328406134} - {fileID: 3575543201062286834} - {fileID: 3575543199601288280} - {fileID: 3575543201335647258} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0.5} @@ -217,9 +217,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200853098928} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -292,6 +292,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.8, y: 0.8, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543201164511461} - {fileID: 3575543200709404420} @@ -299,7 +300,6 @@ RectTransform: - {fileID: 3575543200853098928} - {fileID: 3575543200736016708} m_Father: {fileID: 3575543199475698844} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -373,11 +373,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543200370154277} - {fileID: 3575543199949252307} m_Father: {fileID: 3575543201062286834} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -465,9 +465,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543199809032539} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -534,9 +534,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200370154277} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -616,13 +616,13 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543200306509116} - {fileID: 3575543201356857812} - {fileID: 3575543201337423529} - {fileID: 3575543200656285771} m_Father: {fileID: 3575543199809032539} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -743,6 +743,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3468b3db8d419c745b12124f6432696b, type: 3} m_Name: m_EditorClassIdentifier: + SuppressDisable: 0 --- !u!114 &3575543200370154281 MonoBehaviour: m_ObjectHideFlags: 0 @@ -790,10 +791,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543200396461816} m_Father: {fileID: 3575543199601288280} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -905,6 +906,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3468b3db8d419c745b12124f6432696b, type: 3} m_Name: m_EditorClassIdentifier: + SuppressDisable: 0 --- !u!114 &3575543200394488151 MonoBehaviour: m_ObjectHideFlags: 0 @@ -957,9 +959,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200394488147} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1032,9 +1034,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200978094812} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1108,20 +1110,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -1167,9 +1172,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200370154277} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 1} @@ -1243,20 +1248,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -1302,9 +1310,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200736016708} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1384,10 +1392,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543201305645094} m_Father: {fileID: 3575543199601288280} - 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} @@ -1499,6 +1507,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3468b3db8d419c745b12124f6432696b, type: 3} m_Name: m_EditorClassIdentifier: + SuppressDisable: 0 --- !u!114 &3575543200709404424 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1558,10 +1567,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543200691046844} m_Father: {fileID: 3575543199601288280} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -1673,6 +1682,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3468b3db8d419c745b12124f6432696b, type: 3} m_Name: m_EditorClassIdentifier: + SuppressDisable: 0 --- !u!114 &3575543200736016712 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1732,10 +1742,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543199594005114} m_Father: {fileID: 3575543199601288280} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -1847,6 +1857,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3468b3db8d419c745b12124f6432696b, type: 3} m_Name: m_EditorClassIdentifier: + SuppressDisable: 0 --- !u!114 &3575543200853098932 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1899,9 +1910,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543201062286834} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1967,10 +1978,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543200538069944} m_Father: {fileID: 3575543201062286834} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -2031,12 +2042,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543200978094812} - {fileID: 3575543199809032539} - {fileID: 3575543200860056044} m_Father: {fileID: 3575543199475698844} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -2117,9 +2128,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543201335647258} - 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} @@ -2221,20 +2232,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -2338,10 +2352,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543199395697427} m_Father: {fileID: 3575543199601288280} - 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} @@ -2453,6 +2467,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3468b3db8d419c745b12124f6432696b, type: 3} m_Name: m_EditorClassIdentifier: + SuppressDisable: 0 --- !u!114 &3575543201164511465 MonoBehaviour: m_ObjectHideFlags: 0 @@ -2505,9 +2520,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200709404420} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2578,10 +2593,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3575543201132091707} m_Father: {fileID: 3575543199475698844} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2616,9 +2631,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200370154277} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0.5} @@ -2692,20 +2707,23 @@ MonoBehaviour: m_VerticalAlignment: 1024 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -2751,9 +2769,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543200370154277} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2827,9 +2845,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3575543199328406134} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} diff --git a/Assets/Prefabs/UI/Inventory.prefab b/Assets/Prefabs/UI/Inventory.prefab index 0addea4f8..dd6baefd6 100644 --- a/Assets/Prefabs/UI/Inventory.prefab +++ b/Assets/Prefabs/UI/Inventory.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4075091371340814903} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -104,20 +104,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -163,9 +166,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4075091371340814903} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -239,20 +242,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -300,9 +306,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6584545650613466935} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -376,20 +382,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -497,10 +506,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2279630452912159027} m_Father: {fileID: 2279630453233804081} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -535,9 +544,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2279630452881931921} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -609,12 +618,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2279630452951644481} - {fileID: 2279630453233804081} - {fileID: 2279630454002795611} m_Father: {fileID: 2279630453886260053} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -677,10 +686,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2279630452592903581} m_Father: {fileID: 2279630454002795611} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -715,9 +724,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2279630452357787793} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -791,10 +800,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2279630453710142155} m_Father: {fileID: 2279630452842594753} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -881,9 +890,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6584545650613466935} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -977,10 +986,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2279630452357787793} m_Father: {fileID: 2279630452842594753} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1108,9 +1117,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2279630454000268454} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1203,6 +1212,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3468b3db8d419c745b12124f6432696b, type: 3} m_Name: m_EditorClassIdentifier: + SuppressDisable: 0 --- !u!114 &3026868749259999386 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1255,9 +1265,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6584545650613466935} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1331,20 +1341,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -1390,11 +1403,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 5904147203112258852} - {fileID: 2279630454000268454} m_Father: {fileID: 2279630452951644481} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1468,12 +1481,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 6584545650613466935} - {fileID: 2279630452842594753} - {fileID: 4075091371340814903} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -1493,6 +1506,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Dialog: {fileID: 0} + DragParent: {fileID: 0} Flip: 0 Settings: {fileID: 0} GameManager: {fileID: 0} @@ -2312,6 +2326,7 @@ MonoBehaviour: CellBackgroundColor: {r: 0, g: 0, b: 0, a: 0.9019608} MinTempRange: 1 DoubleClickTime: 0.5 + HitDamageThreshold: 1 EmptyCells: [] --- !u!222 &6932930312706461541 CanvasRenderer: @@ -2379,11 +2394,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2279630453345861720} - {fileID: 2862553520485687858} m_Father: {fileID: 2279630453710142155} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -2451,10 +2466,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2279630452881931921} m_Father: {fileID: 2279630452842594753} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -2574,13 +2589,13 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 25087979752144322} - {fileID: 6451840322166179141} - {fileID: 8682495930185187424} - {fileID: 1941003311334506942} m_Father: {fileID: 2279630453886260053} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -2616,10 +2631,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 5788397503820000463} m_Father: {fileID: 4075091371340814903} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2704,6 +2719,7 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4397116930423727094} - {fileID: 2279630453679143107} @@ -2712,7 +2728,6 @@ RectTransform: - {fileID: 5683613523479270443} - {fileID: 6462754505713931446} m_Father: {fileID: 2279630453886260053} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -2773,9 +2788,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 25087979752144322} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2848,9 +2863,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2279630454000268454} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2926,9 +2941,9 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: -0.7071068, w: 0.7071068} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6584545650613466935} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -3082,9 +3097,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3031152863755518086} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -3236,9 +3251,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2279630453710142155} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -3327,10 +3342,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 8871154407653395989} m_Father: {fileID: 6584545650613466935} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -3385,9 +3400,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4075091371340814903} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -3462,9 +3477,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6584545650613466935} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -3540,20 +3555,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Main Menu Canvas.prefab b/Assets/Prefabs/UI/Main Menu Canvas.prefab index 866d5fb33..e185d1911 100644 --- a/Assets/Prefabs/UI/Main Menu Canvas.prefab +++ b/Assets/Prefabs/UI/Main Menu Canvas.prefab @@ -29,10 +29,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 350889891057474423} m_Father: {fileID: 350889891632477145} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -118,9 +118,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 350889892050671116} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -193,9 +193,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 350889890423887027} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -270,10 +270,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 350889892050671116} m_Father: {fileID: 350889891632477145} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -366,11 +366,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 350889890423887027} - {fileID: 350889891628991064} m_Father: {fileID: 7329274282942065572} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -461,10 +461,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 350889890962861326} m_Father: {fileID: 350889891628991064} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -500,9 +500,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8184616833802884024} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -596,11 +596,11 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.6666667, y: 0.6666667, z: 0.6666667} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 2261466211211207212} - {fileID: 7963881274223503427} m_Father: {fileID: 4533226043457584179} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -695,12 +695,12 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.6666667, y: 0.6666667, z: 0.6666667} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 4533226043526995714} - {fileID: 4533226043829246279} - {fileID: 4533226044611060154} m_Father: {fileID: 4533226043457584179} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -788,8 +788,9 @@ MonoBehaviour: type: 3} StatSheet: {fileID: 0} CurveField: {fileID: 0} + WeaponGroupAssignment: {fileID: 0} Content: {fileID: 4533226043449861658} - SelectedChild: {fileID: 0} + DragParent: {fileID: 0} GameManager: {fileID: 0} CancelClickCatcher: {fileID: 725430339668194415} ButtonGroup: {fileID: 4533226044611060155} @@ -827,13 +828,13 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 8079387348638243065} - {fileID: 7201272822408223301} - {fileID: 4533226043449861658} - {fileID: 8184616833802884024} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -857,7 +858,9 @@ Canvas: m_OverrideSorting: 0 m_OverridePixelPerfect: 0 m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 m_SortingLayerID: 0 m_SortingOrder: 0 m_TargetDisplay: 0 @@ -913,6 +916,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3d7c7b928d043a3449b93bce9de03d1c, type: 3} m_Name: m_EditorClassIdentifier: + CloudRenderer: {fileID: 0} Settings: {fileID: 11400000, guid: cd2344e2001a37544aab0960c164d4ff, type: 2} Dialog: {fileID: 4533226043449861657} PanelPrototype: {fileID: 7329274282942065594} @@ -949,9 +953,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4533226043449861658} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1044,9 +1048,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4533226043449861658} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1120,20 +1124,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -1178,9 +1185,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4533226044611060154} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1234,12 +1241,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2381176780008325752} - {fileID: 4533226043924106331} - {fileID: 2381176779129949493} m_Father: {fileID: 4533226043449861658} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1298,10 +1305,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7329274282942065572} m_Father: {fileID: 4533226043457584179} - 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} @@ -1337,9 +1344,9 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.6666667, y: 0.6666667, z: 0.6666667} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4533226043457584179} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1428,11 +1435,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7329274283166941234} - {fileID: 350889891632477145} m_Father: {fileID: 8079387348638243065} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -1481,8 +1488,9 @@ MonoBehaviour: StatSheet: {fileID: 3416329628306957711, guid: 4f75723ed178a084e813965e84825bd4, type: 3} CurveField: {fileID: 0} + WeaponGroupAssignment: {fileID: 0} Content: {fileID: 350889891057474423} - SelectedChild: {fileID: 0} + DragParent: {fileID: 0} GameManager: {fileID: 0} --- !u!222 &7329274282942065577 CanvasRenderer: @@ -1572,9 +1580,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7329274282942065572} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1650,20 +1658,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: -20 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -1744,9 +1755,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8184616833802884024} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -1806,6 +1817,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 4533226044611060154} m_Modifications: - target: {fileID: 422905925398675622, guid: 2758dfa2744d7ad4d8877545189d116e, @@ -1888,6 +1900,11 @@ PrefabInstance: propertyPath: m_firstOverflowCharacterIndex value: 0 objectReference: {fileID: 0} + - target: {fileID: 1713457305180270767, guid: 2758dfa2744d7ad4d8877545189d116e, + type: 3} + propertyPath: 'm_ActiveFontFeatures.Array.data[0]' + value: 1801810542 + objectReference: {fileID: 0} - target: {fileID: 2297648055057363568, guid: 2758dfa2744d7ad4d8877545189d116e, type: 3} propertyPath: m_Pivot.x @@ -2079,25 +2096,10 @@ PrefabInstance: value: Confirm Button objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 2758dfa2744d7ad4d8877545189d116e, type: 3} ---- !u!114 &2967358985619754986 stripped -MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 1713457305180270767, guid: 2758dfa2744d7ad4d8877545189d116e, - type: 3} - m_PrefabInstance: {fileID: 4533226044147941189} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!224 &2381176779129949493 stripped -RectTransform: - m_CorrespondingSourceObject: {fileID: 2297648055057363568, guid: 2758dfa2744d7ad4d8877545189d116e, - type: 3} - m_PrefabInstance: {fileID: 4533226044147941189} - m_PrefabAsset: {fileID: 0} --- !u!114 &1044359408896957406 stripped MonoBehaviour: m_CorrespondingSourceObject: {fileID: 3501282941175030939, guid: 2758dfa2744d7ad4d8877545189d116e, @@ -2110,11 +2112,30 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!224 &2381176779129949493 stripped +RectTransform: + m_CorrespondingSourceObject: {fileID: 2297648055057363568, guid: 2758dfa2744d7ad4d8877545189d116e, + type: 3} + m_PrefabInstance: {fileID: 4533226044147941189} + m_PrefabAsset: {fileID: 0} +--- !u!114 &2967358985619754986 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 1713457305180270767, guid: 2758dfa2744d7ad4d8877545189d116e, + type: 3} + m_PrefabInstance: {fileID: 4533226044147941189} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1001 &4533226044873879560 PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 4533226044611060154} m_Modifications: - target: {fileID: 422905925398675622, guid: 2758dfa2744d7ad4d8877545189d116e, @@ -2202,6 +2223,11 @@ PrefabInstance: propertyPath: m_firstOverflowCharacterIndex value: 0 objectReference: {fileID: 0} + - target: {fileID: 1713457305180270767, guid: 2758dfa2744d7ad4d8877545189d116e, + type: 3} + propertyPath: 'm_ActiveFontFeatures.Array.data[0]' + value: 1801810542 + objectReference: {fileID: 0} - target: {fileID: 2297648055057363568, guid: 2758dfa2744d7ad4d8877545189d116e, type: 3} propertyPath: m_Pivot.x @@ -2393,7 +2419,22 @@ PrefabInstance: value: Cancel Button objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 2758dfa2744d7ad4d8877545189d116e, type: 3} +--- !u!114 &1044359407629948051 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 3501282941175030939, guid: 2758dfa2744d7ad4d8877545189d116e, + type: 3} + m_PrefabInstance: {fileID: 4533226044873879560} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!224 &2381176780008325752 stripped RectTransform: m_CorrespondingSourceObject: {fileID: 2297648055057363568, guid: 2758dfa2744d7ad4d8877545189d116e, @@ -2412,15 +2453,3 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} m_Name: m_EditorClassIdentifier: ---- !u!114 &1044359407629948051 stripped -MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 3501282941175030939, guid: 2758dfa2744d7ad4d8877545189d116e, - type: 3} - m_PrefabInstance: {fileID: 4533226044873879560} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} - m_Name: - m_EditorClassIdentifier: diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Bool Field.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Bool Field.prefab index 84e750891..9fc83e309 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Bool Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Bool Field.prefab @@ -35,7 +35,6 @@ RectTransform: - {fileID: 7661950295498381397} - {fileID: 7661950294707789146} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -152,7 +151,6 @@ RectTransform: m_Children: - {fileID: 7661950295217243554} m_Father: {fileID: 7661950294707789146} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -230,7 +228,6 @@ RectTransform: m_Children: - {fileID: 7661950294137596689} m_Father: {fileID: 7661950293931311387} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -350,7 +347,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7661950294137596689} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.2, y: 0.2} m_AnchorMax: {x: 0.8, y: 0.8} @@ -427,7 +423,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7661950293931311387} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -501,20 +496,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Button Field.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Button Field.prefab index bc492fa08..2515f64a0 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Button Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Button Field.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 790814198576895811} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -104,20 +104,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -165,10 +168,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 790814197411605233} m_Father: {fileID: 6566784227922820063} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -307,11 +310,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 6566784228232816309} - {fileID: 790814198576895811} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -426,9 +429,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6566784227922820063} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -502,20 +505,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Curve Field.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Curve Field.prefab index ea233162a..5cbdc480d 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Curve Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Curve Field.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5150349054046905327} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.25} m_AnchorMax: {x: 0.5, y: 0.25} @@ -103,9 +103,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5150349054046905327} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0.25} @@ -179,9 +179,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4525093026741206958} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -255,20 +255,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -335,9 +338,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4525093026741206958} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -411,20 +414,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -490,9 +496,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4525093026741206958} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -566,9 +572,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4525093026741206958} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0} @@ -642,20 +648,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -722,9 +731,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4525093026741206958} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -798,20 +807,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -877,11 +889,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2039464565} - {fileID: 2008487938} m_Father: {fileID: 4525093026741206958} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -964,6 +976,7 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 5150349054046905327} - {fileID: 8457868409217303238} @@ -972,7 +985,6 @@ RectTransform: - {fileID: 5150349052900313153} - {fileID: 7117984985042789648} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Enum Field.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Enum Field.prefab index 61980ca29..4634a2775 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Enum Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Enum Field.prefab @@ -31,7 +31,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1444953513611246322} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -105,20 +104,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -171,7 +173,6 @@ RectTransform: - {fileID: 1444953513591056483} - {fileID: 1444953514355799430} m_Father: {fileID: 1444953514731475974} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -312,7 +313,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1444953514731475974} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -386,20 +386,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -468,7 +471,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1444953513611246322} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} m_AnchorMin: {x: 1, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -548,7 +550,6 @@ RectTransform: - {fileID: 1444953513817938006} - {fileID: 1444953513611246322} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Increment Field.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Increment Field.prefab index 112cd3b81..66fbba81a 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Increment Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Increment Field.prefab @@ -33,7 +33,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2544338102157427055} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -169,7 +168,6 @@ RectTransform: - {fileID: 7863247503782211248} - {fileID: 8483308900631515678} m_Father: {fileID: 6770904480725292323} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -228,7 +226,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6770904480725292323} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -302,20 +299,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -388,7 +388,6 @@ RectTransform: - {fileID: 6770904480229951561} - {fileID: 2544338102157427055} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -508,7 +507,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2544338102157427055} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -642,7 +640,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2544338102157427055} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -716,20 +713,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Input Field.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Input Field.prefab index bdcedb118..afc077a82 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Input Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Input Field.prefab @@ -35,7 +35,6 @@ RectTransform: - {fileID: 23155009713813574} - {fileID: 8734896053364945145} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -152,7 +151,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 23155009655760172} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -226,20 +224,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -308,7 +309,6 @@ RectTransform: m_Children: - {fileID: 5938949450847760329} m_Father: {fileID: 23155009655760172} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -367,7 +367,6 @@ RectTransform: - {fileID: 5938949451508194215} - {fileID: 5938949451316023666} m_Father: {fileID: 5938949450847760329} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -422,7 +421,6 @@ RectTransform: m_Children: - {fileID: 5938949450758544618} m_Father: {fileID: 8734896053364945145} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -561,10 +559,13 @@ MonoBehaviour: m_GlobalFontAsset: {fileID: 11400000, guid: 9dcd07b95faae7641a3ff6fccab43c32, type: 2} m_OnFocusSelectAll: 1 m_ResetOnDeActivation: 1 + m_KeepTextSelectionVisible: 0 m_RestoreOriginalTextOnEscape: 1 m_isRichTextEditingAllowed: 0 m_LineLimit: 0 + isAlert: 0 m_InputValidator: {fileID: 0} + m_ShouldActivateOnSelect: 1 --- !u!114 &1618696626055083017 MonoBehaviour: m_ObjectHideFlags: 0 @@ -616,7 +617,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5938949450758544618} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -690,20 +690,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 3 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 1 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -752,7 +755,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5938949450758544618} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -826,20 +828,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 1 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Progress Field.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Progress Field.prefab index c9200c393..18872559c 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Progress Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Progress Field.prefab @@ -31,7 +31,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8181761431199775037} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -107,7 +106,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8181761431199775037} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -187,7 +185,6 @@ RectTransform: - {fileID: 3301729265189646952} - {fileID: 8626591645481506733} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -304,7 +301,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3301729265155698787} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -378,20 +374,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -460,7 +459,6 @@ RectTransform: - {fileID: 4052465884214141673} - {fileID: 1684719062263664779} m_Father: {fileID: 8626591645481506733} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -499,7 +497,6 @@ RectTransform: m_Children: - {fileID: 8181761431199775037} m_Father: {fileID: 3301729265155698787} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Property Label.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Property Label.prefab index 6ec1c92cc..599a29f50 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Property Label.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Property Label.prefab @@ -32,7 +32,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2677123916507168719} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -106,20 +105,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -192,7 +194,6 @@ RectTransform: - {fileID: 2677123916028371621} - {fileID: 6602089867192183683} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -309,7 +310,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2677123916507168719} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -383,20 +383,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Property.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Property.prefab index fd7063dc1..6c64288ee 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Property.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Property.prefab @@ -29,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 9159917045172241900} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -107,20 +107,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -188,10 +191,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 9159917045079857286} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Ranged Float Field.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Ranged Float Field.prefab index 5821edb01..f195ba08f 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Ranged Float Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Ranged Float Field.prefab @@ -31,7 +31,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7146463267720429741} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -106,7 +105,6 @@ RectTransform: m_Children: - {fileID: 3436413162678517982} m_Father: {fileID: 7146463267720429741} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -144,7 +142,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7282863425963355709} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -219,7 +216,6 @@ RectTransform: m_Children: - {fileID: 287045173602649995} m_Father: {fileID: 7146463267720429741} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -258,7 +254,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3222204141728529077} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -353,7 +348,6 @@ RectTransform: - {fileID: 4127690186274268520} - {fileID: 7146463267720429741} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -490,7 +484,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4127690186169542499} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -564,20 +557,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -649,7 +645,6 @@ RectTransform: - {fileID: 7282863425963355709} - {fileID: 3222204141728529077} m_Father: {fileID: 4127690186169542499} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Stat.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Stat.prefab index fcbe746fb..4e3669a40 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Stat.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Stat.prefab @@ -29,11 +29,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 215031283457978355} - {fileID: 6087143909423189777} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -120,9 +120,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 169101331738242590} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0.5} @@ -196,20 +196,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -255,9 +258,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 169101331738242590} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 1} @@ -331,20 +334,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Weapon Group.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Weapon Group.prefab index 95677030e..a27bdfb46 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Weapon Group.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Weapon Group.prefab @@ -29,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7093141058661617964} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -105,20 +105,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -208,9 +211,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7093141058661617964} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -288,11 +291,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 8854537499952373070} - {fileID: 8854537499097178562} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} diff --git a/Assets/Prefabs/UI/Properties Panel/Fancy/Weapon Groups.prefab b/Assets/Prefabs/UI/Properties Panel/Fancy/Weapon Groups.prefab index 77e704a12..c0ed5af9b 100644 --- a/Assets/Prefabs/UI/Properties Panel/Fancy/Weapon Groups.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Fancy/Weapon Groups.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7017012055636029233} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 1} @@ -104,20 +104,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -162,9 +165,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7017012055636029233} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -228,11 +231,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7044292112900681436} - {fileID: 4617351576505394386} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Properties.prefab b/Assets/Prefabs/UI/Properties Panel/Properties.prefab index 29d281e03..d51addf62 100644 --- a/Assets/Prefabs/UI/Properties Panel/Properties.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Properties.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 257019180622654292} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -103,9 +103,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 257019180101986795} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -181,10 +181,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 257019179596293679} m_Father: {fileID: 257019181563268737} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -268,10 +268,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 257019179550429270} m_Father: {fileID: 257019181577240320} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -306,11 +306,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 257019180101986795} - {fileID: 257019181577240320} m_Father: {fileID: 7131821417165215484} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -383,10 +383,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 257019180622654292} m_Father: {fileID: 257019181563268737} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -479,9 +479,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7131821417165215484} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -575,9 +575,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7131821417165215484} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -651,20 +651,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -731,12 +734,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7131821417072393578} - {fileID: 7131821415452796888} - {fileID: 257019181563268737} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -786,10 +789,10 @@ MonoBehaviour: type: 3} CurveField: {fileID: 3018914896466881005, guid: 168887bbd3de8c74eb3f06d3d46dda4e, type: 3} - Content: {fileID: 257019179596293679} WeaponGroupAssignment: {fileID: 8654742830357802168, guid: fbe6efeb205a68946af7a6f1cb8b9904, type: 3} - SelectedChild: {fileID: 0} + Content: {fileID: 257019179596293679} + DragParent: {fileID: 0} GameManager: {fileID: 0} --- !u!222 &7131821417165215473 CanvasRenderer: diff --git a/Assets/Prefabs/UI/Properties Panel/Property Button.prefab b/Assets/Prefabs/UI/Properties Panel/Property Button.prefab index 342160309..440b6cbc2 100644 --- a/Assets/Prefabs/UI/Properties Panel/Property Button.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Property Button.prefab @@ -29,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1613450655389604793} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -106,20 +106,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -187,11 +190,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7085828711539161696} - {fileID: 1613450655044732627} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -319,9 +322,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1613450655389604793} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} diff --git a/Assets/Prefabs/UI/Properties Panel/Property List 1.prefab b/Assets/Prefabs/UI/Properties Panel/Property List 1.prefab index f776c2be8..e2c9744d6 100644 --- a/Assets/Prefabs/UI/Properties Panel/Property List 1.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Property List 1.prefab @@ -29,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2088721703295321218} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -105,20 +105,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -186,12 +189,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 6724740944390240338} - {fileID: 2088721703192714102} - {fileID: 2118837324186690404} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -283,8 +286,12 @@ MonoBehaviour: type: 3} IncrementField: {fileID: 5486709585343280439, guid: 9c14c92a1a08b0a4fb4f6aa6f8504082, type: 3} + StatSheet: {fileID: 0} + CurveField: {fileID: 0} + WeaponGroupAssignment: {fileID: 0} Content: {fileID: 0} - SelectedChild: {fileID: 0} + DragParent: {fileID: 0} + GameManager: {fileID: 0} FoldoutIcon: {fileID: 6485458701090981364} FoldoutRotationDamping: 10 Button: {fileID: 2066200247} @@ -364,9 +371,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2088721703295321218} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -460,9 +467,9 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: -0.7071068, w: 0.7071068} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2088721703295321218} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} diff --git a/Assets/Prefabs/UI/Properties Panel/Property List.prefab b/Assets/Prefabs/UI/Properties Panel/Property List.prefab index a9a55945f..d99bbf8c3 100644 --- a/Assets/Prefabs/UI/Properties Panel/Property List.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Property List.prefab @@ -29,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2088721703295321218} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -105,20 +105,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -186,12 +189,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 6724740944390240338} - {fileID: 2088721703192714102} - {fileID: 2118837324186690404} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -283,8 +286,12 @@ MonoBehaviour: type: 3} IncrementField: {fileID: 5486709585343280439, guid: 9c14c92a1a08b0a4fb4f6aa6f8504082, type: 3} + StatSheet: {fileID: 0} + CurveField: {fileID: 0} + WeaponGroupAssignment: {fileID: 0} Content: {fileID: 0} - SelectedChild: {fileID: 0} + DragParent: {fileID: 0} + GameManager: {fileID: 0} FoldoutIcon: {fileID: 6485458701090981364} FoldoutRotationDamping: 10 Button: {fileID: 2066200247} @@ -364,9 +371,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2088721703295321218} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -460,9 +467,9 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: -0.7071068, w: 0.7071068} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2088721703295321218} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} diff --git a/Assets/Prefabs/UI/Properties Panel/Property Section.prefab b/Assets/Prefabs/UI/Properties Panel/Property Section.prefab index f0629b763..2d2ccb36c 100644 --- a/Assets/Prefabs/UI/Properties Panel/Property Section.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Property Section.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1026668114703092140} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -104,20 +104,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -162,10 +165,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1026668113805589148} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Attribute.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Attribute.prefab index dbad2c53d..c19b97642 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Attribute.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Attribute.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4958798766822876479} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -60,13 +60,15 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] m_text: efficient/organized m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: 52bc194c171fd114e9a962923283262d, type: 2} + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -84,13 +86,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 8 m_fontSizeBase: 8 m_fontWeight: 400 @@ -98,61 +99,42 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 1028 + m_HorizontalAlignment: 4 + m_VerticalAlignment: 1024 + m_textAlignment: 65535 m_characterSpacing: 1.5 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: -1 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 4958798766555897797} - characterCount: 19 - spriteCount: 0 - spaceCount: 0 - wordCount: 2 - linkCount: 0 - lineCount: 1 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} m_hasFontAssetChanged: 0 - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &4958798766635474175 @@ -183,9 +165,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4958798768237988480} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -209,12 +191,14 @@ MonoBehaviour: m_GameObject: {fileID: 4958798766635474175} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 0.44583336, b: 0.050000012, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -227,6 +211,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &4958798766822876478 GameObject: m_ObjectHideFlags: 0 @@ -255,13 +240,13 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4958798767036921042} - {fileID: 4958798767833643858} - {fileID: 4958798767855898775} - {fileID: 4958798766555897796} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -277,7 +262,7 @@ MonoBehaviour: m_GameObject: {fileID: 4958798766822876478} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} m_Name: m_EditorClassIdentifier: m_IgnoreLayout: 0 @@ -332,9 +317,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4958798766822876479} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -364,6 +349,8 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -389,13 +376,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 20 m_fontSizeBase: 20 m_fontWeight: 400 @@ -403,61 +389,42 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 258 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 256 + m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: -1 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 4958798767036921043} - characterCount: 18 - spriteCount: 0 - spaceCount: 1 - wordCount: 1 - linkCount: 0 - lineCount: 1 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} m_hasFontAssetChanged: 0 - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &4958798767101845646 @@ -488,9 +455,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4958798768306156651} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -514,12 +481,14 @@ MonoBehaviour: m_GameObject: {fileID: 4958798767101845646} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 0.44583336, b: 0.050000012, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -532,6 +501,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &4958798767393056018 GameObject: m_ObjectHideFlags: 0 @@ -561,14 +531,14 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4958798767885421271} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.332, y: 0} - m_AnchorMax: {x: 0.332, y: 1} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: -2} - m_SizeDelta: {x: 0, y: 4} + m_SizeDelta: {x: 12.599999, y: 4} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &4958798767393056030 CanvasRenderer: @@ -587,12 +557,14 @@ MonoBehaviour: m_GameObject: {fileID: 4958798767393056018} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.8, g: 0.9333333, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -605,6 +577,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!114 &4958798767393056028 MonoBehaviour: m_ObjectHideFlags: 0 @@ -614,7 +587,7 @@ MonoBehaviour: m_GameObject: {fileID: 4958798767393056018} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -1254083943, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3} m_Name: m_EditorClassIdentifier: m_AspectMode: 2 @@ -646,12 +619,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4958798768237988480} - {fileID: 4958798768306156651} - {fileID: 4958798767966920791} m_Father: {fileID: 4958798766822876479} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -667,11 +640,12 @@ MonoBehaviour: m_GameObject: {fileID: 4958798767833643857} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -113659843, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3} m_Name: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -681,17 +655,20 @@ MonoBehaviour: m_NormalColor: {r: 1, g: 1, b: 1, a: 1} m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} m_ColorMultiplier: 1 m_FadeDuration: 0.1 m_SpriteState: m_HighlightedSprite: {fileID: 0} m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} m_DisabledSprite: {fileID: 0} m_AnimationTriggers: m_NormalTrigger: Normal m_HighlightedTrigger: Highlighted m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted m_DisabledTrigger: Disabled m_Interactable: 0 m_TargetGraphic: {fileID: 0} @@ -733,9 +710,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4958798766822876479} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -765,13 +742,15 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] m_text: easy-going/careless m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: ef74c4c30ca5ced4489f28b914006aad, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: 006954f79490ab54bbc51d74b44d6e1c, type: 2} + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -789,13 +768,12 @@ MonoBehaviour: m_fontColorGradientPreset: {fileID: 0} m_spriteAsset: {fileID: 0} m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 m_overrideHtmlColors: 0 m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 m_fontSize: 8 m_fontSizeBase: 8 m_fontWeight: 400 @@ -803,61 +781,42 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_textAlignment: 1025 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 1024 + m_textAlignment: 65535 m_characterSpacing: 1.5 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: -1 m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_isTextTruncated: 0 + parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 m_horizontalMapping: 0 m_verticalMapping: 0 m_uvLineOffset: 0 m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 m_VertexBufferAutoSizeReduction: 1 - m_firstVisibleCharacter: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 4958798767855898768} - characterCount: 19 - spriteCount: 0 - spaceCount: 0 - wordCount: 2 - linkCount: 0 - lineCount: 1 - pageCount: 1 - materialCount: 1 m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} m_hasFontAssetChanged: 0 - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &4958798767885421270 @@ -886,10 +845,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4958798767393056019} m_Father: {fileID: 4958798768237988480} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -924,9 +883,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4958798767833643858} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.35} m_AnchorMax: {x: 1, y: 0.65} @@ -950,12 +909,14 @@ MonoBehaviour: m_GameObject: {fileID: 4958798767966920790} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.8, g: 0.9333333, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -968,6 +929,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &4958798768237988487 GameObject: m_ObjectHideFlags: 0 @@ -997,12 +959,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4958798768341589565} - {fileID: 4958798766635474168} - {fileID: 4958798767885421271} m_Father: {fileID: 4958798767833643858} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.35} m_AnchorMax: {x: 1, y: 0.65} @@ -1026,12 +988,14 @@ MonoBehaviour: m_GameObject: {fileID: 4958798768237988487} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0, g: 0.06416668, b: 0.154, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -1044,6 +1008,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!114 &4958798768237988481 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1053,7 +1018,7 @@ MonoBehaviour: m_GameObject: {fileID: 4958798768237988487} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -1200242548, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} m_Name: m_EditorClassIdentifier: m_ShowMaskGraphic: 0 @@ -1083,10 +1048,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4958798767101845647} m_Father: {fileID: 4958798767833643858} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.25} m_AnchorMax: {x: 1, y: 0.75} @@ -1121,9 +1086,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4958798768237988480} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1147,12 +1112,14 @@ MonoBehaviour: m_GameObject: {fileID: 4958798768341589564} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0, g: 0.25294134, b: 0.6, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] @@ -1165,3 +1132,4 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Bool Field.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Bool Field.prefab index d005cdba5..d5cefa04e 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Bool Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Bool Field.prefab @@ -29,11 +29,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7661950295498381397} - {fileID: 7661950294707789146} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -116,10 +116,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7661950295217243554} m_Father: {fileID: 7661950294707789146} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -193,10 +193,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7661950294137596689} m_Father: {fileID: 7661950293931311387} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -313,9 +313,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7661950294137596689} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.2, y: 0.2} m_AnchorMax: {x: 0.8, y: 0.8} @@ -389,9 +389,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7661950293931311387} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -465,20 +465,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Button Field.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Button Field.prefab index 0d208cbde..39a19b9cc 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Button Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Button Field.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 790814198576895811} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -104,20 +104,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -165,10 +168,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 790814197411605233} m_Father: {fileID: 6566784227922820063} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -306,11 +309,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 6566784228232816309} - {fileID: 790814198576895811} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -395,9 +398,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6566784227922820063} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -471,20 +474,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Enum Field.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Enum Field.prefab index aded92530..a426e807a 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Enum Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Enum Field.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1444953513611246322} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -104,20 +104,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -165,11 +168,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1444953513591056483} - {fileID: 1444953514355799430} m_Father: {fileID: 1444953514731475974} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -307,9 +310,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1444953514731475974} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -383,20 +386,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -462,9 +468,9 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: -0.7071068, w: 0.7071068} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1444953513611246322} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} m_AnchorMin: {x: 1, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -538,11 +544,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1444953513817938006} - {fileID: 1444953513611246322} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Increment Field.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Increment Field.prefab index db1ffa153..1009b9d25 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Increment Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Increment Field.prefab @@ -30,9 +30,9 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.75, y: 0.75, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2544338102157427055} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -162,12 +162,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3841991687815987397} - {fileID: 7863247503782211248} - {fileID: 8483308900631515678} m_Father: {fileID: 6770904480725292323} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -223,9 +223,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6770904480725292323} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -299,20 +299,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -379,11 +382,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 6770904480229951561} - {fileID: 2544338102157427055} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -470,9 +473,9 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.75, y: 0.75, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2544338102157427055} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -603,9 +606,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2544338102157427055} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -679,20 +682,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Input Field.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Input Field.prefab index d5784a8cb..29050392e 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Input Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Input Field.prefab @@ -29,11 +29,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 23155009713813574} - {fileID: 8734896053364945145} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -117,9 +117,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 23155009655760172} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -193,20 +193,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -271,10 +274,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 5938949450847760329} m_Father: {fileID: 23155009655760172} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -328,11 +331,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 5938949451508194215} - {fileID: 5938949451316023666} m_Father: {fileID: 5938949450847760329} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -383,10 +386,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 5938949450758544618} m_Father: {fileID: 8734896053364945145} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -525,10 +528,13 @@ MonoBehaviour: m_GlobalFontAsset: {fileID: 11400000, guid: 9dcd07b95faae7641a3ff6fccab43c32, type: 2} m_OnFocusSelectAll: 1 m_ResetOnDeActivation: 1 + m_KeepTextSelectionVisible: 0 m_RestoreOriginalTextOnEscape: 1 m_isRichTextEditingAllowed: 0 m_LineLimit: 0 + isAlert: 0 m_InputValidator: {fileID: 0} + m_ShouldActivateOnSelect: 1 --- !u!114 &1618696626055083017 MonoBehaviour: m_ObjectHideFlags: 0 @@ -577,9 +583,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5938949450758544618} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -653,20 +659,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 3 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 1 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -712,9 +721,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5938949450758544618} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -788,20 +797,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 1 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Progress Field.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Progress Field.prefab index 1360e00de..d57409ee5 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Progress Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Progress Field.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8181761431199775037} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -103,9 +103,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8626591645481506733} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.25} m_AnchorMax: {x: 1, y: 0.75} @@ -179,11 +179,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3301729265189646952} - {fileID: 8626591645481506733} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -267,9 +267,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3301729265155698787} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -343,20 +343,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -420,10 +423,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1684719062263664779} m_Father: {fileID: 8626591645481506733} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -458,11 +461,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4052465884214141673} - {fileID: 8181761431199775037} m_Father: {fileID: 3301729265155698787} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Property Label.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Property Label.prefab index 77133101c..f7f4fa9e9 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Property Label.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Property Label.prefab @@ -29,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2677123916507168719} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -105,20 +105,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -185,11 +188,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2677123916028371621} - {fileID: 6602089867192183683} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -273,9 +276,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2677123916507168719} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -349,20 +352,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Property.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Property.prefab index 06e3eca26..f53bd6914 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Property.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Property.prefab @@ -29,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 9159917045172241900} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -107,20 +107,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -187,10 +190,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 9159917045079857286} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Simple/Ranged Float Field.prefab b/Assets/Prefabs/UI/Properties Panel/Simple/Ranged Float Field.prefab index 3a13a994a..c2f68c328 100644 --- a/Assets/Prefabs/UI/Properties Panel/Simple/Ranged Float Field.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Simple/Ranged Float Field.prefab @@ -28,9 +28,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7146463267720429741} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -101,10 +101,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3436413162678517982} m_Father: {fileID: 7146463267720429741} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -139,9 +139,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7282863425963355709} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -212,10 +212,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 287045173602649995} m_Father: {fileID: 7146463267720429741} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -251,9 +251,9 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.75, y: 0.75, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3222204141728529077} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -342,11 +342,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 4127690186274268520} - {fileID: 7146463267720429741} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -450,9 +450,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4127690186169542499} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -526,20 +526,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -605,12 +608,12 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 3217779461217105385} - {fileID: 7282863425963355709} - {fileID: 3222204141728529077} m_Father: {fileID: 4127690186169542499} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Prefabs/UI/Properties Panel/Text Button.prefab b/Assets/Prefabs/UI/Properties Panel/Text Button.prefab index 65d6df6d7..8f001bcfe 100644 --- a/Assets/Prefabs/UI/Properties Panel/Text Button.prefab +++ b/Assets/Prefabs/UI/Properties Panel/Text Button.prefab @@ -31,9 +31,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -107,20 +107,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 diff --git a/Assets/Prefabs/UI/Tab Button Primary.prefab b/Assets/Prefabs/UI/Tab Button Primary.prefab index fa0e184d4..1795e41df 100644 --- a/Assets/Prefabs/UI/Tab Button Primary.prefab +++ b/Assets/Prefabs/UI/Tab Button Primary.prefab @@ -29,9 +29,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7200536746924797989} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -105,20 +105,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -179,10 +182,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 7200536746924797989} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -249,6 +252,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -307,10 +311,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 6493174789768221420} m_Father: {fileID: 5318229203699776728} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} diff --git a/Assets/Resources/Settings.asset b/Assets/Resources/Settings.asset index 692fb08fe..4b17fe993 100644 --- a/Assets/Resources/Settings.asset +++ b/Assets/Resources/Settings.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2e346f533ccee5d2c655b3d8e0817e3f93e9234af06557ee9c6ec13cecb9acd -size 13137 +oid sha256:248373994a9d0caf17b8dcddbedb7b8c1d36001c31ae0f1e695385e6589734e6 +size 12647 diff --git a/Assets/Scenes/ARPG.unity b/Assets/Scenes/ARPG.unity index d735258a9..a7940de8e 100644 --- a/Assets/Scenes/ARPG.unity +++ b/Assets/Scenes/ARPG.unity @@ -409,13 +409,13 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 23420356} serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: -5, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] - m_Father: {fileID: 1037490739} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} --- !u!23 &23420359 MeshRenderer: m_ObjectHideFlags: 0 @@ -1157,7 +1157,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -1618,7 +1618,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -1648,81 +1648,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 125165634} m_CullTransparentMesh: 0 ---- !u!1 &126433269 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 126433270} - - component: {fileID: 126433272} - - component: {fileID: 126433271} - m_Layer: 5 - m_Name: Icon - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &126433270 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 126433269} - m_LocalRotation: {x: 0, y: 0, z: 0.7071068, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 691045497} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 90} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 8, y: 0} - m_SizeDelta: {x: 14, y: -2} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &126433271 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 126433269} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 55bed7a5ff978bf4c8cbda9971585df0, type: 3} - m_Type: 0 - m_PreserveAspect: 1 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &126433272 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 126433269} - m_CullTransparentMesh: 0 --- !u!1 &134113270 GameObject: m_ObjectHideFlags: 0 @@ -1843,7 +1768,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -2280,6 +2205,81 @@ MonoBehaviour: m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 +--- !u!1001 &177891521 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 775333809} + m_Modifications: + - target: {fileID: 1337198075554910, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_Name + value: TinyExplosion + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalPosition.x + value: -4.2346153 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalPosition.y + value: 2.42 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalPosition.z + value: -21.91896 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalRotation.w + value: 0.7071068 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalRotation.x + value: -0.7071068 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: -90 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, type: 3} +--- !u!114 &177891522 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 8662091027736085435, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, + type: 3} + m_PrefabInstance: {fileID: 177891521} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1281fe44325f9b548aa42dc331b17266, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &177891523 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 4441266138185142, guid: 25c7aa9ad705fe143a4d71c1c8deb7d4, + type: 3} + m_PrefabInstance: {fileID: 177891521} + m_PrefabAsset: {fileID: 0} --- !u!1 &178733679 GameObject: m_ObjectHideFlags: 0 @@ -2912,7 +2912,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -3864,7 +3864,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -5081,143 +5081,6 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 100, y: 100} m_Pivot: {x: 0.5, y: 0.5} ---- !u!1 &383790463 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 383790464} - - component: {fileID: 383790466} - - component: {fileID: 383790465} - m_Layer: 5 - m_Name: Strafe RPM - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &383790464 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 383790463} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 691045497} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 8, y: 0} - m_SizeDelta: {x: -16, y: -4} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &383790465 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 383790463} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_text: 18,000 - m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: 3fb7d873bb5a7944bb9a7c73c430c44b, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: b9d2f6c9804cec1489502dcc1c19ec54, type: 2} - m_fontSharedMaterials: [] - m_fontMaterial: {fileID: 0} - m_fontMaterials: [] - m_fontColor32: - serializedVersion: 2 - rgba: 4294967295 - m_fontColor: {r: 1, g: 1, b: 1, a: 1} - m_enableVertexGradient: 0 - m_colorMode: 3 - m_fontColorGradient: - topLeft: {r: 1, g: 1, b: 1, a: 1} - topRight: {r: 1, g: 1, b: 1, a: 1} - bottomLeft: {r: 1, g: 1, b: 1, a: 1} - bottomRight: {r: 1, g: 1, b: 1, a: 1} - m_fontColorGradientPreset: {fileID: 0} - m_spriteAsset: {fileID: 0} - m_tintAllSprites: 0 - m_StyleSheet: {fileID: 0} - m_TextStyleHashCode: -1183493901 - m_overrideHtmlColors: 0 - m_faceColor: - serializedVersion: 2 - rgba: 4294967295 - m_fontSize: 10 - m_fontSizeBase: 10 - m_fontWeight: 400 - m_enableAutoSizing: 1 - m_fontSizeMin: 6 - m_fontSizeMax: 16 - m_fontStyle: 0 - m_HorizontalAlignment: 1 - m_VerticalAlignment: 512 - m_textAlignment: 65535 - m_characterSpacing: 0 - m_characterHorizontalScale: 1 - m_wordSpacing: 0 - m_lineSpacing: 0 - m_lineSpacingMax: 0 - m_paragraphSpacing: 0 - m_charWidthMaxAdj: 0 - m_TextWrappingMode: 1 - m_wordWrappingRatios: 0.4 - m_overflowMode: 0 - m_linkedTextComponent: {fileID: 0} - parentLinkedComponent: {fileID: 0} - m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b - m_enableExtraPadding: 0 - checkPaddingRequired: 0 - m_isRichText: 1 - m_EmojiFallbackSupport: 1 - m_parseCtrlCharacters: 1 - m_isOrthographic: 1 - m_isCullingEnabled: 0 - m_horizontalMapping: 0 - m_verticalMapping: 0 - m_uvLineOffset: 0 - m_geometrySortingOrder: 0 - m_IsTextObjectScaleStatic: 0 - m_VertexBufferAutoSizeReduction: 1 - m_useMaxVisibleDescender: 1 - m_pageToDisplay: 1 - m_margin: {x: 0, y: 0, z: 0, w: 0} - m_isUsingLegacyAnimationComponent: 0 - m_isVolumetricText: 0 - m_hasFontAssetChanged: 0 - m_baseMaterial: {fileID: 0} - m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!222 &383790466 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 383790463} - m_CullTransparentMesh: 0 --- !u!1 &388927454 GameObject: m_ObjectHideFlags: 0 @@ -5325,7 +5188,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -5732,7 +5595,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -5979,7 +5842,6 @@ MonoBehaviour: OverrideIconBlinkSpeed: 0 ShieldIcon: {fileID: 0} HeatsinkBackground: {fileID: 0} - AetherDriveUi: {fileID: 0} EnergyLabel: {fileID: 0} CockpitTemperatureLabel: {fileID: 0} RadiatorTemperatureLabel: {fileID: 0} @@ -5988,18 +5850,12 @@ MonoBehaviour: VisibilityLabel: {fileID: 0} HullDurabilityLabel: {fileID: 0} DistanceLabel: {fileID: 0} - ForwardRPMLabel: {fileID: 0} - StrafeRPMLabel: {fileID: 0} - TurnRPMLabel: {fileID: 0} SensorCooldownFill: {fileID: 0} EnergyFill: {fileID: 0} HullDurabilityFill: {fileID: 0} HeatstrokeMeterFill: {fileID: 0} HypothermiaMeterFill: {fileID: 0} HeatstrokeLimitFill: {fileID: 0} - ForwardRPMFill: {fileID: 0} - StrafeRPMFill: {fileID: 0} - TurnRPMFill: {fileID: 0} --- !u!114 &410701130 MonoBehaviour: m_ObjectHideFlags: 0 @@ -7752,7 +7608,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -8181,7 +8037,7 @@ Camera: m_Depth: 0 m_CullingMask: serializedVersion: 2 - m_Bits: 5632 + m_Bits: 5120 m_RenderingPath: 1 m_TargetTexture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} m_TargetDisplay: 0 @@ -8397,7 +8253,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -11195,105 +11051,6 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 677960091} m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!1 &691045496 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 691045497} - - component: {fileID: 691045500} - - component: {fileID: 691045499} - - component: {fileID: 691045498} - m_Layer: 5 - m_Name: Strafe - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &691045497 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 691045496} - 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_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 1542388328} - - {fileID: 126433270} - - {fileID: 383790464} - m_Father: {fileID: 1735948312} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 1} ---- !u!114 &691045498 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 691045496} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.011764706} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &691045499 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 691045496} - m_CullTransparentMesh: 1 ---- !u!114 &691045500 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 691045496} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreLayout: 0 - m_MinWidth: -1 - m_MinHeight: -1 - m_PreferredWidth: -1 - m_PreferredHeight: 16 - m_FlexibleWidth: -1 - m_FlexibleHeight: -1 - m_LayoutPriority: 1 --- !u!1 &693745763 GameObject: m_ObjectHideFlags: 0 @@ -11510,7 +11267,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -11877,105 +11634,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 719842150} m_CullTransparentMesh: 1 ---- !u!1 &723697980 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 723697981} - - component: {fileID: 723697984} - - component: {fileID: 723697983} - - component: {fileID: 723697982} - m_Layer: 5 - m_Name: Forward - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &723697981 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 723697980} - 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_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 1946192591} - - {fileID: 1463754850} - - {fileID: 1558236436} - m_Father: {fileID: 1735948312} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 1} ---- !u!114 &723697982 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 723697980} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.011764706} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &723697983 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 723697980} - m_CullTransparentMesh: 1 ---- !u!114 &723697984 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 723697980} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreLayout: 0 - m_MinWidth: -1 - m_MinHeight: -1 - m_PreferredWidth: -1 - m_PreferredHeight: 16 - m_FlexibleWidth: -1 - m_FlexibleHeight: -1 - m_LayoutPriority: 1 --- !u!1 &732687889 GameObject: m_ObjectHideFlags: 0 @@ -12167,7 +11825,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -12226,7 +11884,6 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - - {fileID: 1735948312} - {fileID: 232470597} m_Father: {fileID: 60313920} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -12619,6 +12276,94 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0, y: 0} +--- !u!1 &775333807 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 775333809} + - component: {fileID: 775333808} + m_Layer: 0 + m_Name: Impact Feedback + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &775333808 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 775333807} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bfdc38a81d00b0347bb55ad6469535ff, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::ImpactFeedback + HullEffect: {fileID: 177891522} + IntensityScale: 10 + MinEffectScale: 0.3 + Impulse: + m_ImpulseChannel: 1 + m_ImpulseShape: 0 + m_CustomImpulseShape: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_ImpulseDuration: 0.2 + m_ImpulseType: 3 + m_DissipationRate: 0 + m_RawSignal: {fileID: 0} + m_AmplitudeGain: 1 + m_FrequencyGain: 1 + m_RepeatMode: 0 + m_Randomize: 1 + m_TimeEnvelope: + m_AttackShape: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_DecayShape: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_AttackTime: 0 + m_SustainTime: 0.2 + m_DecayTime: 0.7 + m_ScaleWithImpact: 1 + m_HoldForever: 0 + m_ImpactRadius: 100 + m_DirectionMode: 0 + m_DissipationMode: 2 + m_DissipationDistance: 100 + m_PropagationSpeed: 343 +--- !u!4 &775333809 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 775333807} + serializedVersion: 2 + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 177891523} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &776416423 GameObject: m_ObjectHideFlags: 0 @@ -13289,7 +13034,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -13557,7 +13302,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -13862,7 +13607,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -13912,81 +13657,6 @@ MonoBehaviour: m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 ---- !u!1 &853400335 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 853400336} - - component: {fileID: 853400338} - - component: {fileID: 853400337} - m_Layer: 5 - m_Name: Icon - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &853400336 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 853400335} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1214607512} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 8, y: 0} - m_SizeDelta: {x: 10, y: -4} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &853400337 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 853400335} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 4b33557baae0da54a96c0aa97bf752ee, type: 3} - m_Type: 0 - m_PreserveAspect: 1 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &853400338 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 853400335} - m_CullTransparentMesh: 0 --- !u!1 &861158450 GameObject: m_ObjectHideFlags: 0 @@ -14123,6 +13793,7 @@ GameObject: m_Component: - component: {fileID: 887677623} - component: {fileID: 887677622} + - component: {fileID: 887677624} m_Layer: 0 m_Name: Third Person Rig m_TagString: Untagged @@ -14185,6 +13856,29 @@ Transform: - {fileID: 1319157835} m_Father: {fileID: 1665127616} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &887677624 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 887677621} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 00b2d199b96b516448144ab30fb26aed, type: 3} + m_Name: + m_EditorClassIdentifier: Cinemachine::Cinemachine.CinemachineImpulseListener + m_ApplyAfter: 2 + m_ChannelMask: 1 + m_Gain: 1 + m_Use2DDistance: 0 + m_UseCameraSpace: 1 + m_ReactionSettings: + m_SecondaryNoise: {fileID: 0} + m_AmplitudeGain: 1 + m_FrequencyGain: 1 + m_Duration: 1 + m_NoiseOffsets: {x: 0, y: 0, z: 0} --- !u!1 &906767441 GameObject: m_ObjectHideFlags: 0 @@ -14331,7 +14025,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -14469,7 +14163,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -14830,7 +14524,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -14952,143 +14646,6 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 56, y: 56} m_Pivot: {x: 0, y: 0} ---- !u!1 &932757481 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 932757482} - - component: {fileID: 932757484} - - component: {fileID: 932757483} - m_Layer: 5 - m_Name: Turn RPM - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &932757482 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 932757481} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1214607512} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 8, y: 0} - m_SizeDelta: {x: -16, y: -4} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &932757483 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 932757481} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_text: 18,000 - m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: 3fb7d873bb5a7944bb9a7c73c430c44b, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: b9d2f6c9804cec1489502dcc1c19ec54, type: 2} - m_fontSharedMaterials: [] - m_fontMaterial: {fileID: 0} - m_fontMaterials: [] - m_fontColor32: - serializedVersion: 2 - rgba: 4294967295 - m_fontColor: {r: 1, g: 1, b: 1, a: 1} - m_enableVertexGradient: 0 - m_colorMode: 3 - m_fontColorGradient: - topLeft: {r: 1, g: 1, b: 1, a: 1} - topRight: {r: 1, g: 1, b: 1, a: 1} - bottomLeft: {r: 1, g: 1, b: 1, a: 1} - bottomRight: {r: 1, g: 1, b: 1, a: 1} - m_fontColorGradientPreset: {fileID: 0} - m_spriteAsset: {fileID: 0} - m_tintAllSprites: 0 - m_StyleSheet: {fileID: 0} - m_TextStyleHashCode: -1183493901 - m_overrideHtmlColors: 0 - m_faceColor: - serializedVersion: 2 - rgba: 4294967295 - m_fontSize: 10 - m_fontSizeBase: 10 - m_fontWeight: 400 - m_enableAutoSizing: 1 - m_fontSizeMin: 6 - m_fontSizeMax: 16 - m_fontStyle: 0 - m_HorizontalAlignment: 1 - m_VerticalAlignment: 512 - m_textAlignment: 65535 - m_characterSpacing: 0 - m_characterHorizontalScale: 1 - m_wordSpacing: 0 - m_lineSpacing: 0 - m_lineSpacingMax: 0 - m_paragraphSpacing: 0 - m_charWidthMaxAdj: 0 - m_TextWrappingMode: 1 - m_wordWrappingRatios: 0.4 - m_overflowMode: 0 - m_linkedTextComponent: {fileID: 0} - parentLinkedComponent: {fileID: 0} - m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b - m_enableExtraPadding: 0 - checkPaddingRequired: 0 - m_isRichText: 1 - m_EmojiFallbackSupport: 1 - m_parseCtrlCharacters: 1 - m_isOrthographic: 1 - m_isCullingEnabled: 0 - m_horizontalMapping: 0 - m_verticalMapping: 0 - m_uvLineOffset: 0 - m_geometrySortingOrder: 0 - m_IsTextObjectScaleStatic: 0 - m_VertexBufferAutoSizeReduction: 1 - m_useMaxVisibleDescender: 1 - m_pageToDisplay: 1 - m_margin: {x: 0, y: 0, z: 0, w: 0} - m_isUsingLegacyAnimationComponent: 0 - m_isVolumetricText: 0 - m_hasFontAssetChanged: 0 - m_baseMaterial: {fileID: 0} - m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!222 &932757484 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 932757481} - m_CullTransparentMesh: 0 --- !u!1 &933815652 GameObject: m_ObjectHideFlags: 0 @@ -16674,8 +16231,6 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Settings: {fileID: 11400000, guid: cd2344e2001a37544aab0960c164d4ff, type: 2} - TargetSpottedBlinkFrequency: 20 - TargetSpottedBlinkOffset: -0.25 DeathPostTransitionTime: 1 DeathPost: {fileID: 803284856} HeatstrokePost: {fileID: 1404901906} @@ -16710,6 +16265,7 @@ MonoBehaviour: FriendlyTargetIndicator: {fileID: 332734009} ViewDot: {fileID: 146394778} LockIndicator: {fileID: 1876420642} + IncomingLockIndicatorDistance: 30 Crosshairs: - {fileID: 1914685583} - {fileID: 1284802339} @@ -16731,7 +16287,6 @@ MonoBehaviour: NoShieldColor: {r: 0.6, g: 0.6, b: 0.6, a: 1} ShieldIcon: {fileID: 21300000, guid: 2a61aee34fcf7e640a093cb4c4fa56bc, type: 3} NoShieldIcon: {fileID: 21300000, guid: bc1017eafc2627f4aaa4e247f14347fd, type: 3} - IntroDuration: 10 --- !u!4 &1009503730 Transform: m_ObjectHideFlags: 0 @@ -16767,7 +16322,7 @@ MonoBehaviour: Settings: {fileID: 11400000, guid: cd2344e2001a37544aab0960c164d4ff, type: 2} ZoneRoot: {fileID: 2095699057} SectorBrushes: {fileID: 1037490739} - SectorBoundaryBrush: {fileID: 1476765550} + AmbientLight: {fileID: 23420357} SceneCamera: {fileID: 887677622} FogCameras: - {fileID: 559840917} @@ -16778,8 +16333,6 @@ MonoBehaviour: - {fileID: 488792362} - {fileID: 970624071} - {fileID: 2095741464} - FogMaterial: {fileID: 2100000, guid: 2ff39f5d101241043ba1dcde19d92f77, type: 2} - FogFarFadeFraction: 0.125 FarPlaneDistanceMultiplier: 1 AsteroidMeshes: - Mesh: {fileID: 4300004, guid: bdb4c719a85f3f2419f6c573dd1daf15, type: 3} @@ -16847,17 +16400,22 @@ MonoBehaviour: LODHandler: {fileID: 1009503736} SlimeRenderer: {fileID: 1254851254} SlimeGravityCamera: {fileID: 1066823975} - SimpleCommodityPickup: {fileID: 4008709970769624704, guid: 521bfeece7dd5fd4e8f166d38493f18c, + SimpleCommodityPickup: {fileID: 7436534270673427838, guid: 521bfeece7dd5fd4e8f166d38493f18c, type: 3} - CompoundCommodityPickup: {fileID: 7449398549621940518, guid: 366909b6a01d7254d8eef01c333f8e00, + CompoundCommodityPickup: {fileID: 4507103896627202189, guid: 366909b6a01d7254d8eef01c333f8e00, type: 3} - GearPickup: {fileID: 946329779588188460, guid: d2b7e9a9cd7733041b0553682e4b61af, + GearPickup: {fileID: 7390748043139687254, guid: d2b7e9a9cd7733041b0553682e4b61af, type: 3} - WeaponPickup: {fileID: 8842807112802394818, guid: d2cec1d8c3d94074e9d2e6088e1c02d7, + WeaponPickup: {fileID: 5705448000916375656, guid: d2cec1d8c3d94074e9d2e6088e1c02d7, + type: 3} + MinePrefab: {fileID: 7283754118921506074, guid: b04728b2b65e057429eb6e8529299c8a, + type: 3} + CloudPrefab: {fileID: 2914522964471179774, guid: 4084aa3d08e52e04f880ad13daa409b4, type: 3} MapGravityMaterials: - {fileID: 2100000, guid: 841e4091d19548347bd59115047b4e49, type: 2} - {fileID: 2100000, guid: a92fc6d958edb9f46b6e58134f609cc0, type: 2} + GravityField: {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} Tour: 0 TourSwitchTime: 10 TourFollowDistance: 100 @@ -16904,7 +16462,6 @@ MonoBehaviour: NebulaTint: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} Heightmap: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} ParticleColors: {fileID: 2800000, guid: 56db63da398b2d04394ddbccedce943c, type: 3} - GravityCamera: {fileID: 1537342003} --- !u!114 &1009503736 MonoBehaviour: m_ObjectHideFlags: 0 @@ -17135,7 +16692,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -17165,81 +16722,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1012981707} m_CullTransparentMesh: 0 ---- !u!1 &1013676407 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1013676408} - - component: {fileID: 1013676410} - - component: {fileID: 1013676409} - m_Layer: 5 - m_Name: Turn Fill - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1013676408 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1013676407} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1214607512} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0.8, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1013676409 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1013676407} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.101960786} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &1013676410 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1013676407} - m_CullTransparentMesh: 0 --- !u!1 &1029396710 GameObject: m_ObjectHideFlags: 0 @@ -17380,8 +16862,6 @@ Transform: m_LocalScale: {x: 3000, y: 3000, z: 3000} m_ConstrainProportionsScale: 0 m_Children: - - {fileID: 1476765548} - - {fileID: 23420357} - {fileID: 1108843909} - {fileID: 1647230682} - {fileID: 1254851255} @@ -17570,7 +17050,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -17707,7 +17187,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -18488,7 +17968,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -18901,7 +18381,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -19818,105 +19298,6 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0, y: 0} ---- !u!1 &1214607511 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1214607512} - - component: {fileID: 1214607515} - - component: {fileID: 1214607514} - - component: {fileID: 1214607513} - m_Layer: 5 - m_Name: Turn - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1214607512 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1214607511} - 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_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 1013676408} - - {fileID: 853400336} - - {fileID: 932757482} - m_Father: {fileID: 1735948312} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 1} ---- !u!114 &1214607513 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1214607511} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.011764706} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &1214607514 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1214607511} - m_CullTransparentMesh: 1 ---- !u!114 &1214607515 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1214607511} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreLayout: 0 - m_MinWidth: -1 - m_MinHeight: -1 - m_PreferredWidth: -1 - m_PreferredHeight: 16 - m_FlexibleWidth: -1 - m_FlexibleHeight: -1 - m_LayoutPriority: 1 --- !u!1 &1218822609 GameObject: m_ObjectHideFlags: 0 @@ -21162,7 +20543,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -22007,7 +21388,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -22207,7 +21588,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -22394,7 +21775,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -22922,81 +22303,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 1281fe44325f9b548aa42dc331b17266, type: 3} m_Name: m_EditorClassIdentifier: ---- !u!1 &1463754849 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1463754850} - - component: {fileID: 1463754852} - - component: {fileID: 1463754851} - m_Layer: 5 - m_Name: Icon - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1463754850 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1463754849} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 723697981} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 8, y: 0} - m_SizeDelta: {x: 14, y: -2} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1463754851 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1463754849} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 55bed7a5ff978bf4c8cbda9971585df0, type: 3} - m_Type: 0 - m_PreserveAspect: 1 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &1463754852 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1463754849} - m_CullTransparentMesh: 0 --- !u!1 &1464157084 GameObject: m_ObjectHideFlags: 0 @@ -23167,7 +22473,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -23329,96 +22635,6 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} ---- !u!1 &1476765547 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1476765548} - - component: {fileID: 1476765551} - - component: {fileID: 1476765550} - m_Layer: 9 - m_Name: Boundary - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1476765548 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1476765547} - serializedVersion: 2 - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1037490739} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!23 &1476765550 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1476765547} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 0 - m_StaticShadowCaster: 0 - m_MotionVectors: 2 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 0 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 8f45fb3a0f420d5428f1528827d55fa2, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!33 &1476765551 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1476765547} - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} --- !u!1 &1485884351 GameObject: m_ObjectHideFlags: 0 @@ -23589,7 +22805,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -23986,7 +23202,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -24255,7 +23471,7 @@ Camera: m_Depth: 0 m_CullingMask: serializedVersion: 2 - m_Bits: 1536 + m_Bits: 512 m_RenderingPath: 1 m_TargetTexture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} m_TargetDisplay: 0 @@ -24418,81 +23634,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1541341820} m_CullTransparentMesh: 1 ---- !u!1 &1542388327 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1542388328} - - component: {fileID: 1542388330} - - component: {fileID: 1542388329} - m_Layer: 5 - m_Name: Strafe Fill - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1542388328 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1542388327} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 691045497} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0.8, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1542388329 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1542388327} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.101960786} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &1542388330 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1542388327} - m_CullTransparentMesh: 0 --- !u!1 &1547889398 GameObject: m_ObjectHideFlags: 0 @@ -24992,143 +24133,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1558182380} m_CullTransparentMesh: 1 ---- !u!1 &1558236435 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1558236436} - - component: {fileID: 1558236438} - - component: {fileID: 1558236437} - m_Layer: 5 - m_Name: Forward RPM - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1558236436 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1558236435} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 723697981} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 8, y: 0} - m_SizeDelta: {x: -16, y: -4} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1558236437 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1558236435} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_text: 18,000 - m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: 3fb7d873bb5a7944bb9a7c73c430c44b, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: b9d2f6c9804cec1489502dcc1c19ec54, type: 2} - m_fontSharedMaterials: [] - m_fontMaterial: {fileID: 0} - m_fontMaterials: [] - m_fontColor32: - serializedVersion: 2 - rgba: 4294967295 - m_fontColor: {r: 1, g: 1, b: 1, a: 1} - m_enableVertexGradient: 0 - m_colorMode: 3 - m_fontColorGradient: - topLeft: {r: 1, g: 1, b: 1, a: 1} - topRight: {r: 1, g: 1, b: 1, a: 1} - bottomLeft: {r: 1, g: 1, b: 1, a: 1} - bottomRight: {r: 1, g: 1, b: 1, a: 1} - m_fontColorGradientPreset: {fileID: 0} - m_spriteAsset: {fileID: 0} - m_tintAllSprites: 0 - m_StyleSheet: {fileID: 0} - m_TextStyleHashCode: -1183493901 - m_overrideHtmlColors: 0 - m_faceColor: - serializedVersion: 2 - rgba: 4294967295 - m_fontSize: 10 - m_fontSizeBase: 10 - m_fontWeight: 400 - m_enableAutoSizing: 1 - m_fontSizeMin: 6 - m_fontSizeMax: 16 - m_fontStyle: 0 - m_HorizontalAlignment: 1 - m_VerticalAlignment: 512 - m_textAlignment: 65535 - m_characterSpacing: 0 - m_characterHorizontalScale: 1 - m_wordSpacing: 0 - m_lineSpacing: 0 - m_lineSpacingMax: 0 - m_paragraphSpacing: 0 - m_charWidthMaxAdj: 0 - m_TextWrappingMode: 1 - m_wordWrappingRatios: 0.4 - m_overflowMode: 0 - m_linkedTextComponent: {fileID: 0} - parentLinkedComponent: {fileID: 0} - m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b - m_enableExtraPadding: 0 - checkPaddingRequired: 0 - m_isRichText: 1 - m_EmojiFallbackSupport: 1 - m_parseCtrlCharacters: 1 - m_isOrthographic: 1 - m_isCullingEnabled: 0 - m_horizontalMapping: 0 - m_verticalMapping: 0 - m_uvLineOffset: 0 - m_geometrySortingOrder: 0 - m_IsTextObjectScaleStatic: 0 - m_VertexBufferAutoSizeReduction: 1 - m_useMaxVisibleDescender: 1 - m_pageToDisplay: 1 - m_margin: {x: 0, y: 0, z: 0, w: 0} - m_isUsingLegacyAnimationComponent: 0 - m_isVolumetricText: 0 - m_hasFontAssetChanged: 0 - m_baseMaterial: {fileID: 0} - m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!222 &1558236438 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1558236435} - m_CullTransparentMesh: 0 --- !u!1 &1558520821 GameObject: m_ObjectHideFlags: 0 @@ -25740,7 +24744,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -26383,7 +25387,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -26895,7 +25899,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -27761,7 +26765,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 0 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -27899,7 +26903,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -27929,92 +26933,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1733988258} m_CullTransparentMesh: 1 ---- !u!1 &1735948311 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1735948312} - - component: {fileID: 1735948314} - - component: {fileID: 1735948313} - m_Layer: 5 - m_Name: RPM Display - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1735948312 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1735948311} - 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_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 723697981} - - {fileID: 691045497} - - {fileID: 1214607512} - m_Father: {fileID: 746825913} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1735948313 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1735948311} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Padding: - m_Left: 0 - m_Right: 0 - m_Top: 0 - m_Bottom: 0 - m_ChildAlignment: 0 - m_Spacing: 2 - m_ChildForceExpandWidth: 1 - m_ChildForceExpandHeight: 0 - m_ChildControlWidth: 1 - m_ChildControlHeight: 1 - m_ChildScaleWidth: 0 - m_ChildScaleHeight: 0 - m_ReverseArrangement: 0 ---- !u!114 &1735948314 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1735948311} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreLayout: 0 - m_MinWidth: -1 - m_MinHeight: -1 - m_PreferredWidth: -1 - m_PreferredHeight: 14 - m_FlexibleWidth: -1 - m_FlexibleHeight: -1 - m_LayoutPriority: 1 --- !u!1 &1741914909 GameObject: m_ObjectHideFlags: 0 @@ -28259,7 +27177,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -30089,81 +29007,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1943948574} m_CullTransparentMesh: 0 ---- !u!1 &1946192590 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1946192591} - - component: {fileID: 1946192593} - - component: {fileID: 1946192592} - m_Layer: 5 - m_Name: Forward Fill - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1946192591 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1946192590} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 723697981} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0.8, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1946192592 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1946192590} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.101960786} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &1946192593 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1946192590} - m_CullTransparentMesh: 0 --- !u!1 &1952022815 GameObject: m_ObjectHideFlags: 0 @@ -30416,7 +29259,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -31393,7 +30236,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -31710,7 +30553,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -32239,7 +31082,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -32376,7 +31219,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -33519,7 +32362,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -33620,7 +32463,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -33941,7 +32784,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -34071,7 +32914,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -34172,7 +33015,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -34384,7 +33227,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -34724,7 +33567,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -34862,7 +33705,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -34982,7 +33825,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -35138,7 +33981,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -35276,7 +34119,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -35582,7 +34425,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -35719,7 +34562,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -35819,7 +34662,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -35994,7 +34837,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -36151,7 +34994,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -37496,7 +36339,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -37943,7 +36786,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 00000000 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -38255,7 +37098,7 @@ MonoBehaviour: m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 - m_ActiveFontFeatures: 6e72656b + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 @@ -39366,7 +38209,6 @@ MonoBehaviour: OverrideIconBlinkSpeed: 10 ShieldIcon: {fileID: 19222411} HeatsinkBackground: {fileID: 661332569} - AetherDriveUi: {fileID: 1735948311} EnergyLabel: {fileID: 804489113} CockpitTemperatureLabel: {fileID: 212527384} RadiatorTemperatureLabel: {fileID: 1752418078} @@ -39375,18 +38217,12 @@ MonoBehaviour: VisibilityLabel: {fileID: 2122035461} HullDurabilityLabel: {fileID: 697075017} DistanceLabel: {fileID: 0} - ForwardRPMLabel: {fileID: 1558236437} - StrafeRPMLabel: {fileID: 383790465} - TurnRPMLabel: {fileID: 932757483} SensorCooldownFill: {fileID: 1943948575} EnergyFill: {fileID: 271575215} HullDurabilityFill: {fileID: 753112995} HeatstrokeMeterFill: {fileID: 1029396711} HypothermiaMeterFill: {fileID: 79341832} HeatstrokeLimitFill: {fileID: 933815653} - ForwardRPMFill: {fileID: 1946192591} - StrafeRPMFill: {fileID: 1542388328} - TurnRPMFill: {fileID: 1013676408} --- !u!224 &7628189704657849088 RectTransform: m_ObjectHideFlags: 0 @@ -39556,6 +38392,7 @@ SceneRoots: - {fileID: 906767442} - {fileID: 1009503730} - {fileID: 1037490739} + - {fileID: 23420357} - {fileID: 2095699057} - {fileID: 134113271} - {fileID: 666227432} @@ -39565,3 +38402,4 @@ SceneRoots: - {fileID: 990038542} - {fileID: 2135526003} - {fileID: 495677244} + - {fileID: 775333809} diff --git a/Assets/Scenes/FieldShieldTest.unity b/Assets/Scenes/FieldShieldTest.unity index 51c915b7f..b659bb95b 100644 --- a/Assets/Scenes/FieldShieldTest.unity +++ b/Assets/Scenes/FieldShieldTest.unity @@ -811,6 +811,9 @@ MonoBehaviour: Camera: {fileID: 1153356615} TestField: {fileID: 909026488} Properties: {fileID: 401779935} + GrabExtendTime: 1.5 + GrabEnvelopTime: 0.75 + GrabPullTime: 1.5 --- !u!4 &699508827 Transform: m_ObjectHideFlags: 0 @@ -1116,9 +1119,6 @@ MonoBehaviour: TendrilBaseDamping: 2 TendrilTipRadiusAnimationExponent: 2 TendrilFadeExponent: 2 - GrabExtendTime: 1.5 - GrabEnvelopTime: 0.75 - GrabPullTime: 1.5 RefractionAxis: 1 --- !u!114 &909026489 MonoBehaviour: diff --git a/Assets/Scenes/Main Menu.unity b/Assets/Scenes/Main Menu.unity index a37cfffba..4fafe8336 100644 --- a/Assets/Scenes/Main Menu.unity +++ b/Assets/Scenes/Main Menu.unity @@ -892,7 +892,6 @@ MonoBehaviour: NebulaTint: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} Heightmap: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} ParticleColors: {fileID: 2800000, guid: 56db63da398b2d04394ddbccedce943c, type: 3} - GravityCamera: {fileID: 2103364771} --- !u!114 &750375536 MonoBehaviour: m_ObjectHideFlags: 0 @@ -982,7 +981,7 @@ Camera: m_Depth: 0 m_CullingMask: serializedVersion: 2 - m_Bits: 5632 + m_Bits: 5120 m_RenderingPath: 1 m_TargetTexture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} m_TargetDisplay: 0 @@ -1061,16 +1060,6 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.x - value: 512 - objectReference: {fileID: 0} - - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.y - value: 512 - objectReference: {fileID: 0} - target: {fileID: 7852221720816817928, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalScale.x @@ -1086,16 +1075,6 @@ PrefabInstance: propertyPath: m_Materials.Array.data[0] value: objectReference: {fileID: 2100000, guid: b9f52544f98f47146b486fb6e27179bb, type: 2} - - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.x - value: 512 - objectReference: {fileID: 0} - - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.y - value: 512 - objectReference: {fileID: 0} - target: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalScale.x diff --git a/Assets/Scenes/TestScene.unity b/Assets/Scenes/TestScene.unity index 933f4c4ca..45c73ee85 100644 --- a/Assets/Scenes/TestScene.unity +++ b/Assets/Scenes/TestScene.unity @@ -13,7 +13,7 @@ OcclusionCullingSettings: --- !u!104 &2 RenderSettings: m_ObjectHideFlags: 0 - serializedVersion: 9 + serializedVersion: 10 m_Fog: 0 m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} m_FogMode: 3 @@ -38,13 +38,12 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.18113758, g: 0.20078251, b: 0.17357464, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &4 LightmapSettings: m_ObjectHideFlags: 0 - serializedVersion: 12 - m_GIWorkflowMode: 1 + serializedVersion: 13 + m_BakeOnSceneLoad: 0 m_GISettings: serializedVersion: 2 m_BounceScale: 1 @@ -67,9 +66,6 @@ LightmapSettings: m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 m_TextureCompression: 0 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 1024 m_ReflectionCompression: 2 m_MixedBakeMode: 1 m_BakeBackend: 0 @@ -105,7 +101,7 @@ NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 @@ -118,7 +114,7 @@ NavMeshSettings: cellSize: 0.16666666 manualTileSize: 0 tileSize: 256 - accuratePlacement: 0 + buildHeightMesh: 0 maxJobWorkers: 0 preserveTilesOutsideBounds: 0 debug: @@ -153,9 +149,9 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: -1} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1124877095} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -220,20 +216,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 0 m_isCullingEnabled: 0 @@ -248,11 +247,12 @@ MonoBehaviour: m_margin: {x: 0, y: 0, z: 0, w: 0} m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 m_hasFontAssetChanged: 0 m_renderer: {fileID: 62236176} m_maskType: 0 - _SortingLayerID: 0 - _SortingOrder: 0 --- !u!23 &62236176 MeshRenderer: m_ObjectHideFlags: 0 @@ -264,11 +264,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -290,9 +296,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!114 &62236177 MonoBehaviour: @@ -335,11 +343,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 73838348} - {fileID: 1538186655} m_Father: {fileID: 1187011252} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -394,9 +402,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 67477253} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -470,9 +478,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 676739119} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -565,9 +573,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1928037890} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -638,12 +646,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 162042368} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0.0125, z: 1} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1124877095} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!64 &162042370 MeshCollider: @@ -653,9 +662,17 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 162042368} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 4 + serializedVersion: 5 m_Convex: 0 m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} @@ -670,11 +687,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -696,9 +719,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &162042372 MeshFilter: @@ -733,12 +758,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 215995290} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 789220865} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &215995292 MeshRenderer: @@ -751,11 +777,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 m_MotionVectors: 2 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 0 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -777,9 +809,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &215995293 MeshFilter: @@ -794,6 +828,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 1090070598} m_Modifications: - target: {fileID: 7852221720480299766, guid: 046dde0f4600bce41ad33c476f99b309, @@ -876,32 +911,15 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.x - value: 40 - objectReference: {fileID: 0} - - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.y - value: 40 - objectReference: {fileID: 0} - - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.x - value: 20 - objectReference: {fileID: 0} - - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.y - value: 20 - objectReference: {fileID: 0} - target: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalPosition.y value: -4 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} --- !u!4 &229068763 stripped Transform: @@ -949,9 +967,17 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 240056260} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 4 + serializedVersion: 5 m_Convex: 0 m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} @@ -966,11 +992,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -992,9 +1024,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &240056264 MeshFilter: @@ -1011,12 +1045,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 240056260} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 1} m_LocalScale: {x: 0.044999998, y: 0.044999998, z: 3} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 820952285} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &302169896 GameObject: @@ -1045,11 +1080,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2061863457} - {fileID: 686739139} m_Father: {fileID: 1187011252} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -1152,7 +1187,9 @@ Canvas: m_OverrideSorting: 0 m_OverridePixelPerfect: 0 m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 m_SortingLayerID: 0 m_SortingOrder: 0 m_TargetDisplay: 0 @@ -1166,10 +1203,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 676739119} m_Father: {fileID: 0} - m_RootOrder: 8 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1200,12 +1237,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 375851675} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0.7071068, z: -0.7071068, w: 0} m_LocalPosition: {x: 0, y: 10, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1532567794} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 90, y: 180, z: 0} --- !u!20 &375851677 Camera: @@ -1221,9 +1259,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -1255,6 +1301,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: - target: {fileID: 8326552097884649274, guid: 897fa55d98f1f7f40b889f93ce9146f4, @@ -1328,6 +1375,9 @@ PrefabInstance: value: 90 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 897fa55d98f1f7f40b889f93ce9146f4, type: 3} --- !u!1 &441433737 GameObject: @@ -1355,12 +1405,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 441433737} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 4} m_LocalScale: {x: 2, y: 2, z: 2} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1124877095} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!64 &441433739 MeshCollider: @@ -1370,9 +1421,17 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 441433737} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 4 + serializedVersion: 5 m_Convex: 0 m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} @@ -1387,11 +1446,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -1413,9 +1478,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &441433741 MeshFilter: @@ -1453,9 +1520,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2039345446} - 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} @@ -1542,11 +1609,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -1568,9 +1641,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &507446969 MeshFilter: @@ -1587,18 +1662,20 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 507446966} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 5} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1183010124} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1001 &556481138 PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 1090070598} m_Modifications: - target: {fileID: 7852221720480299766, guid: 046dde0f4600bce41ad33c476f99b309, @@ -1681,32 +1758,15 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.x - value: 40 - objectReference: {fileID: 0} - - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.y - value: 40 - objectReference: {fileID: 0} - - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.x - value: 20 - objectReference: {fileID: 0} - - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.y - value: 20 - objectReference: {fileID: 0} - target: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalPosition.y value: -4 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} --- !u!1 &599096482 stripped GameObject: @@ -1769,11 +1829,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 2039345446} - {fileID: 1808942506} m_Father: {fileID: 1236141028} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -1856,9 +1916,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 676739119} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -1924,20 +1984,23 @@ MonoBehaviour: m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -2013,13 +2076,13 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 671490389} - {fileID: 87390263} - {fileID: 1187011252} - {fileID: 1236141028} m_Father: {fileID: 344649059} - 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} @@ -2132,9 +2195,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 302169897} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2200,20 +2263,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -2266,11 +2332,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1691202846} - {fileID: 840997727} m_Father: {fileID: 1187011252} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -2326,9 +2392,11 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 753458616} + serializedVersion: 2 m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} m_LocalPosition: {x: 0, y: -5, z: 0} m_LocalScale: {x: 1024, y: 1024, z: 1024} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1807969627} - {fileID: 1466792827} @@ -2336,7 +2404,6 @@ Transform: - {fileID: 1328848283} - {fileID: 6977256487279145164} m_Father: {fileID: 0} - m_RootOrder: 11 m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} --- !u!1 &789220864 GameObject: @@ -2361,15 +2428,16 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 789220864} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1489231075} - {fileID: 1223346183} - {fileID: 215995291} m_Father: {fileID: 753458617} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &801092328 GameObject: @@ -2397,12 +2465,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 801092328} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.015, y: 0.015, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 820952285} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &801092330 MonoBehaviour: @@ -2427,11 +2496,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -2453,9 +2528,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &801092332 MeshFilter: @@ -2488,15 +2565,16 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 820952284} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1124877095} - {fileID: 240056265} - {fileID: 801092329} m_Father: {fileID: 2067021207} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &840997726 GameObject: @@ -2526,9 +2604,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 719378462} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2594,20 +2672,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -2658,12 +2739,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 855309154} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1328848283} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &855309156 MeshRenderer: @@ -2676,11 +2758,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 m_MotionVectors: 2 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 0 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -2702,9 +2790,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &855309157 MeshFilter: @@ -2719,6 +2809,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: - target: {fileID: 235077144, guid: 897fa55d98f1f7f40b889f93ce9146f4, type: 3} @@ -2791,6 +2882,9 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 897fa55d98f1f7f40b889f93ce9146f4, type: 3} --- !u!1 &942014700 GameObject: @@ -2816,12 +2910,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 942014700} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0.7071068, z: -0.7071068, w: 0} m_LocalPosition: {x: 0, y: 10, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1532567794} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 90, y: 180, z: 0} --- !u!20 &942014702 Camera: @@ -2837,9 +2932,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -2897,9 +3000,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -2933,12 +3044,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 983613690} + serializedVersion: 2 m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} m_LocalPosition: {x: 0, y: 10, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 10 m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} --- !u!1 &1073373262 GameObject: @@ -2971,9 +3083,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -3007,12 +3127,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1073373262} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0.7071068, z: -0.7071068, w: 0} m_LocalPosition: {x: 0, y: 10, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1532567794} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 90, y: 180, z: 0} --- !u!1 &1090070596 GameObject: @@ -3051,15 +3172,16 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1090070596} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1647759374} - {fileID: 229068763} - {fileID: 734604127} m_Father: {fileID: 0} - m_RootOrder: 13 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1124877094 GameObject: @@ -3086,9 +3208,11 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1124877094} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0.25, y: 0.25, z: 0} m_LocalScale: {x: 0.015, y: 0.015, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1520024706} - {fileID: 441433738} @@ -3096,7 +3220,6 @@ Transform: - {fileID: 162042369} - {fileID: 62236174} m_Father: {fileID: 820952285} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1124877096 MonoBehaviour: @@ -3126,6 +3249,8 @@ MonoBehaviour: Secondary: {fileID: 441433740} Influence: {fileID: 1190354611} Label: {fileID: 62236175} + IconContainer: {fileID: 0} + Clickable: {fileID: 0} --- !u!4 &1128149392 stripped Transform: m_CorrespondingSourceObject: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, @@ -3156,15 +3281,16 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1183010123} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1940409868} - {fileID: 507446970} - {fileID: 2067021207} m_Father: {fileID: 0} - m_RootOrder: 7 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1183010125 MonoBehaviour: @@ -3208,6 +3334,8 @@ MonoBehaviour: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 + PlayerLocationLabelColor: {r: 0, g: 0, b: 0, a: 0} + PlayerLocationIconSize: 1.25 --- !u!1 &1187011251 GameObject: m_ObjectHideFlags: 0 @@ -3236,13 +3364,13 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1928037890} - {fileID: 302169897} - {fileID: 719378462} - {fileID: 67477253} m_Father: {fileID: 676739119} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -3315,12 +3443,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1190354608} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 15, y: 15, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1124877095} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!64 &1190354610 MeshCollider: @@ -3330,9 +3459,17 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1190354608} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 4 + serializedVersion: 5 m_Convex: 0 m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} @@ -3347,11 +3484,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -3373,9 +3516,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1190354612 MeshFilter: @@ -3410,12 +3555,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1223346182} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 789220865} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &1223346184 MeshRenderer: @@ -3428,11 +3574,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 m_MotionVectors: 2 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 0 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -3454,9 +3606,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1223346185 MeshFilter: @@ -3494,10 +3648,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 652433664} m_Father: {fileID: 676739119} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -3568,12 +3722,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1307174805} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0.7071068, z: -0.7071068, w: 0} m_LocalPosition: {x: 0, y: 10, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1532567794} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 90, y: 180, z: 0} --- !u!20 &1307174807 Camera: @@ -3589,9 +3744,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -3606,7 +3769,7 @@ Camera: m_Depth: 0 m_CullingMask: serializedVersion: 2 - m_Bits: 5632 + m_Bits: 5120 m_RenderingPath: 1 m_TargetTexture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} m_TargetDisplay: 0 @@ -3684,8 +3847,13 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 8c03374f22d0a3d4882018de66894a84, type: 3} m_Name: m_EditorClassIdentifier: - _volMaterial: {fileID: 2100000, guid: ad63650ae6d6cc542a5aad16694b3c46, type: 2} - GridTransform: {fileID: 753458617} + GridMesh: {fileID: 0} + GridCamera: {fileID: 0} + Settings: {fileID: 0} + NebulaSurfaceHeight: {fileID: 0} + NebulaPatchHeight: {fileID: 0} + NebulaPatch: {fileID: 0} + NebulaTint: {fileID: 0} --- !u!114 &1314993071 MonoBehaviour: m_ObjectHideFlags: 0 @@ -3744,7 +3912,9 @@ MonoBehaviour: m_ShowCustomSorter: 0 breakBeforeColorGrading: 0 m_BeforeTransparentBundles: [] - m_BeforeStackBundles: [] + m_BeforeStackBundles: + - assemblyQualifiedName: UnityEngine.Rendering.PostProcessing.DepthOfField, Assembly-CSharp, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null m_AfterStackBundles: [] --- !u!20 &1314993072 Camera: @@ -3760,9 +3930,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -3796,12 +3974,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1314993065} + serializedVersion: 2 m_LocalRotation: {x: 0.2267062, y: 0.44560468, z: -0.11773936, w: 0.8580083} m_LocalPosition: {x: -299.03247, y: -38.375748, z: -188.30061} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 9 m_LocalEulerAnglesHint: {x: 20, y: 0, z: 0} --- !u!1 &1328848282 GameObject: @@ -3826,15 +4005,16 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1328848282} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1563996706} - {fileID: 1584275846} - {fileID: 855309155} m_Father: {fileID: 753458617} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1388747984 GameObject: @@ -3859,13 +4039,14 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1388747984} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 3} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1955533727} m_Father: {fileID: 2067021207} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1404197274 GameObject: @@ -3960,9 +4141,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -3996,12 +4185,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1404197274} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: -1} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1404197280 MonoBehaviour: @@ -4051,9 +4241,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -4087,12 +4285,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1462895483} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: -1} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1462895486 MonoBehaviour: @@ -4155,12 +4354,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1466792826} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 753458617} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &1466792829 MeshRenderer: @@ -4173,11 +4373,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 m_MotionVectors: 2 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 0 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -4199,9 +4405,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1466792830 MeshFilter: @@ -4254,7 +4462,11 @@ MonoBehaviour: NearClipPlane: 0.3 FarClipPlane: 4096 Dutch: 0 + ModeOverride: 0 LensShift: {x: 0, y: 0} + GateFit: 2 + FocusDistance: 10 + m_SensorSize: {x: 1, y: 1} m_Transitions: m_BlendHint: 0 m_InheritPosition: 0 @@ -4270,13 +4482,14 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1479254159} + serializedVersion: 2 m_LocalRotation: {x: 0.2267062, y: 0.44560468, z: -0.11773936, w: 0.8580083} m_LocalPosition: {x: -299.03247, y: -38.375748, z: -188.30061} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1547641803} m_Father: {fileID: 0} - m_RootOrder: 14 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1489231074 GameObject: @@ -4303,12 +4516,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1489231074} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 789220865} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &1489231076 MeshRenderer: @@ -4321,11 +4535,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 m_MotionVectors: 2 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 0 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -4347,9 +4567,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1489231077 MeshFilter: @@ -4391,12 +4613,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1520024705} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 2} m_LocalScale: {x: 0.87800574, y: 0.87800574, z: 1.7560115} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1124877095} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!64 &1520024707 MeshCollider: @@ -4406,9 +4629,17 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1520024705} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 4 + serializedVersion: 5 m_Convex: 0 m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} @@ -4423,11 +4654,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -4449,9 +4686,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1520024709 MeshFilter: @@ -4484,16 +4723,17 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1532567792} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 1073373264} - {fileID: 1307174806} - {fileID: 942014701} - {fileID: 375851676} m_Father: {fileID: 0} - m_RootOrder: 12 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1538186654 GameObject: @@ -4523,9 +4763,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 67477253} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -4591,20 +4831,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -4656,12 +4899,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1547641802} + serializedVersion: 2 m_LocalRotation: {x: -0.7071068, y: -0, z: -0, w: 0.7071068} m_LocalPosition: {x: -58.728523, y: 4.327759, z: 429.1176} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1479254161} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1547641804 MonoBehaviour: @@ -4770,12 +5014,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1563996705} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1328848283} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &1563996707 MeshRenderer: @@ -4788,11 +5033,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 m_MotionVectors: 2 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 0 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -4814,9 +5065,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1563996708 MeshFilter: @@ -4851,12 +5104,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1584275845} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1328848283} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &1584275847 MeshRenderer: @@ -4869,11 +5123,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 m_MotionVectors: 2 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 0 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -4895,9 +5155,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1584275848 MeshFilter: @@ -4912,6 +5174,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 1090070598} m_Modifications: - target: {fileID: 7852221720480299766, guid: 046dde0f4600bce41ad33c476f99b309, @@ -4994,32 +5257,15 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.x - value: 40 - objectReference: {fileID: 0} - - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.y - value: 40 - objectReference: {fileID: 0} - - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.x - value: 20 - objectReference: {fileID: 0} - - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, - type: 3} - propertyPath: m_LocalScale.y - value: 20 - objectReference: {fileID: 0} - target: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalPosition.y value: -4 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} --- !u!4 &1647759374 stripped Transform: @@ -5055,9 +5301,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 719378462} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -5127,12 +5373,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1807969626} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 753458617} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &1807969629 MeshRenderer: @@ -5145,11 +5392,17 @@ MeshRenderer: m_CastShadows: 0 m_ReceiveShadows: 0 m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 m_MotionVectors: 2 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 0 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -5171,9 +5424,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1807969630 MeshFilter: @@ -5211,9 +5466,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 652433664} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -5279,20 +5534,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -5359,12 +5617,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1812750579} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!850595691 &1821185769 LightingSettings: @@ -5373,8 +5632,7 @@ LightingSettings: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: Settings.lighting - serializedVersion: 3 - m_GIWorkflowMode: 1 + serializedVersion: 10 m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 0 m_RealtimeEnvironmentLighting: 1 @@ -5382,11 +5640,19 @@ LightingSettings: m_AlbedoBoost: 1 m_IndirectOutputScale: 1 m_UsingShadowmask: 0 - m_BakeBackend: 0 + m_BakeBackend: 1 m_LightmapMaxSize: 1024 + m_LightmapSizeFixed: 0 + m_UseMipmapLimits: 1 m_BakeResolution: 50 m_Padding: 2 - m_TextureCompression: 0 + m_LightmapCompression: 0 + m_LightmapPackingMode: 1 + m_LightmapPackingMethod: 0 + m_XAtlasPackingAttempts: 16384 + m_XAtlasBruteForce: 0 + m_XAtlasBlockAlign: 0 + m_XAtlasRepackUnderutilizedLightmaps: 1 m_AO: 0 m_AOMaxDistance: 1 m_CompAOExponent: 0 @@ -5397,13 +5663,11 @@ LightingSettings: m_FilterMode: 1 m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0} m_ExportTrainingData: 0 + m_EnableWorkerProcessBaking: 1 m_TrainingDataDestination: TrainingData m_RealtimeResolution: 1 m_ForceWhiteAlbedo: 0 m_ForceUpdates: 0 - m_FinalGather: 0 - m_FinalGatherRayCount: 1024 - m_FinalGatherFiltering: 1 m_PVRCulling: 1 m_PVRSampling: 1 m_PVRDirectSampleCount: 32 @@ -5413,7 +5677,7 @@ LightingSettings: m_LightProbeSampleCountMultiplier: 4 m_PVRBounces: 2 m_PVRMinBounces: 2 - m_PVREnvironmentMIS: 0 + m_PVREnvironmentImportanceSampling: 0 m_PVRFilteringMode: 0 m_PVRDenoiserTypeDirect: 0 m_PVRDenoiserTypeIndirect: 0 @@ -5427,6 +5691,7 @@ LightingSettings: m_PVRFilteringAtrousPositionSigmaDirect: 0.5 m_PVRFilteringAtrousPositionSigmaIndirect: 2 m_PVRFilteringAtrousPositionSigmaAO: 1 + m_RespectSceneVisibilityWhenBakingGI: 0 --- !u!1 &1928037889 GameObject: m_ObjectHideFlags: 0 @@ -5454,11 +5719,11 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 115022189} - {fileID: 2008674250} m_Father: {fileID: 1187011252} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -5514,11 +5779,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -5540,9 +5811,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1940409867 MeshFilter: @@ -5559,12 +5832,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1940409864} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0.5} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1183010124} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1955533722 GameObject: @@ -5606,9 +5880,17 @@ MeshCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1955533722} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 4 + serializedVersion: 5 m_Convex: 0 m_CookingOptions: 30 m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} @@ -5623,11 +5905,17 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -5649,9 +5937,11 @@ MeshRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_MaskInteraction: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &1955533726 MeshFilter: @@ -5668,12 +5958,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1955533722} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0.25, y: 0.25, z: 0} m_LocalScale: {x: 0.1, y: 0.002, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1388747985} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1988754119 GameObject: @@ -5712,12 +6003,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1988754119} + serializedVersion: 2 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &2008674249 GameObject: @@ -5747,9 +6039,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1928037890} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -5815,20 +6107,23 @@ MonoBehaviour: m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 + m_characterHorizontalScale: 1 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b6167696c m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 1 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 1 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -5882,10 +6177,10 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: - {fileID: 453065208} m_Father: {fileID: 652433664} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -5958,9 +6253,9 @@ RectTransform: 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_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 302169897} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} @@ -6028,20 +6323,22 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2067021206} + serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: -0.5, y: -0.5, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 820952285} - {fileID: 1388747985} m_Father: {fileID: 1183010124} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1001 &6977256487279145163 PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 753458617} m_Modifications: - target: {fileID: 2784739443721397315, guid: efd1f097ce29ffa48bb0045d6502f55d, @@ -6115,6 +6412,13 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 6977256487485077368, guid: efd1f097ce29ffa48bb0045d6502f55d, + type: 3} + insertIndex: -1 + addedObject: {fileID: 599096484} m_SourcePrefab: {fileID: 100100000, guid: efd1f097ce29ffa48bb0045d6502f55d, type: 3} --- !u!4 &6977256487279145164 stripped Transform: @@ -6127,6 +6431,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: - target: {fileID: 7383646976225659329, guid: eb3a880755444d144a4d7f13ef11df77, @@ -6200,4 +6505,26 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: eb3a880755444d144a4d7f13ef11df77, type: 3} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 1988754121} + - {fileID: 1812750581} + - {fileID: 7383646976240752633} + - {fileID: 426221916} + - {fileID: 924112690} + - {fileID: 1404197278} + - {fileID: 1462895485} + - {fileID: 1183010124} + - {fileID: 344649059} + - {fileID: 1314993073} + - {fileID: 983613692} + - {fileID: 753458617} + - {fileID: 1532567794} + - {fileID: 1090070598} + - {fileID: 1479254161} diff --git a/Assets/Scripts/Editor/AmbientEdgeVerify.cs b/Assets/Scripts/Editor/AmbientEdgeVerify.cs new file mode 100644 index 000000000..4a56b6ea9 --- /dev/null +++ b/Assets/Scripts/Editor/AmbientEdgeVerify.cs @@ -0,0 +1,244 @@ +using System; +using System.IO; +using GameCult.Caching; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; + +namespace Aetheria.EditorTools +{ + /// + /// Batchmode check for campaign aetheria-gravity, cut ambient-follows-populated-area: the ambient tint falls softly to + /// dark and never hits an edge (ruling dark-beyond-populated-area). It opens ARPG.unity, takes the Ambient Fog Light the + /// scene wires into ZoneRenderer, sizes it for a generated zone with ZoneRenderer.FitAmbientLight (the call LoadZone + /// makes, not a copy), renders it through an orthographic camera that culls its layer into a target built from the descriptor of the production + /// Fog Tint render texture (B10G11R11_UFloatPack32, the format the Tint cameras write), and checks the + /// radial profile against exp(-(r/P)^2 ln(1/_EdgeBrightness)) times the centre, to within what that format stores (a + /// 5-bit mantissa) wherever the gaussian is at least a few ZoneRenderer.AmbientFloor (P is Zone.PopulatedRadius), that it + /// is lit at Pack.Radius, that the quad's rim and every lit texel beside a dark one are + /// at most two floors, and that no two lit texels are more than half a decade apart. + /// + /// Renders, so it needs a graphics device: run WITHOUT -nographics. + /// Unity -batchmode -projectPath <repo> -executeMethod Aetheria.EditorTools.AmbientEdgeVerify.Run -logFile <path> + /// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. + /// + public static class AmbientEdgeVerify + { + const string Tag = "[AmbientEdgeVerify]"; + const int Size = 512; + const int AmbientLayer = 13; + const string FogTintPath = "Assets/Resources/Fog Tint.renderTexture"; + // A float with a 5-bit mantissa (Fog Tint's blue) steps by 2^-5 of its value, and the target truncates to a step. + const float FormatRelativeError = 1f / 32f; + // The profile is held to the gaussian where it is at least this many floors; below that the format's tail is measured, not held. + const float FaithfulFloors = 8f; + // The rim and every lit texel beside a dark one hold at most this many floors, 2^-14 (the smallest normal of the format's + // floats): the one step to dark is the format's last value. Measured on the Fog Tint format it is 1.5 floors at most. + const float StepToDarkFloors = 2f; + static bool _ok = true; + + static void OnLog(string message, string stack, LogType type) + { + if ((type == LogType.Error || type == LogType.Exception || type == LogType.Assert) && !message.StartsWith(Tag)) + Fail("logged-error", message.Split('\n')[0]); + } + + static void Fail(string check, string detail) + { + Debug.LogError($"{Tag} FAIL {check}: {detail}"); + _ok = false; + } + + public static void Run() + { + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) + { + Debug.LogError($"{Tag} FAIL: no graphics device in this session; rerun batchmode without -nographics."); + EditorApplication.Exit(1); + return; + } + Application.logMessageReceived += OnLog; + var work = Path.Combine(Path.GetTempPath(), "ambient-edge-" + Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(Path.Combine(work, "probe")); + try + { + var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset") + ?? throw new InvalidOperationException("No Settings.asset."); + // Generated zones have the populated radius at about .78 of the pack radius (p50 over 1500 zones): this one's + // pack radius is set so, which puts Pack.Radius where it sits in play, inside the quad's reach. + var probe = GravityFieldParityVerify.BuildZone(settings, Path.Combine(work, "probe"), out _); + var zone = GravityFieldParityVerify.BuildZone(settings, work, out _, probe.PopulatedRadius / .78f); + EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Single); + try + { + var renderer = UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include); + if (renderer == null || renderer.AmbientLight == null) throw new InvalidOperationException("ARPG.unity wires no ZoneRenderer.AmbientLight."); + Check(renderer, zone); + } + finally + { + EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + } + Debug.Log(_ok ? $"{Tag} PASS" : $"{Tag} FAIL: see errors above"); + } + catch (Exception e) + { + Debug.LogError($"{Tag} FAIL exception: {e}"); + _ok = false; + } + finally + { + Application.logMessageReceived -= OnLog; + try { Directory.Delete(work, true); } catch { } + } + EditorApplication.Exit(_ok ? 0 : 1); + } + + // A bare ambient quad for the verifies that run LoadZone on a renderer built in code: the scene's material, no scene. + public static Transform NewAmbientLight() + { + var quad = new GameObject("Ambient Fog Light") { layer = AmbientLayer }; + quad.AddComponent().sharedMesh = Resources.GetBuiltinResource("Quad.fbx"); + quad.AddComponent().sharedMaterial = AssetDatabase.LoadAssetAtPath("Assets/Materials/Brushes/Sector Tint.mat"); + return quad.transform; + } + + static void Check(ZoneRenderer renderer, Zone zone) + { + var production = AssetDatabase.LoadAssetAtPath(FogTintPath); + if (production == null || production.graphicsFormat != GraphicsFormat.B10G11R11_UFloatPack32) + Fail("format", $"Fog Tint is {(production == null ? "missing" : production.graphicsFormat.ToString())}, not the B10G11R11_UFloatPack32 that AmbientFloor and FormatRelativeError describe"); + var light = renderer.AmbientLight; + if (light.parent != null) Fail("wiring", $"the ambient quad sits under {light.parent.name}, whose scale is the pack radius's"); + if (light.gameObject.layer != AmbientLayer) Fail("wiring", $"the ambient quad is on layer {light.gameObject.layer}, not {AmbientLayer}"); + + ZoneRenderer.FitAmbientLight(light, zone); + var meshRenderer = light.GetComponent(); + var material = meshRenderer.sharedMaterial; + var edge = material.GetFloat("_EdgeBrightness"); + var tint = material.GetColor("_Color").linear; + var centre = material.GetFloat("_Depth") * Mathf.Max(tint.r, Mathf.Max(tint.g, tint.b)); + var populated = zone.PopulatedRadius; + var half = light.localScale.x / 2f; + Debug.Log($"{Tag} populated radius {populated:F1} u, pack radius {zone.Pack.Radius:F1} u, quad half-extent {half:F1} u, edge brightness {edge:G3}, centre {centre:G4}"); + if (!(populated > 0f) || !(half > populated)) { Fail("sizing", $"the quad half-extent {half:F1} u does not reach beyond the populated radius {populated:F1} u"); return; } + + Render(light, half * 1.05f, out var value, out var world); + var floor = ZoneRenderer.AmbientFloor; + Debug.Log($"{Tag} format floor {floor:E2} = {floor / centre:E2} of the centre; tail (drawn / floor): " + + string.Join(" ", System.Linq.Enumerable.Select(new[] { 1.5f, 1.75f, 1.9f, 2f, 2.05f, 2.1f, 2.15f, 2.2f }, + k => $"{k}P:{Sample(value, world, new Vector2(k * populated, 0f)) / floor:G3}"))); + var logFall = Mathf.Log(1f / edge); + foreach (var k in new[] { 0f, .5f, 1f, 1.5f, 2f }) + { + var drawn = Sample(value, world, new Vector2(k * populated, 0f)); + Debug.Log($"{Tag} r = {k} P: drawn {drawn:G5}, expected {centre * Mathf.Exp(-k * k * logFall):G5}"); + } + var worstProfile = 0f; + var compared = 0; + var rim = 0f; + for (var i = 0; i < value.Length; i++) + { + if (float.IsNaN(value[i])) { Fail("texels", $"texel {i}: NaN"); return; } + var r = world[i].magnitude; + var expected = centre * Mathf.Exp(-(r / populated) * (r / populated) * logFall); + if (r <= half && expected >= FaithfulFloors * floor) + { + var error = Mathf.Abs(value[i] - expected) / (FormatRelativeError * expected); + worstProfile = Mathf.Max(worstProfile, error); + compared++; + if (error > 1f) { Fail("profile", $"at r = {r / populated:F3} P: expected {expected:G5}, drawn {value[i]:G5}, off by {error:F2} times the format's step"); return; } + } + // The rim: the texels in the quad's outermost ring (within two texels of its edge). + var edgeDistance = half - Mathf.Max(Mathf.Abs(world[i].x), Mathf.Abs(world[i].y)); + if (edgeDistance >= 0f && edgeDistance < 2f * (half * 1.05f * 2f / Size)) rim = Mathf.Max(rim, value[i]); + } + Debug.Log($"{Tag} profile: {compared} texels held to the gaussian, worst error {worstProfile:F3} of the format's step; rim {rim / centre:E2} of the centre"); + if (compared < Size * Size / 16) Fail("profile", $"only {compared} texels were held to the gaussian; the check is vacuous"); + if (rim > floor * StepToDarkFloors) Fail("rim", $"the quad's rim is {rim / floor:G3} times the format floor"); + + var atPack = Sample(value, world, new Vector2(zone.Pack.Radius, 0f)); + Debug.Log($"{Tag} at Pack.Radius: {atPack / centre:E2} of the centre"); + if (!(atPack > 0f)) Fail("pack-radius", "the ambient is zero at Pack.Radius"); + + var worstJump = 0f; + for (var y = 0; y < Size; y++) + for (var x = 0; x < Size; x++) + { + var here = value[y * Size + x]; + if (here <= 0f) continue; + foreach (var next in new[] { x + 1 < Size ? value[y * Size + x + 1] : 0f, y + 1 < Size ? value[(y + 1) * Size + x] : 0f }) + { + if (next <= 0f) { if (here > floor * StepToDarkFloors) Fail("last-step", $"a lit texel of {here / floor:G3} floors sits beside a dark one"); continue; } + worstJump = Mathf.Max(worstJump, Mathf.Abs(Mathf.Log10(here / next))); + } + } + Debug.Log($"{Tag} largest jump between neighbouring lit texels: {worstJump:F3} decades (limit 0.5)"); + if (worstJump > .5f) Fail("jump", $"neighbouring texels differ by {worstJump:F2} decades"); + var lit = 0; + foreach (var v in value) if (v > 0f) lit++; + if (lit < Size * Size / 2) Fail("jump", $"only {lit} texels are lit; the check is vacuous"); + } + + static float Sample(float[] value, Vector2[] world, Vector2 at) + { + var best = 0; + for (var i = 1; i < world.Length; i++) + if ((world[i] - at).sqrMagnitude < (world[best] - at).sqrMagnitude) best = i; + return value[best]; + } + + // Renders the ambient layer through a downward orthographic camera centred on the origin, as the Tint cameras see it, + // and returns the brightest channel of every texel with the world xz of its centre, which is asked of the camera. + static void Render(Transform light, float half, out float[] value, out Vector2[] world) + { + var production = AssetDatabase.LoadAssetAtPath(FogTintPath) ?? throw new InvalidOperationException("No Fog Tint render texture."); + var rt = new RenderTexture(production.descriptor) { filterMode = FilterMode.Point }; + var cameraObject = new GameObject("Ambient Edge Camera"); + var read = new Texture2D(Size, Size, TextureFormat.RGBAFloat, false); + var previous = RenderTexture.active; + try + { + var camera = cameraObject.AddComponent(); + camera.orthographic = true; + camera.orthographicSize = half; + camera.aspect = 1f; + camera.nearClipPlane = .3f; + camera.farClipPlane = 1000f; + camera.cullingMask = 1 << light.gameObject.layer; + camera.clearFlags = CameraClearFlags.SolidColor; + camera.backgroundColor = Color.black; + camera.allowHDR = false; + camera.allowMSAA = false; + camera.targetTexture = rt; + cameraObject.transform.SetPositionAndRotation(new Vector3(0f, 100f, 0f), Quaternion.Euler(90f, 0f, 0f)); + camera.Render(); + + RenderTexture.active = rt; + read.ReadPixels(new Rect(0, 0, Size, Size), 0, 0); + read.Apply(); + var pixels = read.GetPixelData(0); + value = new float[Size * Size]; + for (var i = 0; i < value.Length; i++) + value[i] = Mathf.Max(pixels[4 * i], Mathf.Max(pixels[4 * i + 1], pixels[4 * i + 2])); + world = new Vector2[Size * Size]; + for (var y = 0; y < Size; y++) + for (var x = 0; x < Size; x++) + { + var p = camera.ViewportToWorldPoint(new Vector3((x + .5f) / Size, (y + .5f) / Size, 100f)); + world[y * Size + x] = new Vector2(p.x, p.z); + } + } + finally + { + RenderTexture.active = previous; + UnityEngine.Object.DestroyImmediate(cameraObject); + UnityEngine.Object.DestroyImmediate(read); + rt.Release(); + UnityEngine.Object.DestroyImmediate(rt); + } + } + } +} diff --git a/Assets/Scripts/Editor/AmbientEdgeVerify.cs.meta b/Assets/Scripts/Editor/AmbientEdgeVerify.cs.meta new file mode 100644 index 000000000..0962854de --- /dev/null +++ b/Assets/Scripts/Editor/AmbientEdgeVerify.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 63b03af05dfdae44c89e21ca7ebec892 \ No newline at end of file diff --git a/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs b/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs new file mode 100644 index 000000000..75d97c63f --- /dev/null +++ b/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs @@ -0,0 +1,208 @@ +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using GameCult.Caching; +using UnityEditor; +using UnityEngine; +using CultMath; +using static CultMath.math; + +// Batch proof of the capability presenters' wiring, without a scene: a zone ship is bound to an EntityInstance through the +// game's own SetEntity, and impacts and grabs are published on the ship's Capabilities exactly as the simulation does. A hull absorb spawns +// one hull effect under the instance and, for the player's ship at ScreenShake 1, raises one camera impulse; ScreenShake 0 +// or another ship raises none; a shield absorb spawns no hull effect. The shield ripple itself (ShieldManager.ShowHit +// needs a shield material and a rig) is looked at in the editor, not here. Grabs: a Tractor Beam prefab under the instance +// is bound by the same SetEntity and presents a grab from events alone (emission at Power and the aim at the held point +// from Started to Completed or Cancelled, nothing otherwise, nothing for another entity's grab). +// +// Unity -batchmode -nographics -projectPath -executeMethod CapabilityPresentationSmoke.Run -logFile +// +// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. +public static class CapabilityPresentationSmoke +{ + private const BindingFlags Any = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + + public static void Run() + { + var work = Path.Combine(Path.GetTempPath(), $"capability-presentation-smoke-{Guid.NewGuid():N}"); + GameObject[] objects = null; + try + { + Directory.CreateDirectory(work); + objects = Check(work); + Clean(objects, work); + EditorApplication.Exit(0); + } + catch (Exception exception) + { + Debug.LogException(exception); + Clean(objects, work); + EditorApplication.Exit(1); + } + } + + // Edit mode runs no Awake or Start; the smoke runs the ones the game's scene would have. + private static void Awaken(Component component) => component.GetType().GetMethod("Awake", Any)?.Invoke(component, null); + + private static GameObject[] Check(string work) + { + var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset")?.GameplaySettings + ?? throw new InvalidOperationException("No Settings.asset."); + + var shape = new Shape(5, 4); + foreach (var cell in shape.AllCoordinates) shape[cell] = true; + var hullData = new HullData + { + Name = "Smoke Hull", HullType = HullType.Ship, Shape = shape, Durability = 1000, Mass = 1000, Armor = 0 + }; + var cache = AetheriaStores.Open(Path.Combine(work, "smoke.cc"), catalogWritable: true); + cache.Upsert(new VerseGrammar { Revision = 1 }); + cache.Upsert(hullData); + cache.FlushAsync().Wait(); + var ledger = new ProvenanceLedger(); + for (var i = 1; i <= 8; i++) ledger.Lots[i] = new Lot { Origin = new Attributed(), Quality = 1 }; + var items = new ItemManager(cache, ledger, settings, _ => { }); + var zone = new Zone(items, new PlanetSettings(), new ZonePack(), new GalaxyZone { Name = "Smoke", Owner = null }, null); + var hullRef = items.ItemData.RefOf(items.ItemData.GetByName("Smoke Hull")); + var ship = new Ship(items, zone, new EquippableItem { Data = hullRef, Durability = 1000, Lot = 1 }, new EntitySettings()); + var other = new Ship(items, zone, new EquippableItem { Data = hullRef, Durability = 1000, Lot = 2 }, new EntitySettings()); + zone.Admit(ship, piloted: false); + zone.Admit(other, piloted: false); + + // The scene's side: the tuning object with a pooled effect, and the game manager that names the player's ship. + var feedbackObject = new GameObject("Smoke Impact Feedback"); + var feedback = feedbackObject.AddComponent(); + Awaken(feedback); + var effectObject = new GameObject("Smoke Hull Effect"); + feedback.HullEffect = effectObject.AddComponent(); + var managerObject = new GameObject("Smoke Game Manager"); + var manager = managerObject.AddComponent(); + typeof(ActionGameManager).GetProperty("Instance", Any).SetValue(null, manager); + manager.CurrentEntity = ship; + + var beamPrefab = AssetDatabase.LoadAssetAtPath("Assets/Content/Prefabs/Tractor Beam.prefab") + ?? throw new InvalidOperationException("No Tractor Beam prefab."); + // An entity's instance as the game builds it: the beam is a child before SetEntity on both ship paths, so the + // binder finds it as the game does. + (GameObject Object, EntityInstance Instance, TractorBeam Beam) Bound(string name, Entity entity) + { + var go = new GameObject(name); + var bound = go.AddComponent(); + Awaken(bound); + bound.HullColliders = new HullCollider[0]; + bound.RadiatorHardpoints = new RadiatorHardpoint[0]; + bound.ThrusterHardpoints = new ThrusterHardpoint[0]; + bound.WeaponHardpoints = new WeaponHardpoint[0]; + bound.ArticulationPoints = new ArticulationPoint[0]; + var tractor = ((GameObject)PrefabUtility.InstantiatePrefab(beamPrefab, go.transform)).GetComponent(); + tractor.Power = .8f; + tractor.Direction = Vector3.forward; + bound.SetEntity(null, entity); + return (go, bound, tractor); + } + var (instanceObject, instance, beam) = Bound("Smoke Entity Instance", ship); + var (otherObject, _, otherBeam) = Bound("Smoke Other Instance", other); + + int Effects() => instance.GetComponentsInChildren(true).Count(p => p != null && !p.isOriginalPrototype); + void Expect(string what, int effects, int kicks) + { + if (Effects() != effects || feedback.KicksRaised != kicks) + throw new InvalidOperationException($"{what}: {Effects()} hull effects (want {effects}), {feedback.KicksRaised} impulses (want {kicks})."); + } + AbsorbEvent Hit(AbsorbLayer layer) => new AbsorbEvent(float3(1f, 0f, 2f), float3(0f, 0f, 1f), 100f, DamageType.Kinetic, layer); + + ActionGameManager.PlayerSettings.GraphicsSettings.ScreenShake = 1f; + ship.Capabilities.PublishAbsorb(Hit(AbsorbLayer.Hull)); + Expect("player's hull hit", 1, 1); + var effect = instance.GetComponentsInChildren(true).Single(p => !p.isOriginalPrototype); + var drawn = DrawAhead.Carried(ship, float3(1f, 0f, 2f), ActionGameManager.Clock.Lead); + if (abs(effect.transform.position.x - drawn.x) > 1e-3f || abs(effect.transform.position.z - drawn.z) > 1e-3f) + throw new InvalidOperationException("The hull effect is not at the drawn impact point."); + + ActionGameManager.PlayerSettings.GraphicsSettings.ScreenShake = 0f; + ship.Capabilities.PublishAbsorb(Hit(AbsorbLayer.Hull)); + Expect("hull hit at ScreenShake 0", 2, 1); + + ActionGameManager.PlayerSettings.GraphicsSettings.ScreenShake = 1f; + manager.CurrentEntity = other; + ship.Capabilities.PublishAbsorb(Hit(AbsorbLayer.Hull)); + // An untracked ship is not drawn at (ActionGameManager.DrawsAt, since contact-hud): no hull effect, no impulse. + Expect("hull hit on an untracked ship", 2, 1); + + // Once the player's instruments track it, the same hit is drawn. + other.VisibleEntities.Add(ship); + ship.Capabilities.PublishAbsorb(Hit(AbsorbLayer.Hull)); + Expect("hull hit on a tracked ship", 3, 1); + other.VisibleEntities.Remove(ship); + + manager.CurrentEntity = ship; + ship.Capabilities.PublishAbsorb(Hit(AbsorbLayer.Shield)); + Expect("player's shield hit", 3, 2); + + // Grabs: the beam presents the simulation's events and nothing else. + float Emission() => beam.ParticleSystem.emission.rateOverTimeMultiplier; + void ExpectBeam(string what, float emission, bool towardHeld) + { + beam.Update(); + var forward = beam.transform.forward; + var aimed = towardHeld ? forward.x > .999f : forward.z > .999f; + if (abs(Emission() - emission) > 1e-4f || !aimed) + throw new InvalidOperationException($"{what}: emission {Emission()} (want {emission}), forward {forward} (want {(towardHeld ? "+x" : "+z")})."); + } + GrabEvent Grab(GrabPhase phase, float3 at) => new GrabEvent(new FloatingBodyId(7), phase, at, 1f); + + ExpectBeam("idle beam", 0f, false); + ship.Capabilities.PublishGrab(Grab(GrabPhase.Started, float3(20f, 0f, 0f))); + ExpectBeam("grab started", .8f, true); + foreach (var phase in new[] { GrabPhase.Extend, GrabPhase.Envelop, GrabPhase.Pull }) + { + ship.Capabilities.PublishGrab(Grab(phase, float3(20f, 0f, 0f))); + ExpectBeam($"grab {phase}", .8f, true); + } + ship.Capabilities.PublishGrab(Grab(GrabPhase.Completed, float3(20f, 0f, 0f))); + ExpectBeam("grab completed", 0f, false); + + // A grab cancelled after its item vanished carries no position: the beam goes dark and never turns toward it. + ship.Capabilities.PublishGrab(Grab(GrabPhase.Started, float3(20f, 0f, 0f))); + ExpectBeam("second grab started", .8f, true); + ship.Capabilities.PublishGrab(Grab(GrabPhase.Cancelled, float3(0f, 0f, 0f))); + ExpectBeam("grab cancelled", 0f, false); + + // Aim is on the ground plane: a beam above the held point does not pitch toward it. + var beamHome = beam.transform.position; + beam.transform.position = beamHome + new Vector3(0f, 10f, 0f); + ship.Capabilities.PublishGrab(Grab(GrabPhase.Started, float3(20f, 7f, 0f))); + ExpectBeam("grab from above", .8f, true); + ship.Capabilities.PublishGrab(Grab(GrabPhase.Completed, float3(20f, 7f, 0f))); + beam.transform.position = beamHome; + + // A grab held at the beam's own position has no direction to take: the beam keeps the aim it had. + beam.Direction = Vector3.right; + var atBeam = float3(beam.transform.position.x, 0f, beam.transform.position.z); + ship.Capabilities.PublishGrab(Grab(GrabPhase.Started, atBeam)); + ExpectBeam("grab at the beam", .8f, true); + ship.Capabilities.PublishGrab(Grab(GrabPhase.Completed, atBeam)); + beam.Direction = Vector3.forward; + ExpectBeam("after the grab at the beam", 0f, false); + + // The beam belongs to the ship's entity: another entity's grab, with its own beam bound, moves only that beam. + other.Capabilities.PublishGrab(Grab(GrabPhase.Started, float3(20f, 0f, 0f))); + ExpectBeam("another entity's grab", 0f, false); + otherBeam.Update(); + if (abs(otherBeam.ParticleSystem.emission.rateOverTimeMultiplier - .8f) > 1e-4f) + throw new InvalidOperationException("The other entity's own beam did not present its grab."); + + Debug.Log("CAPABILITY_PRESENTATION_SMOKE ok effects=3 impulses=2 grabs=ok"); + return new[] { feedbackObject, effectObject, managerObject, instanceObject, otherObject }; + } + + private static void Clean(GameObject[] objects, string work) + { + if (objects != null) + foreach (var go in objects) + if (go != null) UnityEngine.Object.DestroyImmediate(go); + try { if (Directory.Exists(work)) Directory.Delete(work, true); } + catch (Exception error) { Debug.LogWarning($"Impact presenter smoke left {work}: {error.Message}"); } + } +} diff --git a/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs.meta b/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs.meta new file mode 100644 index 000000000..05df104cd --- /dev/null +++ b/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b1b27e4493b2cfe48805c786a5090cd3 \ No newline at end of file diff --git a/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs b/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs new file mode 100644 index 000000000..8a170dbde --- /dev/null +++ b/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections; +using System.IO; +using System.Linq; +using GameCult.Caching; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using float2 = CultMath.float2; +using float3 = CultMath.float3; + +// Batch proof that the presenters read the drawn pose through the clock: DrawnPoseTests pins the pose maths headlessly, +// and this is what pins that each presenter passes ActionGameManager.Clock.Lead into it. A zone is loaded into a fresh +// ZoneRenderer with the pickup and mine prefabs ARPG.unity's ZoneRenderer names; a loose Projectile is launched on the +// zone. The zone is stepped once, then the clock is set to leads 0, 0.008 and 0.015 s with no step, and each presenter's +// own Update places its transform. A body is drawn at its last step plus its step velocity times the lead, spelled here +// from the body's fields, so a presenter that reads lead 0 (or half the lead) sits on the step and fails. +// +// Reached: ItemPickup, MineInstance, Projectile.Draw. Not reached: ZoneRenderer.Update (Lower needs a ComputeBuffer, a +// GPU device) and the ActionGameManager markers (they need the ARPG scene running); a Lower split so its record fill is +// pure, or a run with a GPU and ARPG.unity in play mode, would reach them. +// +// Unity -batchmode -nographics -projectPath -executeMethod Aetheria.EditorTools.DrawnPoseWiringVerify.Run -logFile +// +// Do not pass -quit: Run enters play mode (a domain reload), the check runs there, and the Editor exits itself, 0 on +// success and 1 on any failure. +namespace Aetheria.EditorTools +{ + [InitializeOnLoad] + public static class DrawnPoseWiringVerify + { + private const string Tag = "[DrawnPoseWiringVerify]"; + private const string Flag = "DrawnPoseWiringVerify.running"; + private const string Wiring = "DrawnPoseWiringVerify.wiring"; + private const double Budget = 300; // real seconds + private const float RoundSpeed = 100f, Tolerance = 1e-3f; + private static IEnumerator _check; + private static double _started; + private static string _work; + + static DrawnPoseWiringVerify() + { + if (SessionState.GetBool(Flag, false)) EditorApplication.playModeStateChanged += OnPlayMode; + } + + public static void Run() + { + try + { + SessionState.SetString(Wiring, ReadWiring()); + SessionState.SetBool(Flag, true); + EditorApplication.EnterPlaymode(); + } + catch (Exception exception) + { + Debug.LogException(exception); + EditorApplication.Exit(1); + } + } + + private static void OnPlayMode(PlayModeStateChange change) + { + if (change != PlayModeStateChange.EnteredPlayMode) return; + _work = Path.Combine(Path.GetTempPath(), $"drawn-pose-wiring-{Guid.NewGuid():N}"); + Directory.CreateDirectory(_work); + _started = Time.realtimeSinceStartupAsDouble; + _check = Check(); + EditorApplication.update += Step; + } + + private static void Step() + { + try + { + if (Time.realtimeSinceStartupAsDouble - _started > Budget) throw new InvalidOperationException($"The check did not finish in {Budget} seconds."); + if (_check.MoveNext()) return; + Finish(0); + } + catch (Exception exception) + { + Debug.LogException(exception); + Finish(1); + } + } + + private static void Finish(int code) + { + EditorApplication.update -= Step; + SessionState.SetBool(Flag, false); + try { if (Directory.Exists(_work)) Directory.Delete(_work, true); } catch (Exception) { /* a temp directory */ } + EditorApplication.Exit(code); + } + + private static void Require(bool condition, string what) + { + if (!condition) throw new InvalidOperationException(what); + } + + private static IEnumerator Check() + { + var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset")?.GameplaySettings + ?? throw new InvalidOperationException("No Settings.asset."); + settings.FloaterLayerHeight = -1.5f; // nonzero, so a presenter that drops the floater layer fails + + var wired = SessionState.GetString(Wiring, "").Split('|').Select(entry => entry.Split('=')).ToDictionary(pair => pair[0], pair => pair[1]); + var pickupPrefab = AssetDatabase.LoadAssetAtPath(wired["SimpleCommodityPickup"])?.GetComponent(); + var minePrefab = AssetDatabase.LoadAssetAtPath(wired["MinePrefab"])?.GetComponent(); + Require(pickupPrefab != null, "ZoneRenderer.SimpleCommodityPickup is not an ItemPickup in ARPG.unity."); + Require(minePrefab != null, "ZoneRenderer.MinePrefab is not a MineInstance in ARPG.unity."); + + var oneCell = new Shape(1, 1); + oneCell[new CultMath.int2(0, 0)] = true; + var cache = AetheriaStores.Open(Path.Combine(_work, "wiring.cc"), catalogWritable: true); + cache.Upsert(new VerseGrammar { Revision = 1 }); + cache.Upsert(new SimpleCommodityData { Name = "Wiring Ore", Shape = oneCell, MaxStack = 100 }); + cache.FlushAsync().Wait(); + var ledger = new ProvenanceLedger(); + var items = new ItemManager(cache, ledger, settings, _ => { }); + var zone = new Zone(items, new PlanetSettings(), new ZonePack(), null, null); + + var rootObject = new GameObject("Wiring Zone Root"); + var rendererObject = new GameObject("Wiring Zone Renderer"); + rendererObject.SetActive(false); // inactive: ZoneRenderer.Update needs a GPU and is not part of this check + var renderer = rendererObject.AddComponent(); + renderer.ZoneRoot = rootObject.transform; + renderer.SimpleCommodityPickup = pickupPrefab; + renderer.MinePrefab = minePrefab; + renderer.ItemManager = items; + renderer.SectorBrushes = new GameObject("Wiring Brushes").transform; + renderer.AmbientLight = AmbientEdgeVerify.NewAmbientLight(); + renderer.SlimeGravityCamera = new GameObject("Wiring Gravity Camera").AddComponent(); + var slimeObject = new GameObject("Wiring Slime"); + slimeObject.SetActive(false); + renderer.SlimeRenderer = slimeObject.AddComponent(); + renderer.LoadZone(zone); + + var ore = new SimpleCommodity { Data = items.ItemData.RefOf(items.ItemData.GetByName("Wiring Ore")), Quantity = 7 }; + var floating = zone.Release(ore, new float2(3, 4), new float2(10, 0)); + var mine = new Mine + { + Body = new KinematicBody { Position = new float2(-20, 8), Velocity = new float2(0, 14) }, + ArmingDelay = 1e6f, FuseDelay = 1f, Lifetime = 1e6f, BlastRadius = 1f + }; + zone.Lay(mine); + + // A round on its frozen line, no target and no outcome known: drawn at FireOrigin + direction * speed * (T - FireTime). + var shot = new PendingShot + { + ShotId = 1, FireOrigin = new float3(0, 0, 0), FireTime = 0f, TravelDirection = new float2(1, 0), Speed = RoundSpeed, + MaxRange = 1e6f, FireRange = 1e6f, CommitTime = 1e5f, ArrivalTime = 2e5f + }; + var projectile = new GameObject("Wiring Round").AddComponent(); + projectile.Launch(zone, shot, new Vector3(0, 0, 0)); + yield return null; + + zone.Update(.5f); + + var pickup = rootObject.GetComponentsInChildren(true).Single(p => p.Item == ore); + var mineInstance = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None).Single(); + + var pickupVelocity = floating.Body.TotalVelocity; + var mineVelocity = mine.Body.TotalVelocity; + Require(Mathf.Abs(pickupVelocity.x) > 1f && Mathf.Abs(mineVelocity.y) > 1f, "The fixture's bodies stopped: a lead would not move them."); + + Vector2 baseline = default; + foreach (var leadSeconds in new[] { 0f, .008f, .015f }) + { + ActionGameManager.Clock.Reset(); + if (leadSeconds > 0) ActionGameManager.Clock.Advance(leadSeconds, _ => throw new InvalidOperationException("a step ran")); + var lead = ActionGameManager.Clock.Lead; + Require(Mathf.Abs(lead - leadSeconds) < 1e-6f, $"The clock's lead is {lead}, not {leadSeconds}."); + yield return null; + + var seen = pickup.transform.position; + var want = floating.Body.Position + pickupVelocity * lead; + Require(Mathf.Abs(seen.x - want.x) < Tolerance && Mathf.Abs(seen.z - want.y) < Tolerance, + $"ItemPickup at lead {lead}: drawn x/z {seen.x},{seen.z}, the step plus velocity times lead {want.x},{want.y}."); + + seen = mineInstance.transform.position; + want = mine.Body.Position + mineVelocity * lead; + Require(Mathf.Abs(seen.x - want.x) < Tolerance && Mathf.Abs(seen.z - want.y) < Tolerance, + $"MineInstance at lead {lead}: drawn x/z {seen.x},{seen.z}, the step plus velocity times lead {want.x},{want.y}."); + Require(Mathf.Abs(seen.y - DrawAhead.FloaterHeight(zone, settings, new float2(want.x, want.y), lead)) < Tolerance, + $"MineInstance y {seen.y} is not on the floater layer."); + + // The round's line is a function of the drawn time: it moves RoundSpeed * lead along its direction between leads. + seen = projectile.transform.position; + if (leadSeconds == 0f) baseline = new Vector2(seen.x, seen.z); + var moved = new Vector2(seen.x, seen.z) - baseline; + Require(Mathf.Abs(moved.x - RoundSpeed * lead) < Tolerance && Mathf.Abs(moved.y) < Tolerance, + $"Projectile at lead {lead}: drawn {moved.x},{moved.y} past its lead-0 pose, expected {RoundSpeed * lead},0."); + } + ActionGameManager.Clock.Reset(); + Debug.Log($"{Tag} ok: ItemPickup, MineInstance and Projectile draw at the clock's lead (0, 0.008, 0.015 s)"); + } + + // What ARPG.unity's ZoneRenderer names in the pickup and mine fields, read from the saved scene before the play session + // (a scene cannot be opened inside one) and carried across the domain reload as asset paths. + private static string ReadWiring() + { + var scene = EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Additive); + try + { + var found = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None) + .Where(r => r.gameObject.scene == scene).ToArray(); + Require(found.Length == 1, $"ARPG.unity has {found.Length} ZoneRenderers."); + var wired = found[0]; + return string.Join("|", new (string, UnityEngine.Object)[] + { + ("SimpleCommodityPickup", wired.SimpleCommodityPickup), ("MinePrefab", wired.MinePrefab) + }.Select(f => f.Item1 + "=" + (f.Item2 == null ? "" : AssetDatabase.GetAssetPath(f.Item2)))); + } + finally { EditorSceneManager.CloseScene(scene, true); } + } + } +} diff --git a/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs.meta b/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs.meta new file mode 100644 index 000000000..534bebdb6 --- /dev/null +++ b/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c2270cf68a4af384eb715c8b5a55f5e8 \ No newline at end of file diff --git a/Assets/Scripts/Editor/EmojiCheck.cs b/Assets/Scripts/Editor/EmojiCheck.cs new file mode 100644 index 000000000..1f464fd9f --- /dev/null +++ b/Assets/Scripts/Editor/EmojiCheck.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using TMPro; +using UnityEditor; +using UnityEngine; + +// Every single-code-point emoji of the pinned Unicode Emoji version that Twemoji draws, and the Pirates product +// names read from the shipped catalog, render through an ordinary TMP text on the game's body font with no +// missing code point, no blank glyph, ink in the emoji atlas, and each glyph served by the emoji asset or by the +// body font itself, never by a third font. TMP Settings must route emoji by two named routes (operator ruling +// emoji-fallback-route): the global fallback names Emoji.asset and the emoji fallback list is exactly Emoji.asset, +// so dropping either fails. +// Run as -executeMethod EmojiCheck.Run (exit 1 on failure in batchmode, as EngineAssetCheck). Corpus: +// tools/emoji/emoji-singles.txt (from emoji-test.txt); the emoji Twemoji lacks are listed in +// tools/emoji/emoji-unsupported.txt and reported, not rendered; -emojiLimit N spreads N entries evenly for a spike. +// Every fully-qualified multi-code-point sequence (tools/emoji/emoji-sequences.txt: ZWJ, skin tone, flag, keycap, +// tag) must also render as exactly one visible character, which needs `liga` on the rendering component: every +// TMP text in every prefab and scene must have it, and so must one added at runtime (as ActionGameManager's +// FACE AIM mark is), or a family or flag would show as its pieces. +public static class EmojiCheck +{ + const string BodyFontPath = "Assets/Fonts/Ubuntu/Ubuntu-L Small SDF.asset"; + const string PiratesFaction = "Pirates"; + const int Chunk = 64; + + [MenuItem("Aetheria/Text/Check Emoji Rendering")] + public static void Run() + { + var failures = new List(); + var summary = RunCheck(failures); + foreach (var failure in failures.Take(20)) Debug.LogError(failure); + Debug.Log($"EmojiCheck: {summary}; {failures.Count} failure(s)."); + if (Application.isBatchMode) EditorApplication.Exit(failures.Count == 0 ? 0 : 1); + } + + // Public so a scratch driver can mutate TMP Settings in memory and watch this fail; adds to failures. + public static string RunCheck(List failures) + { + var emoji = AssetDatabase.LoadAssetAtPath(EmojiFont.AssetPath); + var body = AssetDatabase.LoadAssetAtPath(BodyFontPath); + if (emoji == null || body == null) + { + failures.Add("EmojiCheck: Emoji.asset or the body font is missing; run EmojiFont.Build first."); + return "nothing checked"; + } + + // Two routes (operator ruling emoji-fallback-route): the emoji fallback list is exactly Emoji.asset, and the global list below names it. + if (TMP_Settings.emojiFallbackTextAssets == null || TMP_Settings.emojiFallbackTextAssets.Count != 1 || TMP_Settings.emojiFallbackTextAssets[0] != emoji) + failures.Add("TMP Settings' emoji fallback list is not exactly Emoji.asset: FE0F-followed bases the body font draws will not reach Twemoji."); + if (TMP_Settings.fallbackFontAssets == null || !TMP_Settings.fallbackFontAssets.Contains(emoji)) + failures.Add("TMP Settings' global fallback list does not name Emoji.asset: the route for every single code point is gone."); + + var unsupported = new HashSet(LoadCodePoints("emoji-unsupported.txt")); + var corpus = LoadSingles().Where(cp => !unsupported.Contains(cp)).ToList(); + var sequences = LoadSequences(); + var missing = new HashSet(); + TMP_Text.MissingCharacterEventCallback onMissing = (unicode, index, source, asset, component) => missing.Add(unicode); + TMP_Text.OnMissingCharacter += onMissing; + + var canvas = new GameObject("EmojiCheck", typeof(Canvas)); + var text = new GameObject("Text", typeof(RectTransform)).AddComponent(); + text.transform.SetParent(canvas.transform, false); + text.font = body; + text.textWrappingMode = TextWrappingModes.NoWrap; + text.rectTransform.sizeDelta = new Vector2(100000, 100000); + + int viaEmoji = 0, viaBody = 0, blank = 0, pirateNames = 0, notOne = 0, runtimeLiga = 0; + var strays = new HashSet(); + try + { + void Render(string content, string label) + { + text.text = content; + text.ForceMeshUpdate(); + for (var i = 0; i < text.textInfo.characterCount; i++) + { + var info = text.textInfo.characterInfo[i]; + if (info.character == ' ' || info.elementType != TMP_TextElementType.Character) continue; + if (info.fontAsset == emoji) viaEmoji++; + else if (info.fontAsset == body) viaBody++; + else if (strays.Add($"{info.fontAsset.name}:{(int)info.character:X}")) + failures.Add($"U+{(int)info.character:X4} in {label} was served by {info.fontAsset.name}, not Emoji.asset or the body font"); + if (info.fontAsset == emoji && info.textElement.glyph.glyphRect.width <= 0) + { + blank++; + failures.Add($"blank glyph U+{(int)info.character:X4} in {label}"); + } + } + } + + for (var i = 0; i < corpus.Count; i += Chunk) + { + var slice = corpus.Skip(i).Take(Chunk).ToList(); + Render(string.Join(" ", slice.Select(char.ConvertFromUtf32)), $"chunk {i}"); + } + + // A text created at runtime inherits liga from TMP Settings, with no wiring of its own. + var runtime = new GameObject("Runtime", typeof(RectTransform)); + runtime.transform.SetParent(canvas.transform, false); + runtimeLiga = runtime.AddComponent().fontFeatures + .Contains(UnityEngine.TextCore.OTL_FeatureTag.liga) ? 1 : 0; + if (runtimeLiga == 0) failures.Add("a TextMeshProUGUI added at runtime does not have liga: TMP Settings' features are not inherited"); + + // Sequences: space-separated groups, each of which must end as one visible character. + for (var i = 0; i < sequences.Count; i += Chunk) + { + var slice = sequences.Skip(i).Take(Chunk).ToList(); + text.text = string.Join(" ", slice.Select(ToText)); + text.ForceMeshUpdate(); + var visible = new List { 0 }; + var shown = new List { "" }; + for (var c = 0; c < text.textInfo.characterCount; c++) + { + var info = text.textInfo.characterInfo[c]; + if (info.character == ' ') { visible.Add(0); shown.Add(""); } + else if (info.isVisible) + { + visible[visible.Count - 1]++; + shown[shown.Count - 1] += $" U+{(int)info.character:X}:{info.fontAsset.name}"; + } + } + if (visible.Count != slice.Count) failures.Add($"sequence chunk {i}: {visible.Count} groups rendered for {slice.Count} sequences"); + for (var g = 0; g < Math.Min(visible.Count, slice.Count); g++) + if (visible[g] != 1) + { + notOne++; + failures.Add($"sequence {slice[g]} rendered {visible[g]} visible characters, not one:{shown[g]}"); + } + } + + // The Pirates names as the shipped catalog stores them, through the game's own catalog reader. + var catalogPath = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "GameData", "Aetheria.cc"); + using (var catalog = AetheriaStores.Open(catalogPath)) + { + var pirates = catalog.GetAll().SingleOrDefault(faction => faction.Name == PiratesFaction); + if (pirates == null) failures.Add($"the catalog has no {PiratesFaction} faction"); + else + { + var key = catalog.RefOf(pirates); + foreach (var product in catalog.GetAll().Where(product => product.Manufacturer.Equals(key))) + { + pirateNames++; + Render(product.Name, $"Pirates product name \"{product.Name}\""); + } + if (pirateNames == 0) failures.Add($"the catalog has no {PiratesFaction} products"); + } + } + } + finally + { + TMP_Text.OnMissingCharacter -= onMissing; + UnityEngine.Object.DestroyImmediate(canvas); + } + + foreach (var cp in missing.OrderBy(c => c)) failures.Add($"missing code point U+{cp:X4}"); + + // Every serialized TMP text has liga (an instance inherits it from its prefab, so this reads the effective value). + int texts = 0, withoutLiga = 0; + EmojiFont.VisitSerializedTexts(component => + { + texts++; + if (!component.fontFeatures.Contains(UnityEngine.TextCore.OTL_FeatureTag.liga)) + { + withoutLiga++; + failures.Add($"TMP text {component.name} has no liga: {GetPath(component)}"); + } + return false; + }); + + // TMP over-allocates atlasTextures by doubling its capacity when a page is added, so entries past + // atlasTextureCount are null by design (3 pages in a 4-slot array). Only the used pages count. + long ink = 0, colour = 0; + for (var i = 0; i < emoji.atlasTextureCount; i++) + { + var page = emoji.atlasTextures[i]; + if (page == null) { failures.Add($"emoji atlas page {i} of {emoji.atlasTextureCount} is null"); continue; } + var pixels = page.GetPixels32(); + ink += pixels.LongCount(p => p.a != 0); + colour += pixels.LongCount(p => p.a != 0 && (p.r != p.g || p.g != p.b)); + } + if (ink == 0) failures.Add("the emoji atlas holds no ink after rendering"); + else if (colour == 0) failures.Add("the emoji atlas holds no coloured pixel: the glyphs rendered monochrome"); + + var pages = emoji.atlasTextureCount; + // Dynamic atlas content is cache: drop it so this check leaves the asset as Build wrote it. + emoji.ClearFontAssetData(true); + if (unsupported.Count > 0) + Debug.LogWarning($"EmojiCheck: Twemoji lacks {unsupported.Count} single-code-point emoji of the Emoji version: " + + string.Join(" ", unsupported.OrderBy(c => c).Select(c => $"U+{c:X4}"))); + return $"{sequences.Count} sequences ({notOne} not one visible character), {texts} serialized TMP texts ({withoutLiga} without liga), runtime text liga {runtimeLiga}; " + + $"checked {corpus.Count} single code points ({unsupported.Count} not drawn by Twemoji, listed in the warning) + {pirateNames} Pirates product names, " + + $"{missing.Count} missing, {viaEmoji} glyphs via the emoji asset, {viaBody} via the body font, {strays.Count} via other fonts, {blank} blank, " + + $"{ink} atlas ink pixels of which {colour} coloured, {pages} atlas pages"; + } + + static string GetPath(Component component) => + component.gameObject.scene.IsValid() ? component.gameObject.scene.path : AssetDatabase.GetAssetPath(component); + + static string ToText(string sequence) => string.Concat(sequence.Split(' ').Select(cp => char.ConvertFromUtf32(Convert.ToInt32(cp, 16)))); + + static List LoadSequences() => + File.ReadAllLines(Path.Combine(Directory.GetParent(Application.dataPath).FullName, "tools", "emoji", "emoji-sequences.txt")) + .Where(l => l.Length > 0).ToList(); + + static List LoadSingles() + { + var all = LoadCodePoints("emoji-singles.txt"); + var args = Environment.GetCommandLineArgs(); + var at = Array.IndexOf(args, "-emojiLimit"); + if (at < 0 || at + 1 >= args.Length) return all; + var limit = int.Parse(args[at + 1]); + return Enumerable.Range(0, limit).Select(i => all[i * all.Count / limit]).ToList(); + } + + static List LoadCodePoints(string file) + { + var path = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "tools", "emoji", file); + return File.ReadAllLines(path).Where(l => l.Length > 0).Select(l => Convert.ToInt32(l, 16)).ToList(); + } +} diff --git a/Assets/Scripts/Editor/EmojiCheck.cs.meta b/Assets/Scripts/Editor/EmojiCheck.cs.meta new file mode 100644 index 000000000..945280e85 --- /dev/null +++ b/Assets/Scripts/Editor/EmojiCheck.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c6f940add256a754daac8460fc79480d \ No newline at end of file diff --git a/Assets/Scripts/Editor/EmojiFont.cs b/Assets/Scripts/Editor/EmojiFont.cs new file mode 100644 index 000000000..9d50b95c1 --- /dev/null +++ b/Assets/Scripts/Editor/EmojiFont.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using TMPro; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.TextCore; +using UnityEngine.TextCore.LowLevel; + +// The one writer of the emoji font asset and of TMP Settings' emoji routing. The font file is the +// output of tools/emoji/fetch_emoji_font.py; the asset is a dynamic COLOR font asset whose atlas pages +// are cache, filled on first use at runtime and cleared here. Every TMP text reaches emoji through TMP +// Settings alone (no component names an emoji font), by two routes that both name only Emoji.asset (operator ruling +// emoji-fallback-route): the global fallback serves every code point, including the 200 text-presentation emoji the +// emoji list alone leaves unresolved; the emoji fallback list is what TMP tries first when FE0F follows, so a keycap +// or FE0F/ZWJ sequence whose first code point the body font also draws reaches Twemoji, whose ligatures collapse it. +// Sequences (ZWJ, skin tone, flag, keycap) resolve only through the emoji font's GSUB ligatures, and TMP applies +// them per component, gated by that component's font features: EnableLigatures writes `liga` into every +// serialized TMP text and into TMP Settings (so a text created later inherits it); there is no global switch. +public static class EmojiFont +{ + public const string FontPath = "Assets/Fonts/Emoji/Twemoji.ttf"; + public const string AssetPath = "Assets/Fonts/Emoji/Emoji.asset"; + + // Colour outlines (COLRv0) are rasterised at one size; 109 is the strike size a CBDT set needs. + const int SamplingPointSize = 64; + const int AtlasPadding = 4; + const int AtlasSize = 2048; + + // Menu entry for interactive use; -executeMethod EmojiFont.Build for batchmode, exit 1 on failure. + [MenuItem("Aetheria/Text/Build Emoji Font")] + public static void Build() + { + var ok = TryBuild(out var message); + if (ok) Debug.Log(message); else Debug.LogError(message); + if (Application.isBatchMode) EditorApplication.Exit(ok ? 0 : 1); + } + + static bool TryBuild(out string message) + { + var font = AssetDatabase.LoadAssetAtPath(FontPath); + if (font == null) + { + message = $"EmojiFont: {FontPath} is missing; run tools/emoji/fetch_emoji_font.py."; + return false; + } + + // An existing asset keeps its GUID, so a second Build changes nothing the settings point at. + var asset = AssetDatabase.LoadAssetAtPath(AssetPath); + if (asset == null) + { + asset = TMP_FontAsset.CreateFontAsset(font, SamplingPointSize, AtlasPadding, GlyphRenderMode.COLOR, + AtlasSize, AtlasSize, AtlasPopulationMode.Dynamic, enableMultiAtlasSupport: true); + if (asset == null) + { + message = $"EmojiFont: TMP could not create a font asset from {FontPath}."; + return false; + } + asset.name = "Emoji"; + AssetDatabase.CreateAsset(asset, AssetPath); + foreach (var page in asset.atlasTextures) + { + page.name = "Emoji Atlas"; + AssetDatabase.AddObjectToAsset(page, asset); + } + asset.material.name = "Emoji Atlas Material"; + AssetDatabase.AddObjectToAsset(asset.material, asset); + } + + // The atlas pages are cache: Build leaves them empty, the same state EmojiCheck restores. + asset.ClearFontAssetData(true); + + // Two routes: the global fallback serves every code point (text-presentation emoji too, U+263A without FE0F); + // the emoji list is tried first when FE0F follows. + TMP_Settings.emojiFallbackTextAssets = new List { asset }; + TMP_Settings.fallbackFontAssets = new List { asset }; + TMP_Settings.defaultSpriteAsset = null; + + EditorUtility.SetDirty(asset); + EditorUtility.SetDirty(TMP_Settings.instance); + AssetDatabase.SaveAssets(); + message = "EmojiFont: built " + AssetPath + " and named it in both of TMP Settings' emoji routes (the global fallback and the emoji fallback list)."; + return true; + } + + // Menu entry for interactive use; -executeMethod EmojiFont.EnableLigatures for batchmode, exit 1 on failure. + // Idempotent: a second run changes nothing and saves nothing. + [MenuItem("Aetheria/Text/Enable Ligatures")] + public static void EnableLigatures() + { + try + { + var settings = TMP_Settings.fontFeatures; + var settingsChanged = Enable(settings); + if (settingsChanged) EditorUtility.SetDirty(TMP_Settings.instance); + var (files, components) = VisitSerializedTexts(text => + { + var features = text.fontFeatures.ToList(); + if (!Enable(features, new SerializedObject(text).FindProperty("m_enableKerning").boolValue)) return false; + text.fontFeatures = features; + EditorUtility.SetDirty(text); + return true; + }); + AssetDatabase.SaveAssets(); + Debug.Log($"EmojiFont: liga added to {components} TMP component(s) in {files} file(s)" + + (settingsChanged ? " and to TMP Settings." : "; TMP Settings already had it.")); + if (Application.isBatchMode) EditorApplication.Exit(0); + } + catch (Exception e) + { + Debug.LogError("EmojiFont.EnableLigatures failed: " + e); + if (Application.isBatchMode) EditorApplication.Exit(1); + } + } + + // A legacy list ([0], no feature serialized) is first converted to [kern] when kerning is on, as TMP does on load. + static bool Enable(List features, bool kerning = true) + { + if (features.Contains(OTL_FeatureTag.liga)) return false; + features.RemoveAll(tag => tag == 0); + if (kerning && !features.Contains(OTL_FeatureTag.kern)) features.Add(OTL_FeatureTag.kern); + features.Add(OTL_FeatureTag.liga); + return true; + } + + // The one walk over every TMP text a serialized asset owns: each prefab and each scene under Assets/, skipping a + // component that belongs to a prefab instance unless that instance overrides its font features (otherwise it + // inherits from its source prefab, which is walked itself). `visit` returns whether it changed the component; + // an asset that changed is saved. Returns the files and components changed. + public static (int files, int components) VisitSerializedTexts(Func visit) + { + int files = 0, components = 0; + bool Owns(TMP_Text text) => + !PrefabUtility.IsPartOfPrefabInstance(text) || + new SerializedObject(text).FindProperty("m_ActiveFontFeatures")?.prefabOverride == true; + int Visit(IEnumerable texts) => texts.Where(Owns).Count(visit); + + foreach (var path in AssetDatabase.FindAssets("t:Prefab", new[] { "Assets" }).Select(AssetDatabase.GUIDToAssetPath)) + { + var root = PrefabUtility.LoadPrefabContents(path); + try + { + var changed = Visit(root.GetComponentsInChildren(true)); + if (changed == 0) continue; + PrefabUtility.SaveAsPrefabAsset(root, path); + files++; + components += changed; + } + finally { PrefabUtility.UnloadPrefabContents(root); } + } + foreach (var path in AssetDatabase.FindAssets("t:Scene", new[] { "Assets" }).Select(AssetDatabase.GUIDToAssetPath)) + { + var scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Additive); + try + { + var changed = Visit(scene.GetRootGameObjects().SelectMany(root => root.GetComponentsInChildren(true))); + if (changed == 0) continue; + EditorSceneManager.SaveScene(scene); + files++; + components += changed; + } + finally { EditorSceneManager.CloseScene(scene, true); } + } + return (files, components); + } +} diff --git a/Assets/Scripts/Editor/EmojiFont.cs.meta b/Assets/Scripts/Editor/EmojiFont.cs.meta new file mode 100644 index 000000000..5888665c0 --- /dev/null +++ b/Assets/Scripts/Editor/EmojiFont.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: bd3a902defe23f14fbe821ca9fb26a08 \ No newline at end of file diff --git a/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs b/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs new file mode 100644 index 000000000..1caf77b6c --- /dev/null +++ b/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs @@ -0,0 +1,262 @@ +using System; +using System.Collections; +using System.IO; +using System.Linq; +using GameCult.Caching; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using float2 = CultMath.float2; + +// Batch proof that ZoneRenderer draws Zone.FloatingItems and nothing else, in a play session with no scene of its own: +// the pickup prefabs are the ones ARPG.unity's ZoneRenderer names (so the wiring is read here too), a zone is loaded +// into a fresh ZoneRenderer, and the zone's own Release, step, expiry and TryPickUp are what move and remove the +// pickups. Zone.Release adds exactly one ItemPickup, placed at the body's position; stepping the zone moves it with the +// body; expiry and TryPickUp each destroy it; an item already in the zone when the renderer loads it is drawn too. +// +// Unity -batchmode -nographics -projectPath -executeMethod FloatingItemsDrawnSmoke.Run -logFile +// +// Do not pass -quit: Run enters play mode (a domain reload), the check runs there, and the Editor exits itself, 0 on +// success and 1 on any failure. Destroy only takes effect in a play session, which is why this is not an edit-mode check. +[InitializeOnLoad] +public static class FloatingItemsDrawnSmoke +{ + private const string Flag = "FloatingItemsDrawnSmoke.running"; + private const string Wiring = "FloatingItemsDrawnSmoke.wiring"; + private static IEnumerator _check; + private const double Budget = 300; // real seconds: batch frames can be far shorter than a game second + private static double _started; + private static string _work; + + static FloatingItemsDrawnSmoke() + { + if (SessionState.GetBool(Flag, false)) EditorApplication.playModeStateChanged += OnPlayMode; + } + + public static void Run() + { + try + { + SessionState.SetString(Wiring, ReadWiring()); + SessionState.SetBool(Flag, true); + EditorApplication.EnterPlaymode(); + } + catch (Exception exception) + { + Debug.LogException(exception); + EditorApplication.Exit(1); + } + } + + private static void OnPlayMode(PlayModeStateChange change) + { + if (change != PlayModeStateChange.EnteredPlayMode) return; + _work = Path.Combine(Path.GetTempPath(), $"floating-items-smoke-{Guid.NewGuid():N}"); + Directory.CreateDirectory(_work); + _started = Time.realtimeSinceStartupAsDouble; + _check = Check(); + EditorApplication.update += Step; + } + + private static void Step() + { + try + { + if (Time.realtimeSinceStartupAsDouble - _started > Budget) throw new InvalidOperationException($"The check did not finish in {Budget} seconds."); + if (_check.MoveNext()) return; + Finish(0); + } + catch (Exception exception) + { + Debug.LogException(exception); + Finish(1); + } + } + + private static void Finish(int code) + { + EditorApplication.update -= Step; + SessionState.SetBool(Flag, false); + try { if (Directory.Exists(_work)) Directory.Delete(_work, true); } catch (Exception) { /* a temp directory */ } + EditorApplication.Exit(code); + } + + private static void Require(bool condition, string what) + { + if (!condition) throw new InvalidOperationException(what); + } + + private static IEnumerator Check() + { + var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset")?.GameplaySettings + ?? throw new InvalidOperationException("No Settings.asset."); + // A floater rides its own layer: a nonzero one (never saved back to the asset), so a presenter that drops it fails. + settings.FloaterLayerHeight = -1.5f; + + // The wiring: the scene's ZoneRenderer names an ItemPickup prefab in each of the four fields, and none of those + // prefabs keeps a script that no longer exists. + var wired = SessionState.GetString(Wiring, "").Split('|').Select(entry => entry.Split('=')).Select(pair => + (Field: pair[0], Pickup: pair[1] == "" ? null : AssetDatabase.LoadAssetAtPath(pair[1])?.GetComponent())).ToArray(); + Require(wired.Length == 4, "The wiring was not carried into the play session."); + foreach (var (name, pickup) in wired) + { + Require(pickup != null, $"ZoneRenderer.{name} is not an ItemPickup in ARPG.unity."); + Require(pickup.ScanLabel != null && pickup.ScanLabelContainer != null, $"{name}'s prefab has no scan label."); + Require(!pickup.GetComponentsInChildren(true).Any(c => c == null), $"{name}'s prefab has a missing script."); + } + + var shape = new Shape(5, 5); + foreach (var cell in shape.AllCoordinates) shape[cell] = true; + var cargoShape = new Shape(4, 4); + foreach (var cell in cargoShape.AllCoordinates) cargoShape[cell] = true; + var oneCell = new Shape(1, 1); + oneCell[new CultMath.int2(0, 0)] = true; + var cache = AetheriaStores.Open(Path.Combine(_work, "smoke.cc"), catalogWritable: true); + cache.Upsert(new VerseGrammar { Revision = 1 }); + cache.Upsert(new HullData { Name = "Smoke Hub", HullType = HullType.Station, Shape = shape, Durability = 1000, Mass = 1000 }); + cache.Upsert(new CargoBayData { Name = "Smoke Crate", Shape = new Shape(), InteriorShape = cargoShape, Durability = 4 }); + cache.Upsert(new GearData + { + Name = "Smoke Spare", Hardpoint = HardpointType.Tool, Shape = oneCell, Durability = 1, + MinimumTemperature = -1000, MaximumTemperature = 1000, OptimalTemperature = 0, PlateauWidth = 2000 + }); + cache.Upsert(new SimpleCommodityData { Name = "Smoke Ore", Shape = oneCell, MaxStack = 100 }); + cache.FlushAsync().Wait(); + var ledger = new ProvenanceLedger(); + for (var i = 1; i <= 8; i++) ledger.Lots[i] = new Lot { Origin = new Attributed(), Quality = 1 }; + var items = new ItemManager(cache, ledger, settings, _ => { }); + var zone = new Zone(items, new PlanetSettings(), new ZonePack(), null, null); + EquippableItem Make(string name, int lot) => new EquippableItem + { + Data = items.ItemData.RefOf(items.ItemData.GetByName(name)), Durability = 1, Lot = lot + }; + + // A station with a crate takes the picked-up stack. It is not admitted: the zone holds no entity for the renderer to draw. + var hubRef = items.ItemData.RefOf(items.ItemData.GetByName("Smoke Hub")); + var taker = new OrbitalEntity(items, zone, new EquippableItem { Data = hubRef, Durability = 1000, Lot = 1 }, default, new EntitySettings()); + Require(taker.TryEquip(Make("Smoke Crate", 2), new CultMath.int2(1, 1)), "The smoke station took no crate."); + + // An item already in the zone when the renderer loads it: drawn from the load, not only from the add. + var early = zone.Release(Make("Smoke Spare", 3), new float2(5, 6), float2.zero); + + // The renderer's side. Inactive while it is configured, so it runs no Awake or Start of the scene's own. + var rootObject = new GameObject("Smoke Zone Root"); + var rendererObject = new GameObject("Smoke Zone Renderer"); + rendererObject.SetActive(false); + var renderer = rendererObject.AddComponent(); + renderer.ZoneRoot = rootObject.transform; + foreach (var (name, pickup) in wired) + typeof(ZoneRenderer).GetField(name).SetValue(renderer, pickup); + renderer.ItemManager = items; + renderer.SectorBrushes = new GameObject("Smoke Brushes").transform; + renderer.AmbientLight = Aetheria.EditorTools.AmbientEdgeVerify.NewAmbientLight(); + renderer.SlimeGravityCamera = new GameObject("Smoke Gravity Camera").AddComponent(); + var slimeObject = new GameObject("Smoke Slime"); + slimeObject.SetActive(false); // the real Slime needs its compute shader; LoadZone only sets its radius + renderer.SlimeRenderer = slimeObject.AddComponent(); + renderer.LoadZone(zone); + yield return null; + + ItemPickup[] Pickups() => rootObject.GetComponentsInChildren(true).Where(p => p != null).ToArray(); + void At(ItemPickup pickup, FloatingItem floating, string what) + { + var lead = ActionGameManager.Clock.Lead; + var at = DrawAhead.Position(floating.Body, lead); + var want = new Vector3(at.x, DrawAhead.FloaterHeight(zone, settings, at, lead), at.y); + Require(Vector3.Distance(pickup.transform.position, want) < 1e-3f, + $"{what}: the pickup is at {pickup.transform.position}, the body at {want}."); + } + + Require(Pickups().Length == 1, $"load: {Pickups().Length} pickups for one existing floating item."); + At(Pickups()[0], early, "load"); + + // Release adds exactly one pickup, at the body's position, bound to its item. + var ore = new SimpleCommodity { Data = items.ItemData.RefOf(items.ItemData.GetByName("Smoke Ore")), Quantity = 7 }; + var released = zone.Release(ore, new float2(3, 4), new float2(10, 0)); + yield return null; + Require(Pickups().Length == 2, $"release: {Pickups().Length} pickups for two floating items."); + var drawn = Pickups().Single(p => p.Item == ore); + At(drawn, released, "release"); + + // Stepping the zone moves the sim body; the pickup follows it on its next update, with nothing of its own. + var before = drawn.transform.position; + zone.Update(.5f); + yield return null; + Require(released.Body.Position.x > 3.5f, "the sim body did not drift."); + At(drawn, released, "step"); + Require(drawn.transform.position != before, "the pickup did not move with the body."); + + // A held item keeps its label lit, so a pull is read as it happens. The label is let go dark first (nothing views + // it), then the zone holds the item through its own TryHold and the label must come up. + var earlyPickup = Pickups().Single(p => p.Item == early.Item); + earlyPickup.LabelPersistDuration = 1; + earlyPickup.LabelFadeDuration = .2f; + // Game time, not frames: batch frames can be far shorter than a game second, so a frame count can run out before the fade. + var labelUntil = Time.time + earlyPickup.LabelPersistDuration + earlyPickup.LabelFadeDuration + 1f; + while (Time.time < labelUntil && earlyPickup.ScanLabel.color.a > .05f) yield return null; + Require(earlyPickup.ScanLabel.color.a <= .05f, "label: an unviewed, unheld label did not go dark."); + Require(zone.TryHold(taker, early.Id), "label: the zone refused to hold the item."); + labelUntil = Time.time + earlyPickup.LabelPersistDuration + earlyPickup.LabelFadeDuration + 1f; + while (Time.time < labelUntil && earlyPickup.ScanLabel.color.a < .95f) yield return null; + Require(earlyPickup.ScanLabel.color.a >= .95f, "label: a held item's label is not lit."); + + // The test scene's stand-in sim and tendril ride the zone's own held-pose curve: its pose at each point of a grab + // is where the zone puts a held item at the same progress. + var (extend, envelop, pull) = (1.5f, .75f, 1.5f); + var holderAt = new CultMath.float3(taker.Position.x, 0f, taker.Position.z); + var claimedAt = new CultMath.float3(early.HeldFrom.x, 0f, early.HeldFrom.y); + foreach (var elapsed in new[] { 0f, extend + envelop - .01f, extend + envelop + .3f, extend + envelop + .75f, extend + envelop + pull }) + { + zone.SetHeldProgress(early.Id, Mathf.Clamp01((elapsed - extend - envelop) / pull)); // the pull starts after Extend and Envelop + zone.Update(.01f); + var want = FieldTester.PulledPosition(claimedAt, holderAt, elapsed, extend, envelop, pull); + Require(Mathf.Abs(early.Body.Position.x - want.x) < 1e-3f && Mathf.Abs(early.Body.Position.y - want.z) < 1e-3f, + $"stand-in pose at {elapsed}s is {want}, the zone holds the item at {early.Body.Position}."); + } + zone.Free(early.Id); + + // Pickup destroys exactly the picked-up item's pickup. + Require(zone.TryPickUp(taker, released.Id), "the station refused a one-cell stack."); + yield return null; + yield return null; + Require(drawn == null, "pickup: the pickup is still there."); + Require(Pickups().Length == 1 && Pickups()[0].Item == early.Item, "pickup: the wrong pickup went."); + + // Expiry destroys the pickup of an item nobody took. + zone.Update(3600f); // far past any lifetime + yield return null; + yield return null; + Require(zone.FloatingItems.Count == 0, "expiry: the item did not expire."); + Require(Pickups().Length == 0, $"expiry: {Pickups().Length} pickups left."); + + // A later release is drawn again, and clearing the renderer takes what is left. + zone.Release(Make("Smoke Spare", 4), new float2(1, 1), float2.zero); + yield return null; + Require(Pickups().Length == 1, "re-release: not drawn."); + renderer.ClearZone(); + yield return null; + yield return null; + Require(Pickups().Length == 0, "clear: pickups left after ClearZone."); + Debug.Log("FLOATING_ITEMS_SMOKE ok"); + } + + // What ARPG.unity's ZoneRenderer names in each pickup field, read from the saved scene before the play session (a + // scene cannot be opened inside one) and carried across the domain reload as the prefabs' asset paths. + private static string ReadWiring() + { + var scene = EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Additive); + try + { + var found = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None) + .Where(r => r.gameObject.scene == scene).ToArray(); + Require(found.Length == 1, $"ARPG.unity has {found.Length} ZoneRenderers."); + var wired = found[0]; + return string.Join("|", new[] + { + ("SimpleCommodityPickup", wired.SimpleCommodityPickup), ("CompoundCommodityPickup", wired.CompoundCommodityPickup), + ("GearPickup", wired.GearPickup), ("WeaponPickup", wired.WeaponPickup) + }.Select(f => f.Item1 + "=" + (f.Item2 == null ? "" : AssetDatabase.GetAssetPath(f.Item2)))); + } + finally { EditorSceneManager.CloseScene(scene, true); } + } +} diff --git a/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs.meta b/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs.meta new file mode 100644 index 000000000..51e4b34a7 --- /dev/null +++ b/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 67544a932f794a2458741c731ef04d11 \ No newline at end of file diff --git a/Assets/Scripts/Editor/FlowFieldParityVerify.cs b/Assets/Scripts/Editor/FlowFieldParityVerify.cs new file mode 100644 index 000000000..90979f7e8 --- /dev/null +++ b/Assets/Scripts/Editor/FlowFieldParityVerify.cs @@ -0,0 +1,302 @@ +using System; +using System.IO; +using GameCult.Caching; +using UnityEditor; +using UnityEngine; + +namespace Aetheria.EditorTools +{ + /// + /// Batchmode check for flow-shader-parity (campaign aetheria-fauna, cut fauna-flow-field): the HLSL globalFlow and + /// slopeFlow of Assets/Shaders/Volumetric.cginc give the values of FlowField (ServerShared) for the same position, + /// scroll, settings and gradient. It drives the real lowering: a Zone is stepped, VolumeSampling.LowerFlow sets the + /// shader globals from the zone's Settings.Flow and FlowScroll, FlowParity.compute reads those globals, and the + /// results are compared with FlowField. It also checks that Settings.asset carries the authored flow under + /// PlanetSettings and that the shader got the zone's scroll (speed times zone time). + /// + /// Dispatches a compute kernel, so it needs a graphics device: run WITHOUT -nographics (as ShieldPanelCut3Verify). + /// Unity -batchmode -projectPath <repo> -executeMethod Aetheria.EditorTools.FlowFieldParityVerify.Run -logFile <path> + /// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. + /// + public static class FlowFieldParityVerify + { + const string Tag = "[FlowFieldParityVerify]"; + // Measured disagreement between the HLSL and the C# on this tree (float32 on both sides, positions to 10000, + // scrolls to 100, through the keyword-gated flow()): max 2.9e-5 of amplitude (the "max error" line this run + // prints). The tolerance is 5x that noise, so constant errors of 0.05% (y factor .501, swirl or amplitude + // x1.0005: 4e-4 to 8e-4) fail; a 0.01% error is at the noise floor and unresolvable. + const float RelativeTolerance = 1.5e-4f; + static float _maxError; + static bool _ok = true; + + static void OnLog(string message, string stack, LogType type) + { + if ((type == LogType.Error || type == LogType.Exception || type == LogType.Assert) && !message.StartsWith(Tag)) + Fail("logged-error", message.Split('\n')[0]); + } + + static void Fail(string check, string detail) + { + Debug.LogError($"{Tag} FAIL {check}: {detail}"); + _ok = false; + } + + public static void Run() + { + if (SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Null) + { + Debug.LogError($"{Tag} FAIL: no graphics device in this session; rerun batchmode without -nographics."); + EditorApplication.Exit(1); + return; + } + + // The flow's error lines (a shader keyword that does not exist, a missing property) fail the check. + Application.logMessageReceived += OnLog; + var work = Path.Combine(Path.GetTempPath(), "flow-parity-" + Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(work); + try + { + var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset") + ?? throw new InvalidOperationException("No Settings.asset."); + var compute = AssetDatabase.LoadAssetAtPath("Assets/Shaders/Compute/FlowParity.compute") + ?? throw new InvalidOperationException("No FlowParity.compute."); + + CheckAuthoredFlow(settings.PlanetSettings.Flow); + + // The authored flow (global term only: its slope amplitudes are authored zero), then a flow with every + // term live and a scroll speed that reaches scrolls up to 100. + var authored = settings.PlanetSettings.Flow; + CheckParity("authored", settings, work, compute, authored, new[] { 0.0, 3.1, 40.0, 100.0 }); + var wide = new FlowSettings + { + GlobalScale = authored.GlobalScale, GlobalAmplitude = authored.GlobalAmplitude, Period = authored.Period, + GlobalScrollSpeed = 1f, SlopeAmplitude = 3f, SwirlAmplitude = 5f + }; + CheckParity("wide", settings, work, compute, wide, new[] { 0.0, 1.0, 17.0, 60.0, 100.0 }); + CheckNoiseClock(compute); + + Debug.Log($"{Tag} max error {_maxError:G4} of amplitude (tolerance {RelativeTolerance:G4})"); + Debug.Log(_ok ? $"{Tag} PASS" : $"{Tag} FAIL: see errors above"); + } + catch (Exception e) + { + Debug.LogError($"{Tag} FAIL exception: {e}"); + _ok = false; + } + finally + { + Application.logMessageReceived -= OnLog; + try { Directory.Delete(work, true); } catch { } + } + EditorApplication.Exit(_ok ? 0 : 1); + } + + // Settings.asset carries the authored flow under PlanetSettings (it moved from DefaultEnvironment unchanged). + static void CheckAuthoredFlow(FlowSettings flow) + { + if (flow == null) { Fail("authored-flow", "PlanetSettings.Flow is null"); return; } + if (flow.GlobalScale != 512f || flow.GlobalAmplitude != 15f || flow.GlobalScrollSpeed != .025f || + flow.Period != 8f || flow.SlopeAmplitude != 0f || flow.SwirlAmplitude != 0f) + Fail("authored-flow", $"PlanetSettings.Flow is {flow.GlobalScale}/{flow.GlobalAmplitude}/{flow.GlobalScrollSpeed}/" + + $"{flow.Period}/{flow.SlopeAmplitude}/{flow.SwirlAmplitude}, authored 512/15/0.025/8/0/0"); + } + + internal static Zone BuildZone(GameSettings settings, string work, FlowSettings flow, double time = 0) + { + var cache = AetheriaStores.Open(Path.Combine(work, Guid.NewGuid().ToString("N") + ".cc"), catalogWritable: true); + cache.Upsert(new VerseGrammar { Revision = 1 }); + cache.FlushAsync().Wait(); + var items = new ItemManager(cache, new ProvenanceLedger(), settings.GameplaySettings, _ => { }); + return new Zone(items, new PlanetSettings { Flow = flow }, new ZonePack { Time = time }, new GalaxyZone { Name = "Parity", Owner = null }, null); + } + + static void CheckParity(string label, GameSettings settings, string work, ComputeShader compute, FlowSettings flow, + double[] zoneTimes) + { + var zone = BuildZone(settings, work, flow); + var kernel = compute.FindKernel("Evaluate"); + var rng = new System.Random(label.Length * 7919); + const int positionCount = 256, gradientCount = 64; + const int count = positionCount; + + var positions = new Vector3[count]; + for (var i = 0; i < positionCount; i++) + positions[i] = new Vector3((float) (rng.NextDouble() * 20000 - 10000), (float) (rng.NextDouble() * 200 - 100), + (float) (rng.NextDouble() * 20000 - 10000)); + // Gradients of any direction and magnitude, plus one zero gradient. + var gradients = new Vector2[count]; + for (var i = 1; i < gradientCount; i++) + { + var angle = rng.NextDouble() * Math.PI * 2; + var magnitude = (float) Math.Exp(rng.NextDouble() * 8 - 4); + gradients[i] = new Vector2((float) Math.Cos(angle) * magnitude, (float) Math.Sin(angle) * magnitude); + } + gradients[0] = Vector2.zero; + + var positionBuffer = new ComputeBuffer(count, 12); + var gradientBuffer = new ComputeBuffer(count, 8); + var globalBuffer = new ComputeBuffer(count, 12); + var slopeBuffer = new ComputeBuffer(count, 12); + var gatedBuffer = new ComputeBuffer(count, 12); + ComputeBuffer noiseBuffer = null; + // flow() reads the nebula's gravity height under FLOW_SLOPE. A ramp rising along the texture's x gives every + // position inside the grid the gradient direction (1, 0), so the slope term is live where a flat height + // would zero it (and the FLOW_SLOPE keyword and its pragma would not matter). + const int rampSize = 64; + var height = new Texture2D(rampSize, rampSize, TextureFormat.RFloat, false) + { filterMode = FilterMode.Point, wrapMode = TextureWrapMode.Clamp }; + var ramp = new float[rampSize * rampSize]; + for (var i = 0; i < ramp.Length; i++) ramp[i] = (i % rampSize) / (float) (rampSize - 1); + height.SetPixelData(ramp, 0); + height.Apply(); + var rampGradient = new CultMath.float2(1f, 0f); + try + { + positionBuffer.SetData(positions); + gradientBuffer.SetData(gradients); + compute.SetBuffer(kernel, "positions", positionBuffer); + compute.SetBuffer(kernel, "gradients", gradientBuffer); + compute.SetBuffer(kernel, "globalOut", globalBuffer); + compute.SetBuffer(kernel, "slopeOut", slopeBuffer); + compute.SetBuffer(kernel, "gatedOut", gatedBuffer); + compute.SetTexture(kernel, "_NebulaSurfaceHeight", height); + compute.SetVector("_NebulaSurfaceHeight_TexelSize", new Vector4(1f / rampSize, 1f / rampSize, rampSize, rampSize)); + // The grid spans 40000: every sampled position (|xz| to 10000) is inside the ramp's uv range. + Shader.SetGlobalVector("_GridTransform", new Vector4(0f, 0f, 40000f, 0f)); + noiseBuffer = new ComputeBuffer(count, 4); + compute.SetBuffer(kernel, "noiseOut", noiseBuffer); + compute.SetInt("count", count); + + var elapsed = 0.0; + foreach (var target in zoneTimes) + { + // Step the zone to the target by an awkward step; the sum is the zone's time. + while (elapsed < target - 1e-9) + { + var dt = (float) Math.Min(0.37, target - elapsed); + zone.Update(dt); + elapsed += dt; + } + VolumeSampling.LowerFlow(zone.Settings.Flow, zone.ExactTime); + + // The shader got the zone's scroll and cycle: the same zone time Zone.Flow evaluates at. + var zoneScroll = zone.FlowScroll; + var lowered = Shader.GetGlobalVector("_FlowScroll"); + if (Math.Abs(lowered.x - zoneScroll.x) > 1e-6 || Math.Abs(lowered.y - zoneScroll.y) > 1e-6) + Fail($"{label}-lowered-scroll", $"at zone time {elapsed:F3} the shader got _FlowScroll ({lowered.x}, {lowered.y}), the zone's is ({zoneScroll.x}, {zoneScroll.y})"); + if (Math.Abs(Shader.GetGlobalFloat("_FlowCycle") - zone.CyclePhase(flow.Period)) > 1e-6) + Fail($"{label}-lowered-cycle", $"at zone time {elapsed:F3} the shader got _FlowCycle {Shader.GetGlobalFloat("_FlowCycle")}, the zone's phase is {zone.CyclePhase(flow.Period)}"); + if (Shader.GetGlobalFloat("_FlowScale") != flow.GlobalScale || Shader.GetGlobalFloat("_FlowAmplitude") != flow.GlobalAmplitude || + Shader.GetGlobalFloat("_FlowSlopeAmplitude") != flow.SlopeAmplitude || + Shader.GetGlobalFloat("_FlowSwirlAmplitude") != flow.SwirlAmplitude || Shader.GetGlobalFloat("_FlowPeriod") != flow.Period) + Fail($"{label}-lowered-settings", "a flow uniform does not equal the zone's FlowSettings"); + + compute.Dispatch(kernel, (count + 63) / 64, 1, 1); + var globalOut = new Vector3[count]; + var slopeOut = new Vector3[count]; + var gatedOut = new Vector3[count]; + globalBuffer.GetData(globalOut); + slopeBuffer.GetData(slopeOut); + gatedBuffer.GetData(gatedOut); + + var at = $"{label} zone time {elapsed:F2} scroll {zoneScroll.x:F4}"; + for (var i = 0; i < positionCount; i++) + { + var p = positions[i]; + var expected = FlowField.Global(flow, new CultMath.float3(p.x, p.y, p.z), zoneScroll); + Compare($"{label}-global", at, i, new Vector3(expected.x, expected.y, expected.z), globalOut[i], flow.GlobalAmplitude); + } + // flow() is the keyword-gated function the nebula and stardust call: the global term plus, under + // FLOW_SLOPE, the slope term of the ramp's gradient. A flow that is live must not read zero. + var live = 0; + var gatedScale = Math.Max(Math.Abs(flow.GlobalAmplitude), Math.Max(Math.Abs(flow.SlopeAmplitude), Math.Abs(flow.SwirlAmplitude))); + for (var i = 0; i < positionCount; i++) + { + var p = positions[i]; + var expected = FlowField.At(flow, new CultMath.float3(p.x, p.y, p.z), zoneScroll, rampGradient); + var e = new Vector3(expected.x, expected.y, expected.z); + if (e.magnitude > .1f * gatedScale) live++; + Compare($"{label}-flow-keywords", at, i, e, gatedOut[i], gatedScale); + } + if (gatedScale != 0f && live < positionCount / 4) + Fail($"{label}-flow-keywords", $"{at}: only {live} of {positionCount} zone flows are live; the check is vacuous"); + var slopeScale = Math.Max(Math.Abs(flow.SlopeAmplitude), Math.Abs(flow.SwirlAmplitude)); + for (var i = 0; i < gradientCount; i++) + { + var g = gradients[i]; + var expected = FlowField.Slope(flow, new CultMath.float2(g.x, g.y)); + Compare($"{label}-slope", at, i, new Vector3(expected.x, expected.y, expected.z), slopeOut[i], slopeScale); + } + } + } + finally + { + positionBuffer.Release(); gradientBuffer.Release(); globalBuffer.Release(); slopeBuffer.Release(); gatedBuffer.Release(); noiseBuffer?.Release(); UnityEngine.Object.DestroyImmediate(height); + } + } + + // The nebula noise the flow advects evolves on the flow clock VolumeSampling lowers as _NebulaNoiseTime, never on + // _Time: with the speed non-zero, the noise changes when _NebulaNoiseTime does and not otherwise (a frame clock + // would not follow the global set here). + static void CheckNoiseClock(ComputeShader compute) + { + const int count = 64; + var kernel = compute.FindKernel("Evaluate"); + var rng = new System.Random(4217); + var positions = new Vector3[count]; + for (var i = 0; i < count; i++) + positions[i] = new Vector3((float) (rng.NextDouble() * 4000 - 2000), (float) (rng.NextDouble() * 100 - 50), (float) (rng.NextDouble() * 4000 - 2000)); + var buffers = new[] { new ComputeBuffer(count, 12), new ComputeBuffer(count, 8), new ComputeBuffer(count, 12), new ComputeBuffer(count, 12), new ComputeBuffer(count, 12), new ComputeBuffer(count, 4) }; + var height = new Texture2D(1, 1, TextureFormat.RFloat, false); + try + { + buffers[0].SetData(positions); + buffers[1].SetData(new Vector2[count]); + compute.SetBuffer(kernel, "positions", buffers[0]); + compute.SetBuffer(kernel, "gradients", buffers[1]); + compute.SetBuffer(kernel, "globalOut", buffers[2]); + compute.SetBuffer(kernel, "slopeOut", buffers[3]); + compute.SetBuffer(kernel, "gatedOut", buffers[4]); + compute.SetBuffer(kernel, "noiseOut", buffers[5]); + compute.SetTexture(kernel, "_NebulaSurfaceHeight", height); + compute.SetInt("count", count); + Shader.SetGlobalFloat("_NebulaNoiseSpeed", 1f); + float[] Noise(float noiseTime) + { + Shader.SetGlobalFloat("_NebulaNoiseTime", noiseTime); + compute.Dispatch(kernel, 1, 1, 1); + var result = new float[count]; + buffers[5].GetData(result); + return result; + } + var a = Noise(0f); + var b = Noise(3f); + var again = Noise(3f); + int moved = 0, repeated = 0; + for (var i = 0; i < count; i++) + { + if (Math.Abs(a[i] - b[i]) > 1e-4f) moved++; + if (b[i] == again[i]) repeated++; + } + if (moved < count / 2) Fail("nebula-noise-clock", $"only {moved} of {count} noise samples follow _NebulaNoiseTime"); + if (repeated != count) Fail("nebula-noise-clock", $"{count - repeated} of {count} noise samples changed with _NebulaNoiseTime held"); + } + finally + { + foreach (var buffer in buffers) buffer.Release(); + UnityEngine.Object.DestroyImmediate(height); + } + } + + // Error is measured against the term's amplitude; a term with no amplitude must be exactly zero and never NaN. + static void Compare(string check, string at, int index, Vector3 expected, Vector3 actual, float amplitude) + { + var error = (expected - actual).magnitude; + if (float.IsNaN(error)) { Fail(check, $"{at} sample {index}: NaN (expected {expected}, shader {actual})"); return; } + if (amplitude != 0f) _maxError = Math.Max(_maxError, error / Math.Abs(amplitude)); + var tolerance = RelativeTolerance * Math.Abs(amplitude); + if (error > tolerance) + Fail(check, $"{at} sample {index}: expected {expected}, shader {actual}, error {error:G4} > {tolerance:G4}"); + } + } +} diff --git a/Assets/Scripts/Editor/FlowFieldParityVerify.cs.meta b/Assets/Scripts/Editor/FlowFieldParityVerify.cs.meta new file mode 100644 index 000000000..50248c5f3 --- /dev/null +++ b/Assets/Scripts/Editor/FlowFieldParityVerify.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 8fae18f5f32f10f43ba892a097f18caa \ No newline at end of file diff --git a/Assets/Scripts/Editor/FlowFieldSceneVerify.cs b/Assets/Scripts/Editor/FlowFieldSceneVerify.cs new file mode 100644 index 000000000..d39874f33 --- /dev/null +++ b/Assets/Scripts/Editor/FlowFieldSceneVerify.cs @@ -0,0 +1,392 @@ +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.Rendering; + +namespace Aetheria.EditorTools +{ + /// + /// Batchmode check for the flow as the scene runs it (campaign aetheria-fauna, cut fauna-flow-field; target + /// invariants flow-one-owner and flow-shader-parity). FlowFieldParityVerify proves the HLSL against FlowField with + /// no scene loaded; this opens ARPG.unity, lets VolumeSampling and Stardust initialise as the game does, drives + /// their own Start and Update with a zone attached, and asserts what the presenters did: + /// - nothing threw and nothing logged an error (a type that cannot initialise in a scene, as VolumeSampling once + /// could when it created its keywords in a static field initializer, throws on its first use); + /// - FLOW_GLOBAL and FLOW_SLOPE are enabled, _FlowAmplitude is the zone's, and the nebula noise clock is the zone's; + /// - the stardust particle buffer changes with the flow and freezes when the zone pauses; + /// - CloudShader pass 0 carries the FLOW_* keywords. + /// The scene is opened before any Aetheria type is touched: run this method alone in its own Unity session, never + /// after FlowFieldParityVerify (which would initialise VolumeSampling outside a MonoBehaviour constructor). + /// Dispatches compute and renders, so it needs a graphics device: run WITHOUT -nographics. + /// Unity -batchmode -projectPath <repo> -executeMethod Aetheria.EditorTools.FlowFieldSceneVerify.Run -logFile <path> + /// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. + /// + public static class FlowFieldSceneVerify + { + const string Tag = "[FlowFieldSceneVerify]"; + static bool _ok = true; + + static void OnLog(string message, string stack, LogType type) + { + if ((type == LogType.Error || type == LogType.Exception || type == LogType.Assert) && !message.StartsWith(Tag)) + Fail("logged-error", message.Split('\n')[0]); + } + + static void Fail(string check, string detail) + { + Debug.LogError($"{Tag} FAIL {check}: {detail}"); + _ok = false; + } + + public static void Run() + { + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) + { + Debug.LogError($"{Tag} FAIL: no graphics device in this session; rerun batchmode without -nographics."); + EditorApplication.Exit(1); + return; + } + + Application.logMessageReceived += OnLog; + try + { + // Before anything else touches the project's types: the scene constructs its MonoBehaviours here. + EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Single); + Check(); + Debug.Log(_ok ? $"{Tag} PASS" : $"{Tag} FAIL: see errors above"); + } + catch (Exception e) + { + Debug.LogError($"{Tag} FAIL exception: {e}"); + _ok = false; + } + finally + { + Application.logMessageReceived -= OnLog; + } + EditorApplication.Exit(_ok ? 0 : 1); + } + + static void Check() + { + var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset") + ?? throw new InvalidOperationException("No Settings.asset."); + var agm = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None).FirstOrDefault(); + var volume = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None).FirstOrDefault(); + var dust = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None).FirstOrDefault(); + if (agm == null || volume == null || dust == null) + { + Fail("scene-objects", $"ARPG.unity has ActionGameManager={agm != null}, VolumeSampling={volume != null}, Stardust={dust != null}"); + return; + } + + // Every flow term live, so FLOW_SLOPE is on; and the same flow with every amplitude zero. + var on = new FlowSettings + { + GlobalScale = 512f, GlobalAmplitude = 15f, GlobalScrollSpeed = .025f, Period = 8f, SlopeAmplitude = 3f, SwirlAmplitude = 5f + }; + var off = new FlowSettings { GlobalScale = on.GlobalScale, GlobalScrollSpeed = on.GlobalScrollSpeed, Period = on.Period }; + var work = Path.Combine(Path.GetTempPath(), "flow-scene-" + Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(work); + try + { + var zone = FlowFieldParityVerify.BuildZone(settings, work, on, 86400.0 * 3 + 12.3); + typeof(ActionGameManager).GetProperty("Instance").GetSetMethod(true).Invoke(null, new object[] { agm }); + typeof(ActionGameManager).GetProperty("Zone").GetSetMethod(true).Invoke(agm, new object[] { zone }); + if (agm.Settings == null) agm.Settings = settings; + + Call(volume, "Start"); + Call(volume, "Update"); + if (!Shader.IsKeywordEnabled("FLOW_GLOBAL")) Fail("scene-keywords", "FLOW_GLOBAL is not enabled after VolumeSampling.Update"); + if (!Shader.IsKeywordEnabled("FLOW_SLOPE")) Fail("scene-keywords", "FLOW_SLOPE is not enabled after VolumeSampling.Update"); + if (Shader.GetGlobalFloat("_FlowAmplitude") != on.GlobalAmplitude) + Fail("scene-amplitude", $"_FlowAmplitude is {Shader.GetGlobalFloat("_FlowAmplitude")}, the zone's flow has {on.GlobalAmplitude}"); + var scroll = Shader.GetGlobalVector("_FlowScroll"); + if (scroll.x != zone.FlowScroll.x || scroll.y != zone.FlowScroll.y) + Fail("scene-scroll", $"_FlowScroll ({scroll.x}, {scroll.y}) is not the zone's ({zone.FlowScroll.x}, {zone.FlowScroll.y})"); + var noiseTime = Shader.GetGlobalFloat("_NebulaNoiseTime"); + if (noiseTime != (float) zone.ExactTime) + Fail("scene-noise-clock", $"_NebulaNoiseTime is {noiseTime}, the zone's time is {(float) zone.ExactTime}"); + + CheckCloudKeywords(); + + // Stardust follows the flow through its own dispatch: the particle buffer read back each frame. + Call(dust, "Start"); + var bufferField = typeof(Stardust).GetField("_particlesBuffer", BindingFlags.NonPublic | BindingFlags.Instance); + float[] Frame() + { + Call(dust, "Update"); + var buffer = (ComputeBuffer) bufferField.GetValue(dust); + var data = new float[buffer.count * 7]; + buffer.GetData(data); + return data; + } + var flowing = Frame(); + VolumeSampling.LowerFlow(off, VolumeSampling.FlowClock); + var still = Frame(); + if (Differing(flowing, still) == 0) Fail("scene-stardust", "the particle buffer is the same with the zone's flow and with no flow"); + + // A paused zone freezes the particles and the nebula noise clock; a running one moves both. + Call(volume, "Update"); + zone.Update(0f); + Call(volume, "Update"); + if (Differing(flowing, Frame()) != 0) Fail("scene-stardust-pause", "the particle buffer moved while the zone was paused"); + if (Shader.GetGlobalFloat("_NebulaNoiseTime") != noiseTime) Fail("scene-noise-clock", "_NebulaNoiseTime moved while the zone was paused"); + zone.Update(.05f); + Call(volume, "Update"); + if (Differing(flowing, Frame()) == 0) Fail("scene-stardust-run", "the particle buffer did not move while the zone ran"); + if (Shader.GetGlobalFloat("_NebulaNoiseTime") == noiseTime) Fail("scene-noise-clock", "_NebulaNoiseTime did not move while the zone ran"); + + CheckStardustUncullable(dust, bufferField); + CheckStardustUnderFog(dust, bufferField); + } + finally + { + try { Directory.Delete(work, true); } catch { } + } + } + + // The event Stardust itself attaches its draw at, read from the class so the verifier cannot agree with a copy of it. + static CameraEvent DrawEvent() => + (CameraEvent) typeof(Stardust).GetField("DrawEvent", BindingFlags.NonPublic | BindingFlags.Static).GetRawConstantValue(); + + // The dust is a command buffer on the target camera, which no culling sees: with every particle 10000 below the + // camera (far past any box a hand could inflate round it) a render still shows dust, and shows none when the + // same particles have no size. + static void CheckStardustUncullable(Stardust dust, FieldInfo bufferField) + { + var camera = dust.TargetCamera; + if (camera == null) { Fail("scene-stardust-uncullable", "Stardust has no TargetCamera"); return; } + var drawEvent = DrawEvent(); + var attached = camera.GetCommandBuffers(drawEvent).Count(buffer => buffer.name == "Stardust"); + if (attached != 1) Fail("scene-stardust-uncullable", $"{attached} Stardust command buffers at {drawEvent} on the target camera, expected 1"); + foreach (var other in Enum.GetValues(typeof(CameraEvent)).Cast().Where(other => other != drawEvent)) + { + var stray = camera.GetCommandBuffers(other).Count(buffer => buffer.name == "Stardust"); + if (stray != 0) Fail("scene-stardust-uncullable", $"{stray} Stardust command buffers at {other}, expected 0"); + } + + var particles = (ComputeBuffer) bufferField.GetValue(dust); + float[] Layout(float size, Vector3 centre, float below) => DustLayout(particles.count, size, centre, below); + + var transform = camera.transform; + var (position, rotation) = (transform.position, transform.rotation); + var (far, flags, background, mask, target) = (camera.farClipPlane, camera.clearFlags, camera.backgroundColor, camera.cullingMask, camera.targetTexture); + var texture = RenderTexture.GetTemporary(64, 64, 24, RenderTextureFormat.ARGB32); + var readback = new Texture2D(64, 64, TextureFormat.RGBA32, false); + var previous = RenderTexture.active; + // Image effects on the camera would write their own frame over the dust; only the dust draw is under test. + var effects = camera.GetComponents().Where(behaviour => behaviour.enabled).ToArray(); + Color32[] Render(float size, Vector3 centre, float below) + { + Call(dust, "Update"); // on a bounded draw this queues the draw for the camera; here it dispatches the compute + particles.SetData(Layout(size, centre, below)); + camera.Render(); + RenderTexture.active = texture; + readback.ReadPixels(new Rect(0, 0, 64, 64), 0, 0); + readback.Apply(); + return readback.GetPixels32(); + } + try + { + foreach (var effect in effects) effect.enabled = false; + camera.clearFlags = CameraClearFlags.SolidColor; + camera.backgroundColor = Color.black; + camera.cullingMask = 1; + camera.targetTexture = texture; + // control: the camera where the scene put it, dust 100 below, inside any box a hand-set extent would give + transform.SetPositionAndRotation(position, Quaternion.Euler(90f, 0f, 0f)); + camera.farClipPlane = 1000f; + var nearWith = Render(5f, position, 100f); var nearWithout = Render(0f, position, 100f); + var nearDiff = 0; for (var i = 0; i < nearWith.Length; i++) if (!nearWith[i].Equals(nearWithout[i])) nearDiff++; + Debug.Log($"{Tag} stardust near-control differing pixels={nearDiff}"); + if (nearDiff == 0) Fail("scene-stardust-uncullable", "control: dust 100 below the camera drew no pixels"); + transform.SetPositionAndRotation(new Vector3(0f, -40000f, 0f), Quaternion.Euler(90f, 0f, 0f)); + camera.farClipPlane = 30000f; + var withDust = Render(400f, transform.position, 10000f); // the material scales a quad by distance^.33, so at this range it needs this size to cover pixels + var without = Render(0f, transform.position, 10000f); + var differing = 0; + for (var i = 0; i < withDust.Length; i++) + if (!withDust[i].Equals(without[i])) differing++; + if (differing == 0) Fail("scene-stardust-uncullable", "the dust 10000 below the camera drew no pixels"); + } + finally + { + RenderTexture.active = previous; + foreach (var effect in effects) effect.enabled = true; + camera.targetTexture = target; + camera.cullingMask = mask; + camera.backgroundColor = background; + camera.clearFlags = flags; + camera.farClipPlane = far; + transform.SetPositionAndRotation(position, rotation); + RenderTexture.ReleaseTemporary(texture); + UnityEngine.Object.DestroyImmediate(readback); + } + } + + // The nebula is an [ImageEffectOpaque] that fogs the whole ray to a depth the dust never writes (B49): dust drawn + // before it is attenuated by the fog, dust drawn after it sits on top at full strength. The dust's contribution to a + // pixel (render with dust minus render without) is read with the cloud renderer off and on, in an HDR target. + static void CheckStardustUnderFog(Stardust dust, FieldInfo bufferField) + { + const int Size = 128; + var camera = dust.TargetCamera; + var cloud = camera == null ? null : camera.GetComponent(); + if (cloud == null) { Fail("scene-stardust-under-fog", "the target camera has no VolumeCloudRenderer"); return; } + var particles = (ComputeBuffer) bufferField.GetValue(dust); + + var transform = camera.transform; + var (position, rotation) = (transform.position, transform.rotation); + var (far, flags, background, mask, target, hdr) = (camera.farClipPlane, camera.clearFlags, camera.backgroundColor, camera.cullingMask, camera.targetTexture, camera.allowHDR); + var texture = RenderTexture.GetTemporary(Size, Size, 24, RenderTextureFormat.ARGBHalf); + var readback = new Texture2D(Size, Size, TextureFormat.RGBAHalf, false); + var previous = RenderTexture.active; + var effects = camera.GetComponents().Where(behaviour => behaviour.enabled).ToArray(); + var fields = new System.Collections.Generic.List(); + GameObject floor = null; + float[] Render(bool fog, float size) + { + cloud.enabled = fog; + for (var frame = 0; frame < 2; frame++) // the cloud's first frame forces ULTRA and fills its history; the second is the settled one + { + Call(dust, "Update"); + particles.SetData(DustLayout(particles.count, size, position, 100f)); + camera.Render(); + } + RenderTexture.active = texture; + readback.ReadPixels(new Rect(0, 0, Size, Size), 0, 0); + readback.Apply(); + return readback.GetPixels().Select(pixel => pixel.r * .2126f + pixel.g * .7152f + pixel.b * .0722f).ToArray(); + } + try + { + foreach (var effect in effects) effect.enabled = false; + camera.allowHDR = true; + camera.clearFlags = CameraClearFlags.SolidColor; + camera.backgroundColor = Color.black; + camera.cullingMask = 1; + camera.targetTexture = texture; + camera.farClipPlane = 1000f; + transform.SetPositionAndRotation(position, Quaternion.Euler(90f, 0f, 0f)); + // The fog only measures a partial density where depth is written: a pixel with no depth is fogged whole (CloudShader sets + // density 1 past the far plane). A floor under the dust gives the march a finite ray. + floor = GameObject.CreatePrimitive(PrimitiveType.Plane); + floor.transform.position = position + Vector3.down * 200f; + floor.transform.localScale = Vector3.one * 100f; + UnityEngine.Object.DestroyImmediate(floor.GetComponent()); + + // The scene's own nebula fields are textures the game renders; here a uniform fill of white fog stands in for them. + foreach (var (name, format) in new[] { ("_NebulaSurfaceHeight", TextureFormat.RFloat), ("_NebulaPatchHeight", TextureFormat.RHalf), ("_NebulaPatch", TextureFormat.RHalf) }) + Shader.SetGlobalTexture(name, Uniform(format, Color.black, fields)); + Shader.SetGlobalTexture("_NebulaTint", Uniform(TextureFormat.RGBA32, Color.white, fields)); + Shader.DisableKeyword("NOISE_SLOPE"); + Shader.SetGlobalFloat("_NebulaFillDensity", .01f); + Shader.SetGlobalFloat("_NebulaFillDistance", 120f); + Shader.SetGlobalFloat("_NebulaFillExponent", 0f); + Shader.SetGlobalFloat("_NebulaFillOffset", 0f); + Shader.SetGlobalFloat("_NebulaPatchDensity", 0f); + Shader.SetGlobalFloat("_NebulaLuminance", .01f); // a fog dimmer than the dust: dust drawn over it would otherwise read as a negative contribution + Shader.SetGlobalFloat("_ExtinctionCoefficient", .25f); // with the fill density, about 40% of the light to the floor is fogged away + Shader.SetGlobalFloat("_SafetyDistance", -1e6f); // below every sample: only the uniform fill, none of the zone's noise + Shader.SetGlobalFloat("_TintLodExponent", 0f); + + var clearBare = Render(false, 0f); + var clearDust = Render(false, 5f); + var fogBare = Render(true, 0f); + var fogDust = Render(true, 5f); + + var fogShown = 0f; + var (clearSum, fogSum, drawn) = (0f, 0f, 0); + for (var i = 0; i < clearBare.Length; i++) + { + fogShown += Mathf.Abs(fogBare[i] - clearBare[i]) / clearBare.Length; + if (clearDust[i] == clearBare[i]) continue; + drawn++; clearSum += clearDust[i] - clearBare[i]; fogSum += fogDust[i] - fogBare[i]; + } + var (clearMean, fogMean) = (drawn == 0 ? 0f : clearSum / drawn, drawn == 0 ? 0f : fogSum / drawn); + Debug.Log($"{Tag} stardust under fog: fog control mean |difference|={fogShown}, dust pixels={drawn}, dust contribution cloud off={clearMean}, cloud on={fogMean}, ratio={(clearMean == 0f ? 0f : fogMean / clearMean)}"); + if (drawn == 0 || clearMean <= 0f) Fail("scene-stardust-under-fog", "control: the dust drew no pixels with the cloud renderer off"); + else if (fogShown < 1e-3f) Fail("scene-stardust-under-fog", "control: the cloud renderer changed no pixels, so no fog is in view"); + else if (fogMean > .9f * clearMean) Fail("scene-stardust-under-fog", "the dust is not attenuated by the fog in front of it: it was drawn after the nebula composites"); + else if (fogMean < .1f * clearMean) Fail("scene-stardust-under-fog", "the dust is erased, not dimmed, by a partial fog"); + } + finally + { + RenderTexture.active = previous; + foreach (var effect in effects) effect.enabled = true; + camera.allowHDR = hdr; + camera.targetTexture = target; + camera.cullingMask = mask; + camera.backgroundColor = background; + camera.clearFlags = flags; + camera.farClipPlane = far; + transform.SetPositionAndRotation(position, rotation); + RenderTexture.ReleaseTemporary(texture); + UnityEngine.Object.DestroyImmediate(readback); + foreach (var field in fields) UnityEngine.Object.DestroyImmediate(field); + if (floor != null) UnityEngine.Object.DestroyImmediate(floor); + } + } + + static Texture2D Uniform(TextureFormat format, Color colour, System.Collections.Generic.List owner) + { + var texture = new Texture2D(1, 1, format, false) { wrapMode = TextureWrapMode.Clamp }; + texture.SetPixel(0, 0, colour); + texture.Apply(); + owner.Add(texture); + return texture; + } + + // A square patch of particles 4 apart, `below` under `centre`. + static float[] DustLayout(int count, float size, Vector3 centre, float below) + { + var side = Mathf.RoundToInt(Mathf.Sqrt(count)); + var data = new float[count * 7]; + for (var i = 0; i < count; i++) + { + data[i * 7 + 0] = centre.x + ((i % side) - side / 2f) * 4f; + data[i * 7 + 1] = centre.y - below; + data[i * 7 + 2] = centre.z + ((i / side) - side / 2f) * 4f; + data[i * 7 + 3] = data[i * 7 + 4] = data[i * 7 + 5] = 1f; + data[i * 7 + 6] = size; + } + return data; + } + + // CloudShader's pass 0 compiles with the flow keywords (it must #include_with_pragmas the shared include). + static void CheckCloudKeywords() + { + var shader = AssetDatabase.LoadAssetAtPath("Assets/Shaders/Raymarching/CloudShader.shader"); + if (shader == null) { Fail("scene-cloud-keywords", "No CloudShader.shader."); return; } + var keywords = ShaderUtil.GetPassKeywords(shader, new PassIdentifier(0, 0), UnityEditor.Rendering.ShaderType.Fragment) + .Select(keyword => keyword.name).ToArray(); + foreach (var name in new[] { "FLOW_GLOBAL", "FLOW_SLOPE" }) + if (!keywords.Contains(name)) Fail("scene-cloud-keywords", $"CloudShader pass 0 does not carry {name}"); + } + + static int Differing(float[] a, float[] b) + { + var count = 0; + for (var i = 0; i < a.Length; i++) + if (Math.Abs(a[i] - b[i]) > 1e-4f) count++; + return count; + } + + // The presenters' own Start and Update, as the game calls them; an exception is a failure that names the type. + static void Call(object target, string method) + { + var info = target.GetType().GetMethod(method, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + if (info == null) { Fail("scene-presenter-exception", $"{target.GetType().Name}.{method} not found"); return; } + try { info.Invoke(target, null); } + catch (TargetInvocationException e) + { + Fail("scene-presenter-exception", $"{target.GetType().Name}.{method} threw {e.InnerException?.GetType().Name}"); + } + } + } +} diff --git a/Assets/Scripts/Editor/FlowFieldSceneVerify.cs.meta b/Assets/Scripts/Editor/FlowFieldSceneVerify.cs.meta new file mode 100644 index 000000000..77339880b --- /dev/null +++ b/Assets/Scripts/Editor/FlowFieldSceneVerify.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 25fbd79fca1de49498c3bebf9f63243b \ No newline at end of file diff --git a/Assets/Scripts/Editor/GravityFieldParityVerify.cs b/Assets/Scripts/Editor/GravityFieldParityVerify.cs new file mode 100644 index 000000000..1753b95ab --- /dev/null +++ b/Assets/Scripts/Editor/GravityFieldParityVerify.cs @@ -0,0 +1,367 @@ +using System; +using System.IO; +using System.Linq; +using GameCult.Caching; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.Rendering; +using CultMath; + +namespace Aetheria.EditorTools +{ + /// + /// Batchmode check for campaign aetheria-gravity, cut grid-lowering: what the Gravity Field pass draws is the sim's + /// height. It builds a zone from Settings.asset's PlanetSettings with three bodies, runs the real lowering + /// (GravityLowering.Lower and CreateField), renders the field through an orthographic camera that culls layer 9 into + /// a float target, and compares every texel with -Zone.GetHeight at the texel centre's world position. It then checks + /// that the texture's gradient points where Zone.GetForce does, and that ARPG.unity and the body prefabs are wired + /// the way the cut leaves them (the gravity cameras cull layer 9 alone, nothing but the run-time field sits on it). + /// + /// Renders, so it needs a graphics device: run WITHOUT -nographics (as FlowFieldParityVerify). + /// Unity -batchmode -projectPath <repo> -executeMethod Aetheria.EditorTools.GravityFieldParityVerify.Run -logFile <path> + /// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. + /// + public static class GravityFieldParityVerify + { + const string Tag = "[GravityFieldParityVerify]"; + const int Size = 256; + // Measured on this tree (the "max error" line this run prints): the largest |texel + GetHeight| over the windows of the three + // frames and windows is 0.0065 u, in the last frame's planetoid window (float32 on both sides, the GPU's log against the CPU's, the + // quad's interpolated world position). The tolerance is 4.6x that. A 0.1% error in the tail constant (.5 -> .501) + // moves the drawn height by 0.053 u where all three tails reach (the planetoid and zone windows), 1.8x the + // tolerance; a reference of zero moves it by about 150 u. + const float Tolerance = 0.03f; + // The worst angle between the texture's central difference and GetForce (B28: 1.0 degrees median zone, 2.9 worst). + const float GradientDegrees = 3f; + static float _maxError, _maxAngle; + static bool _ok = true; + + static void OnLog(string message, string stack, LogType type) + { + if ((type == LogType.Error || type == LogType.Exception || type == LogType.Assert) && !message.StartsWith(Tag)) + Fail("logged-error", message.Split('\n')[0]); + } + + static void Fail(string check, string detail) + { + Debug.LogError($"{Tag} FAIL {check}: {detail}"); + _ok = false; + } + + public static void Run() + { + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) + { + Debug.LogError($"{Tag} FAIL: no graphics device in this session; rerun batchmode without -nographics."); + EditorApplication.Exit(1); + return; + } + + Application.logMessageReceived += OnLog; + var work = Path.Combine(Path.GetTempPath(), "gravity-parity-" + Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(work); + ComputeBuffer wells = null; + GameObject field = null; + try + { + var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset") + ?? throw new InvalidOperationException("No Settings.asset."); + var material = AssetDatabase.LoadAssetAtPath("Assets/Materials/Brushes/Gravity Field.mat") + ?? throw new InvalidOperationException("No Gravity Field.mat."); + + var zone = BuildZone(settings, work, out var orbits); + GravityLowering.Lower(zone, 0f, ref wells); + field = GravityLowering.CreateField(material); + + // Three frames through the one buffer, as ZoneRenderer.Update runs it: the bodies as built, then two moves + // (an orbit's Position is what Zone.GetHeight reads). A lowering that mirrors an axis or stops refreshing + // the upload agrees with the sim in the first frame only where it is symmetric, and not after a move. + CheckFrame("built", zone, orbits); + orbits[1].Position = new float2(-420f, 560f); + orbits[2].Position = new float2(900f, -700f); + GravityLowering.Lower(zone, 0f, ref wells); + CheckFrame("moved", zone, orbits); + orbits[0].Position = new float2(210f, -95f); + orbits[2].Position = new float2(-1800f, 1300f); + GravityLowering.Lower(zone, 0f, ref wells); + CheckFrame("moved-again", zone, orbits); + Debug.Log($"{Tag} max error {_maxError:G4} u (tolerance {Tolerance:G4}); max gradient angle {_maxAngle:F2} degrees (limit {GradientDegrees:F0})"); + + CheckWiring(settings); + Debug.Log(_ok ? $"{Tag} PASS" : $"{Tag} FAIL: see errors above"); + } + catch (Exception e) + { + Debug.LogError($"{Tag} FAIL exception: {e}"); + _ok = false; + } + finally + { + Application.logMessageReceived -= OnLog; + if (field != null) UnityEngine.Object.DestroyImmediate(field); + wells?.Release(); + try { Directory.Delete(work, true); } catch { } + } + EditorApplication.Exit(_ok ? 0 : 1); + } + + static float Core(Zone zone, float mass) => zone.Settings.RocheLimit.Evaluate(mass); + + static Vector2 At(Orbit orbit) => new Vector2(orbit.Position.x, orbit.Position.y); + + // Orbits 0-2 are the sun, the planet and the planetoid, each window centred where the body is now; orbit 3 is the + // body of no strength. The zone window holds all four. + static void CheckFrame(string frame, Zone zone, Orbit[] orbits) + { + CheckTexels(frame + "-planetoid", zone, At(orbits[2]), 4f * Core(zone, 29.2f)); + CheckTexels(frame + "-sun", zone, At(orbits[0]), 4f * Core(zone, 14152f)); + CheckTexels(frame + "-zone", zone, Vector2.zero, 1.05f * zone.Pack.Radius); + CheckGradient(zone, orbits.Select(At).ToArray()); + } + + // A sun (14152 at (-130, 85)), a planet (273.9 at (610, -240)), a planetoid (29.2 at (670, -270)) and a body of + // mass 0, whose well has no strength (a legal body; its curves give c = 0 and R = 0), at (1700, 300): parentless, + // fixed, off both axes and asymmetric, so the zone's wells sit where the verify says before any Update and a + // mirrored or swapped axis cannot agree with the sim. + internal static Zone BuildZone(GameSettings settings, string work, out Orbit[] orbits, float radius = 4182f) + { + var cache = AetheriaStores.Open(Path.Combine(work, "catalog.cc"), Path.Combine(work, "run.cc"), catalogWritable: true); + cache.Upsert(new VerseGrammar { Revision = 1 }); + cache.FlushAsync().Wait(); + var items = new ItemManager(cache, new ProvenanceLedger(), settings.GameplaySettings, _ => { }); + var positions = new[] { new Vector2(-130f, 85f), new Vector2(610f, -240f), new Vector2(670f, -270f), new Vector2(1700f, 300f) }; + var masses = new[] { 14152f, 273.9f, 29.2f, 0f }; + var keys = new CultRecordKey[positions.Length]; + var pack = new ZonePack { Radius = radius }; + for (var i = 0; i < positions.Length; i++) + { + var orbit = keys[i] = cache.Upsert(new OrbitData { FixedPosition = new float2(positions[i].x, positions[i].y) }).Key; + var body = cache.Upsert(new PlanetData + { Name = "Body " + i, Orbit = new CultRecordRef(orbit), Mass = masses[i] }).Key; + pack.Orbits.Add(new CultRecordRef(orbit)); + pack.Planets.Add(new CultRecordRef(body)); + } + var zone = new Zone(items, settings.PlanetSettings, pack, new GalaxyZone { Name = "Gravity Parity", Owner = null }, null); + orbits = keys.Select(k => zone.Orbits[k]).ToArray(); + return zone; + } + + // Renders the field through a downward orthographic camera that culls layer 9 only, centred on `centre` with + // half-size `half`, and returns the depth of every texel with the world xz of the texel's centre, which is asked + // of the camera rather than assumed. + static void Render(Vector2 centre, float half, out float[] depth, out Vector2[] world) + { + var rt = new RenderTexture(Size, Size, 0, RenderTextureFormat.RFloat) { filterMode = FilterMode.Point }; + var cameraObject = new GameObject("Gravity Parity Camera"); + var read = new Texture2D(Size, Size, TextureFormat.RFloat, false); + var previous = RenderTexture.active; + try + { + var camera = cameraObject.AddComponent(); + camera.orthographic = true; + camera.orthographicSize = half; + camera.aspect = 1f; + camera.nearClipPlane = .3f; + camera.farClipPlane = 1000f; + camera.cullingMask = 1 << GravityLowering.FieldLayer; + camera.clearFlags = CameraClearFlags.SolidColor; + camera.backgroundColor = Color.black; + camera.allowHDR = false; + camera.allowMSAA = false; + camera.targetTexture = rt; + cameraObject.transform.SetPositionAndRotation(new Vector3(centre.x, 100f, centre.y), Quaternion.Euler(90f, 0f, 0f)); + camera.Render(); + + RenderTexture.active = rt; + read.ReadPixels(new Rect(0, 0, Size, Size), 0, 0); + read.Apply(); + depth = read.GetPixelData(0).ToArray(); + world = new Vector2[Size * Size]; + for (var y = 0; y < Size; y++) + for (var x = 0; x < Size; x++) + { + var p = camera.ViewportToWorldPoint(new Vector3((x + .5f) / Size, (y + .5f) / Size, 100f)); + world[y * Size + x] = new Vector2(p.x, p.z); + } + } + finally + { + RenderTexture.active = previous; + UnityEngine.Object.DestroyImmediate(cameraObject); + UnityEngine.Object.DestroyImmediate(read); + rt.Release(); + UnityEngine.Object.DestroyImmediate(rt); + } + } + + static void CheckTexels(string window, Zone zone, Vector2 centre, float half) + { + Render(centre, half, out var depth, out var world); + var worst = 0f; + var live = 0; + for (var i = 0; i < depth.Length; i++) + { + var expected = -zone.GetHeight(new float2(world[i].x, world[i].y)); + if (float.IsNaN(depth[i])) { Fail($"{window}-texels", $"texel {i}: NaN"); return; } + var error = Math.Abs(depth[i] - expected); + worst = Math.Max(worst, error); + if (Math.Abs(expected) > 1f) live++; + if (error > Tolerance) + { + Fail($"{window}-texels", $"texel {i} at ({world[i].x:F2}, {world[i].y:F2}): expected {expected:G6}, drawn {depth[i]:G6}, error {error:G4} > {Tolerance:G4}"); + return; + } + } + _maxError = Math.Max(_maxError, worst); + // A window that draws nothing agrees with a zone that is flat: the check must be live. + if (live < depth.Length / 2) Fail($"{window}-texels", $"only {live} of {depth.Length} texels are deeper than 1 u; the check is vacuous"); + Debug.Log($"{Tag} {window}: {depth.Length} texels, max error {worst:G4} u"); + } + + // The texture's central difference (over two 4 u texels, mid-zone) points where GetForce does: depth = -h, so its + // gradient is the force over the exaggeration. This is what the slope readers (the shader's slopeFlow, the nebula + // surface normal, the drawn grid) take from the texture. + static void CheckGradient(Zone zone, Vector2[] bodies) + { + Render(new Vector2(1500f, 0f), 512f, out var depth, out var world); + var compared = 0; + for (var y = 1; y < Size - 1; y++) + for (var x = 1; x < Size - 1; x++) + { + var here = world[y * Size + x]; + if (bodies.Any(b => (b - here).magnitude < 16f)) continue; + // The world step of each texel axis is read from the camera, so a flipped or rotated target is still measured. + var au = world[y * Size + x + 1] - world[y * Size + x - 1]; + var av = world[(y + 1) * Size + x] - world[(y - 1) * Size + x]; + var du = depth[y * Size + x + 1] - depth[y * Size + x - 1]; + var dv = depth[(y + 1) * Size + x] - depth[(y - 1) * Size + x]; + var det = au.x * av.y - au.y * av.x; + var g = new Vector2((du * av.y - dv * au.y) / det, (dv * au.x - du * av.x) / det); + var f = zone.GetForce(new float2(here.x, here.y)); + var angle = Vector2.Angle(g, new Vector2(f.x, f.y)); + if (float.IsNaN(angle) || angle > GradientDegrees) + { + Fail("gradient", $"at ({here.x:F1}, {here.y:F1}) the drawn slope points {angle:F2} degrees from the force (limit {GradientDegrees:F0})"); + return; + } + _maxAngle = Math.Max(_maxAngle, angle); + compared++; + } + if (compared < Size * Size / 2) Fail("gradient", $"only {compared} texels were compared"); + } + + // Main Menu.unity has no ZoneRenderer, so no Gravity Field and no lowered potential: its gravity cameras draw the + // menu's own brush objects (Boundary on layer 9, the Waves on layer 10) and are presentation by spec (follow-up + // menu-grid-brushes), not a reader of the potential. This pins that: a ZoneRenderer in the menu would make its + // cameras readers of the field, and they would have to cull layer 9 alone like ARPG's. + static void CheckTestSceneWiring() + { + EditorSceneManager.OpenScene("Assets/Scenes/TestScene.unity", OpenSceneMode.Single); + try + { + if (CheckPatchCameras("TestScene.unity") < 1) Fail("wiring", "no Fog Patch Displacement camera in TestScene.unity"); + } + finally + { + EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + } + } + + static void CheckMenuWiring() + { + var scene = EditorSceneManager.OpenScene("Assets/Scenes/Main Menu.unity", OpenSceneMode.Single); + try + { + if (UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include) != null) + Fail("wiring", "Main Menu.unity has a ZoneRenderer: its gravity cameras now read the Gravity Field and must cull layer 9 alone"); + var seen = 0; + foreach (var camera in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) + { + if (camera.targetTexture == null || camera.targetTexture.name != "Fog Surface Displacement") continue; + seen++; + const int menuBrushLayers = (1 << 9) | (1 << 10); + if (camera.cullingMask != menuBrushLayers) + Fail("wiring", $"Main Menu camera {camera.name} culls mask {camera.cullingMask}, not the menu brush layers 9 and 10"); + } + if (seen != 1) Fail("wiring", $"{seen} Fog Surface Displacement cameras in Main Menu.unity, expected 1"); + if (CheckPatchCameras("Main Menu.unity") < 1) Fail("wiring", "no Fog Patch Displacement camera in Main Menu.unity"); + } + finally + { + EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + } + } + + // Every scene's Fog Patch Displacement camera: cloudDensity adds the R32 gravity height to the patch texture, so + // a patch camera that culls the gravity layer counts the field twice. Returns how many it found in the open scene. + static int CheckPatchCameras(string sceneName) + { + var found = 0; + foreach (var camera in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) + { + if (camera.targetTexture == null || camera.targetTexture.name != "Fog Patch Displacement") continue; + found++; + if ((camera.cullingMask & 1 << GravityLowering.FieldLayer) != 0) + Fail("wiring", $"camera {camera.name} (target Fog Patch Displacement) in {sceneName} culls layer {GravityLowering.FieldLayer}, the gravity layer"); + } + return found; + } + + static void CheckWiring(GameSettings settings) + { + var scene = EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Single); + try + { + var gravityTargets = new[] { "Fog Surface Displacement", "Slime Gravity", "MinimapGravity" }; + var seen = 0; + foreach (var camera in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) + { + if (camera.targetTexture == null || !gravityTargets.Contains(camera.targetTexture.name)) continue; + seen++; + if (camera.cullingMask != 1 << GravityLowering.FieldLayer) + Fail("wiring", $"camera {camera.name} (target {camera.targetTexture.name}) culls mask {camera.cullingMask}, not layer {GravityLowering.FieldLayer} alone"); + } + if (seen < gravityTargets.Length) Fail("wiring", $"only {seen} gravity cameras found in ARPG.unity"); + + // The patch texture is half-float: it holds the patch layers only, the nebula reads gravity from the R32 surface. + if (CheckPatchCameras("ARPG.unity") != 1) Fail("wiring", "ARPG.unity does not have exactly 1 Fog Patch Displacement camera"); + + // The map screen's gravity camera has no target until MapRenderer gives it one at run time. + var map = UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include); + if (map == null || map.GravityCamera == null) Fail("wiring", "no MapRenderer.GravityCamera in ARPG.unity"); + else if (map.GravityCamera.cullingMask != 1 << GravityLowering.FieldLayer) + Fail("wiring", $"MapRenderer.GravityCamera culls mask {map.GravityCamera.cullingMask}, not layer {GravityLowering.FieldLayer} alone"); + + var renderer = UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include); + if (renderer == null) Fail("wiring", "no ZoneRenderer in ARPG.unity"); + else if (renderer.GravityField == null || renderer.GravityField.shader.name != "Brushes/Gravity Field") + Fail("wiring", "ZoneRenderer.GravityField is not a Brushes/Gravity Field material"); + + foreach (var r in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) + if (r.gameObject.layer == GravityLowering.FieldLayer) + Fail("wiring", $"renderer {r.name} in ARPG.unity sits on layer {GravityLowering.FieldLayer}"); + } + finally + { + EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + } + + CheckMenuWiring(); + CheckTestSceneWiring(); + + foreach (var path in new[] + { + "Assets/Prefabs/RPG/Planets/Planet.prefab", "Assets/Prefabs/RPG/Planets/Gas Giant.prefab", + "Assets/Prefabs/RPG/Planets/Sun.prefab", "Assets/Prefabs/RPG/Wormhole 1.prefab" + }) + { + var prefab = AssetDatabase.LoadAssetAtPath(path); + if (prefab == null) { Fail("wiring", $"no prefab at {path}"); continue; } + foreach (var r in prefab.GetComponentsInChildren(true)) + if (r.gameObject.layer == GravityLowering.FieldLayer) + Fail("wiring", $"renderer {r.name} in {path} sits on layer {GravityLowering.FieldLayer}"); + } + } + } +} diff --git a/Assets/Scripts/Editor/GravityFieldParityVerify.cs.meta b/Assets/Scripts/Editor/GravityFieldParityVerify.cs.meta new file mode 100644 index 000000000..50646bcbb --- /dev/null +++ b/Assets/Scripts/Editor/GravityFieldParityVerify.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ceb2bdab0804463b1998471d47e82fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/ShieldPanelCut3Verify.cs b/Assets/Scripts/Editor/ShieldPanelCut3Verify.cs index aa6f4b151..31348b11d 100644 --- a/Assets/Scripts/Editor/ShieldPanelCut3Verify.cs +++ b/Assets/Scripts/Editor/ShieldPanelCut3Verify.cs @@ -130,7 +130,7 @@ namespace Aetheria.EditorTools static AbsorbEvent Absorb(Vector3 worldPos, Vector3 worldDir, float energy = 5f, DamageType type = DamageType.Kinetic) - => new AbsorbEvent(worldPos.ToCultMath(), worldDir.ToCultMath(), energy, type); + => new AbsorbEvent(worldPos.ToCultMath(), worldDir.ToCultMath(), energy, type, AbsorbLayer.Shield); // ============================================================== // D17/D20: a panel struck in its own spawn frame must absorb that hit, not swallow it. diff --git a/Assets/Scripts/Editor/ShipModPlaySmoke.cs b/Assets/Scripts/Editor/ShipModPlaySmoke.cs index f0753e4e6..08a849801 100644 --- a/Assets/Scripts/Editor/ShipModPlaySmoke.cs +++ b/Assets/Scripts/Editor/ShipModPlaySmoke.cs @@ -96,7 +96,7 @@ public static class ShipModPlaySmoke } Install(package.Visual.Id, Path.GetFullPath(packagePath)); - var (hull, ship) = ShipAuthoringStore.Read(Path.Combine(modsRoot, package.Visual.Id, "ship.cc")); + var (hull, ship, _) = ShipAuthoringStore.Read(Path.Combine(modsRoot, package.Visual.Id, "ship.cc")); ship.Id += ".broken"; hull.Name += " Broken"; hull.Visual = new CultRecordRef(ShipModCatalog.AuthoringKey(ship.Id)); diff --git a/Assets/Scripts/Editor/ShipPrefabAuthoring.cs b/Assets/Scripts/Editor/ShipPrefabAuthoring.cs index 5d5b7352c..d2937b79d 100644 --- a/Assets/Scripts/Editor/ShipPrefabAuthoring.cs +++ b/Assets/Scripts/Editor/ShipPrefabAuthoring.cs @@ -140,12 +140,10 @@ public static class ShipPrefabAuthoring if (values.Length != 7) throw new InvalidOperationException($"Invalid pivot name {name}"); var pivot = AddOrGet(node.gameObject); pivot.Group = ParseInt(values[1], name); - pivot.YawMin = ParseInt(values[2], name); - pivot.YawMax = ParseInt(values[3], name); pivot.PitchMin = ParseInt(values[4], name); pivot.PitchMax = ParseInt(values[5], name); pivot.Speed = ParseInt(values[6], name); - if (pivot.YawMin > pivot.YawMax || pivot.PitchMin > pivot.PitchMax || pivot.Speed <= 0) + if (pivot.PitchMin > pivot.PitchMax || pivot.Speed <= 0) throw new InvalidOperationException($"Invalid articulation range or speed in {name}"); pivots.Add(pivot); } diff --git a/Assets/Scripts/Editor/WireFloatingItems.cs b/Assets/Scripts/Editor/WireFloatingItems.cs new file mode 100644 index 000000000..8065401a5 --- /dev/null +++ b/Assets/Scripts/Editor/WireFloatingItems.cs @@ -0,0 +1,75 @@ +using System; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; + +// Strips the deleted integrator component from the pickup prefabs and points ZoneRenderer's four pickup fields in ARPG.unity at +// each prefab's ItemPickup, then saves the prefabs and the scene. Idempotent: a prefab with no missing script is left as +// it is, and the fields are set to the same values again. +// +// Unity -batchmode -projectPath -executeMethod WireFloatingItems.Run -logFile +// +// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. The menu item runs the same wiring. +public static class WireFloatingItems +{ + private const string ScenePath = "Assets/Scenes/ARPG.unity"; + private const string PickupFolder = "Assets/Prefabs/RPG/Pickups/"; + // The field each prefab filled before this cut (read from ARPG.unity at the cut's base). Icosahedron fills none. + private static readonly (string Field, string Prefab)[] Fields = + { + ("SimpleCommodityPickup", "Tetrahedron"), + ("CompoundCommodityPickup", "Hexahedron"), + ("GearPickup", "Octahedron"), + ("WeaponPickup", "Dodecahedron"), + }; + private static readonly string[] Prefabs = { "Tetrahedron", "Hexahedron", "Octahedron", "Dodecahedron", "Icosahedron" }; + + [MenuItem("Aetheria/Wire Floating Items")] + public static void Menu() => Wire(); + + public static void Run() + { + try + { + Wire(); + EditorApplication.Exit(0); + } + catch (Exception exception) + { + Debug.LogException(exception); + EditorApplication.Exit(1); + } + } + + private static void Wire() + { + foreach (var name in Prefabs) + { + var path = PickupFolder + name + ".prefab"; + var contents = PrefabUtility.LoadPrefabContents(path); + try + { + var removed = GameObjectUtility.RemoveMonoBehavioursWithMissingScript(contents); + if (contents.GetComponent() == null) throw new InvalidOperationException($"{path} has no ItemPickup."); + if (removed > 0) PrefabUtility.SaveAsPrefabAsset(contents, path); + Debug.Log($"WIRE_FLOATING_ITEMS {name} removed={removed}"); + } + finally { PrefabUtility.UnloadPrefabContents(contents); } + } + + var scene = EditorSceneManager.OpenScene(ScenePath, OpenSceneMode.Single); + var renderer = UnityEngine.Object.FindFirstObjectByType(); + if (renderer == null) throw new InvalidOperationException("ARPG.unity has no ZoneRenderer."); + var serialized = new SerializedObject(renderer); + foreach (var (field, prefab) in Fields) + { + var pickup = AssetDatabase.LoadAssetAtPath(PickupFolder + prefab + ".prefab").GetComponent(); + var property = serialized.FindProperty(field) ?? throw new InvalidOperationException($"ZoneRenderer has no {field}."); + property.objectReferenceValue = pickup; + } + serialized.ApplyModifiedProperties(); + EditorSceneManager.MarkSceneDirty(scene); + if (!EditorSceneManager.SaveScene(scene)) throw new InvalidOperationException("The scene did not save."); + Debug.Log("WIRE_FLOATING_ITEMS ok"); + } +} diff --git a/Assets/Scripts/Editor/WireFloatingItems.cs.meta b/Assets/Scripts/Editor/WireFloatingItems.cs.meta new file mode 100644 index 000000000..c84e2a8c8 --- /dev/null +++ b/Assets/Scripts/Editor/WireFloatingItems.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9a56d7dc8471d224f9bed434b39f7c87 \ No newline at end of file diff --git a/Assets/Scripts/Editor/WireImpactFeedback.cs b/Assets/Scripts/Editor/WireImpactFeedback.cs new file mode 100644 index 000000000..650db6981 --- /dev/null +++ b/Assets/Scripts/Editor/WireImpactFeedback.cs @@ -0,0 +1,61 @@ +using System; +using Cinemachine; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; + +// Adds the impact-feedback tuning object to ARPG.unity and the impulse listener to its follow camera, then saves the +// scene. Idempotent: a scene that already has them is left as it is. +// +// Unity -batchmode -projectPath -executeMethod WireImpactFeedback.Run -logFile +// +// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. The menu item runs the same wiring. +public static class WireImpactFeedback +{ + private const string ScenePath = "Assets/Scenes/ARPG.unity"; + // The weapons' own hit effect (the nested prefab AC5's Projectile uses as HitEffect): no new art. + private const string HullEffectPath = "Assets/Prefabs/Fire & Explosion Effects/Prefabs/TinyExplosion.prefab"; + + [MenuItem("Aetheria/Wire Impact Feedback")] + public static void Menu() => Wire(); + + public static void Run() + { + try + { + Wire(); + EditorApplication.Exit(0); + } + catch (Exception exception) + { + Debug.LogException(exception); + EditorApplication.Exit(1); + } + } + + private static void Wire() + { + var scene = EditorSceneManager.OpenScene(ScenePath, OpenSceneMode.Single); + var manager = UnityEngine.Object.FindFirstObjectByType(); + if (manager == null || manager.FollowCamera == null) throw new InvalidOperationException("ARPG.unity has no ActionGameManager with a FollowCamera."); + + if (manager.FollowCamera.GetComponent() == null) + manager.FollowCamera.gameObject.AddComponent(); + + if (UnityEngine.Object.FindFirstObjectByType() == null) + { + var prefab = AssetDatabase.LoadAssetAtPath(HullEffectPath); + if (prefab == null) throw new InvalidOperationException($"No prefab at {HullEffectPath}."); + var root = new GameObject("Impact Feedback"); + var feedback = root.AddComponent(); + var effect = (GameObject) PrefabUtility.InstantiatePrefab(prefab, root.transform); + feedback.HullEffect = effect.GetComponent(); + if (feedback.HullEffect == null) throw new InvalidOperationException("The hull effect prefab has no Prototype."); + EditorUtility.SetDirty(feedback); + } + + EditorSceneManager.MarkSceneDirty(scene); + if (!EditorSceneManager.SaveScene(scene)) throw new InvalidOperationException("The scene did not save."); + Debug.Log("WIRE_IMPACT_FEEDBACK ok"); + } +} diff --git a/Assets/Scripts/Editor/WireImpactFeedback.cs.meta b/Assets/Scripts/Editor/WireImpactFeedback.cs.meta new file mode 100644 index 000000000..5d106d375 --- /dev/null +++ b/Assets/Scripts/Editor/WireImpactFeedback.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9083abd01a947a847847d2f6fc177153 \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/ActionGameManager.cs b/Assets/Scripts/Gameplay/ActionGameManager.cs index 604864aa8..5ee4b474a 100644 --- a/Assets/Scripts/Gameplay/ActionGameManager.cs +++ b/Assets/Scripts/Gameplay/ActionGameManager.cs @@ -113,8 +113,11 @@ public class ActionGameManager : MonoBehaviour //public string StarterShipTemplate = "Longinus"; // The run's credits: seeded from the scenario stage on a new game and from SavedGame on Continue, written by SaveRun. [NonSerialized] public int Credits; - public float TargetSpottedBlinkFrequency = 20; - public float TargetSpottedBlinkOffset = -.25f; + // Presentation scale: the player's own Visibility at which the target panel's VisibilityToTargetFill reads full. + public float OwnSignatureFullScale = 10; + // The music last asked for: Update decides it each frame from what the player's own instruments hold and calls + // PlayMusic only when it changes. + private MusicType? _music; [Header("Postprocessing")] public float DeathPostTransitionTime; @@ -157,6 +160,12 @@ public class ActionGameManager : MonoBehaviour public Prototype FriendlyTargetIndicator; public PlaceUIElementWorldspace ViewDot; public Prototype LockIndicator; + // Presentation tuning: how far from the ship, toward the locker, the incoming-lock indicator sits. + public float IncomingLockIndicatorDistance = 30; + // Presentation tuning: how far from the ship, toward a remembered hostile's bearing, its marker sits; how long a + // sweep flash takes to fade. + public float BearingMarkerDistance = 40; + public float SearchFlashSeconds = .6f; public PlaceUIElementWorldspace[] Crosshairs; public GameObject HitMarker; public float HitMarkerDuration; @@ -177,8 +186,6 @@ public class ActionGameManager : MonoBehaviour public Sprite ShieldIcon; public Sprite NoShieldIcon; - public float IntroDuration; - //public PlayerInput Input; // private CinemachineFramingTransposer _transposer; @@ -196,9 +203,19 @@ public class ActionGameManager : MonoBehaviour private readonly HelmInput _helm = new HelmInput(); private TextMeshProUGUI _faceAimMark; private (HardpointData[] hardpoints, Transform[] barrels, PlaceUIElementWorldspace crosshair)[] _articulationGroups; - private (LockWeapon targetLock, PlaceUIElementWorldspace indicator, Rotate spin)[] _lockingIndicators; + // The outgoing progress indicators on the player's target: one per lock weapon (its Lock, shown only on a hostile target) + // and one per scanner (its scan Progress, shown on any target: a scan reads no stance). + private (Func progress, bool hostileOnly, PlaceUIElementWorldspace indicator, Rotate spin)[] _progressIndicators; + private (PlaceUIElementWorldspace indicator, Rotate spin) _incomingLockIndicator; private Dictionary _visibleHostileIndicators = new Dictionary(); private Dictionary _visibleFriendlyIndicators = new Dictionary(); + // Display-only: a marker per remembered hostile (shares HostileTargetIndicator's pool), the Search warnings the last + // ticks delivered (bearing, zone time; a per-tick buffer), and the sweep flashes drawn from them. + private readonly Dictionary _bearingMarkers = new Dictionary(); + private readonly List<(float2 bearing, float time)> _pendingSweeps = new List<(float2, float)>(); + private readonly List<(PlaceUIElementWorldspace indicator, Image image, float2 bearing, float time)> _sweepFlashes = + new List<(PlaceUIElementWorldspace, Image, float2, float)>(); + private readonly List _markerScratch = new List(); private List _shipSubscriptions = new List(); private List _targetSubscriptions = new List(); private readonly Dictionary _debugLastShots = new Dictionary(); @@ -231,6 +248,8 @@ public class ActionGameManager : MonoBehaviour public ItemManager ItemManager { get; private set; } public Zone Zone { get; private set; } + public static SimClock Clock { get; } = new SimClock(1f / 60f); + private bool _zoneEntered; private readonly (float2 direction, string name)[] _directions = { (float2(0, 1), "Front"), @@ -317,7 +336,7 @@ public class ActionGameManager : MonoBehaviour Input.Global.ZoneMap.performed += context => { ToggleMenuTab(MenuTab.Map); - MenuMap.Position = CurrentEntity.Position.xz; + MenuMap.Position = DrawAhead.Position(CurrentEntity, Clock.Lead).xz; }; Input.Global.Inventory.performed += context => ToggleMenuTab(MenuTab.Inventory); @@ -341,6 +360,19 @@ public class ActionGameManager : MonoBehaviour foreach (var wormhole in ZoneRenderer.WormholeInstances.Keys) { if (!(length(wormhole.Position - CurrentEntity.Position.xz) < Settings.GameplaySettings.WormholeExitRadius)) continue; + if (wormhole.Exit) + { + // The exit gate leads nowhere: RunGoal decides whether it is open, and an open one ends the run. + if (RunGoal.ExitOpen(Zone)) Win(); + else + { + Dialog.Clear(); + Dialog.Title.text = $"The exit gate is sealed. {RunGoal.Boss(Zone)?.Name ?? "Its guardian"} holds it shut."; + Dialog.Show(); + Dialog.MoveToCursor(); + } + return; + } EnterWormhole(wormhole); } Dock(); @@ -409,22 +441,9 @@ public class ActionGameManager : MonoBehaviour Input.Player.TargetNext.performed += context => CurrentEntity.TargetNext(); Input.Player.TargetPrevious.performed += context => CurrentEntity.TargetPrevious(); - // Cut 2 (docs/fire-control-cut.md): cycles the aim point among the current target's revealed - // subsystems -- decides nothing itself, only calls the one writer (TrySelectTargetItem), same - // predicate (FireControl.IsRevealed) the AI path uses. Entity-only: a chunk has no subsystems. - Input.Player.CycleTargetItem.performed += context => - { - var target = CurrentEntity.Target.Value.Entity; - if (target == null) return; - var revealed = target.Equipment.Where(x => FireControl.IsRevealed(CurrentEntity, x)).ToArray(); - if (revealed.Length == 0) - { - CurrentEntity.TrySelectTargetItem(null); - return; - } - var currentItemIndex = Array.IndexOf(revealed, CurrentEntity.ResolvedTargetItem); - CurrentEntity.TrySelectTargetItem(revealed[(currentItemIndex + 1) % revealed.Length]); - }; + // Cut 2 (docs/fire-control-cut.md): steps the aim through the target's schematic rows -- every mount this ship + // has located, empty or not, minus the ones it saw destroyed. Decides nothing: the entity owns the cycle. + Input.Player.CycleTargetItem.performed += context => CurrentEntity.CycleAim(); #endregion @@ -715,14 +734,16 @@ public class ActionGameManager : MonoBehaviour galaxyZone.Contents = new Zone(ItemManager, Settings.PlanetSettings, galaxyZone.PackedContents, galaxyZone, CurrentGalaxy); } Zone = galaxyZone.Contents; + _zoneEntered = true; // the clock forgets its lead between frames, never inside a step PlayMusic(MusicType.Overworld); + _music = MusicType.Overworld; Zone.Log = s => Debug.Log($"Zone: {s}"); if (CurrentEntity != null) { CurrentEntity.Deactivate(); - CurrentEntity.Zone.Entities.Remove(CurrentEntity); + CurrentEntity.Zone.Remove(CurrentEntity); CurrentEntity.Zone = Zone; Zone.Admit(CurrentEntity, piloted: false); } @@ -805,7 +826,6 @@ public class ActionGameManager : MonoBehaviour } else { - //StartCoroutine(IntroCutscene(targetEntity as Ship)); BindToEntity(targetEntity); } @@ -853,35 +873,6 @@ public class ActionGameManager : MonoBehaviour BindToEntity(staged.Player); } - private IEnumerator IntroCutscene(Ship ship) - { - ZoneRenderer.PerspectiveEntity = ship; - var entityPosition = ship.Position.xz; - var followOrbit = Zone.Orbits.Keys.MinBy(o => lengthsq(Zone.GetOrbitPosition(o) - entityPosition)); - var followPlanet = ZoneRenderer.Planets[Zone.Planets.FirstOrDefault(p => p.Value.Orbit.Key.Equals(followOrbit)).Key]; - DockCamera.Follow = followPlanet.Body.transform; - var rootOrbit = followOrbit; - while (Zone.Orbits[rootOrbit].Data.Parent.IsSet()) - rootOrbit = Zone.Orbits[rootOrbit].Data.Parent.Key; - var rootPlanet = ZoneRenderer.Planets[Zone.Planets.FirstOrDefault(p => p.Value.Orbit.Key.Equals(rootOrbit)).Key]; - DockCamera.LookAt = rootPlanet.Body.transform; - - var shipVelocity = ship.GetBehavior().Limit; - var followOrbitPosition = Zone.GetOrbitPosition(followOrbit); - var shipDirection = normalize(Zone.GetOrbitPosition(rootOrbit) - followOrbitPosition); - ship.Position.xz = followOrbitPosition - shipDirection * shipVelocity * IntroDuration; - - var startTime = Time.time; - while (Time.time - startTime < IntroDuration) - { - ship.Direction = shipDirection; - ship.Velocity = shipDirection * shipVelocity; - yield return null; - } - - BindToEntity(ship); - } - public void Dock() { if (CurrentEntity.Parent != null) return; @@ -948,7 +939,7 @@ public class ActionGameManager : MonoBehaviour Dialog.MoveToCursor(); // TODO: SFX: Fail } - else if (CurrentEntity.GetBehavior() == null && CurrentEntity.GetBehavior() == null) + else if (CurrentEntity.GetBehavior() == null) { Dialog.Clear(); Dialog.Title.text = "Can't undock. Missing thruster component!"; @@ -1012,9 +1003,17 @@ public class ActionGameManager : MonoBehaviour foreach (var indicator in _visibleFriendlyIndicators) Destroy(indicator.Value.gameObject); _visibleFriendlyIndicators.Clear(); + + foreach (var marker in _bearingMarkers.Values) RetireMarker(marker); + _bearingMarkers.Clear(); + foreach (var flash in _sweepFlashes) RetireFlash(flash.indicator, flash.image); + _sweepFlashes.Clear(); + _pendingSweeps.Clear(); - if(_lockingIndicators!=null) foreach(var (_, indicator, _) in _lockingIndicators) + if(_progressIndicators!=null) foreach(var (_, _, indicator, _) in _progressIndicators) indicator.GetComponent().ReturnToPool(); + if(_incomingLockIndicator.indicator != null) _incomingLockIndicator.indicator.GetComponent().ReturnToPool(); + _incomingLockIndicator = default; DisablePlayerInput(); Cursor.lockState = CursorLockMode.None; GameplayUI.gameObject.SetActive(false); @@ -1076,11 +1075,6 @@ public class ActionGameManager : MonoBehaviour foreach (var group in _articulationGroups) group.crosshair.gameObject.SetActive(true); - _shipSubscriptions.Add(CurrentEntity.TargetedByCount.Subscribe(count => - { - PlayMusic(count > 0 ? MusicType.Combat : MusicType.Overworld); - })); - _shipSubscriptions.Add(CurrentEntity.Target.Subscribe(target => { // Clear previous subscriptions related to currently targeted enemy @@ -1152,12 +1146,18 @@ public class ActionGameManager : MonoBehaviour _shipSubscriptions.Add(CurrentEntity.Death.Subscribe(Die)); - _lockingIndicators = CurrentEntity.GetBehaviors() + var progressSources = CurrentEntity.GetBehaviors().Select(x => ((Func) (() => x.Lock), true)) + .Concat(CurrentEntity.GetBehaviors().Select(x => ((Func) (() => x.Progress), false))); + _progressIndicators = progressSources .Select(x => { var i = LockIndicator.Instantiate(); - return (x, i, i.GetComponent()); + return (x.Item1, x.Item2, i, i.GetComponent()); }).ToArray(); + + var incoming = LockIndicator.Instantiate(); + incoming.gameObject.SetActive(false); + _incomingLockIndicator = (incoming, incoming.GetComponent()); } private void UpdatePlayerPanel() @@ -1178,16 +1178,18 @@ public class ActionGameManager : MonoBehaviour } } - // A chunk's simulated position is planar (Zone.ChunkPose); the renderer draws it at the asteroid layer's height. + // A chunk's pose is planar (Zone.ChunkPose), read at the drawn time so the reticle sits on the drawn rock; the renderer + // draws it at the asteroid layer's height. private float3 ChunkWorldPosition(ChunkId chunk) { - var pose = CurrentEntity.Zone.ChunkPose(chunk.Field, chunk.Index); + var zone = CurrentEntity.Zone; + var pose = zone.ChunkPose(chunk.Field, chunk.Index, DrawAhead.Time(zone, Clock.Lead)); return float3(pose.x, Settings.PlanetSettings.AsteroidVerticalOffset, pose.y); } - private void Die(CauseOfDeath cause) + // The one way a run ends, won or lost: the run is cleared and the main menu returns. + private void EndRun() { - var deathTime = Time.time; UnbindEntity(); CurrentEntity = null; MainMenu.gameObject.SetActive(true); @@ -1195,6 +1197,21 @@ public class ActionGameManager : MonoBehaviour CurrentGalaxy = null; RunSave.Clear(CultCache); SavePlayerSettings(); + } + + private void Win() + { + EndRun(); + Dialog.Clear(); + Dialog.Title.text = "You have escaped the Terminus. This was the demo; the whole of it is yet to come."; + Dialog.Show(); + Dialog.MoveToCursor(); + } + + private void Die(CauseOfDeath cause) + { + var deathTime = Time.time; + EndRun(); Observable.EveryUpdate() .Where(_ => Time.time - deathTime < DeathPostTransitionTime) .Subscribe(_ => @@ -1256,6 +1273,36 @@ public class ActionGameManager : MonoBehaviour // TODO: SFX: Music } + // What the player's own instruments say about combat, nothing a hostile knows: a hostile tracked, a paint on the + // player, or a remembered hostile the player still has a bearing on (a reveal younger than BearingMemory). + private void UpdateMusic() + { + var combat = CurrentEntity.VisibleEnemies.Count > 0 || CurrentEntity.IncomingPaints.Count > 0; + combat |= CurrentEntity.RememberedHostiles.Any(); + var type = combat ? MusicType.Combat : MusicType.Overworld; + if (_music == type) return; + _music = type; + PlayMusic(type); + } + + // An indicator's fill is how far the player's own sensors have resolved the ship from a track toward identifying + // it (ContactOf.Info over the detection-to-gear span): nothing of what the ship sees of the player. + private void PlaceFill(VisibleTargetIndicator indicator, Entity subject) + { + indicator.Fill.enabled = subject.Active; + if (!subject.Active) return; + var settings = Settings.GameplaySettings; + indicator.Fill.fillAmount = saturate(unlerp(settings.TargetDetectionInfoThreshold, settings.TargetGearInfoThreshold, + CurrentEntity.ContactOf(subject).Info)); + } + + // Whether an effect drawn at `subject`'s true position may be drawn: the player's own ship, or a ship its + // instruments track. The one seam for impact and hit effects (follow-up presentation-gated-on-tracked); a bearing + // alone (Detected without Tracked) places nothing there. No player ship, nothing to gate on. + public static bool DrawsAt(Entity subject) => + Instance == null || Instance.CurrentEntity == null || subject == null || subject == Instance.CurrentEntity || + Instance.CurrentEntity.ContactOf(subject).Tracked; + void Update() { if(!_paused) @@ -1269,30 +1316,14 @@ public class ActionGameManager : MonoBehaviour foreach (var indicator in _visibleHostileIndicators) { indicator.Value.gameObject.SetActive(indicator.Key!=CurrentEntity.Target.Value.Entity); - indicator.Value.Place.Target = indicator.Key.Position.ToUnity(); - if (!indicator.Key.Active) - indicator.Value.Fill.enabled = false; - else - { - indicator.Value.Fill.fillAmount = - saturate(indicator.Key.EntityInfoGathered[CurrentEntity] / Settings.GameplaySettings.TargetDetectionInfoThreshold); - indicator.Value.Fill.enabled = - !(indicator.Key.EntityInfoGathered[CurrentEntity] > Settings.GameplaySettings.TargetDetectionInfoThreshold) || - sin(TargetSpottedBlinkFrequency * Time.time) + TargetSpottedBlinkOffset > 0; - } + indicator.Value.Place.Target = DrawAhead.Position(indicator.Key, Clock.Lead).ToUnity(); + PlaceFill(indicator.Value, indicator.Key); } foreach (var indicator in _visibleFriendlyIndicators) { indicator.Value.gameObject.SetActive(indicator.Key!=CurrentEntity.Target.Value.Entity); - indicator.Value.Place.Target = indicator.Key.Position.ToUnity(); - if (!indicator.Key.Active) - indicator.Value.Fill.enabled = false; - else - { - indicator.Value.Fill.enabled = true; - indicator.Value.Fill.fillAmount = - saturate(indicator.Key.EntityInfoGathered[CurrentEntity] / Settings.GameplaySettings.TargetDetectionInfoThreshold); - } + indicator.Value.Place.Target = DrawAhead.Position(indicator.Key, Clock.Lead).ToUnity(); + PlaceFill(indicator.Value, indicator.Key); } var look = Input.Player.Look.ReadValue(); var sensitivity = PlayerSettings.InputSettings.Sensitivity; @@ -1313,23 +1344,36 @@ public class ActionGameManager : MonoBehaviour ship.Turn = _helm.Demand(ship, _viewDirection.xz, Input.Player.Turn.ReadValue()); } + UpdateMusic(); UpdateFireControlDebug(CurrentEntity.Target.Value); var target = CurrentEntity.Target.Value.Entity; if (target != null) { var threshold = Settings.GameplaySettings.TargetDetectionInfoThreshold; - TargetVisibilityFill.fillAmount = lerp(.25f, .75f, (CurrentEntity.EntityInfoGathered[target] - threshold)/(1-threshold)); - VisibilityToTargetFill.fillAmount = lerp(.25f, .75f, target.EntityInfoGathered[CurrentEntity] / threshold); + TargetVisibilityFill.fillAmount = lerp(.25f, .75f, (CurrentEntity.ContactOf(target).Info - threshold)/(1-threshold)); + VisibilityToTargetFill.fillAmount = lerp(.25f, .75f, saturate(CurrentEntity.Visibility / OwnSignatureFullScale)); TargetHitpointsFill.fillAmount = lerp(.25f, .75f, target.Hull.Durability / target.EquippedHull.Data.Durability); TargetShieldsFill.fillAmount = target.Shield == null ? 0 : lerp(.25f, .75f, target.Shield.Progress); } - var tractorPower = Input.Player.TractorBeam.ReadValue(); - CurrentEntity.TractorPower = - saturate(CurrentEntity.TractorPower + sign(tractorPower - CurrentEntity.TractorPower) * Time.deltaTime * 2); + CurrentEntity.TractorCommand = Input.Player.TractorBeam.ReadValue(); } - Zone.Update(Time.deltaTime); } + // One clock steps the zone, paused or not: a paused frame feeds it no real time. + // A zone entered inside a step (a wormhole) ends this frame's stepping: the rest of its steps are the old zone's. + void EnterNewZone() { if (_zoneEntered) { Clock.Reset(); _zoneEntered = false; } } + EnterNewZone(); + var steppedZone = Zone; + Clock.Advance(_paused ? 0f : Time.deltaTime, delta => + { + if (Zone != steppedZone) return; + steppedZone.Update(delta); + // A warning lives one tick, so sweeps are collected per tick, never read per frame. + if (CurrentEntity != null && CurrentEntity.Zone == steppedZone) + foreach (var warning in CurrentEntity.IncomingPaints) + if (warning.Mode == PaintMode.Search) _pendingSweeps.Add((warning.Bearing, steppedZone.Time)); + }); + EnterNewZone(); } private static string ResultLabel(ShotResult result) => result switch @@ -1395,7 +1439,7 @@ public class ActionGameManager : MonoBehaviour : $"base {d.PBase:P1}"; DebugInfoText.text = - $"FIRE CONTROL - {selectedItem.Data.Name}\n" + + $"FIRE CONTROL - {ItemManager.Title(selectedItem.EquippableItem)}\n" + $"{gates}\n" + $"range {d.Range:F0} [{d.MinRange:F0}..{d.MaxRange:F0}]\n" + $"info {d.Info:F3}/{d.InfoDemandCeiling:F3} sensor {d.PSensor:F3}\n" + @@ -1416,13 +1460,15 @@ public class ActionGameManager : MonoBehaviour { if (CurrentEntity == null || CurrentEntity.Parent != null) return; + var lead = Clock.Lead; + var ownDrawn = DrawAhead.Position(CurrentEntity, lead); ViewDot.Target = ZoneRenderer.EntityInstances[CurrentEntity].LookAtPoint.position; var target = CurrentEntity.Target.Value; if (target.Chunk is ChunkId chunk) TargetIndicator.Target = ChunkWorldPosition(chunk).ToUnity(); else if (target.Entity != null) - TargetIndicator.Target = target.Entity.Position.ToUnity(); - var distance = length(ViewDot.Target.ToCultMath() - CurrentEntity.Position); + TargetIndicator.Target = DrawAhead.Position(target.Entity, lead).ToUnity(); + var distance = length(ViewDot.Target.ToCultMath() - ownDrawn); foreach (var (_, barrels, crosshair) in _articulationGroups) { var averagePosition = Vector3.zero; @@ -1432,18 +1478,112 @@ public class ActionGameManager : MonoBehaviour crosshair.Target = averagePosition; } - foreach (var (targetLock, indicator, spin) in _lockingIndicators) + foreach (var (progress, hostileOnly, indicator, spin) in _progressIndicators) { - var showLockingIndicator = targetLock.Lock > .01f && CurrentEntity.Target.Value.Entity != null && CurrentEntity.IsHostileTo(CurrentEntity.Target.Value.Entity); - indicator.gameObject.SetActive(showLockingIndicator); - if(showLockingIndicator) + var value = progress(); + var targetEntity = CurrentEntity.Target.Value.Entity; + var showIndicator = value > .01f && targetEntity != null && (!hostileOnly || CurrentEntity.IsHostileTo(targetEntity)); + indicator.gameObject.SetActive(showIndicator); + if(showIndicator) { - indicator.Target = CurrentEntity.Target.Value.Entity.Position.ToUnity(); - indicator.NoiseAmplitude = Settings.GameplaySettings.LockIndicatorNoiseAmplitude * (1 - targetLock.Lock); - indicator.NoiseFrequency = Settings.GameplaySettings.LockIndicatorFrequency.Evaluate(targetLock.Lock); - spin.Speed = Settings.GameplaySettings.LockSpinSpeed.Evaluate(targetLock.Lock); + indicator.Target = DrawAhead.Position(targetEntity, lead).ToUnity(); + ApplyLockProgress(indicator, spin, value); } } + + // The strongest lock or scan on the player's ship, read only from IncomingPaints (never another ship's LockWeapon or + // Scanner). A Scan paint's Strength is the scan's progress (ruling scan-is-an-act). Search paints (ping sweeps) are + // this class's sweep flashes (UpdateSweepFlashes). Same curves as the outgoing indicator, driven by the warning's Strength. + var warnings = CurrentEntity.IncomingPaints; + var strongest = -1; + for (var w = 0; w < warnings.Count; w++) + if ((warnings[w].Mode is PaintMode.Track or PaintMode.Scan) && (strongest < 0 || warnings[w].Strength > warnings[strongest].Strength)) strongest = w; + var (incomingIndicator, incomingSpin) = _incomingLockIndicator; + incomingIndicator.gameObject.SetActive(strongest >= 0); + if (strongest >= 0) + { + var warning = warnings[strongest]; + incomingIndicator.Target = DrawAhead.AtBearing(CurrentEntity, warning.Bearing, IncomingLockIndicatorDistance, lead).ToUnity(); + ApplyLockProgress(incomingIndicator, incomingSpin, warning.Strength); + } + + UpdateBearingMarkers(); + UpdateSweepFlashes(); + } + + // One marker per remembered hostile (a contact held by a bearing only): at the bearing the book keeps, labelled with the + // classes it claimed. Never at the subject's position, never read from its gear. + private void UpdateBearingMarkers() + { + var remembered = CurrentEntity.RememberedHostiles.ToList(); + _markerScratch.Clear(); + foreach (var subject in _bearingMarkers.Keys) + if (!remembered.Contains(subject)) _markerScratch.Add(subject); + foreach (var subject in _markerScratch) + { + RetireMarker(_bearingMarkers[subject]); + _bearingMarkers.Remove(subject); + } + foreach (var subject in remembered) + { + if (!_bearingMarkers.TryGetValue(subject, out var marker)) + { + marker = HostileTargetIndicator.Instantiate(); + marker.Fill.enabled = false; + _bearingMarkers.Add(subject, marker); + } + marker.gameObject.SetActive(true); + var bearing = CurrentEntity.ContactOf(subject).Bearing; + marker.Place.Target = DrawAhead.AtBearing(CurrentEntity, bearing, BearingMarkerDistance, Clock.Lead).ToUnity(); + marker.ShowLabel(string.Join(", ", CurrentEntity.ClaimedClasses(subject).Select(c => c.Name))); + } + } + + // A pooled indicator goes back as the next hostile indicator will want it: label hidden, fill restored. + private static void RetireMarker(VisibleTargetIndicator marker) + { + marker.ShowLabel(null); + marker.Fill.enabled = true; + marker.GetComponent().ReturnToPool(); + } + + private static void RetireFlash(PlaceUIElementWorldspace indicator, Image image) + { + if (image != null) image.color = new Color(image.color.r, image.color.g, image.color.b, 1); + indicator.GetComponent().ReturnToPool(); + } + + // A ping crossing the player draws one flash toward the pinger, fading over SearchFlashSeconds of zone time. + private void UpdateSweepFlashes() + { + foreach (var (bearing, time) in _pendingSweeps) + { + var indicator = LockIndicator.Instantiate(); + ApplyLockProgress(indicator, indicator.GetComponent(), 0); // a pooled lock indicator keeps its last tightening + _sweepFlashes.Add((indicator, indicator.GetComponentInChildren(), bearing, time)); + } + _pendingSweeps.Clear(); + for (var i = _sweepFlashes.Count - 1; i >= 0; i--) + { + var (indicator, image, bearing, time) = _sweepFlashes[i]; + var age = Zone.Time - time; + if (age < 0 || age >= SearchFlashSeconds) + { + RetireFlash(indicator, image); + _sweepFlashes.RemoveAt(i); + continue; + } + indicator.Target = DrawAhead.AtBearing(CurrentEntity, bearing, IncomingLockIndicatorDistance, Clock.Lead).ToUnity(); + if (image != null) image.color = new Color(image.color.r, image.color.g, image.color.b, 1 - age / SearchFlashSeconds); + } + } + + // The one lock-indicator curve: outgoing (the player's own lock) and incoming (the warning's strength) both tighten through it. + private void ApplyLockProgress(PlaceUIElementWorldspace indicator, Rotate spin, float progress) + { + indicator.NoiseAmplitude = Settings.GameplaySettings.LockIndicatorNoiseAmplitude * (1 - progress); + indicator.NoiseFrequency = Settings.GameplaySettings.LockIndicatorFrequency.Evaluate(progress); + spin.Speed = Settings.GameplaySettings.LockSpinSpeed.Evaluate(progress); } } diff --git a/Assets/Scripts/Gameplay/ArticulationPoint.cs b/Assets/Scripts/Gameplay/ArticulationPoint.cs index 427b74c0f..10648f09a 100644 --- a/Assets/Scripts/Gameplay/ArticulationPoint.cs +++ b/Assets/Scripts/Gameplay/ArticulationPoint.cs @@ -4,15 +4,14 @@ using UnityEngine; using CultMath; using static CultMath.math; +// Presentation only: the barrel follows the point its group's solution places (EntityInstance), which FireControl has +// already clamped to the arc. This decides no arc; Speed and the pitch clamp are how the picture slews. public class ArticulationPoint : MonoBehaviour { public Transform Target; public int Group; - public float YawMin; - public float YawMax; - public float PitchMin; public float PitchMax; @@ -30,7 +29,7 @@ public class ArticulationPoint : MonoBehaviour var yaw = Vector2.SignedAngle(new Vector2(0, 1), new Vector2(targetLocal.x, targetLocal.z)); var pitch = Vector2.SignedAngle(new Vector2(1, 0), new Vector2(targetLocal.z, targetLocal.y)); - var targetYaw = clamp(_yaw - yaw, YawMin, YawMax); + var targetYaw = _yaw - yaw; var targetPitch = clamp(_pitch - pitch, PitchMin, PitchMax); if (abs(targetYaw - _yaw) < Speed * Time.deltaTime) diff --git a/Assets/Scripts/Gameplay/CapabilityPresentationBinder.cs b/Assets/Scripts/Gameplay/CapabilityPresentationBinder.cs index c2ada7f9d..b9e866c20 100644 --- a/Assets/Scripts/Gameplay/CapabilityPresentationBinder.cs +++ b/Assets/Scripts/Gameplay/CapabilityPresentationBinder.cs @@ -8,27 +8,18 @@ using UnityEngine; // playground-cut.md fork L: "presentation is chosen per item, independently of capability... one // presentation... can visualize any subset of an item's capabilities"). This binder has no knowledge // of FieldDriver or any other concrete presentation, and no knowledge of what publishes events -- -// today the FieldShieldTest scene calls Bind() directly; a real capability owner will do the same -// later without this binder changing. +// EntityInstance binds every entity's events, and the FieldShieldTest scene binds its stand-in sim's the same way. public class CapabilityPresentationBinder : MonoBehaviour { private readonly List _subscriptions = new List(); - private Func _grabTargetResolver; - private Func _grabInitialVelocityResolver; // Subscribes every presenter interface implemented by components on this object or its children to - // the matching stream of `events`. `grabTargetResolver`/`grabInitialVelocityResolver` resolve a - // GrabEvent's plain target handle to the live Transform/velocity a grab presenter needs; the owner - // of `events` supplies them (the test scene today; the real pickup capability's caller later). - public void Bind(CapabilityEvents events, Func grabTargetResolver = null, - Func grabInitialVelocityResolver = null) + // the matching stream of `events`. + public void Bind(CapabilityEvents events) { Unbind(); if (events == null) return; - _grabTargetResolver = grabTargetResolver; - _grabInitialVelocityResolver = grabInitialVelocityResolver; - foreach (var presenter in GetComponentsInChildren(true)) { var p = presenter; @@ -38,12 +29,7 @@ public class CapabilityPresentationBinder : MonoBehaviour foreach (var presenter in GetComponentsInChildren(true)) { var p = presenter; - _subscriptions.Add(events.Grab.Subscribe(e => - { - var target = _grabTargetResolver?.Invoke(e.TargetHandle); - var velocity = _grabInitialVelocityResolver?.Invoke(e.TargetHandle) ?? Vector3.zero; - p.Grab(e, target, velocity); - })); + _subscriptions.Add(events.Grab.Subscribe(e => p.Grab(e))); } foreach (var presenter in GetComponentsInChildren(true)) @@ -63,8 +49,6 @@ public class CapabilityPresentationBinder : MonoBehaviour { foreach (var s in _subscriptions) s.Dispose(); _subscriptions.Clear(); - _grabTargetResolver = null; - _grabInitialVelocityResolver = null; } private void OnDisable() => Unbind(); diff --git a/Assets/Scripts/Gameplay/CapabilityPresenters.cs b/Assets/Scripts/Gameplay/CapabilityPresenters.cs index 34e46dd39..61cc78aac 100644 --- a/Assets/Scripts/Gameplay/CapabilityPresenters.cs +++ b/Assets/Scripts/Gameplay/CapabilityPresenters.cs @@ -10,13 +10,10 @@ public interface IAbsorbPresenter void Absorb(AbsorbEvent e); } -// Grab needs a live Transform to animate, which the engine-free GrabEvent cannot carry (its -// TargetHandle is a plain identity, not a Unity reference). The binder resolves the handle through a -// delegate supplied by the event source's owner and hands the presenter the result, along with the -// initial velocity the target was already moving with (also owner-supplied, for the same reason). +// Presenters read the event and the simulated pose, never a Transform the sim does not own. public interface IGrabPresenter { - void Grab(GrabEvent e, Transform target, Vector3 initialVelocity); + void Grab(GrabEvent e); } public interface IMeleePresenter diff --git a/Assets/Scripts/Gameplay/EntityInstance.cs b/Assets/Scripts/Gameplay/EntityInstance.cs index fb356dd75..e263bac27 100644 --- a/Assets/Scripts/Gameplay/EntityInstance.cs +++ b/Assets/Scripts/Gameplay/EntityInstance.cs @@ -64,6 +64,7 @@ public class EntityInstance : MonoBehaviour public Dictionary BarrelIndices { get; private set; } public Dictionary RadiatorMeshes { get; private set; } public Transform LookAtPoint { get; private set; } + private Dictionary _groupAims; public Entity Entity { get; private set; } public ZoneRenderer ZoneRenderer { get; private set; } public Transform LocalSpace { get; private set; } @@ -166,6 +167,13 @@ public class EntityInstance : MonoBehaviour if(Shield) Shield.Entity = entity; + + // Landed impacts reach the screen through the entity's one binding: the shield ripple (ShieldManager) and the + // hull reaction and camera kick (ImpactPresenter) subscribe to the Absorb stream the simulation publishes. + var impacts = gameObject.GetComponent() ?? gameObject.AddComponent(); + impacts.Entity = entity; + (gameObject.GetComponent() ?? gameObject.AddComponent()) + .Bind(entity.Capabilities); foreach (var hullCollider in HullColliders) hullCollider.Entity = entity; foreach (var item in entity.Equipment) @@ -179,14 +187,15 @@ public class EntityInstance : MonoBehaviour { var pingInstance = Instantiate(PingPrefab); var pingMesh = pingInstance.GetComponent(); - pingInstance.position = entity.Position.ToUnity(); + pingInstance.position = DrawAhead.Position(entity, ActionGameManager.Clock.Lead).ToUnity(); _pingBrightness = pingMesh.material.GetFloat("_Depth"); _currentPing = (pingInstance, pingMesh); }; sensor.OnPingEnd += OnSensorPingEnd; } - if (behavior is InstantWeapon instantWeapon) + // A mine layer's presentation is the mine it lays (MineInstance, drawn by ZoneRenderer from Zone.Mines). + if (behavior is InstantWeapon instantWeapon && !FireControl.IsMineLayer(instantWeapon)) { var data = (InstantWeaponData) instantWeapon.Data; if (!_instantWeaponManagers.ContainsKey(data)) @@ -276,39 +285,22 @@ public class EntityInstance : MonoBehaviour // HullColliders no longer publish Hit or a blast event at all (R8). LookAtPoint = new GameObject($"{entity.Name} Look Point").transform; - + + // One aim point per articulation group, placed each LateUpdate where the group's first weapon aims. + _groupAims = new Dictionary(); foreach (var articulationPoint in ArticulationPoints) { - articulationPoint.Target = LookAtPoint; + if (!_groupAims.TryGetValue(articulationPoint.Group, out var aim)) + _groupAims[articulationPoint.Group] = aim = new GameObject($"{entity.Name} Aim {articulationPoint.Group}").transform; + articulationPoint.Target = aim; } _subscriptions.Add(Entity.HullDamage.Subscribe(_ => { - if (Entity.Hull.Durability < .01f) + if (Entity.Hull.IsDestroyed) { if (!this) return; _destroyed = true; - foreach (var gear in Entity.Equipment) - { - if (gear != Entity.EquippedHull && Random.value < ZoneRenderer.Settings.LootDropProbability) - { - ZoneRenderer.DropItem( - Entity.Position.ToUnity(), - Random.onUnitSphere * ZoneRenderer.Settings.LootDropVelocity, - gear.EquippableItem); - } - } - - foreach (var cargo in Entity.CargoBays) - { - foreach (var item in cargo.Cargo.Keys) - { - ZoneRenderer.DropItem( - Entity.Position.ToUnity(), - Random.onUnitSphere * ZoneRenderer.Settings.LootDropVelocity, - item); - } - } if (DestroyEffect != null) { var t = Instantiate(DestroyEffect).transform; @@ -398,11 +390,23 @@ public class EntityInstance : MonoBehaviour x.Value.material.SetFloat("_Emission", Entity.ItemManager.GameplaySettings.TemperatureEmissionCurve.Evaluate(x.Key.RadiatorTemperature)); } - LookAtPoint.position = transform.position + Entity.Aim.ToUnity() * - (!Entity.Target.Value.IsNone ? max(Entity.TargetRange,Entity.ItemManager.GameplaySettings.ConvergenceMinimumDistance) : 10000); - LocalSpace.localPosition = transform.position = Entity.Position.ToUnity(); + // The drawn pose first: the camera's LookAt and the barrels read this frame's pose, not the last frame's. + var drawn = DrawAhead.Position(Entity, ActionGameManager.Clock.Lead); + LocalSpace.localPosition = transform.position = drawn.ToUnity(); + var aimDistance = !Entity.Target.Value.IsNone + ? max(Entity.TargetRange, Entity.ItemManager.GameplaySettings.ConvergenceMinimumDistance) + : 10000; + LookAtPoint.position = transform.position + Entity.Aim.ToUnity() * aimDistance; + foreach (var group in _groupAims) + { + var weapon = group.Key >= 0 && group.Key < Entity.WeaponGroups.Length ? Entity.WeaponGroups[group.Key].weapons.FirstOrDefault() : null; + if (weapon == null) { group.Value.position = LookAtPoint.position; continue; } + var barrel = Barrels.TryGetValue(weapon.Item.Hardpoint, out var barrels) ? barrels[0].position : transform.position; + var direction = FireControl.Solution(weapon, Entity, Entity.Target.Value).Direction; + group.Value.position = barrel + new Vector3(direction.x, 0, direction.y) * aimDistance; + } if (_influenceInstance) - _influenceInstance.position = new Vector3(Entity.Position.x, 0, Entity.Position.z); + _influenceInstance.position = new Vector3(drawn.x, 0, drawn.z); } public virtual void OnDestroy() diff --git a/Assets/Scripts/Gameplay/FieldDriver.cs b/Assets/Scripts/Gameplay/FieldDriver.cs index dd6b36cc3..1c5d0a352 100644 --- a/Assets/Scripts/Gameplay/FieldDriver.cs +++ b/Assets/Scripts/Gameplay/FieldDriver.cs @@ -63,11 +63,7 @@ public class FieldDriver : MonoBehaviour, IAbsorbPresenter, IGrabPresenter, IMel // public float GrabScaleAnimationExponent = .5f; [Inspectable] - public float GrabExtendTime; - [Inspectable] - public float GrabEnvelopTime; - [Inspectable] - public float GrabPullTime; + public float TendrilTipScale = 1; [Inspectable] public RectTransform.Axis RefractionAxis = RectTransform.Axis.Horizontal; @@ -81,29 +77,17 @@ public class FieldDriver : MonoBehaviour, IAbsorbPresenter, IGrabPresenter, IMel private float _meleeTime; private bool _meleeActive; private MeshCollider _collider; - private Transform _grabObject; - private Vector3 _grabObjectStartPos; - private Vector3 _grabObjectStartTendrilBasePos; - private Vector3 _grabObjectEndPos; - private Vector3 _grabObjectVelocity; - private float _grabObjectScale; + private bool _grabbing; + private GrabPhase _grabPhase; private float _grabTime; - private TendrilPhase _grabPhase; + private float _phaseDuration; + private Vector3 _grabStart; + private Vector3 _grabStartTendrilBase; private Vector3 _tendrilBasePos; private Vector3 _tendrilBendTarget; private Vector3 _tendrilTargetPos; private float _fadePoint; - // Named distinctly from the global GrabPhase (CapabilityEvents.cs): this is FieldDriver's own - // internal tendril-animation timing, still owned here until a real pickup capability exists to - // publish per-phase GrabEvent transitions (see Grab(GrabEvent, Transform, Vector3) below). - private enum TendrilPhase - { - Extend, - Envelop, - Pull - } - private struct FieldHit { public float3 Position; @@ -181,32 +165,41 @@ public class FieldDriver : MonoBehaviour, IAbsorbPresenter, IGrabPresenter, IMel _meleeTime = 0; } - public bool CanGrab => _grabObject == null; - - public void GrabObject(Transform t, Vector3 v) - { - _grabPhase = TendrilPhase.Extend; - _grabObject = t; - _grabObjectStartPos = t.position; - _grabObjectVelocity = v; - _grabObjectScale = t.localScale.x; - _tendrilBasePos = _grabObjectStartTendrilBasePos = _collider.ClosestPoint(_grabObjectStartPos); - _fadePoint = .999f; - } - // IAbsorbPresenter: delegates straight to the existing hit-buffer mechanism. e.DamageType is not // read -- the field shield has no per-damage-type visual today; it rides along in the event for // presentations that do vary by type (the mask itself is absorb-capability data, out of scope here). public void Absorb(AbsorbEvent e) => AddHit(e.Position, e.Direction, e.Magnitude); - // IGrabPresenter: only the Started phase does anything today. FieldDriver still times the - // extend/envelop/pull animation itself (TendrilPhase above, driven by GrabExtendTime/ - // GrabEnvelopTime/GrabPullTime) because no capability yet publishes those phase transitions; - // once one does, this is where FieldDriver would react to Envelop/Pull/Completed/Cancelled too. - public void Grab(GrabEvent e, Transform target, Vector3 initialVelocity) + // IGrabPresenter: the simulation owns the grab; this draws the tendril from the events alone. Started records + // where the item is held and where the tendril leaves the field; Extend, Envelop and Pull set the phase and + // restart the real-time phase clock over the event's duration (it clamps at 1 until the next event, so a + // slowed simulation stretches the wait, not the animation); Completed and Cancelled end it. + public void Grab(GrabEvent e) { - if (e.Phase == GrabPhase.Started && target != null) - GrabObject(target, initialVelocity); + switch (e.Phase) + { + case GrabPhase.Started: + _grabbing = true; + _grabPhase = GrabPhase.Started; + _grabStart = e.TargetPosition.ToUnity(); + _tendrilBasePos = _grabStartTendrilBase = _collider.ClosestPoint(_grabStart); + _tendrilTargetPos = _grabStart; + _fadePoint = .999f; + break; + case GrabPhase.Extend: + case GrabPhase.Envelop: + case GrabPhase.Pull: + if (!_grabbing) break; + _grabPhase = e.Phase; + _grabTime = 0; + _phaseDuration = e.PhaseDuration; + break; + case GrabPhase.Completed: + case GrabPhase.Cancelled: + _grabbing = false; + _field.SetFloat("_TendrilInfluence", 0); + break; + } } // IMeleePresenter: the field shield's swing shape comes from its own authored curves @@ -277,74 +270,47 @@ public class FieldDriver : MonoBehaviour, IAbsorbPresenter, IGrabPresenter, IMel } - if(_grabObject != null) + if (_grabbing && _grabPhase != GrabPhase.Started) { - _grabTime += Time.deltaTime / _grabPhase switch + _grabTime = min(1, _grabTime + Time.deltaTime / max(_phaseDuration, 1e-4f)); + _tendrilBasePos = damp(_tendrilBasePos.ToCultMath(), _tendrilTargetPos.ToCultMath(), TendrilBaseDamping, Time.deltaTime).ToUnity(); + switch (_grabPhase) { - TendrilPhase.Extend => GrabExtendTime, - TendrilPhase.Envelop => GrabEnvelopTime, - TendrilPhase.Pull => GrabPullTime, - _ => throw new ArgumentOutOfRangeException() - }; - if (_grabTime > 1) - { - _grabTime = 0; - if (_grabPhase == TendrilPhase.Envelop) - { - _grabObjectEndPos = _grabObject.position; - } - if (_grabPhase == TendrilPhase.Pull) - { - Destroy(_grabObject.gameObject); - _grabObject = null; - _field.SetFloat("_TendrilInfluence", 0); - } - else _grabPhase++; - } - - if (_grabObject != null) - { - _tendrilBasePos = damp(_tendrilBasePos.ToCultMath(), _grabObject.position.ToCultMath(), TendrilBaseDamping, Time.deltaTime).ToUnity(); - switch (_grabPhase) - { - case TendrilPhase.Extend: - _tendrilBendTarget = _grabObjectStartPos; - _grabObject.position += _grabObjectVelocity * Time.deltaTime; - _tendrilTargetPos = lerp( - lerp(_grabObjectStartTendrilBasePos.ToCultMath(), _grabObjectStartPos.ToCultMath(), _grabTime), - lerp(_grabObjectStartPos.ToCultMath(), _grabObject.position.ToCultMath(), _grabTime), - pow(_grabTime, TendrilExtensionExponent)).ToUnity(); - _field.SetFloat("_TendrilInfluence", pow(_grabTime, TendrilExtendBaseAnimationExponent)); - _field.SetFloat("_TendrilSize", lerp(TendrilBaseRadius/2,TendrilBaseRadius,pow(_grabTime, TendrilExtendBaseAnimationExponent))); - _field.SetFloat("_TendrilRadius", _grabObjectScale * pow(_grabTime, TendrilTipRadiusAnimationExponent) * TendrilTipRadius); - break; - case TendrilPhase.Envelop: - _tendrilBendTarget = _grabObjectStartPos; - _tendrilTargetPos = _grabObject.position += _grabObjectVelocity * Time.deltaTime * (1-_grabTime); - _field.SetFloat("_TendrilInfluence", 1); - _field.SetFloat("_TendrilSize", TendrilBaseRadius); - _field.SetFloat("_TendrilRadius", _grabObjectScale * TendrilTipRadius); - break; - case TendrilPhase.Pull: - _tendrilTargetPos = _grabObject.position = lerp(_grabObjectEndPos.ToCultMath(), transform.position.ToCultMath(), _grabTime*_grabTime).ToUnity(); - _tendrilBendTarget = lerp(_grabObjectStartPos.ToCultMath(), _grabObjectEndPos.ToCultMath(), _grabTime*_grabTime).ToUnity(); - if (_fadePoint > .99 && transform.InverseTransformPoint(_grabObject.position).sqrMagnitude < 1) - _fadePoint = _grabTime; - _field.SetFloat("_TendrilInfluence", pow(smoothstep(1, _fadePoint, _grabTime), TendrilFadeExponent)); - _field.SetFloat("_TendrilSize", TendrilBaseRadius); - _field.SetFloat("_TendrilRadius", _grabObjectScale * TendrilTipRadius); - break; - default: - throw new ArgumentOutOfRangeException(); - } - var tendrilRadii = EnvelopeRadiiOrFallback(); - _field.SetVector("_TendrilBase", Vector3.Scale(transform.InverseTransformPoint(_tendrilBasePos).normalized, tendrilRadii)); - _field.SetVector("_TendrilBend", Vector3.Scale(transform.InverseTransformPoint(_tendrilBendTarget), tendrilRadii)); - _field.SetVector("_TendrilTarget", Vector3.Scale(transform.InverseTransformPoint(_tendrilTargetPos), tendrilRadii)); + case GrabPhase.Extend: + _tendrilBendTarget = _grabStart; + _tendrilTargetPos = lerp( + lerp(_grabStartTendrilBase.ToCultMath(), _grabStart.ToCultMath(), _grabTime), + _grabStart.ToCultMath(), + pow(_grabTime, TendrilExtensionExponent)).ToUnity(); + _field.SetFloat("_TendrilInfluence", pow(_grabTime, TendrilExtendBaseAnimationExponent)); + _field.SetFloat("_TendrilSize", lerp(TendrilBaseRadius/2,TendrilBaseRadius,pow(_grabTime, TendrilExtendBaseAnimationExponent))); + _field.SetFloat("_TendrilRadius", TendrilTipScale * pow(_grabTime, TendrilTipRadiusAnimationExponent) * TendrilTipRadius); + break; + case GrabPhase.Envelop: + _tendrilBendTarget = _grabStart; + _tendrilTargetPos = _grabStart; + _field.SetFloat("_TendrilInfluence", 1); + _field.SetFloat("_TendrilSize", TendrilBaseRadius); + _field.SetFloat("_TendrilRadius", TendrilTipScale * TendrilTipRadius); + break; + case GrabPhase.Pull: + // The curve of Zone's held pose (Zone.HeldPull): the tip rides the item the simulation pulls in. + _tendrilTargetPos = lerp(_grabStart.ToCultMath(), transform.position.ToCultMath(), Zone.HeldPull(_grabTime)).ToUnity(); + _tendrilBendTarget = _grabStart; + if (_fadePoint > .99 && transform.InverseTransformPoint(_tendrilTargetPos).sqrMagnitude < 1) + _fadePoint = _grabTime; + _field.SetFloat("_TendrilInfluence", pow(smoothstep(1, _fadePoint, _grabTime), TendrilFadeExponent)); + _field.SetFloat("_TendrilSize", TendrilBaseRadius); + _field.SetFloat("_TendrilRadius", TendrilTipScale * TendrilTipRadius); + break; } + var tendrilRadii = EnvelopeRadiiOrFallback(); + _field.SetVector("_TendrilBase", Vector3.Scale(transform.InverseTransformPoint(_tendrilBasePos).normalized, tendrilRadii)); + _field.SetVector("_TendrilBend", Vector3.Scale(transform.InverseTransformPoint(_tendrilBendTarget), tendrilRadii)); + _field.SetVector("_TendrilTarget", Vector3.Scale(transform.InverseTransformPoint(_tendrilTargetPos), tendrilRadii)); } } - + private float almostIdentity( float x ) { return x*x*(2.0f-x); @@ -358,7 +324,7 @@ public class FieldDriver : MonoBehaviour, IAbsorbPresenter, IGrabPresenter, IMel private const int GIZMO_STEPS = 16; private void OnDrawGizmosSelected() { - if (_grabObject != null) + if (_grabbing) { Vector3 previous = _tendrilBasePos; for (int i = 1; i <= GIZMO_STEPS; i++) diff --git a/Assets/Scripts/Gameplay/GameSettings.cs b/Assets/Scripts/Gameplay/GameSettings.cs index 2548f1a13..65e134755 100644 --- a/Assets/Scripts/Gameplay/GameSettings.cs +++ b/Assets/Scripts/Gameplay/GameSettings.cs @@ -11,14 +11,10 @@ using UnityEngine; public class GameSettings : ScriptableObject { public string StartingHullName = "Longinus"; - public float PickupLifetime = 30; - public float LootDropProbability = .25f; - public float LootDropVelocity = 25; public float HeatstrokePhasingFloor = 0; public float HeatstrokePhasingFrequency = 5; public float WormholeDistanceRatio; public float DefaultViewDistance; - public float MinimapZoneGravityRange; public float[] MinimapZoomLevels; public int DefaultMinimapZoom; public ExponentialCurve IconSize; diff --git a/Assets/Scripts/Gameplay/GridObject.cs b/Assets/Scripts/Gameplay/GridObject.cs deleted file mode 100644 index 82d64199a..000000000 --- a/Assets/Scripts/Gameplay/GridObject.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using CultMath; -using CultMath.UnityBridge; -using UnityEngine; -using static CultMath.math; -using Random = UnityEngine.Random; - -public class GridObject : MonoBehaviour -{ - public float RotationSpeed; - public float GridOffset; - public float GridAttraction; - public float Gravity; - public float Drag = .1f; - public float LaunchDrag; - - private float2 _selfVelocity; - private float _timeOffset; - - public Zone Zone { get; set; } - public Vector3 Velocity { get; set; } - - private void Start() - { - _timeOffset = Random.value * 100; - } - - void Update() - { - var t = transform; - t.localRotation = Quaternion.Euler(sin(Time.time - _timeOffset * RotationSpeed) * 90, 0, cos(Time.time - _timeOffset * RotationSpeed) * 90); - - if (Zone == null) return; - - var position = t.position; - var gridHeight = Zone.GetHeight(position.Flatland().ToCultMath()) + GridOffset; - Velocity += Vector3.up * (sign(gridHeight - position.y) * GridAttraction * Time.deltaTime); - Velocity *= max(0, 1 - LaunchDrag * Time.deltaTime); - var normal = Zone.GetNormal(position.Flatland().ToCultMath()); - var force = new float2(normal.x, normal.z); - var forceMagnitude = lengthsq(force); - if (forceMagnitude > .001f) - { - var fa = 1 / (1 - forceMagnitude) - 1; - _selfVelocity += normalize(force) * Zone.Settings.GravityStrength * fa * Gravity; - } - - _selfVelocity *= max(0, 1 - Drag * Time.deltaTime); - t.position = position + (Velocity + new Vector3(_selfVelocity.x, 0, _selfVelocity.y)) * Time.deltaTime; - } -} \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/GridObject.cs.meta b/Assets/Scripts/Gameplay/GridObject.cs.meta deleted file mode 100644 index 335d81a85..000000000 --- a/Assets/Scripts/Gameplay/GridObject.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 737f47c158214f0995ba2835f040ed96 -timeCreated: 1618441439 \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/HullCollider.cs b/Assets/Scripts/Gameplay/HullCollider.cs index 8d9275eb4..795de4755 100644 --- a/Assets/Scripts/Gameplay/HullCollider.cs +++ b/Assets/Scripts/Gameplay/HullCollider.cs @@ -1,17 +1,12 @@ using UnityEngine; -using CultMath.UnityBridge; // Cut 4 (docs/fire-control-cut.md): Hit, Splash, SendHit and SendSplash are deleted -- their last callers // (ConstantLaser, ConstantLightning, ConstantParticleWeapon, HitscanEffect) are gone too (see those // files and FireControl.Detonate, 12.4(b)'s renamed Splash). Nothing decides or applies damage through a Unity -// collider any more (R8): -// this component is now purely a physics surface for ship-on-ship collision impulse, not hit detection. +// collider any more (R8), and no collision callback writes an Entity (cut sim-contact): ship contact is +// Zone's, through Contacts.Step. This component holds the hull's collider for authoring, smokes and click +// picking, and writes nothing. public class HullCollider : MonoBehaviour { public Entity Entity { get; set; } - - private void OnCollisionEnter(Collision other) - { - Entity.Velocity += other.impulse.ToCultMath().xz / Time.deltaTime; - } } diff --git a/Assets/Scripts/Gameplay/ImpactFeedback.cs b/Assets/Scripts/Gameplay/ImpactFeedback.cs new file mode 100644 index 000000000..6c1f43df1 --- /dev/null +++ b/Assets/Scripts/Gameplay/ImpactFeedback.cs @@ -0,0 +1,39 @@ +using Cinemachine; +using UnityEngine; + +// Presentation tuning for landed impacts (ImpactPresenter reads it, nothing in the simulation does): the hull +// reaction's effect prefab and size, how strongly a hit's share of the hull reads (Feedback.Cue's intensityScale), +// and the camera impulse. A scene component, so the scene is where it is tuned; absent in menus and test scenes, +// where ImpactPresenter does nothing. +public class ImpactFeedback : MonoBehaviour +{ + public static ImpactFeedback Instance { get; private set; } + + // A scene instance of a pooled hit effect (Prototype); a hit spawns one under the struck EntityInstance. + public Prototype HullEffect; + + // Multiplies a hit's share of the receiver's max durability before it saturates to 0..1 (Feedback.Cue). + public float IntensityScale = 10f; + + // The effect's scale never drops below this, so the lightest hit still reads. + public float MinEffectScale = .3f; + + public CinemachineImpulseDefinition Impulse = new CinemachineImpulseDefinition(); + + // Impulses raised since the scene loaded; the batchmode smoke reads it. + public int KicksRaised { get; private set; } + + private void Awake() => Instance = this; + + private void OnDestroy() + { + if (Instance == this) Instance = null; + } + + // Raises one camera impulse of the given force, travelling along `direction` from `position`. + public void Kick(Vector3 position, Vector3 direction, float force) + { + KicksRaised++; + Impulse.CreateEvent(position, direction.normalized * force); + } +} diff --git a/Assets/Scripts/Gameplay/ImpactFeedback.cs.meta b/Assets/Scripts/Gameplay/ImpactFeedback.cs.meta new file mode 100644 index 000000000..1d5613e95 --- /dev/null +++ b/Assets/Scripts/Gameplay/ImpactFeedback.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: bfdc38a81d00b0347bb55ad6469535ff \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/ImpactPresenter.cs b/Assets/Scripts/Gameplay/ImpactPresenter.cs new file mode 100644 index 000000000..9796ec753 --- /dev/null +++ b/Assets/Scripts/Gameplay/ImpactPresenter.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using CultMath.UnityBridge; +using UnityEngine; + +// How one entity's landed impacts look and feel: the hull reaction at the drawn impact point, and the player's camera +// kick. The simulation publishes each impact once on the entity's Capabilities (FireControl); Feedback.Cue decides how +// hard it reads and whether the camera feels it, DrawAhead.Carried decides where it is drawn; this decides nothing. +// The hull effect is drawn only where the player's instruments place the ship (ActionGameManager.DrawsAt). +// The shield ripple is ShieldManager's. Everything here is display-only and runs in real time. +public class ImpactPresenter : MonoBehaviour, IAbsorbPresenter +{ + public Entity Entity; + + private readonly List _live = new List(); + + public void Absorb(AbsorbEvent e) + { + var feedback = ImpactFeedback.Instance; + if (feedback == null || Entity == null) return; + + var manager = ActionGameManager.Instance; + var cue = Feedback.Cue(e, Entity.EquippedHull.Data.Durability, + manager != null && Entity == manager.CurrentEntity, + ActionGameManager.PlayerSettings.GraphicsSettings.ScreenShake, feedback.IntensityScale); + var point = DrawAhead.Carried(Entity, cue.Position, ActionGameManager.Clock.Lead).ToUnity(); + + if (e.Layer == AbsorbLayer.Hull && feedback.HullEffect != null && ActionGameManager.DrawsAt(Entity)) + { + _live.RemoveAll(live => live == null || !live.gameObject.activeSelf); + var effect = feedback.HullEffect.Instantiate(); + var size = Mathf.Max(feedback.MinEffectScale, cue.Intensity); + effect.transform.SetParent(transform, false); + effect.transform.position = point; + effect.transform.localScale = Vector3.one * (size / Mathf.Max(transform.lossyScale.x, 1e-3f)); + _live.Add(effect); + } + + if (cue.Shake > 0f) + feedback.Kick(point, new Vector3(cue.Direction.x, 0f, cue.Direction.z), cue.Shake); + } + + // A live effect is a pooled child of this instance; hand it back before the instance takes it down with it. + private void OnDestroy() + { + foreach (var live in _live) + if (live != null && live.gameObject.activeSelf) live.ReturnToPool(); + } +} diff --git a/Assets/Scripts/Gameplay/ImpactPresenter.cs.meta b/Assets/Scripts/Gameplay/ImpactPresenter.cs.meta new file mode 100644 index 000000000..4c69429bc --- /dev/null +++ b/Assets/Scripts/Gameplay/ImpactPresenter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 775c61f785344d54b9f41ad3328cecee \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/ItemPickup.cs b/Assets/Scripts/Gameplay/ItemPickup.cs index 2a6621194..1378d6e28 100644 --- a/Assets/Scripts/Gameplay/ItemPickup.cs +++ b/Assets/Scripts/Gameplay/ItemPickup.cs @@ -4,9 +4,14 @@ using CultMath; using CultMath.UnityBridge; using UnityEngine; using static CultMath.math; +using Random = UnityEngine.Random; +// How one floating item looks. Zone owns the item's every fact (existence, position, expiry, pickup); once bound, +// this reads the latest sim body and draws, spun for show, and writes nothing back (rulings unity-presents-only-r3 +// and sim-speed-presentation). An unbound pickup (FieldTester's test scene) leaves its transform alone. public class ItemPickup : MonoBehaviour { + public float RotationSpeed = 1f; public float LabelFadeDuration = .5f; public float LabelPersistDuration = 3; public float LabelDisplayAngle = 15; @@ -15,28 +20,51 @@ public class ItemPickup : MonoBehaviour public TextMeshPro ScanLabel; public ItemInstance Item { get; set; } - public ZoneRenderer ZoneRenderer { get; set; } public float3 ViewOrigin { get; set; } public float3 ViewDirection { get; set; } private float _displayTime; + private float _timeOffset; + private Zone _zone; + private GameplaySettings _settings; + private FloatingItem _floating; + + public void Bind(Zone zone, FloatingItem floating, GameplaySettings settings) + { + _zone = zone; + _settings = settings; + _floating = floating; + Item = floating.Item; + _timeOffset = Random.value * 100; + Place(); + } + + private void Place() + { + var lead = ActionGameManager.Clock.Lead; + var p = DrawAhead.Position(_floating.Body, lead); + transform.position = new Vector3(p.x, DrawAhead.FloaterHeight(_zone, _settings, p, lead), p.y); + } private void Update() { + if (_floating != null) + { + Place(); + transform.localRotation = Quaternion.Euler( + sin(Time.time - _timeOffset * RotationSpeed) * 90, 0, cos(Time.time - _timeOffset * RotationSpeed) * 90); + } + var diff = transform.position.ToCultMath() - ViewOrigin; var toThis = normalize(diff); var viewAngle = acos(dot(toThis, ViewDirection)) * Mathf.Rad2Deg; if (length(diff) < LabelDisplayMaxDistance && viewAngle < LabelDisplayAngle) _displayTime = Time.time; + if (_floating?.Holder != null) _displayTime = Time.time; var targetAlpha = Time.time - _displayTime < LabelPersistDuration ? 1 : 0; var c = ScanLabel.color; c.a = c.a + sign(targetAlpha - c.a) * (Time.deltaTime / LabelFadeDuration); ScanLabel.color = c; ScanLabelContainer.rotation = Quaternion.LookRotation((-toThis).ToUnity()); } - - private void OnDestroy() - { - ZoneRenderer?.DestroyLoot(this); - } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Gameplay/MineInstance.cs b/Assets/Scripts/Gameplay/MineInstance.cs new file mode 100644 index 000000000..006f7d631 --- /dev/null +++ b/Assets/Scripts/Gameplay/MineInstance.cs @@ -0,0 +1,76 @@ +using CultMath; +using CultMath.UnityBridge; +using UnityEngine; +using static CultMath.math; +using Random = UnityEngine.Random; + +// How one laid mine looks. Zone owns the mine's every fact (position, arming, trigger, end); this reads them and +// draws, and writes nothing back. The pose is the latest sim body, spun for show; the pulse runs in real time +// (rulings unity-presents-only-r3 and sim-speed-presentation). +public class MineInstance : MonoBehaviour +{ + public MeshRenderer MeshRenderer; + public int EmissionSubmesh = 2; + public AnimationCurve EmissionCurve; + public float ActiveCycleDuration = 1f; + public float ArmedCycleDuration = .25f; + public float ActiveEmission = 100f; + public float ArmedEmission = 1000f; + public float RotationSpeed = 1f; + // The blast's particles; the effect prefab destroys itself when its particle system stops. + public GameObject HitEffect; + public float HitEffectScale = 10f; + + private Zone _zone; + private GameplaySettings _settings; + private Mine _mine; + private Material _material; + private float _timeOffset; + private float _pulse; + private float _emission; + + public void Bind(Zone zone, Mine mine, GameplaySettings settings) + { + _zone = zone; + _settings = settings; + _mine = mine; + _material = MeshRenderer.materials[EmissionSubmesh]; + _timeOffset = Random.value * 100; + Place(); + } + + private void Update() + { + Place(); + transform.localRotation = Quaternion.Euler( + sin(Time.time - _timeOffset * RotationSpeed) * 90, 0, cos(Time.time - _timeOffset * RotationSpeed) * 90); + + // None before the mine arms, then slow while it waits and fast once its fuse is lit. + var armed = _mine.Armed(_zone.Time); + var counting = _mine.TriggeredAt != null; + var target = !armed ? 0f : counting ? ArmedEmission : ActiveEmission; + _emission = lerp(_emission, target, Time.deltaTime * 10); + _pulse = (_pulse + Time.deltaTime / (counting ? ArmedCycleDuration : ActiveCycleDuration)) % 1; + _material.SetFloat("_Emission", _emission * EmissionCurve.Evaluate(_pulse)); + } + + private void Place() + { + var lead = ActionGameManager.Clock.Lead; + var p = DrawAhead.Position(_mine.Body, lead); + transform.position = new Vector3(p.x, DrawAhead.FloaterHeight(_zone, _settings, p, lead), p.y); + } + + // The mine left Zone.Mines, which only its blast does: show it where it was drawn last. + public void Blast() + { + var effect = Instantiate(HitEffect, transform.position, Quaternion.identity); + effect.transform.localScale = Vector3.one * HitEffectScale; + Destroy(gameObject); + } + + private void OnDestroy() + { + if (_material) Destroy(_material); + } +} diff --git a/Assets/Scripts/Gameplay/MineInstance.cs.meta b/Assets/Scripts/Gameplay/MineInstance.cs.meta new file mode 100644 index 000000000..6640716ed --- /dev/null +++ b/Assets/Scripts/Gameplay/MineInstance.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 35c62f5e26769f645b1a1614a70422e1 \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/ShieldManager.cs b/Assets/Scripts/Gameplay/ShieldManager.cs index 05a303e6d..0514cf1e7 100644 --- a/Assets/Scripts/Gameplay/ShieldManager.cs +++ b/Assets/Scripts/Gameplay/ShieldManager.cs @@ -5,14 +5,37 @@ using System.Linq; using CultMath; using CultMath.UnityBridge; using static CultMath.math; +using UniRx; using UnityEngine; -public class ShieldManager : MonoBehaviour +public class ShieldManager : MonoBehaviour, IAbsorbPresenter { public Prototype ShieldPrototype; public float CollisionHitDuration = 3; - public Entity Entity { get; set; } + private Entity _entity; + private IDisposable _contacts; + + // Ship-on-ship contact is Zone's (Contacts.Step); this shield only presents it. + public Entity Entity + { + get => _entity; + set + { + _contacts?.Dispose(); + _entity = value; + _contacts = value?.Zone.Contacted.Subscribe(Present); + } + } + + private void OnDestroy() => _contacts?.Dispose(); + + private void Present(ContactEvent contact) + { + if (contact.A != Entity && contact.B != Entity) return; + if (Entity.Shield != null && Entity.Shield.Item.Active.Value) + ShowHit(DrawAhead.Carried(Entity, float3(contact.Point.x, Entity.Position.y, contact.Point.y), ActionGameManager.Clock.Lead).ToUnity(), CollisionHitDuration); + } private ShieldEnvelope _envelope; private bool _loggedMissingEnvelope; @@ -29,55 +52,12 @@ public class ShieldManager : MonoBehaviour Debug.LogWarning("ShieldManager has no ShieldEnvelope; falling back to its own transform for the hit direction.", this); } - private void OnCollisionEnter(Collision other) + // A shot the shield took ripples it where the shot landed, drawn on the hull as it is drawn. The hull layer is + // ImpactPresenter's. + public void Absorb(AbsorbEvent e) { - var otherShield = other.collider.GetComponent(); - if (!otherShield) - { - var gridObject = other.collider.GetComponent(); - if (gridObject) - { - var itemPickup = other.collider.GetComponent(); - if (itemPickup) - { - if (Entity.CargoBays.Any(c => c.TryStore(itemPickup.Item))) - { - // TODO: Pickup notification! - Destroy(itemPickup.gameObject); - } - else - { - // TODO: Pickup failed notification! - var cp = other.GetContact(0); - gridObject.Velocity += cp.normal * 25; - Debug.Log("Attempted item pickup, but no space in cargo bay!"); - } - } - else - { - Debug.Log("Shield collision occurred with grid object, but other collider isn't an item pickup!"); - } - } - else - Debug.Log("Shield collision occurred, but other collider isn't a shield or a grid object!"); - return; - } - var contact = other.GetContact(0); - var normal = normalize(float2(contact.normal.x, contact.normal.z)); - var tangent = normal.Rotate(ItemRotation.CounterClockwise); - var v1n = dot(normal, Entity.Velocity); - var v1t = dot(tangent, Entity.Velocity); - var v2n = dot(normal, otherShield.Entity.Velocity); - //var v2t = dot(tangent, otherShield.Entity.Velocity); - - var v1np = PostCollisionVelocity(v1n, Entity.Mass, v2n, otherShield.Entity.Mass); - Entity.Velocity = tangent * v1t + normal * v1np; - if(Entity.Shield != null && Entity.Shield.Item.Active.Value) ShowHit(contact.point, CollisionHitDuration); - } - - private float PostCollisionVelocity(float v1, float m1, float v2, float m2) - { - return (v1 * (m1 - m2) + m2 * v2) / (m1 + m2); + if (e.Layer != AbsorbLayer.Shield || Entity == null || Entity.Shield == null || !Entity.Shield.Item.Active.Value || !ActionGameManager.DrawsAt(Entity)) return; + ShowHit(DrawAhead.Carried(Entity, e.Position, ActionGameManager.Clock.Lead).ToUnity(), CollisionHitDuration); } public void ShowHit(Vector3 point, float duration) diff --git a/Assets/Scripts/Gameplay/ShipInstance.cs b/Assets/Scripts/Gameplay/ShipInstance.cs index cc110fc8f..3befea9b0 100644 --- a/Assets/Scripts/Gameplay/ShipInstance.cs +++ b/Assets/Scripts/Gameplay/ShipInstance.cs @@ -18,16 +18,7 @@ public class ShipInstance : EntityInstance public int MaxParticleCount; } - private class AetherDriveInstance - { - public AetherDrive Drive; - public ParticleSystem Particles; - public float BaseEmission; - public float BaseForce; - } - private ThrusterInstance[] _thrusters; - private AetherDriveInstance _aetherDrive; public Ship Ship { get; private set; } @@ -47,20 +38,6 @@ public class ShipInstance : EntityInstance return; } Ship = ship; - var drive = ship.GetBehavior(); - if (drive != null) - { - var particles = Instantiate(EngineAssets.Load(drive.DriveData.Particles), transform, false); - var main = particles.main; - main.customSimulationSpace = LocalSpace; - _aetherDrive = new AetherDriveInstance - { - Drive = drive, - BaseEmission = particles.emission.rateOverTimeMultiplier, - Particles = particles, - BaseForce = particles.forceOverLifetime.z.curveMultiplier - }; - } _thrusters = ship.GetBehaviors().Select(thruster => { var effectData = (ThrusterData) thruster.Data; @@ -115,19 +92,6 @@ public class ShipInstance : EntityInstance TractorBeam.Power = Entity.TractorPower; TractorBeam.Direction = Entity.Aim.ToUnity(); - if (_aetherDrive != null) - { - var thrust = length(_aetherDrive.Drive.ThrustDirection); - var forceOverLifetime = _aetherDrive.Particles.forceOverLifetime; - forceOverLifetime.xMultiplier = _aetherDrive.Drive.ThrustDirection.x * _aetherDrive.BaseForce; - forceOverLifetime.zMultiplier = _aetherDrive.Drive.ThrustDirection.y * _aetherDrive.BaseForce; - var emissionModule = _aetherDrive.Particles.emission; - // Cut 8 (operator ask 2026-09-19): intent (thrust) times condition -- presentation reads the - // simulation's own ratio rather than recomputing any part of it. AetherDrive.Condition is the - // equivalent of Thruster.Condition below (Torque in place of Thrust). - emissionModule.rateOverTimeMultiplier = _aetherDrive.BaseEmission * thrust * _aetherDrive.Drive.Condition; - } - foreach (var thrusterInstance in _thrusters) { var emissionModule = thrusterInstance.System.emission; @@ -138,6 +102,6 @@ public class ShipInstance : EntityInstance emissionModule.rateOverTimeMultiplier = thrusterInstance.BaseEmission * thrusterInstance.Thruster.Axis * thrusterInstance.Thruster.Condition; } - transform.rotation = Ship.Rotation.ToUnity(); + transform.rotation = DrawAhead.Rotation(Ship, ActionGameManager.Clock.Lead).ToUnity(); } } \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/TimedDestroy.cs b/Assets/Scripts/Gameplay/TimedDestroy.cs deleted file mode 100644 index fbbd86f8c..000000000 --- a/Assets/Scripts/Gameplay/TimedDestroy.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using UnityEngine; - -public class TimedDestroy : MonoBehaviour -{ - public float Duration; - - private float _startTime; - - private void Start() - { - _startTime = Time.time; - } - - public void Update() - { - if(Time.time - _startTime > Duration) Destroy(gameObject); - } -} \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/TimedDestroy.cs.meta b/Assets/Scripts/Gameplay/TimedDestroy.cs.meta deleted file mode 100644 index 2f6bac661..000000000 --- a/Assets/Scripts/Gameplay/TimedDestroy.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5d5539a23b814254b038a16f32f1d8a9 -timeCreated: 1618453298 \ No newline at end of file diff --git a/Assets/Scripts/Gameplay/TractorBeam.cs b/Assets/Scripts/Gameplay/TractorBeam.cs index 579cc813f..64a6a5f1a 100644 --- a/Assets/Scripts/Gameplay/TractorBeam.cs +++ b/Assets/Scripts/Gameplay/TractorBeam.cs @@ -1,33 +1,51 @@ using System; using UnityEngine; +using CultMath.UnityBridge; -public class TractorBeam : MonoBehaviour +// Presents the ship's grab: while the simulation holds an item, the beam looks along the ground-plane vector to the +// point the item was held from and emits at Power. Zone pulls the held item along the segment from the ship to that +// point (docs/aetheria-release-map.md L11), which is why GrabEvent.TargetPosition on Started is the exact aim and no +// pose lookup is needed. Idle, the beam turns with Direction and emits nothing. The simulation decides every grab fact. +public class TractorBeam : MonoBehaviour, IGrabPresenter { public ParticleSystem ParticleSystem; - public float Radius; - public float Traction; - public float Distance; - + public float Power { get; set; } public Vector3 Direction { get; set; } + private bool _grabbing; + private Vector3 _heldPoint; + private Vector3 _heldDirection; + + // Cancelled can carry no position (a vanished item), so only Started is read for one. + public void Grab(GrabEvent e) + { + switch (e.Phase) + { + case GrabPhase.Started: + _grabbing = true; + _heldPoint = e.TargetPosition.ToUnity(); + _heldDirection = Direction; + break; + case GrabPhase.Completed: + case GrabPhase.Cancelled: + _grabbing = false; + break; + } + } + public void Update() { - transform.rotation = Quaternion.LookRotation(Direction); - var emission = ParticleSystem.emission; - if (Power > .01f) + var look = Direction; + if (_grabbing) { - var objectFound = false; - foreach (var o in Physics.SphereCastAll(transform.position, Radius, Direction, Distance, 1 << 21)) - { - var gridObject = o.collider.GetComponent(); - if (gridObject == null) continue; - objectFound = true; - gridObject.Velocity += Vector3.Normalize(transform.position - gridObject.transform.position) * (Traction * Time.deltaTime); - } - - emission.rateOverTimeMultiplier = objectFound ? Power : 0; + var toHeld = _heldPoint - transform.position; + toHeld.y = 0; + if (toHeld.sqrMagnitude > 1e-6f) _heldDirection = toHeld; + look = _heldDirection; } - else emission.rateOverTimeMultiplier = 0; + transform.rotation = Quaternion.LookRotation(look); + var emission = ParticleSystem.emission; + emission.rateOverTimeMultiplier = _grabbing ? Power : 0; } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Gameplay/Weapons/GuidedProjectile.cs b/Assets/Scripts/Gameplay/Weapons/GuidedProjectile.cs index 26a6db650..7e02d2613 100644 --- a/Assets/Scripts/Gameplay/Weapons/GuidedProjectile.cs +++ b/Assets/Scripts/Gameplay/Weapons/GuidedProjectile.cs @@ -87,7 +87,7 @@ public class GuidedProjectile : MonoBehaviour // The resolution. A round that detonated (a hit, or a burst) bursts now, at the simulation's burst point when // it has one; a round the simulation resolved without a detonation (a contact or delayed round that missed, // one whose target is gone) just falls away, with no explosion to show. - public void Resolve(bool detonated, Vector3? point) + public void Resolve(bool detonated, Vector3? point, bool showHitEffect) { // A round that already faded out (overshot, out of flight) still shows the simulation's detonation: only a // round that has been killed is done. The fade is stopped so it cannot Kill the round a second time. @@ -102,7 +102,7 @@ public class GuidedProjectile : MonoBehaviour // short of it), and is skipped when the round never knew where its target was. Vector3? effectAt = point ?? (TargetPosition != null ? TargetPosition() : Target ? Target.position : (Vector3?) null); if (point.HasValue) transform.position = point.Value; - if (HitEffect != null && effectAt.HasValue) + if (HitEffect != null && showHitEffect && effectAt.HasValue) { var ht = HitEffect.Instantiate(); ht.position = effectAt.Value; diff --git a/Assets/Scripts/Gameplay/Weapons/GuidedProjectileManager.cs b/Assets/Scripts/Gameplay/Weapons/GuidedProjectileManager.cs index 876dda1f6..1b5290640 100644 --- a/Assets/Scripts/Gameplay/Weapons/GuidedProjectileManager.cs +++ b/Assets/Scripts/Gameplay/Weapons/GuidedProjectileManager.cs @@ -17,7 +17,8 @@ public class GuidedProjectileManager : InstantWeaponEffectManager var bindings = new CompositeDisposable(); zone.ShotCommitted.Where(o => o.ShotId == shotId && o.HasBurstPoint).Subscribe(o => p.BurstAt(At(o))).AddTo(bindings); zone.ShotResolved.Where(o => o.ShotId == shotId) - .Subscribe(o => p.Resolve(o.Result == ShotResult.Hit || o.Result == ShotResult.Burst, o.HasBurstPoint ? At(o) : (Vector3?) null)) + .Subscribe(o => p.Resolve(o.Result == ShotResult.Hit || o.Result == ShotResult.Burst, o.HasBurstPoint ? At(o) : (Vector3?) null, + ActionGameManager.DrawsAt(o.Target))) .AddTo(bindings); // The binding outlives a fade-out until the shot's own arrival (the moment the simulation resolves it), plus a // second of margin; a shot no longer pending has nothing left to resolve. @@ -44,7 +45,7 @@ public class GuidedProjectileManager : InstantWeaponEffectManager p.SourceEntity = source.Entity; if (target != null) p.Target = target.transform; else p.TargetPosition = () => burst; - p.Frequency = launcher.DodgeFrequency; + p.Frequency = item.Evaluate(MunitionParts.Of(item).EvasionFrequency); var hp = item.Hardpoint; var barrel = source.GetBarrel(hp); p.StartPosition = (p.transform.position = barrel.position).ToCultMath(); @@ -53,8 +54,8 @@ public class GuidedProjectileManager : InstantWeaponEffectManager p.LiftCurve = launcher.LiftCurve.ToCurve(); p.ThrustCurve = launcher.ThrustCurve.ToCurve(); p.Velocity = barrel.forward * weapon.Velocity; - p.Thrust = item.Evaluate(launcher.Thrust); - p.TopSpeed = item.Evaluate(launcher.MissileVelocity); + p.Thrust = item.Evaluate(MunitionParts.Of(item).Acceleration); + p.TopSpeed = item.Evaluate(MunitionParts.Of(item).MaxSpeed); Bind(p, source.Entity.Zone, shotId); // A round with no target (a fused round fired at none) has no transform to hand a listener. OnFireGuided.OnNext((source.Entity, target != null ? target.transform : null, p)); @@ -65,7 +66,7 @@ public class GuidedProjectileManager : InstantWeaponEffectManager p.ShotId = shotId; p.Source = source.transform; p.SourceEntity = source.Entity; - p.Frequency = guidance.DodgeFrequency; + p.Frequency = item.Evaluate(MunitionParts.Of(item).EvasionFrequency); var hp = item.Hardpoint; var barrel = source.GetBarrel(hp); p.StartPosition = (p.transform.position = barrel.position).ToCultMath(); @@ -74,9 +75,13 @@ public class GuidedProjectileManager : InstantWeaponEffectManager p.LiftCurve = guidance.LiftCurve.ToCurve(); p.ThrustCurve = guidance.ThrustCurve.ToCurve(); p.Velocity = barrel.forward * weapon.Velocity; - p.Thrust = item.Evaluate(guidance.Thrust); - p.TopSpeed = item.Evaluate(guidance.MissileVelocity); - p.TargetPosition = () => (source.Entity.Position + length(source.LookAtPoint.position.ToCultMath() - source.Entity.Position) * source.Entity.Aim).ToUnity(); + p.Thrust = item.Evaluate(MunitionParts.Of(item).Acceleration); + p.TopSpeed = item.Evaluate(MunitionParts.Of(item).MaxSpeed); + p.TargetPosition = () => + { + var drawn = DrawAhead.Position(source.Entity, ActionGameManager.Clock.Lead); + return (drawn + length(source.LookAtPoint.position.ToCultMath() - drawn) * source.Entity.Aim).ToUnity(); + }; Bind(p, source.Entity.Zone, shotId); } else Debug.LogError($"Weapon {item.Data.Name} linked to {name} effect, but is not a Launcher!"); diff --git a/Assets/Scripts/Gameplay/Weapons/Projectile.cs b/Assets/Scripts/Gameplay/Weapons/Projectile.cs index 70b591649..e5f0b1e86 100644 --- a/Assets/Scripts/Gameplay/Weapons/Projectile.cs +++ b/Assets/Scripts/Gameplay/Weapons/Projectile.cs @@ -1,59 +1,97 @@ -using System.Collections; +using System; +using System.Collections; +using UniRx; using UnityEngine; -using static CultMath.math; -// Cut 3 (docs/fire-control-cut.md): the raycast, shield branch and SendHit are deleted -- FireControl already -// decided this shot's fate before this object was ever spawned (R8). What is left is pure flight-path -// presentation: fly, and disappear at Range or ShotId's resolution, whichever comes first. -// Cut 6b, 6.2 (12.4(b): Apply's own switch on the frozen Fuse decides this now, not Step): the flak-round -// blast resolves in the simulation, through FireControl.Detonate -- a MonoBehaviour calling it would be -// exactly the authority Cut 3 spent itself deleting, so the blast-distance/blast-radius fields this object -// used to carry for that are gone. This object's job stays fly-and-disappear. +// A ballistic round, drawn by DrawAhead.Round from what the simulation publishes and deciding nothing. The simulation +// owns the round's facts (the PendingShot copy taken at spawn, replaced by the sim's record at ShotCommitted, and the +// outcome it publishes), so this object stores no motion state of its own and computes no position, time, range or +// impact point: each frame it asks DrawAhead.Round where the round is at sim time plus the clock's Lead (the same +// draw-ahead ships use). The round ends on the sim's word: ShotResolved ends one that hit or burst, and +// DrawAhead.RoundOver ends one the sim published as a miss. The barrel is only where the round is first seen: its +// offset from the drawn line decays to zero over BlendTime sim seconds. The trail's fade after the end stays real time +// (pure presentation, ruling sim-speed-presentation). public class Projectile : MonoBehaviour { public TrailRenderer Trail; - public float Gravity; - public float Drag = .1f; public Prototype HitEffect; + // Sim seconds over which the barrel's offset from the sim line decays to nothing. + public float BlendTime = .1f; + + private PendingShot _shot; + private Zone _zone; + private CultMath.float3 _barrel; + private ShotOutcome _known; private bool _alive; + private CompositeDisposable _binding; - // Cut 3: FireControl.Fire's ShotId -- this projectile's handle onto Zone.ShotCommitted/ShotResolved. - public int ShotId { get; set; } - public Zone Zone { get; set; } - - public Vector3 StartPosition { get; set; } - public Vector3 Velocity { get; set; } - public Entity SourceEntity { get; set; } - public float Range { get; set; } - - private void OnEnable() + // Takes the shot as the sim holds it, the zone whose sim time it is drawn at, and where the barrel is as this round is first seen. + public void Launch(Zone zone, PendingShot shot, Vector3 barrel) { + _zone = zone; + _shot = shot; + _barrel = new CultMath.float3(barrel.x, barrel.y, barrel.z); + _known = null; + _binding?.Dispose(); + _binding = new CompositeDisposable( + zone.ShotCommitted.Where(o => o.ShotId == shot.ShotId).Subscribe(Committed), + zone.ShotResolved.Where(o => o.ShotId == shot.ShotId).Subscribe(Resolve)); _alive = true; + transform.forward = new Vector3(shot.TravelDirection.x, 0, shot.TravelDirection.y); + Draw(); } - // Update is called once per frame void Update() { - if (SourceEntity == null) return; - - if(_alive) - { - var t = transform; - Velocity -= Vector3.up * (Gravity * Time.deltaTime); - Velocity *= max(0, 1 - Drag * Time.deltaTime); - t.forward = Velocity.normalized; - - transform.position += Velocity * Time.deltaTime; - var distanceTraveled = (transform.position - StartPosition).magnitude; - if(distanceTraveled > Range) - StartCoroutine(Kill()); - } + if (_alive) Draw(); } - IEnumerator Kill() + private void Draw() + { + var lead = ActionGameManager.Clock.Lead; + var drawn = DrawAhead.Time(_zone, lead); + transform.position = V(DrawAhead.Round(_shot, _known, _barrel, BlendTime, drawn)); + if (DrawAhead.RoundOver(_shot, _known, drawn)) Finish(); + } + + // The sim's commit: the record it holds now (a contact burst's arrival is shortened here) and what it decided. + private void Committed(ShotOutcome outcome) + { + if (_zone.TryGetShot(outcome.ShotId, out var record)) _shot = record; + _known = outcome; + } + + // The simulation's verdict. A round that hit or burst is drawn at its end and stops; a miss keeps flying. + private void Resolve(ShotOutcome outcome) + { + if (!_alive) return; + _known = outcome; + if (outcome.Result == ShotResult.Miss) return; + Draw(); + if (HitEffect != null && ActionGameManager.DrawsAt(outcome.Target)) HitEffect.Instantiate().position = transform.position; + Finish(); + } + + private static Vector3 V(CultMath.float3 p) => new Vector3(p.x, p.y, p.z); + + private void Finish() { _alive = false; + _binding?.Dispose(); + _binding = null; + StartCoroutine(Fade()); + } + + void OnDisable() + { + _alive = false; + _binding?.Dispose(); + _binding = null; + } + + IEnumerator Fade() + { var startTime = Time.time; var lifetime = Trail.time; while (Time.time - startTime < lifetime) diff --git a/Assets/Scripts/Gameplay/Weapons/ProjectileManager.cs b/Assets/Scripts/Gameplay/Weapons/ProjectileManager.cs index 56cfdcf80..216756cf9 100644 --- a/Assets/Scripts/Gameplay/Weapons/ProjectileManager.cs +++ b/Assets/Scripts/Gameplay/Weapons/ProjectileManager.cs @@ -1,32 +1,17 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using Random = UnityEngine.Random; +using UnityEngine; public class ProjectileManager : InstantWeaponEffectManager { public Prototype ProjectilePrototype; - public bool InheritVelocity; + // The round is drawn by DrawAhead from what the simulation publishes, so there is nothing to aim, jitter + // or inherit here: spread is priced by FireControl, and the sim's round inherits nothing from its shooter. public override void Fire(InstantWeapon weapon, EquippedItem item, EntityInstance source, EntityInstance target, int shotId) { + var zone = source.Entity.Zone; + if (!zone.TryGetShot(shotId, out var shot)) return; var p = ProjectilePrototype.Instantiate(); - var hp = item.Hardpoint; - var barrel = source.GetBarrel(hp); - var angle = weapon.Spread / 2; - p.ShotId = shotId; - p.SourceEntity = source.Entity; - p.Velocity = Quaternion.Euler( - Random.Range(-angle, angle), - Random.Range(-angle, angle), - Random.Range(-angle, angle)) * - barrel.forward * - weapon.Velocity; - p.StartPosition = p.transform.position = barrel.position + p.Velocity * (Random.value * Time.deltaTime); - if(InheritVelocity) - p.Velocity += new Vector3(source.Entity.Velocity.x, 0, source.Entity.Velocity.y); - p.Range = weapon.Range; - p.Zone = source.Entity.Zone; + p.Launch(zone, shot, source.GetBarrel(item.Hardpoint).position); p.Trail.Clear(); } } diff --git a/Assets/Scripts/ServerShared/AetheriaStores.cs b/Assets/Scripts/ServerShared/AetheriaStores.cs index f265151c9..4697fe272 100644 --- a/Assets/Scripts/ServerShared/AetheriaStores.cs +++ b/Assets/Scripts/ServerShared/AetheriaStores.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using GameCult.Caching; using GameCult.Caching.MessagePack; @@ -6,16 +7,22 @@ using GameCult.Caching.MessagePack; // Aetheria's stores: one home store per type, composed here and nowhere else. public static class AetheriaStores { - public static readonly Type[] CatalogTypes = { typeof(ItemData), typeof(ShipAuthoring), typeof(Faction), typeof(FactionProductData), typeof(PersonalityAttribute), typeof(NameFile), typeof(InputLayout), typeof(Loadout), typeof(FieldKindData) }; + public static readonly Type[] CatalogTypes = { typeof(ItemData), typeof(ShipAuthoring), typeof(Faction), typeof(FactionProductData), typeof(PersonalityAttribute), typeof(NameFile), typeof(InputLayout), typeof(Loadout), typeof(FieldKindData), typeof(VerseGrammar), typeof(VerseVerb) }; public static readonly Type[] RunTypes = { typeof(OrbitData), typeof(BodyData), typeof(SavedZone), typeof(SavedGame), typeof(ProvenanceLedger) }; public static readonly Type[] PlayerTypes = { typeof(PlayerSettings) }; // Attaches (hydrates) the catalog read-only unless catalogWritable, then the run and player stores when given. // Throws when a [CultGlobal] type routed to the catalog has no record. The one exemption is a writable catalog with // no records at all, a seed store being authored from nothing; a populated catalog is held to it however it opens. - public static CultCache Open(string catalogPath, string runPath = null, string playerPath = null, bool catalogWritable = false) + // The registry is the process-wide one unless the caller scopes it (the test host does, so its own document types never + // become catalog globals); the global check above is judged against whichever registry opened the cache. + public static CultCache Open(string catalogPath, string runPath = null, string playerPath = null, bool catalogWritable = false, + CultDocumentRegistry registry = null) { - var cache = new CultCache(); + // A read-only open of an absent catalog would hydrate an empty game; a shipped player missing its catalog stops here. + if (!catalogWritable && !File.Exists(catalogPath)) + throw new FileNotFoundException($"Catalog {catalogPath} does not exist; a read-only open never invents one.", catalogPath); + var cache = new CultCache(registry); try { cache.AddBackingStore(new SingleFileMessagePackBackingStore(catalogPath, !catalogWritable), CatalogTypes); @@ -33,6 +40,7 @@ public static class AetheriaStores // cut.md), stat modifiers, role usage (Cut 7). Fails loudly, naming the item. foreach (var data in cache.GetAll()) CultRecordRefs.Validate(data); foreach (var data in cache.GetAll()) CultRecordRefs.Validate(data); + VerseGrammarValidation.ValidateAll(cache.GetAll()); return cache; } catch @@ -72,11 +80,15 @@ public static class CultRecordRefs { StatValidation.ValidateHeatResponse(data); StatValidation.ValidateStatModifiers(data.Name, data.Behaviors); + StatValidation.ValidateMunitionParts(data.Name, data.Behaviors); + StatValidation.ValidateMineLayerFlat(data.Name, data.Behaviors); StatValidation.ValidateRoleUsage(data.Name, data.Roles, data.Behaviors); } if (document is ConsumableItemData consumable) { StatValidation.ValidateStatModifiers(consumable.Name, consumable.Behaviors); + StatValidation.ValidateMunitionParts(consumable.Name, consumable.Behaviors); + StatValidation.ValidateMineLayerFlat(consumable.Name, consumable.Behaviors); StatValidation.ValidateRoleUsage(consumable.Name, consumable.Roles, consumable.Behaviors); } } diff --git a/Assets/Scripts/ServerShared/Agents/States/Combat.cs b/Assets/Scripts/ServerShared/Agents/States/Combat.cs index b64cd7d06..52a235637 100644 --- a/Assets/Scripts/ServerShared/Agents/States/Combat.cs +++ b/Assets/Scripts/ServerShared/Agents/States/Combat.cs @@ -33,22 +33,24 @@ public class CombatState : BaseState _availableLockingWeapons.Clear(); var toTarget = target.Position - _agent.Ship.Position; - var targetDistance = length(toTarget); + var targetDistance = length(toTarget.xz); // Cut 2 (docs/fire-control-cut.md): aim at whichever revealed weapon on the target hits hardest at // this range, or clear the aim point when nothing qualifies -- the same predicate - // (FireControl.IsRevealed) and the same writer (TrySelectTargetItem) the player path uses. + // (FireControl.IsRevealed) and the same writer (TrySelectTargetItem) the player path uses. Which weapons it + // believes the target has, and how hard each hits, come from its book's claims, not the target's live gear + // (aetheria-ew, classify-from-belief; ew-claim-weapon-measure-ruled: the claimed design's rated figures); the + // reveal's Item is the aim and stays the truth. EquippedItem bestTargetItem = null; var bestTargetDps = float.MinValue; - foreach (var targetItem in target.Equipment) + foreach (var reveal in _agent.Ship.RevealedWeapons(target)) { - if (!(targetItem.Behaviors.FirstOrDefault(b => b is Weapon) is Weapon targetWeapon)) continue; - if (!FireControl.IsRevealed(_agent.Ship, targetItem)) continue; - var dps = targetWeapon.RangeDamagePerSecond(targetDistance); + if (!FireControl.IsRevealed(_agent.Ship, reveal.Item)) continue; + var dps = reveal.Claimed.Behaviors.OfType().First().RatedRangeDamagePerSecond(targetDistance); if (dps > bestTargetDps) { bestTargetDps = dps; - bestTargetItem = targetItem; + bestTargetItem = reveal.Item; } } _agent.Ship.TrySelectTargetItem(bestTargetItem); @@ -108,9 +110,8 @@ public class CombatState : BaseState // Cut 3 (docs/fire-control-cut.md): the one prediction function, shared with FireControl.Fire's // own snapshot and the roll's deviation measurement -- two separate predictions here and in the // roll would let an AI aim at one point and get judged for missing a different one. - var targetHullData = _agent.ItemManager.GetData(target.Hull) as HullData; var predictedPosition = FireControl.PredictedIntercept(testWeapon, _agent.Ship, target); - predictedPosition.y = _agent.Ship.Zone.GetHeight(predictedPosition.xz) + targetHullData.GridOffset; + predictedPosition.y = target.RideHeight(predictedPosition.xz); toTarget = normalize(predictedPosition - _agent.Ship.Position); } @@ -138,8 +139,8 @@ public class CombatState : BaseState var maxRange = Single.MinValue; foreach (var weapon in _agent.Ship.Weapons) { - if (weapon.Range < minRange) - minRange = weapon.Range; + if (weapon.MinRange < minRange) + minRange = weapon.MinRange; if (weapon.Range > maxRange) maxRange = weapon.Range; } @@ -152,7 +153,7 @@ public class CombatState : BaseState float dps = 0; foreach (var weapon in _agent.Ship.Weapons) { - if (weapon.Item.Online.Value && weapon.MinRange < range && range < weapon.Range) + if (weapon.Item.Online.Value) dps += weapon.RangeDamagePerSecond(range); } diff --git a/Assets/Scripts/ServerShared/Behaviors/AetherDrive.cs b/Assets/Scripts/ServerShared/Behaviors/AetherDrive.cs deleted file mode 100644 index e8498ca7f..000000000 --- a/Assets/Scripts/ServerShared/Behaviors/AetherDrive.cs +++ /dev/null @@ -1,185 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -using GameCult.Caching; -using MessagePack; -using Newtonsoft.Json; -using CultMath; -using static CultMath.math; - -[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), EntityTypeRestriction(HullType.Ship), RuntimeInspectable] -public class AetherDriveData : BehaviorData -{ - [Inspectable, JsonProperty("diameters"), Key(1)] - public float3 RotorDiameter; - - [Inspectable, JsonProperty("masses"), Key(2)] - public float3 RotorMass; - - [Inspectable, JsonProperty("rpm"), Key(3), RuntimeInspectable] - public PerformanceStat MaximumRpm; - - [Inspectable, JsonProperty("couplingLambdas"), Key(4)] - public float3 CouplingLambda; - - [Inspectable, JsonProperty("lambdaMultiplier"), Key(5)] - public PerformanceStat LambdaMultiplier; - - [Inspectable, JsonProperty("couplingEfficiency"), Key(6), RuntimeInspectable] - public PerformanceStat CouplingEfficiency; - - [Inspectable, JsonProperty("torque"), Key(7), RuntimeInspectable] - public PerformanceStat Torque; - - [Inspectable, JsonProperty("torqueProfile"), Key(8), RuntimeInspectable] - public BezierCurve TorqueProfile; - - [Inspectable, JsonProperty("draw"), Key(9), RuntimeInspectable] - public PerformanceStat EnergyDraw; - - [Inspectable, JsonProperty("passiveCoupling"), Key(10), RuntimeInspectable] - public PerformanceStat PassiveCoupling; - - [Inspectable, JsonProperty("rpmAudio"), Key(11), RuntimeInspectable] - public uint RpmAudioParameter; - - [Inspectable, JsonProperty("torqueAudio"), Key(12), RuntimeInspectable] - public uint TorqueRatioAudioParameter; - - [Inspectable, CultInspectorAssetGuid, JsonProperty("particles"), Key(13)] - public string Particles; - - public override Behavior CreateInstance(EquippedItem item) - { - return new AetherDrive(this, item); - } - - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new AetherDrive(this, item); - } -} - -public class AetherDrive : Behavior, IPowerConsumer -{ - private AetherDriveData _data; - private float3 _axis; - - public float3 Thrust { get; private set; } - public float3 Rpm { get; private set; } - public float MaximumRpm { get; private set; } - public float2 ThrustDirection { get; private set; } - - public AetherDriveData DriveData => _data; - - // Cut 8 (operator ask 2026-09-19): the equivalent quantity to Thruster.Condition -- Torque is the stat that - // actually governs this behaviour's rotor spin-up (PowerRequest/Execute above both read it), so it is what - // "broken" means for a drive. 1f for the item-less ConsumableItemEffect case, same reasoning as Thruster. - public float Condition => Item?.ConditionRatio(_data.Torque) ?? 1f; - - public float3 Axis - { - get => _axis; - set => _axis = clamp(value, -1, 1); - } - - public AetherDrive(AetherDriveData data, EquippedItem item) : base(data, item) - { - _data = data; - } - - public AetherDrive(AetherDriveData data, ConsumableItemEffect item) : base(data, item) - { - _data = data; - } - - // Cut 3 (docs/stats-and-power-cut.md): the request PowerBus needs before Execute runs. Only the rotor - // spin-up (torque accelerating Rpm toward MaximumRpm) costs power -- spending existing spin into thrust - // (Execute's decay-to-thrust arithmetic below) is free, same as before. Pure and side-effect-free: it reads - // Rpm but does not write it, so Execute's own identical arithmetic a few lines later -- which does perform - // the real decay -- produces the same numbers Rpm actually moves by. Accepts the recompute (Q3's ruling). - // - // Nominal-request ruling (docs/stats-and-power-cut.md, operator ruling 2026-09-19): Torque, LambdaMultiplier, - // MaximumRpm, PassiveCoupling and EnergyDraw are all registered request fields (StatValidation. - // PowerRequestFields) -- read nominally (what full power would produce) so Torque carrying its own - // PowerSupply term (Cut 7's brownout curve) no longer makes this tick's request depend on this tick's own - // grant. Execute below is unchanged: it calls the real, curved Evaluate, so the actual spin-up still - // degrades with whatever the bus actually grants. - public float PowerRequest(float dt) - { - var couplingLambda = _data.CouplingLambda * Item.EvaluateNominalPower(_data.LambdaMultiplier) * max(abs(_axis), EvaluateNominalPower(_data.PassiveCoupling)); - var rpmAfterDecay = decay(Rpm, couplingLambda, dt); - var maximumRpm = EvaluateNominalPower(_data.MaximumRpm); - var torqueProfile = float3( - _data.TorqueProfile.Evaluate(rpmAfterDecay.x / maximumRpm), - _data.TorqueProfile.Evaluate(rpmAfterDecay.y / maximumRpm), - _data.TorqueProfile.Evaluate(rpmAfterDecay.z / maximumRpm)); - var potentialTorque = EvaluateNominalPower(_data.Torque) * torqueProfile; - var potentialRpmDelta = potentialTorque / length(_data.RotorMass) * dt; - var actualRpmDelta = min(maximumRpm - rpmAfterDecay, potentialRpmDelta); - var torqueRatio = actualRpmDelta / potentialRpmDelta; - var draw = torqueRatio * EvaluateNominalPower(_data.EnergyDraw) / 3; - return (draw.x + draw.y + draw.z) * dt; - } - - // Cut 5 (docs/stats-and-power-cut.md §1.3, PowerTiers.cs): Medium -- mobility, same as Thruster. - public int DefaultPowerTier => PowerTiers.Medium; - - public override bool Execute(float dt) - { - var rotorSpeed = Rpm * _data.RotorDiameter / 100; - - var forward = normalize(Entity.Direction); - var right = forward.Rotate(ItemRotation.Clockwise); - - var speed = float2(dot(Entity.Velocity, forward), dot(Entity.Velocity, right)); - var couplingEfficiency = Evaluate(_data.CouplingEfficiency); - var efficiency = float3(saturate(1 - speed / max(rotorSpeed.xy, 1) * sign(_axis.xy)) * couplingEfficiency, 1); - - Thrust = (Rpm - decay(Rpm, _data.CouplingLambda, dt)) * _data.RotorMass * efficiency; - - var couplingLambda = _data.CouplingLambda * Item.Evaluate(_data.LambdaMultiplier) * max(abs(_axis), Evaluate(_data.PassiveCoupling)); - var previousRpm = Rpm; - Rpm = decay(Rpm, couplingLambda, dt); - var rpmLoss = previousRpm - Rpm; - var force = rpmLoss * _data.RotorMass * efficiency; - - var heat = rpmLoss * _data.RotorMass * (1 - couplingEfficiency); - AddHeat((heat.x + heat.y + heat.z)*ItemManager.GameplaySettings.AetherHeatMultiplier); - - ThrustDirection = forward * (_axis.x * force.x / Entity.Mass) + right * (_axis.y * force.y / Entity.Mass); - Entity.Velocity += ThrustDirection; - - Entity.Direction = mul(Entity.Direction, - CultMath.float2x2.Rotate(force.z * _axis.z * ItemManager.GameplaySettings.AetherTorqueMultiplier / Entity.Mass)); - - if(float.IsNaN(Entity.Velocity.x)) - ItemManager.Log("FUCK FUCK FUCK FUCK"); - - MaximumRpm = Evaluate(_data.MaximumRpm); - var torqueProfile = float3( - _data.TorqueProfile.Evaluate(Rpm.x / MaximumRpm), - _data.TorqueProfile.Evaluate(Rpm.y / MaximumRpm), - _data.TorqueProfile.Evaluate(Rpm.z / MaximumRpm)); - var potentialTorque = Evaluate(_data.Torque) * torqueProfile; - var potentialRpmDelta = potentialTorque / length(_data.RotorMass) * dt; - var actualRpmDelta = min(MaximumRpm - Rpm, potentialRpmDelta); - var torqueRatio = actualRpmDelta / potentialRpmDelta; - - Item.SetAudioParameter(SpecialAudioParameter.Intensity, max(max(abs(_axis.x), abs(_axis.y)), abs(_axis.z))); - Item.SetAudioParameter(_data.RpmAudioParameter, (Rpm.x + Rpm.y + Rpm.z) / 3 / MaximumRpm); - Item.SetAudioParameter(_data.TorqueRatioAudioParameter, max(max(torqueRatio.x, torqueRatio.y), torqueRatio.z)); - - // Cut 7 (docs/stats-and-power-target.md): actualRpmDelta already derives from Evaluate(_data.Torque) - // above, so a Torque stat carrying a PowerSupply term already shrinks the rotor's spin-up under a - // partial grant -- this no longer demands a full one, only that supply has not been cut to true zero. - if (Item.PowerSupply > 1e-4f) - { - Rpm += actualRpmDelta; - return true; - } - - return false; - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/AetherDrive.cs.meta b/Assets/Scripts/ServerShared/Behaviors/AetherDrive.cs.meta deleted file mode 100644 index 96fd33b04..000000000 --- a/Assets/Scripts/ServerShared/Behaviors/AetherDrive.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2022c838bbc64a0d86cfbd477e6a379c -timeCreated: 1618332827 \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Behaviors.cs b/Assets/Scripts/ServerShared/Behaviors/Behaviors.cs index 4bc5731a7..0cbe11186 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Behaviors.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Behaviors.cs @@ -93,11 +93,6 @@ public interface IActivatedBehavior void Deactivate(); } -public interface IAnalogBehavior -{ - float Axis { get; set; } -} - public interface IEventBehavior { void ResetEvents(); @@ -157,7 +152,7 @@ public interface IPowerConsumer Union(9, typeof(WearData)), Union(10, typeof(VelocityConversionData)), Union(11, typeof(VelocityLimitData)), - Union(12, typeof(AetherDriveData)), + // Union(12): retired, do not reuse -- was AetherDriveData (retire-longinusx; parked/aether-drive) // Union(14, typeof(TowingControllerData)), Union(15, typeof(CooldownData)), Union(16, typeof(HeatData)), @@ -187,6 +182,17 @@ public interface IPowerConsumer // superseded draft quoted -- checked directly here rather than trusted from that document. Union(39, typeof(TargetingSystemData)), Union(40, typeof(MineLayerData)), + Union(41, typeof(ThrottleLockData)), + Union(42, typeof(VapourDumpData)), + Union(43, typeof(MunitionHullData)), + Union(44, typeof(MunitionThrusterData)), + Union(45, typeof(MunitionSeekerData)), + Union(46, typeof(MunitionControlData)), + Union(47, typeof(MunitionFuelData)), + Union(48, typeof(PickupData)), + Union(49, typeof(LaunchSuppressorData)), + Union(50, typeof(ListenerData)), + Union(51, typeof(ScannerData)), JsonObject(MemberSerialization.OptIn)] public abstract class BehaviorData { diff --git a/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs index bc80bc1e5..8d048083d 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs @@ -54,6 +54,15 @@ public class ChargedWeaponData : InstantWeaponData { return new ChargedWeapon(this, item); } + + // The one formula of a charged weapon's damage per second at a range (see InstantWeaponData.RangeDamagePerSecond). + internal static float RangeDamagePerSecond(float damage, float chargeFiringDamageMultiplier, float cooldown, float chargeTime, + float rangeFactor) => + damage * chargeFiringDamageMultiplier * rangeFactor / (cooldown + chargeTime); + + public override float RatedRangeDamagePerSecond(float range) => + RangeDamagePerSecond(PerRound(Damage.Max, Count.Max), ChargeFiringDamageMultiplier, Cooldown.Max, ChargeTime.Max, + RatedRangeFactor(range)); } public class ChargedWeapon : InstantWeapon @@ -75,13 +84,14 @@ public class ChargedWeapon : InstantWeapon // authored charge-up speed IS its sustained rate of fire, not a second, disconnected number. protected override float RateOverride => Evaluate(_data.ChargeEnergy); - public override float DamagePerSecond => Damage * _data.ChargeFiringDamageMultiplier / (Cooldown + ChargeTime); + // The charge multiplier lives in the formula alone: Damage is lerped by charge for the shot itself (UpdateStats), so the + // live reads take the uncharged damage, and a nominal weapon reads its design's rated figure at every charge. + private float _unchargedDamage; + public override float DamagePerSecond => _unchargedDamage * _data.ChargeFiringDamageMultiplier / (Cooldown + ChargeTime); public override float RangeDamagePerSecond(float range) { - return Damage * - _data.ChargeFiringDamageMultiplier * - _data.DamageCurve.Evaluate(saturate(unlerp(MinRange, Range, range))) / - (Cooldown + ChargeTime); + return ChargedWeaponData.RangeDamagePerSecond(_unchargedDamage, _data.ChargeFiringDamageMultiplier, Cooldown, ChargeTime, + RangeFactor(range)); } public event Action OnStartCharging; @@ -121,6 +131,7 @@ public class ChargedWeapon : InstantWeapon ChargeTime = Evaluate(_data.ChargeTime); ChargeEnergy = Evaluate(_data.ChargeEnergy); ChargeHeat = Evaluate(_data.ChargeHeat); + _unchargedDamage = Damage; Damage *= lerp(1, _data.ChargeFiringDamageMultiplier, saturate(_charge)); Heat *= lerp(1, _data.ChargeFiringHeatMultiplier, saturate(_charge)); Spread *= lerp(1, _data.ChargeFiringSpreadMultiplier, saturate(_charge)); @@ -134,7 +145,6 @@ public class ChargedWeapon : InstantWeapon if (_charging) { _charge += dt / ChargeTime; - Item.SetAudioParameter(SpecialAudioParameter.ChargeLevel, saturate(_charge)); if (!_charged) { AddHeat(ChargeHeat * (dt / ChargeTime)); @@ -151,7 +161,6 @@ public class ChargedWeapon : InstantWeapon _coolingDown = true; _charge = 0; OnFailed?.Invoke(); - Item.FireAudioEvent(ChargedWeaponAudioEvent.Fail); CauseDamage(_data.FailureDamage); } } @@ -166,7 +175,6 @@ public class ChargedWeapon : InstantWeapon if(!_charging && CanFire && !FireControl.Refuses(this, Entity)) { OnStartCharging?.Invoke(); - Item.FireAudioEvent(ChargedWeaponAudioEvent.Start); _charging = true; _charged = false; } @@ -182,7 +190,6 @@ public class ChargedWeapon : InstantWeapon _charge = 0; } OnStopCharging?.Invoke(); - Item.FireAudioEvent(ChargedWeaponAudioEvent.Stop); _charging = false; } } diff --git a/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs index e9dab4ce6..cc0015dbe 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs @@ -23,6 +23,12 @@ public class ConstantWeaponData : WeaponData { return new ConstantWeapon(this, item); } + + // The one formula of a beam's damage per second at a range (see InstantWeaponData.RangeDamagePerSecond). + internal static float RangeDamagePerSecond(float damage, float rangeFactor) => damage * rangeFactor; + + public override float RatedRangeDamagePerSecond(float range) => + RangeDamagePerSecond(Damage.Max, RatedRangeFactor(range)); } public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerConsumer @@ -49,7 +55,7 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerC public override float DamagePerSecond => Damage; public override float RangeDamagePerSecond(float range) { - return Damage * _data.DamageCurve.Evaluate(saturate(unlerp(MinRange, Range, range))); + return ConstantWeaponData.RangeDamagePerSecond(Damage, RangeFactor(range)); } public event Action OnReloadBegin; @@ -170,7 +176,7 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerC CauseWearDamage(dt); AddHeat(Evaluate(_data.Heat) * dt); - Entity.VisibilitySources[this] = Evaluate(_data.Visibility); + Entity.SetSignature(this, SignatureChannel.LaunchFlash, Evaluate(_data.Visibility), Item); // Cut 4 (docs/fire-control-cut.md): a beam is a sequence of rolls, not a continuous truth -- one // FireControl.Fire per BeamResolveInterval, for that interval's worth of Damage, through the same diff --git a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs index 2801110c9..043df920c 100644 --- a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs @@ -30,6 +30,16 @@ public class InstantWeaponData : WeaponData { return new InstantWeapon(this, item); } + + // The one formula of an instant weapon's damage per second at a range; the live weapon calls it with its evaluated + // stats, the design with its rated ones. A burst's round carries its share of the totals: PerRound, the one divisor + // UpdateStats and the rated read both use. + internal static float PerRound(float total, float burstCount) => total / (int) burstCount; + + internal static float RangeDamagePerSecond(float damage, float cooldown, float rangeFactor) => damage * rangeFactor / cooldown; + + public override float RatedRangeDamagePerSecond(float range) => + RangeDamagePerSecond(PerRound(Damage.Max, Count.Max), Cooldown.Max, RatedRangeFactor(range)); } public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerConsumer @@ -61,7 +71,7 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerCo public override float DamagePerSecond => Damage / Cooldown; public override float RangeDamagePerSecond(float range) { - return Damage * _data.DamageCurve.Evaluate(saturate(unlerp(MinRange, Range, range))) / Cooldown; + return InstantWeaponData.RangeDamagePerSecond(Damage, Cooldown, RangeFactor(range)); } public override int Ammo @@ -129,9 +139,9 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerCo BurstTime = Evaluate(_data.BurstTime); Cooldown = Evaluate(_data.Cooldown); - Damage /= (int) BurstCount; - Heat /= (int) BurstCount; - Energy /= (int) BurstCount; + Damage = InstantWeaponData.PerRound(Damage, BurstCount); + Heat = InstantWeaponData.PerRound(Heat, BurstCount); + Energy = InstantWeaponData.PerRound(Energy, BurstCount); } // Cut 4 (docs/stats-and-power-cut.md §7 Q4): capacity and rate, resolved fresh rather than off the cached @@ -230,7 +240,6 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerCo } } - var firedThisFrame = false; _burstTimer += dt; while (_burstRemaining > 0 && _burstTimer > 0) { @@ -270,14 +279,9 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerCo // Evaluate it into a local first. var shotId = FireControl.Fire(this, Item, Entity); OnFire?.Invoke(shotId); - if(!firedThisFrame) - { - Item.FireAudioEvent(WeaponAudioEvent.Fire); - firedThisFrame = true; - } CauseWearDamage(1); AddHeat(Heat); - Entity.VisibilitySources[this] = Visibility; + Entity.SetSignature(this, SignatureChannel.LaunchFlash, Visibility, Item); } return true; } diff --git a/Assets/Scripts/ServerShared/Behaviors/LaunchSuppressor.cs b/Assets/Scripts/ServerShared/Behaviors/LaunchSuppressor.cs new file mode 100644 index 000000000..47d79ec52 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/LaunchSuppressor.cs @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using MessagePack; +using Newtonsoft.Json; +using static CultMath.math; + +// Electronic warfare, hide-launch (campaign aetheria-ew, invariants lie-is-own-emission and lies-cost-real-heat): a +// gear that thins its own ship's launch flash. It never stores a factor and never writes a signature: Entity.SetSignature +// asks each equipped suppressor at write time, so the order in which a weapon and a suppressor execute decides nothing. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable] +public class LaunchSuppressorData : BehaviorData +{ + // The multiplier on the flash, clamped to 0..1: a suppressor never brightens a launch. + [Inspectable, JsonProperty("factor"), Key(1), RuntimeInspectable] + public PerformanceStat Factor = new PerformanceStat(); + + // Heat paid to the suppressor's own cell per unit of strength it removed. + [Inspectable, JsonProperty("heatPerUnit"), Key(2)] + public PerformanceStat HeatPerUnit = new PerformanceStat(); + + // Above this item temperature the suppressor scales nothing and pays nothing. + [Inspectable, JsonProperty("ratedTemperature"), Key(3)] + public PerformanceStat RatedTemperature = new PerformanceStat(); + + public override Behavior CreateInstance(EquippedItem item) + { + return new LaunchSuppressor(this, item); + } + public override Behavior CreateInstance(ConsumableItemEffect item) + { + return new LaunchSuppressor(this, item); + } +} + +public class LaunchSuppressor : Behavior +{ + private readonly LaunchSuppressorData _data; + + public LaunchSuppressor(LaunchSuppressorData data, EquippedItem item) : base(data, item) + { + _data = data; + } + public LaunchSuppressor(LaunchSuppressorData data, ConsumableItemEffect item) : base(data, item) + { + _data = data; + } + + // Called by Entity.SetSignature for every light signature the ship writes; the strength passes through unchanged + // unless this is a launch flash and the suppressor is running below its rated temperature. + internal float Suppress(SignatureChannel channel, float strength) + { + if (channel != SignatureChannel.LaunchFlash || Item == null || !Item.Active.Value || Temperature > Evaluate(_data.RatedTemperature)) + return strength; + var scaled = strength * clamp(Evaluate(_data.Factor), 0f, 1f); + AddHeat((strength - scaled) * Evaluate(_data.HeatPerUnit)); + return scaled; + } + + public override bool Execute(float dt) => true; +} diff --git a/Assets/Scripts/ServerShared/Behaviors/LaunchSuppressor.cs.meta b/Assets/Scripts/ServerShared/Behaviors/LaunchSuppressor.cs.meta new file mode 100644 index 000000000..f25a2a088 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/LaunchSuppressor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be58ee6eb8c74ea89518ee8200add0ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Launcher.cs b/Assets/Scripts/ServerShared/Behaviors/Launcher.cs index e443bdf1d..439394df0 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Launcher.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Launcher.cs @@ -18,14 +18,7 @@ public class LauncherData : LockWeaponData [InspectableAnimationCurve, JsonProperty("liftCurve"), Key(28)] public float4[] LiftCurve; - [Inspectable, JsonProperty("thrust"), Key(29)] - public PerformanceStat Thrust = new PerformanceStat(); - - [Inspectable, JsonProperty("frequency"), Key(30)] - public float DodgeFrequency; - - [Inspectable, JsonProperty("missileSpeed"), Key(31), RuntimeInspectable] - public PerformanceStat MissileVelocity = new PerformanceStat(); + // Keys 29-31 were Thrust, DodgeFrequency and MissileVelocity, retired for the munition parts (MunitionParts.cs); do not reuse. public override Behavior CreateInstance(EquippedItem item) { @@ -45,14 +38,7 @@ public class GuidedWeaponData : InstantWeaponData [InspectableAnimationCurve, JsonProperty("liftCurve"), Key(23)] public float4[] LiftCurve; - [Inspectable, JsonProperty("thrust"), Key(24)] - public PerformanceStat Thrust = new PerformanceStat(); - - [Inspectable, JsonProperty("frequency"), Key(25)] - public float DodgeFrequency; - - [Inspectable, JsonProperty("missileSpeed"), Key(26), RuntimeInspectable] - public PerformanceStat MissileVelocity = new PerformanceStat(); + // Keys 24-26 were Thrust, DodgeFrequency and MissileVelocity, retired for the munition parts (MunitionParts.cs); do not reuse. public override Behavior CreateInstance(EquippedItem item) { diff --git a/Assets/Scripts/ServerShared/Behaviors/Listener.cs b/Assets/Scripts/ServerShared/Behaviors/Listener.cs new file mode 100644 index 000000000..beb622741 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Listener.cs @@ -0,0 +1,44 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using MessagePack; +using Newtonsoft.Json; + +// Passive listening gear (ruling sensor-stat-set): hears other ships' emissions at a multiple of their own range, +// bearing only. It emits nothing; Entity.HearingMultiple asks each active listener at hearing time. Its power is the +// design's EnergyDraw and its activity is the item's Active, as for sensors. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable] +public class ListenerData : BehaviorData +{ + // How many times an emitter's own reach this listener hears it at. + [Inspectable, JsonProperty("multiple"), Key(1), RuntimeInspectable] + public PerformanceStat Multiple = new PerformanceStat(); + + public override Behavior CreateInstance(EquippedItem item) + { + return new Listener(this, item); + } + public override Behavior CreateInstance(ConsumableItemEffect item) + { + return new Listener(this, item); + } +} + +public class Listener : Behavior +{ + private readonly ListenerData _data; + + public Listener(ListenerData data, EquippedItem item) : base(data, item) + { + _data = data; + } + public Listener(ListenerData data, ConsumableItemEffect item) : base(data, item) + { + _data = data; + } + + public float Multiple => Evaluate(_data.Multiple); + + public override bool Execute(float dt) => true; +} diff --git a/Assets/Scripts/ServerShared/Behaviors/Listener.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Listener.cs.meta new file mode 100644 index 000000000..be694c775 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Listener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b0e1f6c2d7a4e39a8c4d1f27e6b3a90 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/LockWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/LockWeapon.cs index 16f56b72d..271aa64c3 100644 --- a/Assets/Scripts/ServerShared/Behaviors/LockWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/LockWeapon.cs @@ -23,6 +23,11 @@ public class LockWeaponData : InstantWeaponData [Inspectable, JsonProperty("decay"), Key(25)] public PerformanceStat Decay = new PerformanceStat(); + + // The ratio of how far this lock sees to how far others hear it (ruling sensor-stat-set); a design without it + // reads as 1. + [Inspectable, JsonProperty("interceptFactor"), Key(34)] + public PerformanceStat InterceptFactor; public override Behavior CreateInstance(EquippedItem item) { @@ -50,6 +55,7 @@ public class LockWeapon : InstantWeapon public float LockAngle { get; private set; } public float DirectionImpact { get; private set; } public float Decay { get; private set; } + public float InterceptFactor => _data.InterceptFactor == null ? 1f : Evaluate(_data.InterceptFactor); public override float Progress => saturate(_cooldown > 0 ? _cooldown : _lock); @@ -102,6 +108,8 @@ public class LockWeapon : InstantWeapon { var lerp = 1 - unlerp(0, 90, degrees); _lock = saturate(_lock + pow(lerp, DirectionImpact) * dt * LockSpeed * pow(Entity.EntityInfoGathered[target], SensorImpact)); + target.ReceivePaint(Entity, Item, PaintMode.Track, Lock); + Entity.Emit(Item, Range / InterceptFactor); } else _lock = saturate(_lock - dt * Decay); } @@ -109,4 +117,3 @@ public class LockWeapon : InstantWeapon return base.Execute(dt); } } - diff --git a/Assets/Scripts/ServerShared/Behaviors/MunitionParts.cs b/Assets/Scripts/ServerShared/Behaviors/MunitionParts.cs new file mode 100644 index 000000000..d25cd4f41 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/MunitionParts.cs @@ -0,0 +1,125 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System; +using System.Linq; +using MessagePack; +using Newtonsoft.Json; + +// A missile type's stats, as five dedicated gear-part behaviours on the launcher's own design, one per gear +// category the entity cut will derive them from (ruling drones-and-munitions-are-entities: "dedicated gear so a +// missile thruster is not the same as a ship thruster"). Ruling missile-stats-now-gear-later, in the operator's +// words: "For now these stats will belong to the missile, later they will be derived from gear." Each part becomes +// a derivation from (or moves onto) that munition gear when munitions are entities. +// +// Each part is its own BehaviorData because every stat walker (role validation, StatModifier targeting, AetherDb +// roles, the trade panel) reads PerformanceStat fields one level deep. The parts are inert: nothing here executes, +// and no ship-wide reader (thrust allocator, sensing, signatures) reads them, because a missile thruster is not a +// ship thruster and a seeker is not a ship sensor. MunitionParts.Of is the one read path. +public abstract class MunitionPartData : BehaviorData +{ + public override Behavior CreateInstance(EquippedItem item) => new MunitionPart(this, item); + public override Behavior CreateInstance(ConsumableItemEffect consumable) => new MunitionPart(this, consumable); +} + +// What a part instantiates to: no state and no override, so Execute stays the default true. +public sealed class MunitionPart : Behavior +{ + public MunitionPart(MunitionPartData data, EquippedItem item) : base(data, item) { } + public MunitionPart(MunitionPartData data, ConsumableItemEffect consumable) : base(data, consumable) { } +} + +public static class MunitionParts +{ + // The design's one part of that type. Catalog load and Upsert refuse a munition without exactly one of each. + public static T Of(EquippedItem item) where T : MunitionPartData => + item.Behaviors.Select(b => b.Data).OfType().Single(); +} + +// The missile hull. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public sealed class MunitionHullData : MunitionPartData +{ + [Inspectable, JsonProperty("durability"), Key(1), RuntimeInspectable] + public PerformanceStat Durability = new PerformanceStat(); + + // Metres. + [Inspectable, JsonProperty("radius"), Key(2)] + public PerformanceStat Radius = new PerformanceStat(); +} + +// The missile thruster. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public sealed class MunitionThrusterData : MunitionPartData +{ + // The main motor, m/s^2. + [Inspectable, JsonProperty("acceleration"), Key(1), RuntimeInspectable] + public PerformanceStat Acceleration = new PerformanceStat(); + + // The sideways acceleration cap, m/s^2. + [Inspectable, JsonProperty("lateral"), Key(2)] + public PerformanceStat Lateral = new PerformanceStat(); + + // m/s. + [Inspectable, JsonProperty("maxSpeed"), Key(3), RuntimeInspectable] + public PerformanceStat MaxSpeed = new PerformanceStat(); + + // The strength of this motor's DrivePlume at full throttle, as ThrusterData.Visibility. A datum only: it is + // never registered as the launching ship's signature. + [Inspectable, JsonProperty("visibility"), Key(4)] + public PerformanceStat Visibility = new PerformanceStat(); +} + +// The seeker. Passive here: it reads a target and emits nothing. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public sealed class MunitionSeekerData : MunitionPartData +{ + // Detection power, as SensorData.Sensitivity. + [Inspectable, JsonProperty("sensitivity"), Key(1)] + public PerformanceStat Sensitivity = new PerformanceStat(); + + // The full cone, in degrees (ruling sensor-stat-set's name and unit). + [Inspectable, JsonProperty("beamWidth"), Key(2)] + public PerformanceStat BeamWidth = new PerformanceStat(); + + // Metres. + [Inspectable, JsonProperty("range"), Key(3)] + public PerformanceStat Range = new PerformanceStat(); +} + +// Guidance and its cognition. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public sealed class MunitionControlData : MunitionPartData +{ + // The proportional-navigation constant. + [Inspectable, JsonProperty("navigation"), Key(1)] + public PerformanceStat Navigation = new PerformanceStat(); + + // The share of Lateral spent jinking. + [Inspectable, JsonProperty("evasion"), Key(2)] + public PerformanceStat Evasion = new PerformanceStat(); + + // Hz. + [Inspectable, JsonProperty("evasionFrequency"), Key(3), RuntimeInspectable] + public PerformanceStat EvasionFrequency = new PerformanceStat(); + + // Seconds. + [Inspectable, JsonProperty("lifetime"), Key(4)] + public PerformanceStat Lifetime = new PerformanceStat(); + + // The missile's own skill, 0 to 1 (ruling missile-cognition: "a smarter missile can better spend its delta v"). + // Four uses: guidance efficiency, when to jink against point defense, how much fuel it keeps for the terminal, + // and the price of the hit. + [Inspectable, JsonProperty("cognition"), Key(5)] + public PerformanceStat Cognition = new PerformanceStat(); +} + +// The tank. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public sealed class MunitionFuelData : MunitionPartData +{ + // Total manoeuvre budget, m/s. + [Inspectable, JsonProperty("deltaV"), Key(1)] + public PerformanceStat DeltaV = new PerformanceStat(); +} diff --git a/Assets/Scripts/ServerShared/Behaviors/MunitionParts.cs.meta b/Assets/Scripts/ServerShared/Behaviors/MunitionParts.cs.meta new file mode 100644 index 000000000..cf0a1097e --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/MunitionParts.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d4eac117ca042aaba71d1f6491b4617 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Pickup.cs b/Assets/Scripts/ServerShared/Behaviors/Pickup.cs new file mode 100644 index 000000000..29cd9c383 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Pickup.cs @@ -0,0 +1,171 @@ +using System; +using System.Linq; +using CultMath; +using MessagePack; +using Newtonsoft.Json; +using static CultMath.math; +using float2 = CultMath.float2; + +// The tractor beam: the capability that lets a ship collect floating items. It spins its beam up in sim time toward +// the pilot's command, and once the beam is up claims the free item nearest its axis and runs one timed grab +// (extend, envelop, pull) that ends in Zone.TryPickUp, the one commit of a pickup. Its stats are flat +// (Min == Max), as the other behaviours that carry their own timings. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable] +public class PickupData : BehaviorData +{ + // How far along the beam's axis an item can be claimed, and how far off the axis. + [Inspectable, JsonProperty("range"), Key(1), RuntimeInspectable] + public PerformanceStat Range = new PerformanceStat(); + + [Inspectable, JsonProperty("beamRadius"), Key(2), RuntimeInspectable] + public PerformanceStat BeamRadius = new PerformanceStat(); + + // The spin-up (0..1) needed to claim an item, and to keep a grab going. + [Inspectable, JsonProperty("grabPower"), Key(3), RuntimeInspectable] + public PerformanceStat GrabPower = new PerformanceStat(); + + // Seconds of each phase of a grab. + [Inspectable, JsonProperty("extendTime"), Key(4), RuntimeInspectable] + public PerformanceStat ExtendTime = new PerformanceStat(); + + [Inspectable, JsonProperty("envelopTime"), Key(5), RuntimeInspectable] + public PerformanceStat EnvelopTime = new PerformanceStat(); + + [Inspectable, JsonProperty("pullTime"), Key(6), RuntimeInspectable] + public PerformanceStat PullTime = new PerformanceStat(); + + // Spin-up and spin-down, in power per sim second. + [Inspectable, JsonProperty("spinRate"), Key(7), RuntimeInspectable] + public PerformanceStat SpinRate = new PerformanceStat(); + + public override Behavior CreateInstance(EquippedItem item) + { + return new Pickup(this, item); + } + + // A beam is a piece of gear the pilot holds on; no consumable carries one. + public override Behavior CreateInstance(ConsumableItemEffect item) => + throw new NotSupportedException("pickup: gear only"); +} + +// Owns this ship's beam power and its one grab. Power is written only here; Zone owns the held item's pose. +public class Pickup : Behavior, IAlwaysUpdatedBehavior +{ + private readonly PickupData _data; + // Power and the grab clock are kept in double so a fixed tick count lands on the same side of a boundary + // whatever dt the zone steps by. + private double _power; + private bool _grabbing; + private FloatingBodyId _target; + private double _elapsed; + // How many of Envelop and Pull have been published so far (0, 1 or 2). + private int _published; + + public Pickup(PickupData data, EquippedItem item) : base(data, item) + { + _data = data; + } + + // The beam's spun-up state in [0, 1]: what the pilot's command has driven it to. + public float Power => (float) _power; + + public void Update(float dt) + { + var active = Item.Active.Value; + var command = active ? Math.Clamp(Entity.TractorCommand, 0f, 1f) : 0f; + var step = (double) Evaluate(_data.SpinRate) * dt; + _power = Math.Clamp(_power + Math.Clamp(command - _power, -step, step), 0.0, 1.0); + + var zone = Entity.Zone; + var grabPower = Evaluate(_data.GrabPower); + var extend = (double) Evaluate(_data.ExtendTime); + var envelop = (double) Evaluate(_data.EnvelopTime); + var pull = (double) Evaluate(_data.PullTime); + var range = Evaluate(_data.Range); + var radius = Evaluate(_data.BeamRadius); + var origin = Entity.Position.xz; + + if (!_grabbing) + { + if (!active || _power < grabPower) return; + var item = Select(zone, origin, range, radius); + if (item == null || !zone.TryHold(Entity, item.Id)) return; + _grabbing = true; + _target = item.Id; + _elapsed = 0; + _published = 0; + Publish(GrabPhase.Started, item, 0); + Publish(GrabPhase.Extend, item, (float) extend); + return; + } + + var held = zone.FloatingItems.FirstOrDefault(f => f.Id.Equals(_target)); + if (held == null || !ReferenceEquals(held.Holder, Entity)) + { + _grabbing = false; + Entity.Capabilities.PublishGrab(new GrabEvent(_target, GrabPhase.Cancelled, float3(0), 0)); + return; + } + + var pulling = _elapsed >= extend + envelop; + if (!active || _power < grabPower || (!pulling && !InBeam(held.Body.Position, origin, range, radius, out _))) + { + _grabbing = false; + zone.Free(_target); + Publish(GrabPhase.Cancelled, held, 0); + return; + } + + _elapsed += dt; + if (_published < 1 && _elapsed >= extend) { _published = 1; Publish(GrabPhase.Envelop, held, (float) envelop); } + if (_published < 2 && _elapsed >= extend + envelop) { _published = 2; Publish(GrabPhase.Pull, held, (float) pull); } + if (_published == 2) + zone.SetHeldProgress(_target, pull > 0 ? (float) ((_elapsed - extend - envelop) / pull) : 1f); + if (_elapsed < extend + envelop + pull) return; + + _grabbing = false; + if (zone.TryPickUp(Entity, _target)) Publish(GrabPhase.Completed, held, 0); + else + { + zone.Free(_target); + Publish(GrabPhase.Cancelled, held, 0); + } + } + + // The one beam region: within Range along the aim axis (never behind) and BeamRadius off it. Selection claims + // from it and the grab holds on to its item only while the item stays in it. A zero aim has no region. + private bool InBeam(float2 position, float2 origin, float range, float radius, out float off) + { + off = 0; + var aim = Entity.Aim.xz; + if (lengthsq(aim) <= 0) return false; + var axis = normalize(aim); + var to = position - origin; + var along = dot(to, axis); + off = length(to - axis * along); + return along >= 0 && along <= range && off <= radius; + } + + // The free item nearest the beam axis within the beam region that some cargo bay can store whole (the bay's own + // TryFindSpace, the test TryStore opens with); ties go to the lowest id. A zero aim selects nothing. + private FloatingItem Select(Zone zone, float2 origin, float range, float radius) + { + FloatingItem best = null; + var bestOff = float.MaxValue; + foreach (var floating in zone.FloatingItems) + { + if (floating.Holder != null) continue; + if (!InBeam(floating.Body.Position, origin, range, radius, out var off)) continue; + if (!Entity.CargoBays.Any(bay => bay.TryFindSpace(floating.Item))) continue; + if (off < bestOff || (off == bestOff && floating.Id.Value < best.Id.Value)) + { + best = floating; + bestOff = off; + } + } + return best; + } + + private void Publish(GrabPhase phase, FloatingItem item, float duration) => + Entity.Capabilities.PublishGrab(new GrabEvent(item.Id, phase, float3(item.Body.Position.x, DrawAhead.FloaterHeight(Entity.Zone, Entity.ItemManager.GameplaySettings, item.Body.Position, 0), item.Body.Position.y), duration)); +} diff --git a/Assets/Scripts/ServerShared/Behaviors/Pickup.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Pickup.cs.meta new file mode 100644 index 000000000..34947e359 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Pickup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac7678d240564331be7486588d28c5ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Radiator.cs b/Assets/Scripts/ServerShared/Behaviors/Radiator.cs index a43a1a5c7..0c9239a0a 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Radiator.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Radiator.cs @@ -118,7 +118,7 @@ public class Radiator : Behavior, IAlwaysUpdatedBehavior, IInitializableBehavior Emissivity = Evaluate(_data.Emissivity); var rad = pow(RadiatorTemperature, ItemManager.GameplaySettings.HeatRadiationExponent) * ItemManager.GameplaySettings.HeatRadiationMultiplier * Emissivity; RadiatorTemperature -= rad * delta; - Entity.VisibilitySources[this] = rad; + Entity.SetSignature(this, SignatureChannel.Thermal, rad, Item); } public void Initialize() diff --git a/Assets/Scripts/ServerShared/Behaviors/Reactor.cs b/Assets/Scripts/ServerShared/Behaviors/Reactor.cs index e5321ac17..14cc1424c 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Reactor.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Reactor.cs @@ -94,8 +94,6 @@ public class Reactor : Behavior Draw = 0; } - Item.SetAudioParameter(SpecialAudioParameter.Intensity, max(.25f, 1 - 1 / CurrentLoadRatio)); - AddHeat(heat); return true; } diff --git a/Assets/Scripts/ServerShared/Behaviors/Reflector.cs b/Assets/Scripts/ServerShared/Behaviors/Reflector.cs index b5c4b4ad6..6b7f70a10 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Reflector.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Reflector.cs @@ -43,7 +43,7 @@ public class Reflector : Behavior public override bool Execute(float dt) { - Entity.VisibilitySources[this] = Evaluate(_data.CrossSection) * Entity.Zone.GetLight(Entity.Position.xz); + Entity.SetSignature(this, SignatureChannel.Reflection, Evaluate(_data.CrossSection) * Entity.Zone.GetLight(Entity.Position.xz), Item); return true; } diff --git a/Assets/Scripts/ServerShared/Behaviors/Scanner.cs b/Assets/Scripts/ServerShared/Behaviors/Scanner.cs new file mode 100644 index 000000000..c1e9ede41 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Scanner.cs @@ -0,0 +1,100 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using MessagePack; +using Newtonsoft.Json; +using static CultMath.math; + +// Inspection (campaign aetheria-release, rulings quiet-gear-identifiable-hull-layout-known, scan-held-beam, +// scan-is-an-act): a gear that, held on the ship's tracked target within Range for ScanTime, reveals everything fitted to +// that target, quiet gear that never acts included. The scan is an emission like a lock: the target is painted and +// third parties hear it at Range over the intercept factor. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable] +public class ScannerData : BehaviorData +{ + // The planar distance to the target within which a scan builds. + [Inspectable, JsonProperty("range"), Key(1), RuntimeInspectable] + public PerformanceStat Range = new PerformanceStat(); + + // Seconds a held scan takes to finish; a broken scan decays over the same span. + [Inspectable, JsonProperty("scanTime"), Key(2), RuntimeInspectable] + public PerformanceStat ScanTime = new PerformanceStat(); + + // The ratio of how far this scanner sees to how far others hear it (ruling sensor-stat-set); a design without it + // reads as 1. + [Inspectable, JsonProperty("interceptFactor"), Key(3)] + public PerformanceStat InterceptFactor; + + public override Behavior CreateInstance(EquippedItem item) + { + return new Scanner(this, item); + } + public override Behavior CreateInstance(ConsumableItemEffect item) + { + return new Scanner(this, item); + } +} + +public class Scanner : Behavior, IProgressBehavior +{ + private readonly ScannerData _data; + private Entity _target; + private float _built; + private double _heldAt; + + // The scan's progress now: what Execute last built, less ScanTime-relative decay over the time since a tick last held + // it (ruling scan-held-beam: a broken scan decays over ScanTime, the item inactive or destroyed included). Derived from + // the zone clock, never from tick order, so a scanner decays on the tick it breaks whether its host runs Execute + // before the always-updated pass (EquippedItem) or after it (ConsumableItemEffect). The one decay site. It is the + // progress against the ship's target now: a scan built on another ship reads 0 the moment the target changes, whether + // or not the item is running to reset it. + public float Progress => _target == Entity.Target.Value.Entity ? Remaining(_heldAt) : 0f; + + public Scanner(ScannerData data, EquippedItem item) : base(data, item) + { + _data = data; + } + public Scanner(ScannerData data, ConsumableItemEffect item) : base(data, item) + { + _data = data; + } + + private float Remaining(double since) + { + if (_built <= 0f) return 0f; + var now = Entity.Zone?.ExactTime ?? since; + return saturate(_built - (float) (now - since) / Evaluate(_data.ScanTime)); + } + + // Runs only while the item is Active. The scan builds while the ship's own Target is a tracked ship within Range, and + // is painted and emitted on every tick it builds; at 1 the target's fitted items enter the book and the scan starts over. + // A tick that does not hold the scan builds nothing, and the zone clock carries its decay (Progress). + public override bool Execute(float dt) + { + var target = Entity.Target.Value.Entity; + if (_target != target) + { + _built = 0f; + _target = target; + } + + var range = Evaluate(_data.Range); + if (target != null && Entity.VisibleEntities.Contains(target) && Entity.TargetRange <= range) + { + // Decay over the ticks since the last held one, not counting this tick, which holds. + var progress = saturate(Remaining(_heldAt + dt) + dt / Evaluate(_data.ScanTime)); + _built = progress; + _heldAt = Entity.Zone?.ExactTime ?? _heldAt; + target.ReceivePaint(Entity, Item, PaintMode.Scan, progress); + Entity.Emit(Item, range / (_data.InterceptFactor == null ? 1f : Evaluate(_data.InterceptFactor))); + if (progress >= 1f) + { + Entity.RecordInspection(target); + _built = 0f; + } + } + + return true; + } +} diff --git a/Assets/Scripts/ServerShared/Behaviors/Scanner.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Scanner.cs.meta new file mode 100644 index 000000000..1eb6935e7 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Scanner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf9e034c7a31410ea1c516f46b43825c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Sensor.cs b/Assets/Scripts/ServerShared/Behaviors/Sensor.cs index 8eeadbb7d..cf9d161f0 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Sensor.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Sensor.cs @@ -24,8 +24,7 @@ public class SensorData : BehaviorData [Inspectable, JsonProperty("pingEnergy"), Key(6), RuntimeInspectable] public PerformanceStat PingEnergy; - [Inspectable, JsonProperty("pingVisibility"), Key(7), RuntimeInspectable] - public PerformanceStat PingVisibility; + // Key 7 (pingVisibility) is retired: never reuse it. [Inspectable, JsonProperty("pingRange"), Key(8), RuntimeInspectable] public PerformanceStat PingRange; @@ -38,6 +37,16 @@ public class SensorData : BehaviorData [Inspectable, JsonProperty("pingRadiusExponent"), Key(11)] public float PingRadiusExponent = .5f; + + // The width in degrees of the cone a ping sweeps, about the sensor's facing (ruling illuminator-beamforming: + // how much a ping reveals is a stat). 360 or more is omnidirectional; a design without it reads as 360. + [Inspectable, JsonProperty("beamWidth"), Key(12)] + public PerformanceStat BeamWidth; + + // The ratio of how far this sensor sees to how far others hear it (ruling sensor-stat-set); a design without it + // reads as 1. + [Inspectable, JsonProperty("interceptFactor"), Key(13)] + public PerformanceStat InterceptFactor; public override Behavior CreateInstance(EquippedItem item) { @@ -61,7 +70,14 @@ public class Sensor : Behavior, IEventBehavior, IPowerConsumer private float _pingLerp; private bool _pinging; private float _pingRadius; - private HashSet _pingedEntities = new HashSet(); + + // The subjects this ping's wavefront has reached, in the beam or not; each is crossed at most once per ping. + // Ping() is the one reset. A sweeping tick drops every subject no longer in the zone, so a subject that + // leaves and comes back inside the front is reached again, as a ship arriving inside the front is. + private readonly HashSet _reached = new HashSet(); + + // The zone the ping began in: a ping belongs to it, and ends when the pinger is anywhere else. + private Zone _pingZone; public float Cooldown { @@ -73,6 +89,19 @@ public class Sensor : Behavior, IEventBehavior, IPowerConsumer get => _pingRadius; } + public float BeamWidth => _data.BeamWidth == null ? 360f : Evaluate(_data.BeamWidth); + + public float InterceptFactor => _data.InterceptFactor == null ? 1f : Evaluate(_data.InterceptFactor); + + public float2 Facing => Direction.xz; + + // Whether the offset `diff` (length `dist`) from this sensor lies inside its beam. + private bool InBeam(float2 diff, float dist) + { + var beam = BeamWidth; + return beam >= 360f || dot(Facing, diff) >= dist * cos(beam * .5f * .0174533f); + } + public float PingBrightness => pow(1 - _pingLerp, _data.PingRadiusExponent); public event Action OnPingStart; @@ -114,12 +143,12 @@ public class Sensor : Behavior, IEventBehavior, IPowerConsumer // nothing would ever fill this capacitor; bypass it rather than starving such an instance forever. if(_pingCooldown < 0 && (Item == null || _capacitor.TrySpend(_capacitor.Capacity))) { - Entity.VisibilitySources[this] = Evaluate(_data.PingVisibility); _pinging = true; + _pingZone = Entity.Zone; _pingCooldown = 1; _pingLerp = 0; _pingRadius = 0; - _pingedEntities.Clear(); + _reached.Clear(); OnPingStart?.Invoke(); } } @@ -140,15 +169,15 @@ public class Sensor : Behavior, IEventBehavior, IPowerConsumer // instance never reaches PowerBus.Step (see Ping()) and so never accrues charge. if (Item != null) _capacitor.AddCharge(_capacitor.RequestedFill(dt) * Item.PowerSupply); + if (_pinging && Entity.Zone != _pingZone) EndPing(); + var sweeping = _pinging; if (_pinging) { _pingLerp += dt / _data.PingDuration; _pingRadius = lerp(0, Evaluate(_data.PingRange), pow(_pingLerp, _data.PingRadiusExponent)); - if (_pingLerp > 1) - { - _pinging = false; - OnPingEnd?.Invoke(); - } + _reached.IntersectWith(Entity.Zone.Entities); + Entity.Emit(Item, Evaluate(_data.PingRange) / InterceptFactor); + if (_pingLerp > 1) EndPing(); } _pingCooldown -= dt / Evaluate(_data.PingCooldown); @@ -160,17 +189,44 @@ public class Sensor : Behavior, IEventBehavior, IPowerConsumer var diff = entity.Position.xz - Entity.Position.xz; var dist = length(diff); + var obscuration = Entity.Zone.Obscuration(Entity.Position.xz, entity.Position.xz); float previous, next; Entity.EntityInfoGathered.TryGetValue(entity, out previous); - if (!_pingedEntities.Contains(entity) && dist < _pingRadius) + + var sensitivity = Evaluate(_data.Sensitivity); + var response = _data.PingBoost == null ? 0f : Evaluate(_data.PingBoost); + var credit = 0f; + var heard = false; + + // The first sweeping tick this ping's wavefront is past the entity is its one crossing. Inside the beam + // it paints the subject (it learns it is swept), credits this sensor, and is returned to every ally; an + // ally hears it silently (ruling sensor-stat-set item 3): credit, no paint, no emission. + if (sweeping && dist < _pingRadius && _reached.Add(entity) && InBeam(diff, dist)) { - _pingedEntities.Add(entity); - next = saturate(previous + Gain(entity.Visibility, Evaluate(_data.Sensitivity), Evaluate(_data.PingBoost), dist, dt, true)); + heard = true; + entity.ReceivePaint(Entity, Item, PaintMode.Search, 0); + credit += Gain(entity.Visibility, sensitivity, response, dist, dt, true, obscuration); + var pingReturn = new PingReturn(entity, dist, obscuration, Evaluate(_data.PingRange)); + foreach (var ally in Entity.Zone.Entities) + if (ally != Entity && ally != entity && ally.Faction != null && ally.Faction == Entity.Faction && !ally.IsHostileTo(Entity)) + ally.ReceiveReturn(pingReturn); } + + // An ally's ping returned off this subject (ruling ally-echo-bistatic-oval): heard while the + // illuminated and received ranges sit inside the oval Rt x Rr < PingRange^2, credited at their geometric mean. + foreach (var r in Entity.PingReturns) + { + if (r.Subject != entity || r.IlluminatedRange * dist >= r.MaxRange * r.MaxRange) continue; + heard = true; + credit += Gain(entity.Visibility, sensitivity, response, sqrt(r.IlluminatedRange * dist), dt, true, sqrt(r.IlluminatedObscuration * obscuration)); + } + + if (heard) + next = saturate(previous + credit); else { var angle = acos(dot(forward, normalize(diff))); - next = saturate(previous + Gain(entity.Visibility, Evaluate(_data.Sensitivity), _data.SensitivityCurve.Evaluate(angle / PI), dist, dt, false)); + next = saturate(previous + Gain(entity.Visibility, sensitivity, _data.SensitivityCurve.Evaluate(angle / PI), dist, dt, false, obscuration)); } next *= 1 - ItemManager.GameplaySettings.TargetInfoDecay * dt; //Context.Log($"{entity.Name} visibility {(int)(previous * 100)}% -> {(int)(next * 100)}%"); @@ -179,15 +235,23 @@ public class Sensor : Behavior, IEventBehavior, IPowerConsumer return true; } + private void EndPing() + { + _pinging = false; + OnPingEnd?.Invoke(); + } + // Mining Cut 3 (docs/mining-cut-refresh.md): the one detection gain rule -- the info one observation of a // target adds. A ping adds `visibility × sensitivity × PingBoost × distance` once; a passive tick adds // `visibility × sensitivity × curve(angle/π) × dt / distance`. `response` is PingBoost for a ping and the - // sensitivity curve at the bearing for a passive tick. The entity loop above and the chunk query - // (Entity.ChunkInfo, through PassiveRate) both call this; nothing else multiplies these terms. - public static float Gain(float visibility, float sensitivity, float response, float distance, float dt, bool ping) => - ping + // sensitivity curve at the bearing for a passive tick. `obscuration` is the fraction of the signal that + // survives the vapour clouds on the sight line (Zone.Obscuration, 1f with none), scaling both. The entity + // loop above and the chunk query (Entity.ChunkInfo, through PassiveRate) both call this; nothing else + // multiplies these terms. + public static float Gain(float visibility, float sensitivity, float response, float distance, float dt, bool ping, float obscuration) => + (ping ? visibility * sensitivity * response * distance - : visibility * sensitivity * response * dt / distance; + : visibility * sensitivity * response * dt / distance) * obscuration; // The passive gain per second this sensor draws from a target of `visibility` at the planar `position`: // Gain over one second, with the bearing measured from this sensor's own facing exactly as Execute does. @@ -195,7 +259,8 @@ public class Sensor : Behavior, IEventBehavior, IPowerConsumer { var diff = position - Entity.Position.xz; var angle = acos(dot(Direction.xz, normalize(diff))); - return Gain(visibility, Evaluate(_data.Sensitivity), _data.SensitivityCurve.Evaluate(angle / PI), length(diff), 1f, false); + return Gain(visibility, Evaluate(_data.Sensitivity), _data.SensitivityCurve.Evaluate(angle / PI), length(diff), 1f, false, + Entity.Zone.Obscuration(Entity.Position.xz, position)); } // An upper bound on sensitivity x response over every bearing, so PassiveRate(v, p) <= v x this / distance diff --git a/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs b/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs index 5e56e4c42..430536591 100644 --- a/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs +++ b/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs @@ -95,13 +95,13 @@ public class StatModifier : Behavior, IInitializableBehavior, IDisposable, IAlwa .Where(g => string.IsNullOrEmpty(data.RequireBehavior) || entity.ItemManager.GetData(g.EquippableItem).Behaviors.Any(b => b.GetType().Name == data.RequireBehavior)); return typeof(EquippableItemData).IsAssignableFrom(targetType) - ? gear.Where(g => entity.ItemManager.GetData(g.EquippableItem).GetType() == targetType) + ? gear.Where(g => targetType.IsAssignableFrom(entity.ItemManager.GetData(g.EquippableItem).GetType())) .Select(g => new Target(g, statField.GetValue(entity.ItemManager.GetData(g.EquippableItem)) as PerformanceStat)) .Where(t => t.Stat != null) .ToArray() - : gear.Where(g => entity.ItemManager.GetData(g.EquippableItem).Behaviors.Any(bd => bd.GetType() == targetType)) + : gear.Where(g => entity.ItemManager.GetData(g.EquippableItem).Behaviors.Any(bd => targetType.IsAssignableFrom(bd.GetType()))) .SelectMany(g => entity.ItemManager.GetData(g.EquippableItem).Behaviors - .Where(bd => bd.GetType() == targetType) + .Where(bd => targetType.IsAssignableFrom(bd.GetType())) .Select(bd => new Target(g, statField.GetValue(bd) as PerformanceStat))) .Where(t => t.Stat != null) .ToArray(); diff --git a/Assets/Scripts/ServerShared/Behaviors/TargetingSystem.cs b/Assets/Scripts/ServerShared/Behaviors/TargetingSystem.cs index 96d9f3703..b0b839258 100644 --- a/Assets/Scripts/ServerShared/Behaviors/TargetingSystem.cs +++ b/Assets/Scripts/ServerShared/Behaviors/TargetingSystem.cs @@ -31,7 +31,7 @@ public class TargetingSystemData : BehaviorData // Cut 6d (docs/fire-control-cut.md): grouping tightness, not a probability. FireControl.Sigma derives a // Gaussian kernel's sigma as 1/Precision, in hull-schematic cell units -- a higher number groups tighter - // around whatever is aimed at (Entity.TargetItem's cells, or the hull's own centre of mass unaimed). + // around whatever is aimed at (Entity.AimedAt: an item's cells or a mount's; the hull's own centre of mass unaimed). // Consumed by Cut 3's roll (folded into HitProbability as pOnHull) and by Commit's cell draw, both through // the one kernel function -- never re-derived separately. [Inspectable, JsonProperty("precision"), Key(3), RuntimeInspectable] diff --git a/Assets/Scripts/ServerShared/Behaviors/ThrottleLock.cs b/Assets/Scripts/ServerShared/Behaviors/ThrottleLock.cs new file mode 100644 index 000000000..52fcc926f --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/ThrottleLock.cs @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using MessagePack; +using Newtonsoft.Json; + +// Presence marks the lock: Entity.ThrottleLocked is true while an active effect carries one, and the thrust +// allocator then bounds every forward-pushing column at full throttle from below in its solve. The behaviour +// holds no state and does nothing itself; turning stays with the pilot. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable] +public class ThrottleLockData : BehaviorData +{ + public override Behavior CreateInstance(EquippedItem item) + { + return new ThrottleLock(this, item); + } + public override Behavior CreateInstance(ConsumableItemEffect item) + { + return new ThrottleLock(this, item); + } +} + +public class ThrottleLock : Behavior +{ + public ThrottleLock(ThrottleLockData data, EquippedItem item) : base(data, item) + { + } + + public ThrottleLock(ThrottleLockData data, ConsumableItemEffect item) : base(data, item) + { + } + + public override bool Execute(float dt) => true; +} diff --git a/Assets/Scripts/ServerShared/Behaviors/ThrottleLock.cs.meta b/Assets/Scripts/ServerShared/Behaviors/ThrottleLock.cs.meta new file mode 100644 index 000000000..01ac8c635 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/ThrottleLock.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 558ff9ad01ba4fd4987d5e6ba4f31e4d \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Thruster.cs b/Assets/Scripts/ServerShared/Behaviors/Thruster.cs index be0d79900..a349ad744 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Thruster.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Thruster.cs @@ -25,6 +25,11 @@ public class ThrusterData : BehaviorData [Inspectable, CultInspectorAssetGuid, JsonProperty("Particles"), Key(5)] public string ParticlesPrefab; + + // The gimbal's slew rate in degrees per second: the part's own stat, as a weapon's traverse is + // (ruling mount-arc-gun-traverse). The swing limit is the hardpoint's FiringArc, the row its Row. + [Inspectable, JsonProperty("slew"), Key(6), RuntimeInspectable] + public PerformanceStat Slew = new PerformanceStat(); public override Behavior CreateInstance(EquippedItem item) { @@ -37,12 +42,24 @@ public class ThrusterData : BehaviorData } } -public class Thruster : Behavior, IAnalogBehavior, IPowerConsumer +public class Thruster : Behavior, IPowerConsumer { // Live: heat, quality, durability and power move this stat after construction, so it is read, never cached. public float Thrust => Evaluate(_data.Thrust); + // Thrust at a full grant, the same stat read without the power-supply term: what a column promises. Live, like Thrust. + public float NominalThrust => EvaluateNominalPower(_data.Thrust); public float Torque { get; } + // This thruster's effect per unit throttle at the given thrust, in the body frame: xy is the push (x starboard, y + // forward), z the clockwise yaw rate in rad/s. Zero when the item is absent or offline. The one geometry owner for + // the allocator and the envelope. + public float3 Column(float thrust) + { + if (Item == null || !Item.Active.Value) return default; + var push = -float2(0, 1).Rotate(Item.EquippableItem.Rotation) * thrust / Entity.Mass; + return float3(push.x, push.y, Torque * thrust * ItemManager.GameplaySettings.TorqueMultiplier / Entity.Mass); + } + public float Axis { get => _input; @@ -84,53 +101,30 @@ public class Thruster : Behavior, IAnalogBehavior, IPowerConsumer // registered request field (StatValidation.PowerRequestFields) -- read nominally, same reasoning as every // other IPowerConsumer in this cut, though EnergyUsage carries no PowerSupply term in Thruster's own shipped // catalog today; Thrust (the field Cut 7 curves) is a separate stat Execute reads with the real Evaluate. - public float PowerRequest(float dt) => _input > .01f ? _input * EvaluateNominalPower(_data.EnergyUsage) : 0f; + public float PowerRequest(float dt) => _input > 0f ? _input * EvaluateNominalPower(_data.EnergyUsage) : 0f; // Cut 5 (docs/stats-and-power-cut.md §1.3, PowerTiers.cs): Medium -- mobility. Losing thrust for a tick // under brownout is an inconvenience, not the cascading failure a starved radiator or shield causes. public int DefaultPowerTier => PowerTiers.Medium; - // What this thruster adds to the ship's manoeuvre envelope: Execute's own arithmetic at full input, read live. - // Its push is Thrust / Mass along its mount, into the matching body - // axis, even for a flank thruster that only turns (it pushes whenever it turns); its turn is |Torque| * Thrust * - // TorqueMultiplier / Mass into the side its Torque sign fires on, when |Torque| clears the floor. Zero when the - // item is offline or unpowered, the same gates Execute applies. - public ManoeuvreEnvelope Manoeuvre() - { - if (Item == null || !Item.Active.Value || Item.PowerSupply <= 1e-4f) return default; - var settings = ItemManager.GameplaySettings; - var thrust = Thrust; - var acceleration = thrust / Entity.Mass; - var forward = normalize(Entity.Direction); - var right = forward.Rotate(ItemRotation.Clockwise); - var push = -forward.Rotate(Item.EquippableItem.Rotation); - var along = dot(push, forward); - var across = dot(push, right); - var turn = abs(Torque) > settings.TorqueFloor ? abs(Torque) * thrust * settings.TorqueMultiplier / Entity.Mass : 0f; - return new ManoeuvreEnvelope( - max(along, 0f) * acceleration, max(-along, 0f) * acceleration, - max(-across, 0f) * acceleration, max(across, 0f) * acceleration, - Torque > 0f ? turn : 0f, Torque < 0f ? turn : 0f); - } - public override bool Execute(float dt) { - Item.SetAudioParameter(SpecialAudioParameter.Intensity, _input); // Cut 7 (docs/stats-and-power-target.md): "continuous consumers brown out ... through a power supply // curve on their performance stats." Thrust below is a plain Evaluate() read, so once the catalog's own // Thrust stat carries a PowerSupply term, a partial grant already comes back reduced -- this gate no // longer demands a full grant, only that the thruster is being asked to do anything (_input) and that it // has not been cut to true zero supply (the epsilon PowerBus itself already treats as "nothing granted"). - if(_input > .01f && Item.PowerSupply > 1e-4f) + if(_input > 0f && Item.PowerSupply > 1e-4f) { var thrust = Thrust; Entity.Velocity -= Direction.xz * _input * thrust / Entity.Mass * dt; - Entity.Direction = mul(Entity.Direction, - CultMath.float2x2.Rotate(_input * Torque * thrust * ItemManager.GameplaySettings.TorqueMultiplier / Entity.Mass * dt)); + var turnRate = _input * Torque * thrust * ItemManager.GameplaySettings.TorqueMultiplier / Entity.Mass; + Entity.Direction = mul(Entity.Direction, CultMath.float2x2.Rotate(turnRate * dt)); + Entity.TurnRate += turnRate; AddHeat(_input * Evaluate(_data.Heat) * dt); var vis = _input * Evaluate(_data.Visibility); - if (!Entity.VisibilitySources.ContainsKey(this) || vis > Entity.VisibilitySources[this]) - Entity.VisibilitySources[this] = vis; + if (!Entity.VisibilitySources.TryGetValue(this, out var burn) || vis > burn.Strength) + Entity.SetSignature(this, SignatureChannel.DrivePlume, vis, Item); return true; } return false; diff --git a/Assets/Scripts/ServerShared/Behaviors/TurretController.cs b/Assets/Scripts/ServerShared/Behaviors/TurretController.cs index be092f7a0..cb65eba58 100644 --- a/Assets/Scripts/ServerShared/Behaviors/TurretController.cs +++ b/Assets/Scripts/ServerShared/Behaviors/TurretController.cs @@ -64,13 +64,12 @@ public class TurretController : Behavior, IInitializableBehavior var diff = target.Position - Entity.Position; if (_predictShots) { - var targetHullData = Entity.ItemManager.GetData(target.Hull) as HullData; var targetVelocity = float3(target.Velocity.x, 0, target.Velocity.y); var predictedPosition = first_order_intercept( Entity.Position, float3.zero, _shotSpeed, target.Position, targetVelocity ); - predictedPosition.y = Entity.Zone.GetHeight(predictedPosition.xz) + targetHullData.GridOffset; + predictedPosition.y = target.RideHeight(predictedPosition.xz); Entity.Aim = normalize(predictedPosition - Entity.Position); } else diff --git a/Assets/Scripts/ServerShared/Behaviors/VapourDump.cs b/Assets/Scripts/ServerShared/Behaviors/VapourDump.cs new file mode 100644 index 000000000..3e035f9b8 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/VapourDump.cs @@ -0,0 +1,61 @@ +using MessagePack; +using Newtonsoft.Json; + +// A coolant dump that becomes a vapour cloud: the first time it runs it vents one cloud around its venter, +// drifting with the venter's velocity. Radius, Opacity and Lifetime are evaluated through the host, so role +// quality applies as for any other stat. Later runs vent nothing. +[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable] +public class VapourDumpData : BehaviorData +{ + [Inspectable, JsonProperty("radius"), Key(1), RuntimeInspectable] + public PerformanceStat Radius = new PerformanceStat(); + + // How much of a sight line's signal a fresh cloud removes, in [0, 1]. + [Inspectable, JsonProperty("opacity"), Key(2), RuntimeInspectable] + public PerformanceStat Opacity = new PerformanceStat(); + + // Seconds from venting until the cloud has faded away and is removed. + [Inspectable, JsonProperty("lifetime"), Key(3), RuntimeInspectable] + public PerformanceStat Lifetime = new PerformanceStat(); + + public override Behavior CreateInstance(EquippedItem item) + { + return new VapourDump(this, item); + } + + public override Behavior CreateInstance(ConsumableItemEffect item) + { + return new VapourDump(this, item); + } +} + +public class VapourDump : Behavior +{ + private VapourDumpData _data; + private bool _vented; + + public VapourDump(VapourDumpData data, EquippedItem item) : base(data, item) + { + _data = data; + } + + public VapourDump(VapourDumpData data, ConsumableItemEffect item) : base(data, item) + { + _data = data; + } + + public override bool Execute(float dt) + { + if (_vented) return true; + _vented = true; + Entity.Zone.Vent(new VapourCloud + { + Body = new KinematicBody { Position = Entity.Position.xz, Velocity = Entity.Velocity }, + Radius = Evaluate(_data.Radius), + Opacity = Evaluate(_data.Opacity), + Lifetime = Evaluate(_data.Lifetime), + Venter = Entity + }); + return true; + } +} diff --git a/Assets/Scripts/ServerShared/Behaviors/VapourDump.cs.meta b/Assets/Scripts/ServerShared/Behaviors/VapourDump.cs.meta new file mode 100644 index 000000000..86ef08913 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/VapourDump.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 961a74683c574807a300eb26694f206d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Visibility.cs b/Assets/Scripts/ServerShared/Behaviors/Visibility.cs index 1311f7cff..07dcb3cf2 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Visibility.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Visibility.cs @@ -15,6 +15,9 @@ public class VisibilityData : BehaviorData [Inspectable, JsonProperty("visibilityDecay"), Key(2)] public PerformanceStat VisibilityDecay = new PerformanceStat(); + + [Inspectable, JsonProperty("channel"), Key(3)] + public SignatureChannel Channel = SignatureChannel.Thermal; public override Behavior CreateInstance(EquippedItem item) { @@ -41,7 +44,7 @@ public class Visibility : Behavior public override bool Execute(float dt) { - Entity.VisibilitySources[this] = Evaluate(_data.Visibility); + Entity.SetSignature(this, _data.Channel, Evaluate(_data.Visibility), Item); return true; } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs index 82febb067..6a01f81ca 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs @@ -37,8 +37,16 @@ public abstract class WeaponData : BehaviorData [Inspectable, JsonProperty("range"), Key(6)] public PerformanceStat Range = new PerformanceStat(); - [InspectableAnimationCurve, JsonProperty("damageCurve"), Key(7)] - public BezierCurve DamageCurve; + // Key 7 was the damage curve, retired and never reused. + + // The range up to which a round does its full damage; from here to Range damage lerps to DamageAtMaxRange. Unauthored + // is no falloff (Tracking's precedent): +infinity clamps to Range in RangeFactor. + [Inspectable, JsonProperty("effectiveRange"), Key(35)] + public PerformanceStat EffectiveRange = new PerformanceStat { Min = float.PositiveInfinity, Max = float.PositiveInfinity }; + + // The multiplier on damage at Range, the end of the lerp (0 is nothing arriving at maximum range). + [Inspectable, JsonProperty("damageAtMaxRange"), Key(36)] + public float DamageAtMaxRange; [Inspectable, CultInspectorAssetGuid, JsonProperty("effect"), Key(8)] public string EffectPrefab; @@ -71,6 +79,25 @@ public abstract class WeaponData : BehaviorData // weapon-tracking-authored). Unauthored is a mount that follows anything: FireControl.PMount reads +infinity as 1. [Inspectable, JsonProperty("tracking"), Key(33), RuntimeInspectable] public PerformanceStat Tracking = new PerformanceStat { Min = float.PositiveInfinity, Max = float.PositiveInfinity }; + + // What an observer who believes this is the design measures it by (aetheria-ew, ew-claim-weapon-measure-ruled): the + // design's rated figures, each stat's Max (what a stat with no terms resolves to), through the same formula the + // live weapon's RangeDamagePerSecond runs over its evaluated stats. Never the carrier's quality, heat, wear or power. + public abstract float RatedRangeDamagePerSecond(float range); + public float RatedRangeFactor(float at) => RangeFactor(MinRange.Max, EffectiveRange.Max, Range.Max, DamageAtMaxRange, at); + + // The one function of how much of a weapon's damage arrives at a planar range: 0 outside [min, max] (inclusive, as + // FireControl.Designated), 1 up to the effective range, then one lerp to damageAtMax at max. An effective range outside + // [min, max] clamps into it. + public static float RangeFactor(float min, float effective, float max, float damageAtMax, float at) + { + if (at < min || at > max) return 0f; + var e = clamp(effective, min, max); + return e >= max ? 1f : lerp(1f, damageAtMax, saturate(unlerp(e, max, at))); + } + + [IgnoreMember] + public float RatedRange => Range.Max; } public abstract class Weapon : Behavior, IActivatedBehavior @@ -81,11 +108,13 @@ public abstract class Weapon : Behavior, IActivatedBehavior public abstract float RangeDamagePerSecond(float range); public abstract int Ammo { get; } public WeaponData WeaponData => _data; + public float RangeFactor(float at) => WeaponData.RangeFactor(MinRange, EffectiveRange, Range, _data.DamageAtMaxRange, at); public float Damage { get; protected set; } public float Penetration { get; protected set; } public float DamageSpread { get; protected set; } public float MinRange { get; protected set; } + public float EffectiveRange { get; protected set; } public float Range { get; protected set; } public float Energy { get; protected set; } public float Heat { get; protected set; } @@ -112,14 +141,10 @@ public abstract class Weapon : Behavior, IActivatedBehavior // so a weapon is never safed against one. public bool StanceAllowsFire => Entity.Target.Value.Entity == null || Entity.IsHostileTo(Entity.Target.Value.Entity); - // Cut 3 (docs/fire-control-cut.md, Q2): player fire is arc-gated like everyone else's. This is the same - // predicate (FireControl.InArc) Combat.cs and TurretController.cs gate AI and turret fire with, read at - // the one point every shooter's trigger passes through (InstantWeapon.Trigger) -- not a parallel check, and - // not the AI's own AgentMinHitProbability heuristic, which is a "worth it" decision layered above this - // gate, not the gate itself. With no target set, behaviour is unchanged (nothing to bear on). - // Cut 5, 5.4 (Soul finding 11): the point-blank special case this used to carry moved into InArc itself -- - // one bearing test, one owner, so every caller (not just this one) gets a point-blank shot that bears. - // FireControl owns the gate, including its one exemption: a fused weapon fires out of arc. + // The trigger gate for player and AI shooters alike, read at the one point every shooter's trigger passes + // through (InstantWeapon.Trigger). A gun fires on its solution (FireControl.Solution) without the aim, else + // along the aim when the aim is inside its arc, else it holds. An AI shooter's aim is its intercept, so its + // fire is unchanged. FireControl owns the gate, including its exemption: a fused weapon fires out of arc. public bool ArcAllowsFire => FireControl.ArcPermitsFire(this, Entity); public Weapon(WeaponData data, EquippedItem item) : base(data, item) @@ -138,6 +163,7 @@ public abstract class Weapon : Behavior, IActivatedBehavior Penetration = Evaluate(_data.Penetration); DamageSpread = Evaluate(_data.DamageSpread); MinRange = Evaluate(_data.MinRange); + EffectiveRange = Evaluate(_data.EffectiveRange); Range = Evaluate(_data.Range); Energy = Evaluate(_data.Energy); Heat = Evaluate(_data.Heat); diff --git a/Assets/Scripts/ServerShared/CapabilityEvents.cs b/Assets/Scripts/ServerShared/CapabilityEvents.cs index 9e3c26635..025975815 100644 --- a/Assets/Scripts/ServerShared/CapabilityEvents.cs +++ b/Assets/Scripts/ServerShared/CapabilityEvents.cs @@ -7,30 +7,35 @@ using UniRx; using CultMath; // Capability event contract (docs/headless-playground-cut.md fork L, operator ruling 2026-09-17): -// pickup, impact absorption, melee blade and propulsion are separate item capabilities. Simulation -// (not yet built -- this file only stands up the wire shape) will own each capability's rules and -// emit these events; any number of presentations (the field shield today, later an IFS shatter -// plane or an advected particle field) subscribe to the event kinds they visualize and decide -// nothing about the rule. This file has no engine dependency: it compiles into the headless -// Aetheria.Shared build (see Aetheria.Shared.csproj) with no publisher wired up yet. +// pickup, impact absorption, melee blade and propulsion are separate item capabilities. Simulation owns +// each capability's rules and emits these events (FireControl publishes Absorb; the others are not yet +// built); any number of presentations (the field shield today, later an IFS shatter plane or an advected +// particle field) subscribe to the event kinds they visualize and decide nothing about the rule. This file +// has no engine dependency: it compiles into the headless Aetheria.Shared build (see Aetheria.Shared.csproj). -// One absorbed impact: a hit landing on the item's shield/armor capability. DamageType rides along -// so presenters can vary visuals per type; the damage-type mask itself belongs to the absorb -// capability's own data and is out of scope for this cut (operator, 2026-09-17) -- this struct only -// carries the hit's existing type through, unfiltered. +// Which layer of the receiver took an absorbed impact. +public enum AbsorbLayer { Shield, Hull } + +// One absorbed impact on a shield or a hull, published once per receiver by FireControl on that entity's +// Entity.Capabilities. Position is a world point on the receiver's sim pose at the tick the impact lands (a +// presenter draws it with DrawAhead.Carried); Direction is the way the impact travels. DamageType rides along +// so presenters can vary visuals per type; the damage-type mask itself belongs to the absorb capability's own +// data and is out of scope (operator, 2026-09-17) -- this struct only carries the hit's existing type through. public readonly struct AbsorbEvent { public readonly float3 Position; public readonly float3 Direction; public readonly float Magnitude; public readonly DamageType DamageType; + public readonly AbsorbLayer Layer; - public AbsorbEvent(float3 position, float3 direction, float magnitude, DamageType damageType) + public AbsorbEvent(float3 position, float3 direction, float magnitude, DamageType damageType, AbsorbLayer layer) { Position = position; Direction = direction; Magnitude = magnitude; DamageType = damageType; + Layer = layer; } } @@ -47,19 +52,18 @@ public enum GrabPhase Cancelled } -// The target is identified by a plain handle, not a Unity type: the simulation will own the real -// target identity (a loot drop or item instance id) once the pickup capability exists. Today's only -// publisher (the FieldShieldTest scene) hands out its own handles; nothing here interprets them. +// One phase of a grab. The target is the floating item the Pickup behaviour holds (the FieldShieldTest scene +// publishes its own handles as ids); nothing here interprets it. public readonly struct GrabEvent { - public readonly int TargetHandle; + public readonly FloatingBodyId Target; public readonly GrabPhase Phase; public readonly float3 TargetPosition; public readonly float PhaseDuration; - public GrabEvent(int targetHandle, GrabPhase phase, float3 targetPosition, float phaseDuration) + public GrabEvent(FloatingBodyId target, GrabPhase phase, float3 targetPosition, float phaseDuration) { - TargetHandle = targetHandle; + Target = target; Phase = phase; TargetPosition = targetPosition; PhaseDuration = phaseDuration; @@ -101,10 +105,10 @@ public readonly struct ThrustEvent } } -// Per-entity (or per-item) source of capability events. One instance is owned by whatever will -// eventually decide these rules; today the FieldShieldTest scene stands in for that owner. Follows -// the Subject-per-event-kind idiom already used on Entity (IncomingHit, HullDamage, etc): each -// event kind gets its own stream, and a subscriber to one kind never sees another. +// Per-entity source of capability events: one instance per Entity (Entity.Capabilities), published by +// FireControl for Absorb; the FieldShieldTest scene keeps its own instance. Follows the Subject-per-event-kind +// idiom already used on Entity (IncomingHit, HullDamage, etc): each event kind gets its own stream, and a +// subscriber to one kind never sees another. public class CapabilityEvents { private readonly Subject _absorb = new Subject(); diff --git a/Assets/Scripts/ServerShared/Contacts.cs b/Assets/Scripts/ServerShared/Contacts.cs new file mode 100644 index 000000000..a5630ca5f --- /dev/null +++ b/Assets/Scripts/ServerShared/Contacts.cs @@ -0,0 +1,68 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System.Linq; +using CultMath; +using static CultMath.math; +using float2 = CultMath.float2; + +// A ship touching a ship (aetheria-release cut sim-contact; ruling unity-presents-only-r3): the simulation owns +// contact between ships. Orbital entities (stations, turrets) sit on the orbital layer above the ship plane and floaters +// below it, so neither touches a ship (ruling aetheria-gravity:orbitals-above-floaters-below). Each hull is a disc about its centre of mass that bounds every occupied cell, and +// two discs that touch while closing along the line between their centres take the normal impulse +// j = -(1 + e)(v_rel . n) / (1/m1 + 1/m2) (ruling ship-bounce-restitution-setting): momentum is conserved, the +// result is frame-independent, and a pair that has separated is not bounced again. e is +// GameplaySettings.ContactRestitution. +// Presentations read Zone.Contacted; no Unity collision callback writes an Entity. +public readonly struct ContactEvent +{ + public readonly Entity A; + public readonly Entity B; + public readonly float2 Point; + // Unit vector from A to B. + public readonly float2 Normal; + + public ContactEvent(Entity a, Entity b, float2 point, float2 normal) + { + A = a; + B = b; + Point = point; + Normal = normal; + } +} + +public static class Contacts +{ + public static float Radius(Entity e) => e.HullData.Reach(e.ItemManager.GameplaySettings.SchematicCellSize); + + // For each unordered pair of the zone's ships, in list order: if their discs touch and are closing along + // the normal, the impulse moves each one's velocity along the normal only (the tangent components are + // untouched), and the contact is published. Pairs resolve one after another in list order, each from the + // velocities the earlier pairs left, so a body touching two others in one tick depends on that order; the + // total momentum does not. A docked entity (it has a Parent and takes its parent's pose) and an inactive one + // are not hulls in the zone. No positional push-out. + public static void Step(Zone zone) + { + var entities = zone.Entities.OfType().Where(e => e.Active && e.Parent == null).ToArray(); + var radii = entities.Select(Radius).ToArray(); + for (var i = 0; i < entities.Length; i++) + for (var j = i + 1; j < entities.Length; j++) + { + var a = entities[i]; + var b = entities[j]; + var offset = b.Position.xz - a.Position.xz; + var distance = length(offset); + // Coincident centres have no normal. + if (distance <= 0f || distance >= radii[i] + radii[j]) continue; + var n = offset / distance; + var closing = dot(n, b.Velocity - a.Velocity); + if (closing >= 0f) continue; + + var impulse = -(1f + a.ItemManager.GameplaySettings.ContactRestitution) * closing / (1f / a.Mass + 1f / b.Mass); + a.Velocity -= n * (impulse / a.Mass); + b.Velocity += n * (impulse / b.Mass); + zone.Contacted.OnNext(new ContactEvent(a, b, a.Position.xz + n * radii[i], n)); + } + } +} diff --git a/Assets/Scripts/ServerShared/Contacts.cs.meta b/Assets/Scripts/ServerShared/Contacts.cs.meta new file mode 100644 index 000000000..1cba80257 --- /dev/null +++ b/Assets/Scripts/ServerShared/Contacts.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c1e5a3b9d4f4e2a8b6c0d1f2e3a4b5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/DrawAhead.cs b/Assets/Scripts/ServerShared/DrawAhead.cs new file mode 100644 index 000000000..49ca0a3d0 --- /dev/null +++ b/Assets/Scripts/ServerShared/DrawAhead.cs @@ -0,0 +1,162 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using CultMath; +using GameCult.Caching; +using static CultMath.math; + +// Pure presentation statics over sim state, never called by ServerShared, with no state of their own: the sim owns every +// pose and no presenter stores one, a previous state or a velocity of its own. +// The rule: a presenter draws every moving thing at the drawn time T = Zone.ExactTime + Clock.Lead. A pose the sim defines +// in closed form of time (an orbit, a belt chunk, a well, the field's height, the flow scroll) is that function evaluated +// at T; a pose the sim integrates (a ship, a kinematic body) is its last step plus its step velocity times Lead; a child +// is drawn where its parent is. DrawAhead.Time is the one definition of T. Ships ride the field at that drawn xz and T (a +// ship's height is the field's there, not the last step's). A ballistic round's flight is presentation +// (ruling projectile-flight-is-presentation), drawn from the sim's facts: its frozen line, the published outcome, the +// commit tick, the impact cell on the target's drawn pose, the burst point. +public static class DrawAhead +{ + // The drawn time: the one definition of T. + public static double Time(Zone zone, float lead) => zone.ExactTime + lead; + + // An orbit's node at the drawn time: the rail law at T, not the step's memo. + public static float2 Orbit(Zone zone, CultRecordKey orbit, float lead) => zone.OrbitPositionAt(orbit, Time(zone, lead)); + + // The field's height at a point at the drawn time, its wells where their rails put them at T. + public static float Height(Zone zone, float2 planar, float lead) => zone.GetHeight(planar, Time(zone, lead)); + + // The drawn height of a floater (loot, mines): the field at the drawn time plus the floater layer. + public static float FloaterHeight(Zone zone, GameplaySettings settings, float2 planar, float lead) => Height(zone, planar, lead) + settings.FloaterLayerHeight; + + // A ship in a wormhole animation has its pose scripted by the step, not integrated from Velocity and TurnRate, + // so it is drawn where the step put it: extrapolating a scripted pose draws a streak that resets every step. + // A child is drawn where its parent is drawn, as the step copies the parent's pose onto it. + public static float3 Position(Entity entity, float lead) + { + if (entity is Ship { WormholeAnimationInProgress: true }) return entity.Position; + if (entity.Parent != null) return Position(entity.Parent, lead); + // A body on a rail (a station) is on its orbit at T: the rail is closed form, not integrated. + var planar = entity is OrbitalEntity { OrbitData: var orbit } && orbit.IsSet() + ? Orbit(entity.Zone, orbit, lead) + : entity.Position.xz + entity.Velocity * lead; + return float3(planar.x, entity.RideHeight(planar, Time(entity.Zone, lead)), planar.y); + } + + // The point `distance` out along a planar bearing from the ship's drawn position: where the HUD anchors a marker to the + // ship the camera follows (an incoming lock, a remembered contact, a ping's flash). + public static float3 AtBearing(Entity origin, float2 bearing, float distance, float lead) + { + var at = Position(origin, lead); + return float3(at.x + bearing.x * distance, at.y, at.z + bearing.y * distance); + } + + // One well as the shader takes it: its body's rail at the drawn time, with the strength, core and reference the sim's + // GetHeight sums with. GravityLowering copies it into the shader's record and decides nothing. + public readonly struct DrawnWell + { + public readonly float2 Position; + public readonly float Strength, CoreRadius, Reference; + public DrawnWell(float2 position, float strength, float coreRadius, float reference) + { + Position = position; + Strength = strength; + CoreRadius = coreRadius; + Reference = reference; + } + } + + public static DrawnWell Well(Zone zone, Planet body, float lead) => + new DrawnWell(Orbit(zone, body.BodyData.Orbit.Key, lead), body.WellStrength, body.RocheLimit, zone.WellReference(body)); + + // A free body (a vapour cloud) drawn where the frame falls lead sim seconds after the last step, by the velocity + // that step moved it with: the launch velocity and the drift together. + public static float2 Position(KinematicBody body, float lead) => body.Position + body.TotalVelocity * lead; + + // The ship's rotation turned about its own up axis by the rate its last step turned, for lead seconds. + public static quaternion Rotation(Ship ship, float lead) => + ship.WormholeAnimationInProgress ? ship.Rotation : Turned(ship.Rotation, ship.TurnRate * lead); + + // q turned about its own up axis by the angle, in the sense Direction turns for a positive TurnRate. + public static quaternion Turned(quaternion q, float angle) + { + var u = float3(q.x, q.y, q.z); + var up = float3(0, 1, 0); + up += 2 * (q.w * cross(u, up) + cross(u, cross(u, up))); + var half = angle * .5f; + var s = sin(half); + var t = new quaternion(up.x * s, up.y * s, up.z * s, cos(half)); + // Hamilton product t * q: CultMath carries no quaternion product (a gap in CultMath, not filled here). + return normalize(new quaternion( + t.w * q.x + t.x * q.w + t.y * q.z - t.z * q.y, + t.w * q.y - t.x * q.z + t.y * q.w + t.z * q.x, + t.w * q.z + t.x * q.y - t.y * q.x + t.z * q.w, + t.w * q.w - t.x * q.x - t.y * q.y - t.z * q.z)); + } + + // A ballistic round at the drawn time (DrawAhead.Time, passed in by the caller; the target's lead is that time less its zone's step time, derived here, never a second input): on its frozen line while the outcome is unknown or a + // miss, with the barrel's offset from that line decaying to nothing over blendTime sim seconds from the moment of firing. + // A round the sim published as a hit or burst steers from its line, from the commit tick, onto where it ends by the + // time damage lands: a burst's frozen point, else the impact cell on the target's drawn pose; and is held there after. + public static float3 Round(in PendingShot shot, ShotOutcome known, float3 barrel, float blendTime, double drawnTime) + { + var time = (float) drawnTime; + var drawn = Lifted(shot, Line(shot, known?.Result, time), barrel, blendTime, time); + if (known == null || known.Result == ShotResult.Miss) return drawn; + var end = known.HasBurstPoint + ? float3(known.BurstPoint.x, shot.FireOrigin.y, known.BurstPoint.y) + : Impact(known.Target, known.Cell, (float) (drawnTime - known.Target.Zone.ExactTime)); + var commit = shot.ArrivalTime - known.ArrivalIn; + var steer = shot.ArrivalTime > commit ? saturate((time - commit) / (shot.ArrivalTime - commit)) : 1f; + return drawn + (end - drawn) * steer; + } + + // The impact cell's centre on the target's drawn pose. + public static float3 Impact(Entity target, int2 cell, float lead) + { + var world = target.ToWorldPoint((float2) cell); + return Carried(target, float3(world.x, target.Position.y, world.y), lead); + } + + // A world point on the target's sim pose, moved and turned with the target for lead seconds exactly as Position and + // Rotation draw the entity: the one owner of where a point on a hull is drawn, for the drawn round's end and for + // impact presenters. + public static float3 Carried(Entity target, float3 simPoint, float lead) + { + var at = Position(target, lead); + var offset = float2(simPoint.x - target.Position.x, simPoint.z - target.Position.z); + var turned = mul(offset, CultMath.float2x2.Rotate(Turn(target, lead))); + return float3(at.x + turned.x, at.y + (simPoint.y - target.Position.y), at.z + turned.y); + } + + // Whether the drawn flight is over by time: only a published miss ends by the clock. A hit or burst ends on ShotResolved. + public static bool RoundOver(in PendingShot shot, ShotOutcome known, double drawnTime) => + known != null && known.Result == ShotResult.Miss && (float) drawnTime >= RoundEnd(shot, ShotResult.Miss); + + // The sim time a round's drawn line ends, for what is known of its outcome. A round that hit or burst (or whose outcome + // is not yet published) ends at its ArrivalTime; a round the sim has published as a Miss flies on to the weapon's frozen + // range and never ends short of its own arrival (a direct round's FireRange is measured to any target, in range or not). + public static float RoundEnd(in PendingShot shot, ShotResult? known) => + known == ShotResult.Miss + ? max(shot.ArrivalTime, shot.FireTime + (shot.Speed > .01f ? shot.MaxRange / shot.Speed : 0f)) + : shot.ArrivalTime; + + // The frozen line a round follows until it steers: from its frozen origin along its frozen direction at its frozen + // speed, held at RoundEnd once it has flown that far. With no outcome known the round is drawn no further than its + // arrival point and waits there for the sim to publish one. + private static float2 Line(in PendingShot shot, ShotResult? known, float time) + { + if (shot.Speed <= .01f) return shot.FireOrigin.xz; + var flown = clamp(time - shot.FireTime, 0f, RoundEnd(shot, known) - shot.FireTime); + return shot.FireOrigin.xz + shot.TravelDirection * (shot.Speed * flown); + } + + private static float Turn(Entity entity, float lead) => + entity is Ship { WormholeAnimationInProgress: true } ? 0f : entity.TurnRate * lead; + + private static float3 Lifted(in PendingShot shot, float2 planar, float3 barrel, float blendTime, float time) + { + var blend = blendTime > 0 ? saturate(1 - (time - shot.FireTime) / blendTime) : 0f; + return float3(planar.x, shot.FireOrigin.y, planar.y) + (barrel - shot.FireOrigin) * blend; + } +} diff --git a/Assets/Scripts/ServerShared/DrawAhead.cs.meta b/Assets/Scripts/ServerShared/DrawAhead.cs.meta new file mode 100644 index 000000000..628d71b5d --- /dev/null +++ b/Assets/Scripts/ServerShared/DrawAhead.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 007fe4255cd84c26a010151a399f45c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Entity.cs b/Assets/Scripts/ServerShared/Entity.cs index e7a4b853f..3bd39b063 100644 --- a/Assets/Scripts/ServerShared/Entity.cs +++ b/Assets/Scripts/ServerShared/Entity.cs @@ -5,6 +5,7 @@ using GameCult.Caching; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using MessagePack; using UniRx; @@ -14,14 +15,23 @@ using int2 = CultMath.int2; public abstract class Entity { + // Every hull cell's temperature (kelvin) when the entity is built. + public const float StartingCellTemperature = 280; + public Zone Zone; public Faction Faction; + // The mark of a zone's boss, written only by ZoneGenerator and restored from the pack. RunGoal reads it. + public bool IsBoss; public EquippableItem Hull; public EquippedItem EquippedHull; public float3 Position; public float2 Direction = float2(0,1); public float2 Velocity; + // Rad per sim second, signed as the step turns Direction: the sum of this step's rotation actuators' applied + // angle over the step. Runtime only, zeroed at the start of Update, so a staged, loaded or wormhole write to + // Direction is never a turn. Read only by presenters that draw ahead of the step. + public float TurnRate; // Runtime only, never saved; Entity.Update is the one writer of both. Acceleration is the planar velocity change // across the base update over its delta (thrust, not the drag or gravity a subclass applies before calling it), @@ -59,24 +69,67 @@ public abstract class Entity private readonly ReactiveProperty _target = new ReactiveProperty(TargetRef.None); public IReadOnlyReactiveProperty Target => _target; - // Cut 2 (docs/fire-control-cut.md): the stored aim-point slot. Written only by TrySelectTargetItem - // below, and nulled whenever Target changes (subscribed in Activate). Do not read this field directly - // outside Entity -- read ResolvedTargetItem, which re-validates on every call, so decay (or the item - // leaving the target) drops the aim point the moment it is no longer earned, with no loop that has to - // notice and clear it. - public ReactiveProperty TargetItem = new ReactiveProperty((EquippedItem)null); + // The one aim slot on the Target (docs/fire-control-cut.md, Cut 2): a revealed item or a mount of the hull this + // observer believes the target to be, never both. Written only by TrySelectTargetItem (a revealed item: Combat's path + // and the player's) and TrySelectMount (a believed mount), and nulled whenever Target changes (subscribed in + // Activate). Do not read it outside Entity -- read ResolvedAim, which re-validates both gates on every call, so decay, + // a perceived destruction, or the item leaving the target drops the aim the moment it is no longer earned, with no + // loop that has to notice and clear it. (Not `Aim`: that is the pilot's pointing direction below.) + public AimTarget AimedAt { get; private set; } // Where the pilot points: reticle, lock cone, tractor, guided rounds, fire direction. Steers nothing; the // hull turns only by Ship.Turn. public float3 Aim; - + public string Name; + + // Names the entity for assertion messages and logs: xunit and the debugger format an object by walking its graph + // unless it has a ToString, and an Entity's graph is the whole zone. Entity has no id; Name is the hull's or the scenario's. + public override string ToString() => $"{GetType().Name} '{Name}'"; // public int Population; // public Dictionary Personality = new Dictionary(); public readonly Dictionary Messages = new Dictionary(); - public readonly Dictionary VisibilitySources = new Dictionary(); + private readonly Dictionary _visibilitySources = new Dictionary(); + // A read-only view: the only writes are SetSignature and the decay loop in Update, both below. + // A ReadOnlyDictionary over the private field, created once: a cast back to Dictionary fails. + private ReadOnlyDictionary _visibilityView; + public IReadOnlyDictionary VisibilitySources => _visibilityView ??= new ReadOnlyDictionary(_visibilitySources); + + // The one writer of VisibilitySources (the decay loop in Update is the one decayer). Every light signature + // names its channel and the item that produced it (null for the hull). Emission is active emission (paints now, + // Entity.Emit after emissions-heard), never light: ruling visibility-per-capability-reveal, map R1. + public void SetSignature(object source, SignatureChannel channel, float strength, EquippedItem item) + { + if (channel == SignatureChannel.Emission) + throw new ArgumentException("Emission is active emission, never a light signature.", nameof(channel)); + // A light signature is thinned by the ship's own gear at the moment it is written (aetheria-ew, lie-is-own-emission): + // each equipped suppressor folds the strength in equipment order and pays for what it alone removed. + foreach (var suppressor in GetBehaviors()) + strength = suppressor.Suppress(channel, strength); + _visibilitySources[source] = new Signature(channel, strength, item, ClaimOf(item)); + } + + // What this ship's acts claim (aetheria-ew, lie-is-own-emission, classify-from-belief): per equipped item, the + // equippable class every act of that item is stamped with (SetSignature, Emit, ReceivePaint). The hull is the + // item EquippedHull, so its claim lives in the same slot as every other: the hull class its own acts carry and + // the profile an observer derives (ClaimedHull) are one value. The truth unless claimed otherwise. Claim is the + // one write port; its production writer is the EW behaviour of cut ew-masquerade, tests only until then. + // Deactivate clears the slots. Aim, damage and physics keep the truth. + private readonly Dictionary _itemClaims = new Dictionary(); + public HullData ClaimedHull => (ClaimOf(EquippedHull) as HullData) ?? HullData; + public EquippableItemData ClaimOf(EquippedItem item) => + item == null ? null : _itemClaims.TryGetValue(item, out var claimed) ? claimed : item.Data; + internal void Claim(HullData hull) => Claim(EquippedHull, hull); + internal void Claim(EquippedItem item, EquippableItemData claimed) + { + // One hull class in the book: a hull class is claimed by the hull and only by the hull, whichever side asks. + if (claimed != null && (item == EquippedHull) != (claimed is HullData)) + throw new ArgumentException("Only the hull claims a hull class, and the hull claims nothing else.", nameof(claimed)); + if (claimed == null) _itemClaims.Remove(item); + else _itemClaims[item] = claimed; + } public readonly ReactiveDictionary EntityInfoGathered = new ReactiveDictionary(); public (List weapons, List items)[] WeaponGroups; @@ -125,7 +178,11 @@ public abstract class Entity public bool OverrideShutdown { get; set; } - public float TractorPower { get; set; } + // The pilot's tractor command (0..1); the Pickup behaviour spins its beam toward it. + public float TractorCommand; + + // The beam's spun-up state: Pickup's, or 0 without one. + public float TractorPower => GetBehavior()?.Power ?? 0f; public bool Active { @@ -149,9 +206,11 @@ public abstract class Entity public ItemManager ItemManager { get; } public int AssignedPopulation => PopulationAssignments.Sum(pa => pa.AssignedPopulation); public float Mass { get; private set; } - public float Visibility => VisibilitySources.Values.Sum(); + public float Visibility => VisibilitySources.Values.Sum(s => s.Strength); public Subject IncomingHit = new Subject(); + // One per entity, created with it, never replaced: FireControl publishes each landed impact on it (Absorb). + public readonly CapabilityEvents Capabilities = new CapabilityEvents(); public Subject<(int2 pos, float damage)> ArmorDamage = new Subject<(int2, float)>(); public Subject<(EquippedItem item, float damage)> ItemDamage = new Subject<(EquippedItem, float)>(); // public Subject ItemOffline = new Subject(); @@ -162,8 +221,46 @@ public abstract class Entity public Subject HeatstrokeDeath = new Subject(); public Subject HypothermiaRisk = new Subject(); public Subject HypothermiaDeath = new Subject(); - public Subject TargetedBy = new Subject(); - public ReactiveProperty TargetedByCount = new ReactiveProperty(0); + // Selection tells the selected ship nothing: a warning comes only from a paint. A search paint is a ping + // sweeping this ship (Sensor.Execute); a track paint is a lock (LockWeapon.Execute). Each reports into the + // inbox the tick it paints; PublishInbox publishes the inbox once, so a warning lives exactly one tick after + // its last paint. + // The inbox keeps who painted and with what beside the warning: the warning is all a reader of IncomingPaints + // gets, the emitter and item are for PublishInbox, which records the emitter's reveal. + private readonly struct PendingPaint + { + public readonly PaintWarning Warning; + public readonly Entity Emitter; + public readonly EquippedItem Item; + + public PendingPaint(PaintWarning warning, Entity emitter, EquippedItem item) + { + Warning = warning; + Emitter = emitter; + Item = item; + } + } + private readonly List _paintInbox = new List(); + private readonly List _incomingPaints = new List(); + public IReadOnlyList IncomingPaints => _incomingPaints; + // An ally's sensor posts a return on the tick its ping crosses a subject; published with paints, read by this + // ship's own sensors for one tick. + private readonly List _returnInbox = new List(); + private readonly List _pingReturns = new List(); + internal IReadOnlyList PingReturns => _pingReturns; + // What this ship's active sensors and lock paints emit this tick (Emit), heard by other ships' Sense (ruling + // sensor-stat-set): written in Update, read by Sense in the same tick, cleared by the next PublishInbox. + private readonly List _emissions = new List(); + // What this observer has seen each ship's items do (ruling visibility-per-capability-reveal), keyed (subject, + // item). Written only by RecordReveal (an act, or a scan through RecordInspection, enters) and EndReveals (an end the observer perceives, or a departed + // subject's entries aged past BearingMemory), cleared by Deactivate (ruling reveal-ends-on-perception). + private readonly Dictionary> _reveals = new Dictionary>(); + // The mounts of each subject whose item this observer perceived destroyed (PerceivesDestroyed), so the target cycle + // skips them and no aim rests on them: observer state, written only by RecordSeenDestroyed in Sense, dropped with the + // subject's reveals (EndReveals) and cleared by Deactivate. Truth enters only through the one perception rule. + private readonly Dictionary> _seenDestroyed = new Dictionary>(); + private readonly List _endedItems = new List(); + private readonly List _agedSubjects = new List(); public ReactiveProperty CurrentSecurityLevel = new ReactiveProperty(SecurityLevel.Open); public ReadOnlyReactiveProperty PresencePermitted; @@ -194,12 +291,10 @@ public abstract class Entity return presencePermitted; }), initialValue: true); - foreach (var item in Equipment) - foreach (var behavior in item.Behaviors) - { - if(behavior is IInitializableBehavior initializableBehavior) - initializableBehavior.Initialize(); - } + // One initialiser for everything that computes targets here: gear and the effects still running, so a + // consumable active across a refit retargets to the new items exactly as gear does. + InitializeBehaviors(Equipment.SelectMany(item => item.Behaviors)); + InitializeBehaviors(_activeConsumables.SelectMany(effect => effect.Behaviors)); foreach(var entity in Zone.Entities) { EntityInfoGathered[entity] = 0; @@ -220,9 +315,13 @@ public abstract class Entity VisibleEntities.Remove(remove.Value); VisibleEnemies.Remove(remove.Value); VisibleFriendlies.Remove(remove.Value); - // A stance lasts the sitting: it goes with an entity gone for good (destroyed, warped away, unloaded), not - // with a ship docking, which leaves the zone parented to its dock (TryDock) and rejoins it on undock. - if (remove.Value.Parent == null) _iffOverrides.Remove(remove.Value); + if (remove.Value == this) + { + // A ship out of the zone is no longer published to: it holds no warnings (nothing would ever clear them). + _paintInbox.Clear(); + _incomingPaints.Clear(); + } + ReleaseStance(remove.Value); if (_grudgeSubscriptions.TryGetValue(remove.Value, out var grudgeSubs)) { foreach (var s in grudgeSubs) s.Dispose(); @@ -244,13 +343,6 @@ public abstract class Entity { if (Target.Value.Entity == remove.Value) SetTarget(TargetRef.None); })); - // Only an entity is ever targeted by: a chunk has no one to tell. - _subscriptions.Add(Target.Subscribe(target => target.Entity?.TargetedBy.OnNext(this))); - _subscriptions.Add(TargetedBy.Subscribe(enemy => - { - TargetedByCount.Value++; - enemy.Target.Where(t => t.Entity != this).Take(1).Subscribe(_ => TargetedByCount.Value--); - })); // _subscriptions.Add(EntityInfoGathered.ObserveReplace().Subscribe(replace => @@ -300,16 +392,16 @@ public abstract class Entity _watchedEntitySubscriptions.Remove(disappearingEntity.Value); })); - // Cut 2 (docs/fire-control-cut.md): a Target change nulls the aim point. Fires immediately on - // subscribe with whatever Target already holds, which is harmless -- TargetItem starts null anyway. - _subscriptions.Add(Target.Subscribe(_ => TargetItem.Value = null)); + // Cut 2 (docs/fire-control-cut.md): a Target change nulls the aim. Fires immediately on + // subscribe with whatever Target already holds, which is harmless -- AimedAt starts empty anyway. + _subscriptions.Add(Target.Subscribe(_ => AimedAt = AimTarget.None)); // 9.3 (docs/fire-control-cut.md, Soul C3): a Target surviving Deactivate can point at an entity // this zone removed while inactive -- Deactivate disposes the Zone.Entities.ObserveRemove // subscription that is the only thing that nulls a stale Target, and EntityInfoGathered was just // rebuilt above from the zone's *current* membership, not from whatever Target still remembers. // Reconcile here, now that both the fresh EntityInfoGathered and the Target-change subscription - // above are live (so this write also clears TargetItem through it): an active entity's Target + // above are live (so this write also clears the aim through it): an active entity's Target // must always be an entity it has info on. Activate owns this reconciliation rather than // Deactivate nulling Target outright, because nulling on every dock would throw away a target // that is still alive and simply never changed while docked -- the common case, and not the one @@ -324,15 +416,15 @@ public abstract class Entity GenerateWeaponGroups(); } - // Cut 2 (docs/fire-control-cut.md): the only writer of TargetItem. Accepts null (clearing the aim - // point) or an item belonging to the current Target that FireControl.IsRevealed resolves true for this - // entity as observer. Returns whether the write took effect; a rejected non-null selection leaves - // TargetItem unchanged. + // Cut 2 (docs/fire-control-cut.md): one of the aim slot's two writers (the other is TrySelectMount). Accepts null + // (clearing the aim) or a revealed item (FireControl.IsRevealed: this entity saw it act) belonging to the current + // Target. A fitted item the observer has only located is aimed as its mount, never as an item. Returns whether the + // write took effect; a rejected non-null selection leaves the aim unchanged. public bool TrySelectTargetItem(EquippedItem item) { if (item == null) { - TargetItem.Value = null; + AimedAt = AimTarget.None; return true; } @@ -340,17 +432,64 @@ public abstract class Entity if (Target.Value.Entity == null || item.Entity != Target.Value.Entity || !FireControl.IsRevealed(this, item)) return false; - TargetItem.Value = item; + AimedAt = AimTarget.OfItem(item); return true; } - // The read path for TargetItem (see the field's own comment): null once the aimed item is no longer - // revealed to this entity, or no longer belongs to the current Target, even though nothing wrote - // TargetItem.Value at the moment that became true. Re-checked on every call; never cached. - public EquippedItem ResolvedTargetItem => - TargetItem.Value != null && Target.Value.Entity == TargetItem.Value.Entity && FireControl.IsRevealed(this, TargetItem.Value) - ? TargetItem.Value - : null; + // The aim slot's other writer: a mount of the hull this entity believes the Target to be (LayoutOf, by reference), + // unless this entity perceived that mount's item destroyed (SeenDestroyed). Reads only observer state, so whether a + // mount can be aimed at says nothing of the Target's truth (ruling cycle-skips-only-perceived-destroyed). + public bool TrySelectMount(HardpointData mount) + { + if (!MountAimable(Target.Value.Entity, mount)) return false; + AimedAt = AimTarget.OfMount(mount); + return true; + } + + private bool MountAimable(Entity subject, HardpointData mount) => + subject != null && mount != null && LayoutOf(subject).Contains(mount) && !SeenDestroyed(subject, mount); + + // The read path for the aim slot (see its comment): the aim only while its gate still holds -- an item still revealed + // and still the Target's, a mount still in the believed layout and not seen destroyed -- else none, even though + // nothing wrote the slot at the moment that stopped being true. Re-checked on every call; never cached. + public AimTarget ResolvedAim + { + get + { + var subject = Target.Value.Entity; + var aim = AimedAt; + if (subject == null) return AimTarget.None; + if (aim.Item != null) return FireControl.IsRevealed(this, aim.Item) ? aim : AimTarget.None; + return MountAimable(subject, aim.Mount) ? aim : AimTarget.None; + } + } + + public EquippedItem ResolvedTargetItem => ResolvedAim.Item; + + // What the cycle visits on `subject`, in schematic order: its rows (revealed items, then every mount of the hull this + // ship believes it to be, empty or not) minus the mounts this ship saw destroyed. Reads the same rows the schematic + // shows and the record, never `subject`'s equipment or live Durability. + public IEnumerable AimCycle(Entity subject) => + SchematicRows(subject) + .Where(r => r.Item != null || !SeenDestroyed(subject, r.Mount)) + .Select(r => r.Item != null ? AimTarget.OfItem(r.Item) : AimTarget.OfMount(r.Mount)); + + // The player's cycle key: steps the aim to the next AimCycle entry after the resolved one and wraps; an entry its + // writer refuses (a revealed item since destroyed) is passed over; nothing to visit clears the aim. + public void CycleAim() + { + var subject = Target.Value.Entity; + if (subject == null) return; + var cycle = AimCycle(subject).ToList(); + var now = ResolvedAim; + var index = cycle.FindIndex(a => a.Item == now.Item && a.Mount == now.Mount && (now.Item != null || now.Mount != null)); + for (var step = 1; step <= cycle.Count; step++) + { + var next = cycle[(index + step + cycle.Count) % cycle.Count]; + if (next.Item != null ? TrySelectTargetItem(next.Item) : TrySelectMount(next.Mount)) return; + } + AimedAt = AimTarget.None; + } // Mining Cut 3 (docs/mining-cut-refresh.md): the one writer of Target, called by the player's handlers and the // agents alike. A chunk is taken only while this entity can see it, so a rock in darkness cannot be picked; an @@ -364,22 +503,30 @@ public abstract class Entity // Mining Cut 3 (Q14 A): this entity's info on a chunk, computed when asked and stored nowhere. It is the value // the per-tick sensor rule (Sensor.Execute, through Sensor.Gain) would settle at for a target this bright, - // here, now. Each active sensor applies x <- saturate(x + G_i dt)(1 - k dt) every tick, so with n sensors the - // info settles where the gain balances the decay: sum(G_i) / (n k), capped at 1. A ping adds nothing that - // lasts, so only the passive gain enters. + // here, now (PassiveInfo at the chunk's brightness), capped at 1. public float ChunkInfo(ChunkId chunk) { var visibility = Zone.ChunkVisibility(chunk); if (visibility <= 0f) return 0f; - var position = Zone.ChunkPose(chunk.Field, chunk.Index).xy; + return saturate(PassiveInfo(Zone.ChunkPose(chunk.Field, chunk.Index).xy, visibility)); + } + + // The info a target of `signature` at `position` would settle at under this entity's passive sensing, before + // the cap at 1. Each active sensor applies x <- saturate(x + G_i dt)(1 - k dt) every tick, so with n sensors the + // info settles where the gain balances the decay: sum(G_i) / (n k). A ping adds nothing that lasts, so only the + // passive gain enters. ChunkInfo asks it for a chunk's brightness; Sense asks it for a unit signature once per + // ship, because it is linear in the signature below saturation and so answers for every act at a place. Zero + // with no active sensor. + public float PassiveInfo(float2 position, float signature) + { var rate = 0f; var sensors = 0; foreach (var sensor in ActiveSensors()) { - rate += sensor.PassiveRate(visibility, position); + rate += sensor.PassiveRate(signature, position); sensors++; } - return sensors == 0 ? 0f : saturate(rate / (sensors * ItemManager.GameplaySettings.TargetInfoDecay)); + return sensors == 0 ? 0f : rate / (sensors * ItemManager.GameplaySettings.TargetInfoDecay); } // Mining Cut 3: the detection threshold, read through the chunk path. A chunk is visible exactly as an entity @@ -606,10 +753,44 @@ public abstract class Entity return max(gain, 0f) / (sensors * ItemManager.GameplaySettings.TargetInfoDecay * threshold) * 1.0001f; } - // Every sensor behaviour that runs this tick: those on active equipment, and those of active consumables. - private IEnumerable ActiveSensors() => - Equipment.Where(item => item.Active.Value).SelectMany(item => item.Behaviors).OfType() - .Concat(_activeConsumables.SelectMany(effect => effect.Behaviors).OfType()); + // Every sensor behaviour that runs this tick: those on active equipment, and those of active consumables. The + // list is this entity's one buffer, refilled per call (Sense asks once per other ship per tick, allocating + // nothing), so callers use it before asking again. + private readonly List _activeSensors = new List(); + private List ActiveSensors() + { + _activeSensors.Clear(); + for (var i = 0; i < Equipment.Count; i++) + { + var item = Equipment[i]; + if (!item.Active.Value) continue; + foreach (var behavior in item.Behaviors) + if (behavior is Sensor sensor) _activeSensors.Add(sensor); + } + foreach (var effect in _activeConsumables) + foreach (var behavior in effect.Behaviors) + if (behavior is Sensor sensor) _activeSensors.Add(sensor); + return _activeSensors; + } + + // How much of an emission's reach this observer's instruments hear it at (ruling sensor-stat-set: listeners hear at + // a multiple of an emitter's own range): the largest of 1 (any active sensor) and each active listener's Multiple, + // 0 with neither. Catalog values come from AetherDb sensor-stat-set. + private float HearingMultiple() + { + var multiple = ActiveSensors().Count > 0 ? 1f : 0f; + for (var i = 0; i < Equipment.Count; i++) + { + var item = Equipment[i]; + if (!item.Active.Value) continue; + foreach (var behavior in item.Behaviors) + if (behavior is Listener listener) multiple = max(multiple, listener.Multiple); + } + foreach (var effect in _activeConsumables) + foreach (var behavior in effect.Behaviors) + if (behavior is Listener listener) multiple = max(multiple, listener.Multiple); + return multiple; + } // Cut 12.3 (docs/fire-control-cut.md): "armour absorbs first" -- the per-cell armour phase, split out of // what used to be Absorb's own first half (moved verbatim from DamageSchematic's per-cell body, Cut 3) so @@ -776,6 +957,297 @@ public abstract class Entity VisibleEntities.Clear(); VisibleEnemies.Clear(); VisibleFriendlies.Clear(); + _paintInbox.Clear(); + _incomingPaints.Clear(); + _returnInbox.Clear(); + _pingReturns.Clear(); + _emissions.Clear(); + _reveals.Clear(); + _seenDestroyed.Clear(); + _itemClaims.Clear(); + } + + // Zone.Update runs this on every entity before any entity updates, so a paint made during tick N is published + // at the start of tick N+1 whatever order the emitter and this ship update in; a paint that stops is gone + // one tick later for every ordering. + internal void PublishInbox() + { + _emissions.Clear(); // written in Update, read by Sense in the same tick + _incomingPaints.Clear(); + foreach (var paint in _paintInbox) + { + _incomingPaints.Add(paint.Warning); + RecordReveal(paint.Emitter, paint.Item, SignatureChannel.Emission, paint.Warning.EmitterClass); + } + _paintInbox.Clear(); + _pingReturns.Clear(); + _pingReturns.AddRange(_returnInbox); + _returnInbox.Clear(); + } + + internal void ReceiveReturn(PingReturn pingReturn) + { + if (!_active) return; + _returnInbox.Add(pingReturn); + } + + // The callers are Sensor.Execute (a sweeping ping) and LockWeapon.Execute (a lock paint): this ship's `item` emits this + // tick and is heard by another ship's Sense within `hearRange` (the emitter's range over its intercept factor, + // fixed here), bearing only. + internal void Emit(EquippedItem item, float hearRange) + { + if (!_active) return; + _emissions.Add(new ActiveEmission(item, hearRange, ClaimOf(item))); + } + + // The callers are Sensor.Execute (a Search paint, Strength 0) and LockWeapon.Execute (a Track paint, Strength + // the emitter's own Lock at that paint). The emitter's class is the class its ship claims for the item (ClaimOf: the + // item's data unless claimed otherwise; null with no item: a consumable's effect, which has no item and so is never + // revealed). + internal void ReceivePaint(Entity emitter, EquippedItem item, PaintMode mode, float strength) + { + if (!_active) return; + _paintInbox.Add(new PendingPaint(new PaintWarning(normalize((emitter.Position - Position).xz), emitter.ClaimOf(item), mode, strength), emitter, item)); + } + + // The reveal book's one way in and its one membership gate (callers: Sense, PublishInbox and RecordInspection, all in + // this file): this observer saw `item` of `subject` act on `channel`, now, from this bearing. An item-less act (hull + // radiation, a consumable) reveals nothing, and neither does a subject that is not in the zone: a departed + // subject's entries are never created or refreshed, from any caller, and neither does an item this observer + // perceives destroyed (PerceivesDestroyed). A later act of the same item replaces the + // earlier one. `claimed` is the class the carrier (signature, emission or paint) stamped: what this observer's + // classifying readers will believe of the act; `item` stays the aim and book key. + internal void RecordReveal(Entity subject, EquippedItem item, SignatureChannel? channel, EquippableItemData claimed) + { + if (!_active || item == null || !Zone.Entities.Contains(subject) || PerceivesDestroyed(subject, item)) return; + if (!_reveals.TryGetValue(subject, out var book)) + _reveals[subject] = book = new Dictionary(); + book[item] = new Reveal(item, channel, normalize((subject.Position - Position).xz), Zone.Time, claimed); + } + + // A finished scan (Scanner.Execute; rulings scan-is-an-act, quiet-gear-identifiable-hull-layout-known: quiet gear + // that never acts stays identifiable through special gear): this observer learns every fitted item of `subject`, + // channel null. It records what the item claims, not what it is (ClaimOf, as every act's carrier stamps it: the + // aetheria-ew one judge, classify-from-belief), skips the hull (its class is the track's to give) and a destroyed + // item, and goes through RecordReveal's gate like any act. It calls no EndReveals: a scan ends nothing + // (reveal-ends-on-perception). + internal void RecordInspection(Entity subject) + { + foreach (var item in subject.Equipment) + { + if (item == subject.EquippedHull || item.EquippableItem.IsDestroyed) continue; + RecordReveal(subject, item, null, subject.ClaimOf(item)); + } + } + + // This observer resolves `subject`'s gear (ContactOf's Identified gate) and `item` of it is destroyed: the one rule + // for a destroyed item an observer perceives, read by the book's entry (RecordReveal), its end (Sense) and the + // seen-destroyed record (RecordSeenDestroyed). + private bool PerceivesDestroyed(Entity subject, EquippedItem item) => + item.EquippableItem.IsDestroyed + && EntityInfoGathered.TryGetValue(subject, out var info) && info >= ItemManager.GameplaySettings.TargetGearInfoThreshold; + + // A stance lasts the sitting: it goes with a subject gone for good (destroyed, warped away, unloaded) once the book no + // longer remembers it, not with a ship docking, which leaves the zone parented to its dock (TryDock) and rejoins it on + // undock. Called when the subject leaves the zone and when the book drops it, so the override and the book end together. + private void ReleaseStance(Entity subject) + { + if (subject.Parent == null && !Zone.Entities.Contains(subject) && !_reveals.ContainsKey(subject)) _iffOverrides.Remove(subject); + } + + // This observer perceives `subject`'s gear (ContactOf's Identified gate): each of its destroyed items leaves its mount + // in the seen-destroyed record. The same PerceivesDestroyed Sense ends reveals by, applied to mounts. The record is read + // only for mounts of LayoutOf (MountAimable, AimCycle), so a true mount outside the believed layout is never asked for. + private void RecordSeenDestroyed(Entity subject) + { + // Indexed: Sense runs for every pair of ships every tick. + for (var i = 0; i < subject.Equipment.Count; i++) + { + var item = subject.Equipment[i]; + if (item.Hardpoint == null || !PerceivesDestroyed(subject, item)) continue; + if (!_seenDestroyed.TryGetValue(subject, out var seen)) _seenDestroyed[subject] = seen = new HashSet(); + seen.Add(item.Hardpoint); + } + } + + private bool SeenDestroyed(Entity subject, HardpointData mount) => + _seenDestroyed.TryGetValue(subject, out var seen) && seen.Contains(mount); + + // The book's one way out (caller: Sense): `item` null ends every reveal of `subject`, otherwise that item's. + // The subject's key goes with its last entry; ending all of them also drops the subject's seen-destroyed record. + private void EndReveals(Entity subject, EquippedItem item) + { + if (item == null) _seenDestroyed.Remove(subject); + if (!_reveals.TryGetValue(subject, out var book)) return; + if (item != null) book.Remove(item); + else book.Clear(); + if (book.Count != 0) return; + _reveals.Remove(subject); + ReleaseStance(subject); + } + + // The subjects this observer holds any reveal of, departed ones included until the prune: with VisibleEntities, every + // contact it has (ContactOf is Detected for a tracked subject or one with a young reveal). + public IReadOnlyCollection RevealedSubjects => _reveals.Keys; + + // The hostile subjects this observer holds only by a bearing: revealed, Detected, not Tracked (what bearing markers and + // the music show). Hostile is the observer's own live stance (IsHostileTo): the observer always knows its own decision, + // and an override outlives a departed subject exactly as long as the book remembers it (ReleaseStance). Reads the book + // and ContactOf, never the subject's Position or gear. + public IEnumerable RememberedHostiles => RevealedSubjects.Where(s => IsHostileTo(s) && ContactOf(s) is { Detected: true, Tracked: false }); + + // What this observer has seen `subject`'s items do: each item's latest act, and nothing the subject's present + // gear or Durability says (ruling contact-reads-book-aim-reads-live). A reveal ends only on what this observer + // perceives (ruling reveal-ends-on-perception): the destruction of an item of a ship it identifies, the death, + // dock or warp of a subject its instruments could see leave, or, for a subject that has left the zone, the + // freshest entry aging past BearingMemory; Deactivate clears it all. Whether an item can be aimed at now is + // FireControl.IsRevealed's question, not this one. + public IEnumerable RevealsOf(Entity subject) => + _reveals.TryGetValue(subject, out var book) ? book.Values : Enumerable.Empty(); + + // The weapons this observer believes `subject` has: each reveal whose claimed class carries a weapon behaviour, in the + // subject's equipment order (never the book's slot order, which follows when reveals were made and ended). The one + // classifying read of the book for weapons, shared by the enemy schematic and Combat (aetheria-ew, classify-from-belief); + // a gun claimed as a non-weapon is not listed, though RevealsOf holds it for aim. + public IEnumerable RevealedWeapons(Entity subject) => + InFittedOrder(subject, RevealsOf(subject).Where(r => r.Claimed != null && r.Claimed.Behaviors.Any(b => b is WeaponData))); + + // The gear this observer believes `subject` has: each reveal whose claimed class carries no weapon behaviour and is not a + // hull, in the order of RevealedWeapons. A hull's layout is known, not revealed, so it is never a gear row. + public IEnumerable RevealedGear(Entity subject) => + InFittedOrder(subject, RevealsOf(subject).Where(r => r.Claimed != null && !(r.Claimed is HullData) && !r.Claimed.Behaviors.Any(b => b is WeaponData))); + + private static IEnumerable InFittedOrder(Entity subject, IEnumerable reveals) => + reveals.OrderBy(r => FittedIndex(subject, r.Item)).ThenBy(r => r.Item.EquippableItem.Lot); + + // The classes `subject` has claimed to this observer, distinct and by name: what a bearing marker is labelled with. Reads + // each reveal's Claimed only, never the item's true data (aetheria-ew, classify-from-belief). + public IEnumerable ClaimedClasses(Entity subject) => + RevealsOf(subject).Select(r => r.Claimed).Where(c => c != null).Distinct().OrderBy(c => c.Name, StringComparer.Ordinal); + + // A revealed item's place in the subject's equipment; gear the subject no longer carries follows all fitted gear + // (ties among it fall to the lot, a stable id), never ahead of it. + private static int FittedIndex(Entity subject, EquippedItem item) + { + var index = subject.Equipment.IndexOf(item); + return index < 0 ? int.MaxValue : index; + } + + // The rows of `subject`'s schematic as this ship reads it: its own weapons when `subject` is this ship (each row its + // own data and live range, nothing to doubt about your own ship), otherwise the revealed weapons (each row the claimed + // class and that design's rated range) then the revealed gear (each row the claimed class, no range), then one mount + // row for every mount of the hull this ship believes `subject` to be (LayoutOf), empty or not and whether or not a + // revealed item has a row of its own (ruling quiet-gear-identifiable-hull-layout-known): the rows never compare the + // subject's items to the believed layout, so a liar and an honest ship of the claimed hull show the same count. The + // one owner of which rows, which class and which range an enemy schematic shows; the Unity SchematicDisplay renders it. + public IEnumerable SchematicRows(Entity subject) + { + if (subject == this) + return subject.Equipment.Where(i => i.Behaviors.Any(b => b.Data is WeaponData)).Select(i => new SchematicRow(i, i.Data, true)); + var claimed = RevealedWeapons(subject).Concat(RevealedGear(subject)).Select(r => new SchematicRow(r.Item, r.Claimed, false)).ToList(); + return claimed.Concat(LayoutOf(subject).Select(h => new SchematicRow(h))); + } + + // Where `subject`'s mounts are as this ship believes them: the hull it is identified as (Contact.Profile, the claimed + // hull), never the subject's own HullData; empty below identification. Derived on every read, nothing stored. + public IReadOnlyList LayoutOf(Entity subject) => ContactOf(subject).Profile?.Hardpoints ?? (IReadOnlyList) Array.Empty(); + + // Whether this observer's book for `subject` holds `item`: the book's membership, no live gear read. + internal bool HasReveal(Entity subject, EquippedItem item) => + _reveals.TryGetValue(subject, out var book) && book.ContainsKey(item); + + // The one derivation of how much this observer holds of `subject`: see Contact. + public Contact ContactOf(Entity subject) + { + var settings = ItemManager.GameplaySettings; + var info = EntityInfoGathered.TryGetValue(subject, out var gathered) ? gathered : 0f; + var tracked = VisibleEntities.Contains(subject); + var any = false; + var freshest = default(Reveal); + foreach (var reveal in RevealsOf(subject)) + if (!any || reveal.Time > freshest.Time) + { + any = true; + freshest = reveal; + } + var remembered = any && Zone.Time - freshest.Time < settings.BearingMemory; + var detected = tracked || remembered; + var bearing = tracked ? normalize((subject.Position - Position).xz) : remembered ? freshest.Bearing : default; + var identified = info >= settings.TargetGearInfoThreshold; + // Profile is the one derivation of the hull this observer believes (no stored belief until the judge, ew-masquerade). + return new Contact(detected, tracked, detected && any, identified, bearing, info, identified ? subject.ClaimedHull : null); + } + + // What this observer's instruments receive of other ships' acts this tick (Zone.Update calls it once, after every + // entity has updated): every light signature of an item that would alone settle this observer's passive info above + // TargetDetectionInfoThreshold is revealed (ruling visibility-per-capability-reveal). Hull radiation names no + // item and only feeds the track. One PassiveInfo per ship. Zone.Update calls it + // for every entity after all of them have updated, so what a ship shows is what every observer receives on that + // tick whatever order the zone lists them in. + internal void Sense() + { + if (!_active) return; + var threshold = ItemManager.GameplaySettings.TargetDetectionInfoThreshold; + var hearing = HearingMultiple(); + var entities = Zone.Entities; + for (var i = 0; i < entities.Count; i++) + { + var other = entities[i]; + if (other == this) continue; + var perSignature = -1f; + foreach (var signature in other._visibilitySources.Values) + { + if (signature.Item == null) continue; + if (perSignature < 0f) perSignature = PassiveInfo(other.Position.xz, 1f); + if (signature.Strength * perSignature > threshold) RecordReveal(other, signature.Item, signature.Channel, signature.Claimed); + } + // Every emission this ship made this tick that reaches this observer is revealed, bearing only (ruling + // sensor-stat-set), through RecordReveal's one gate. It feeds no track. + if (hearing > 0 && other._emissions.Count > 0) + { + var planar = length(other.Position.xz - Position.xz); + var obscuration = Zone.Obscuration(Position.xz, other.Position.xz); + for (var j = 0; j < other._emissions.Count; j++) + { + var emission = other._emissions[j]; + if (planar <= emission.HearRange * hearing * obscuration) RecordReveal(other, emission.Item, SignatureChannel.Emission, emission.Claimed); + } + } + // The observer resolves this ship's gear (PerceivesDestroyed), so it perceives an item of it destroyed: the + // item's mount is recorded and its reveal ends here; RecordReveal refuses the same item's lingering flash. + RecordSeenDestroyed(other); + if (_reveals.TryGetValue(other, out var book)) + { + foreach (var item in book.Keys) + if (PerceivesDestroyed(other, item)) _endedItems.Add(item); + for (var j = 0; j < _endedItems.Count; j++) EndReveals(other, _endedItems[j]); + _endedItems.Clear(); + } + } + // A subject that left the zone (death, dock, warp, any removal) is perceived gone under the light-act gate: as + // bright as its whole Visibility was at removal, from where it was. A re-admitted subject did not leave. + var departures = Zone.Departures; + for (var i = 0; i < departures.Count; i++) + { + var departure = departures[i]; + if (!_reveals.ContainsKey(departure.Subject) || entities.Contains(departure.Subject)) continue; + if (departure.Signature * PassiveInfo(departure.Position, 1f) > threshold) EndReveals(departure.Subject, null); + } + // What stays of a departed subject is memory: pruned once its freshest entry is as old as ContactOf stops + // remembering it. + var memory = ItemManager.GameplaySettings.BearingMemory; + foreach (var pair in _reveals) + { + if (entities.Contains(pair.Key)) continue; + var freshest = float.MinValue; + foreach (var reveal in pair.Value.Values) freshest = Math.Max(freshest, reveal.Time); + if (Zone.Time - freshest >= memory) _agedSubjects.Add(pair.Key); + } + // A record of a subject that left and holds no book (a quiet ship, never seen to act) has no entry to age: it goes now. + foreach (var subject in _seenDestroyed.Keys) + if (!entities.Contains(subject) && !_reveals.ContainsKey(subject)) _agedSubjects.Add(subject); + for (var i = 0; i < _agedSubjects.Count; i++) EndReveals(_agedSubjects[i], null); + _agedSubjects.Clear(); } public Entity(ItemManager itemManager, Zone zone, EquippableItem hull, EntitySettings settings) @@ -792,10 +1264,10 @@ public abstract class Entity for(int i=0; i(), new List()); - ItemDestroyed = ItemDamage.Where(x => x.item.EquippableItem.Durability < .01f).Select(x=>x.item); + ItemDestroyed = ItemDamage.Where(x => x.item.EquippableItem.IsDestroyed).Select(x=>x.item); WeaponDestroyed = ItemDestroyed.Select(x => x.Behaviors.FirstOrDefault(b => b is Weapon) as Weapon).Where(x => x != null); HullArmorDepleted = ArmorDamage.Where(x => Armor[x.pos.x, x.pos.y] < .01f).Select(x => x.pos); - Death = HullDamage.Where(_ => Hull.Durability < .01f).Select(_ => CauseOfDeath.HullDestroyed) + Death = HullDamage.Where(_ => Hull.IsDestroyed).Select(_ => CauseOfDeath.HullDestroyed) .Merge(HeatstrokeDeath.Select(_ => CauseOfDeath.Heatstroke)) .Merge(HypothermiaDeath.Select(_ => CauseOfDeath.Hypothermia)) .Merge(ItemDestroyed.Where(i=>i.GetBehavior()!=null).Select(_ => CauseOfDeath.CockpitDestroyed)) @@ -854,9 +1326,23 @@ public abstract class Entity public void ActivateConsumable(ConsumableItem item) { - _activeConsumables.Add(new ConsumableItemEffect(item, this)); + var effect = new ConsumableItemEffect(item, this); + // The same hook Activate runs over Equipment: a behaviour that computes its targets there (StatModifier) + // would otherwise reach its second tick uninitialised. + InitializeBehaviors(effect.Behaviors); + _activeConsumables.Add(effect); } + private static void InitializeBehaviors(IEnumerable behaviors) + { + foreach (var behavior in behaviors.ToList()) + if (behavior is IInitializableBehavior initializable) + initializable.Initialize(); + } + + // Derived, never written: true iff an active consumable effect carries a ThrottleLock. + public bool ThrottleLocked => _activeConsumables.Any(e => e.Behaviors.OfType().Any()); + public ConsumableItemEffect FindActiveConsumable(ConsumableItemData data) { return _activeConsumables.FirstOrDefault(ac => ac.Data == data); @@ -914,7 +1400,7 @@ public abstract class Entity Armor[v.x, v.y] += Hardpoints[v.x, v.y].Armor; MaxArmor[v.x, v.y] += Hardpoints[v.x, v.y].Armor; } - Temperature[v.x, v.y] = 280; + Temperature[v.x, v.y] = StartingCellTemperature; ThermalMass[v.x, v.y] = hullData.Mass * hullData.SpecificHeat / cellCount; } GearOccupancy = new EquippedItem[hullData.Shape.Width, hullData.Shape.Height]; @@ -1268,7 +1754,7 @@ public abstract class Entity { bay.DockedShip = ship; ship.SetParent(this); - Zone.Entities.Remove(ship); + Zone.Remove(ship); ship.Deactivate(); ship.Docked.OnNext(this); } @@ -1355,13 +1841,17 @@ public abstract class Entity yield return b; } + // The phase between the items' performance update and the power bus: what an entity commands its items to do this + // tick, read from the same liveness and stats Execute then acts on. Ship's allocation lives here. + protected virtual void UpdateThrottles() { } + public virtual void Update(float delta) { + TurnRate = 0; if (!_active) return; var velocityBefore = Velocity; LimitClamp = float2(0, 0); - var hullData = ItemManager.GetData(Hull) as HullData; // Mining Cut 3: a chunk target is lost the moment this entity can no longer see it -- the lost-track rule // through the chunk path. One check of the one slot per tick, not a detection loop over chunks. @@ -1373,16 +1863,17 @@ public abstract class Entity var localSecurityLevel = Zone.GetSecurityLevel(Position.xz); if (CurrentSecurityLevel.Value != localSecurityLevel) CurrentSecurityLevel.Value = localSecurityLevel; - foreach (var v in VisibilitySources.Keys.ToArray()) + foreach (var v in _visibilitySources.Keys.ToArray()) { - VisibilitySources[v] = decay(VisibilitySources[v], ItemManager.GameplaySettings.VisibilityDecay, delta); + _visibilitySources[v] = _visibilitySources[v].WithStrength(decay(_visibilitySources[v].Strength, ItemManager.GameplaySettings.VisibilityDecay, delta)); - if (VisibilitySources[v] < 0.1f) VisibilitySources.Remove(v); + if (_visibilitySources[v].Strength < 0.1f) _visibilitySources.Remove(v); } UpdateTemperature(delta); foreach (var item in _orderedEquipment) item.UpdatePerformance(); + UpdateThrottles(); if (_active) { @@ -1441,11 +1932,16 @@ public abstract class Entity for (var i = 0; i < _activeConsumables.Count; i++) { _activeConsumables[i].Update(delta); - if (_activeConsumables[i].RemainingDuration < 0) + if (_activeConsumables[i].RemainingDuration <= 0) { // Cut 2 Gate 1 fix (docs/stats-and-power-cut.md): an expired consumable dropped out of this // list without ever telling the resolver, leaving its generation/cache/modifier entries // reachable (keyed by this ConsumableItemEffect instance) for the rest of the process. + // A StatModifier's attachments are keyed by its target items, not by the effect, so Forget alone + // leaves a boost attached to its targets: dispose each behaviour first. + foreach (var behavior in _activeConsumables[i].Behaviors) + if (behavior is IDisposable disposable) + disposable.Dispose(); Resolver.Forget(_activeConsumables[i]); _activeConsumables.RemoveAt(i--); } @@ -1475,12 +1971,22 @@ public abstract class Entity Position = Parent.Position; Velocity = Parent.Velocity; } - else Position.y = Zone.GetHeight(Position.xz) + hullData.GridOffset; + else Position.y = RideHeight(Position.xz); Acceleration = delta > 0f ? (Velocity + LimitClamp - velocityBefore) / delta : float2(0, 0); Manoeuvre.Observe(Acceleration, delta, ItemManager.GameplaySettings.SolutionWindow); } + // The height above the field of the layer this kind of entity rides on (GameplaySettings): ships the ship plane, + // orbital entities the orbital layer above it. + public abstract float LayerHeight { get; } + + // Where an unparented entity sits on the field at a planar point: the zone's height there plus the layer this kind of + // entity rides on. The step rides at its own time and xz, the presenter at the drawn time and its drawn xz (DrawAhead). + public float RideHeight(float2 planar, double time) => Zone.GetHeight(planar, time) + LayerHeight; + + public float RideHeight(float2 planar) => RideHeight(planar, Zone.ExactTime); + private void UpdateTemperature(float delta) { var hullData = ItemManager.GetData(Hull) as HullData; @@ -1562,7 +2068,7 @@ public abstract class Entity MaxTemp = NewTemperature[v.x, v.y]; } - VisibilitySources[this] = radiation; + SetSignature(this, SignatureChannel.Thermal, radiation, null); var swap = Temperature; Temperature = NewTemperature; NewTemperature = swap; @@ -1646,7 +2152,6 @@ public class EquippedItem : IStatContext private bool _thermalOnline; private bool _durabilityOnline; - public WwiseMetaSoundBank SoundBank; public Behavior[] Behaviors { get; } public Dictionary BehaviorGroups { get; } @@ -1672,10 +2177,6 @@ public class EquippedItem : IStatContext public ReadOnlyReactiveProperty Active { get; } public ItemManager ItemManager { get; } - public Subject AudioEvents { get; } = new Subject(); - public Subject<(uint id, float v)> AudioParameters { get; } = new Subject<(uint id, float v)>(); - public Dictionary AudioParameterValues { get; } = new Dictionary(); - private float oldTemperature; public float Temperature { @@ -1687,77 +2188,6 @@ public class EquippedItem : IStatContext } } - public void FireAudioEvent(uint eventId, bool skipVerify = false) - { - if(SoundBank != null && (skipVerify || SoundBank.IncludedEvents.Any(o => o.Id == eventId))) - AudioEvents.OnNext(eventId); - } - - public void FireAudioEvent(WwiseSoundBinding soundBinding) - { - FireAudioEvent(soundBinding.PlayEvent); - } - - public void PlaySound(WwiseLoopingSoundBinding soundBinding) - { - FireAudioEvent(soundBinding.PlayEvent); - } - - public void StopSound(WwiseLoopingSoundBinding soundBinding) - { - FireAudioEvent(soundBinding.StopEvent); - } - - public void FireAudioEvent(WeaponAudioEvent weaponAudioEvent) - { - if (SoundBank == null) return; - var eventObject = SoundBank.GetEvent(weaponAudioEvent); - if (eventObject == null) - { - ItemManager.Log($"Attempted to trigger {Enum.GetName(typeof(WeaponAudioEvent), weaponAudioEvent)} weapon audio event, but the soundbank doesn't support it!"); - return; - } - FireAudioEvent(eventObject.Id, true); - } - - public void FireAudioEvent(ChargedWeaponAudioEvent weaponAudioEvent) - { - if (SoundBank == null) return; - var eventObject = SoundBank.GetEvent(weaponAudioEvent); - if (eventObject == null) - { - ItemManager.Log($"Attempted to trigger {Enum.GetName(typeof(ChargedWeaponAudioEvent), weaponAudioEvent)} weapon audio event, but the soundbank doesn't support it!"); - return; - } - FireAudioEvent(eventObject.Id, true); - } - - public void SetAudioParameter(uint id, float v, bool skipVerify = false) - { - if (SoundBank != null && (skipVerify || SoundBank.GameParameters.Any(o => o.Id == id))) - { - AudioParameterValues[id] = v; - AudioParameters.OnNext((id, v)); - } - } - - // public void SetAudioParameter(WwiseParameterBinding binding) - // { - // FireAudioEvent(binding.Parameter); - // } - - public void SetAudioParameter(SpecialAudioParameter p, float v) - { - if (SoundBank == null) return; - var metaObject = SoundBank.GetParameter(p); - if (metaObject == null) - { - ItemManager.Log($"Attempted to set {Enum.GetName(typeof(ChargedWeaponAudioEvent), p)} audio parameter, but the soundbank doesn't support it!"); - return; - } - SetAudioParameter(metaObject.Id, v, true); - } - public EquippedItem(ItemManager itemManager, EquippableItem item, int2 position, Entity entity, HardpointData hardpoint) { ItemManager = itemManager; @@ -1821,7 +2251,7 @@ public class EquippedItem : IStatContext // RefreshInputCapacitor implementation now calls for a request-field stat, and it pins that stat's own // PowerSupplyFactor to 1 regardless of what Terms the stat declares -- so a direct PowerSupply term on a // request field can no longer make the request depend on its own answer, and the six shipped records this - // ruling exists to make legal again (RadiatorData.PumpedHeat, AetherDriveData.Torque) are not an authoring + // ruling exists to make legal again (RadiatorData.PumpedHeat) are not an authoring // error to refuse. What is still refused: a request field fed a PowerSupply-tainted value through a // *modifier chain* (StatModifier.ValidateNoPowerSupplyChain, StatModifier.cs) -- EvaluateNominalPower // forwards ScaleModifier/ConstantModifier to the item's real, non-nominal resolver entries (same as @@ -1837,8 +2267,8 @@ public class EquippedItem : IStatContext // Nominal-request ruling (docs/stats-and-power-cut.md, operator ruling 2026-09-19): what this item wants at // full power supply, not what it is currently managing -- the read every PowerRequest/RefreshReserve/ // RefreshInputCapacitor implementation uses for a stat named in StatValidation.PowerRequestFields, so a stat - // that is both what a request asks for and what it also produces (RadiatorData.PumpedHeat, AetherDriveData. - // Torque) stops being circular at the root instead of being forbidden outright. Only PowerSupply is pinned: + // that is both what a request asks for and what it also produces (RadiatorData.PumpedHeat) + // stops being circular at the root instead of being forbidden outright. Only PowerSupply is pinned: // Heat and Durability are NOT, because they are not the term a request would be circular through -- this // tick's PowerBus.Step (which calls PowerRequest) always runs before this tick's grant exists, so nothing // here could depend on an answer that has not been computed yet, and a hot or worn item honestly asking for @@ -1951,17 +2381,12 @@ public class EquippedItem : IStatContext deltaTemp * ItemManager.GameplaySettings.DeltaTempWearExponent ) * Data.Durability / Data.ThermalResilience; ThermalOnline.Value = ThermalPerformance > performanceThreshold || Entity.OverrideShutdown && EquippableItem.OverrideShutdown; - DurabilityOnline.Value = EquippableItem.Durability > .01f; + DurabilityOnline.Value = !EquippableItem.IsDestroyed; oldTemperature = temp; } public void Update(float delta) { - foreach (var audioStat in Data.AudioStats) - { - SetAudioParameter(audioStat.Parameter, Evaluate(audioStat.Stat)); - } - if (Active.Value) { foreach (var group in BehaviorGroups.Values) @@ -2126,7 +2551,7 @@ public class EquippedCargoBay : EquippedItem // Returns true only when ALL of the items are successfully stored public bool TryStore(SimpleCommodity item) { - TryFindSpace(item, out var positions); + if (!TryFindSpace(item, out var positions)) return false; foreach (var position in positions) { if (TryStore(item, position)) return true; @@ -2332,6 +2757,4 @@ public class BehaviorGroup return null; } - - //public IAnalogBehavior Axis; } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/EntitySerializer.cs b/Assets/Scripts/ServerShared/EntitySerializer.cs index 6fb749b29..7f934b937 100644 --- a/Assets/Scripts/ServerShared/EntitySerializer.cs +++ b/Assets/Scripts/ServerShared/EntitySerializer.cs @@ -28,6 +28,7 @@ public static class EntitySerializer else throw new ArgumentException("Attempted to pack an instance of abstract class Entity!"); pack.Settings = entity.Settings; + pack.Boss = entity.IsBoss; pack.Hull = entity.Hull; pack.Name = entity.Name; @@ -81,6 +82,7 @@ public static class EntitySerializer private static void Restore(ItemManager itemManager, Zone zone, EntityPack pack, Entity entity) { entity.Name = pack.Name; + entity.IsBoss = pack.Boss; entity.Faction = itemManager.ItemData.Get(pack.Faction); entity.Children = pack.Children.Select(c => { @@ -187,6 +189,8 @@ public abstract class EntityPack [Key(14)] public EntitySettings Settings; [Key(15)] public CultRecordRef Faction; [Key(16)] public int[][] WeaponGroups; + // Keys 17-20 belong to the subclasses; the base's next free key is 21. + [Key(21)] public bool Boss; private int _price; diff --git a/Assets/Scripts/ServerShared/Enums.cs b/Assets/Scripts/ServerShared/Enums.cs index 2b5a9637b..63d2674db 100644 --- a/Assets/Scripts/ServerShared/Enums.cs +++ b/Assets/Scripts/ServerShared/Enums.cs @@ -49,8 +49,7 @@ public enum HardpointType Energy, Ballistic, Launcher, - ControlModule, - AetherDrive + ControlModule } public enum WeaponType @@ -204,34 +203,6 @@ public enum TemperatureUnit Fahrenheit } -public enum WeaponAudioEvent -{ - Fire, - Hit, - Miss -} - -public enum ChargedWeaponAudioEvent -{ - Start, - Stop, - Fail -} - -public enum SpecialAudioParameter -{ - ShipVelocity, - ChargeLevel, - TargetLock, - Intensity, -} - -public enum LoopingAudioEvent -{ - Play, - Stop -} - public enum MusicType { Overworld, diff --git a/Assets/Scripts/ServerShared/Environment.cs b/Assets/Scripts/ServerShared/Environment.cs index 2424ca214..737033e4e 100644 --- a/Assets/Scripts/ServerShared/Environment.cs +++ b/Assets/Scripts/ServerShared/Environment.cs @@ -9,7 +9,7 @@ using float2 = CultMath.float2; public class ZoneEnvironment { [JsonProperty("nebula"), Key(0)] public NebulaSettings Nebula; - [JsonProperty("flow"), Key(1)] public FlowSettings Flow; + // Key 1 is retired (it held the flow, now PlanetSettings.Flow); never reuse it. [JsonProperty("noise"), Key(2)] public NoiseSettings Noise; [JsonProperty("lighting"), Key(3)] public AmbientLightingSettings Lighting; [JsonProperty("grid"), Key(4)] public GridSettings Grid; diff --git a/Assets/Scripts/ServerShared/Feedback.cs b/Assets/Scripts/ServerShared/Feedback.cs new file mode 100644 index 000000000..218028052 --- /dev/null +++ b/Assets/Scripts/ServerShared/Feedback.cs @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using CultMath; +using static CultMath.math; + +// What an impact presenter renders, derived once. Engine-free and never called by ServerShared: FireControl +// publishes the fact (AbsorbEvent), this derives how it reads, and every presenter (visual, audio, camera) renders +// the same cue instead of computing its own. +public readonly struct ImpactCue +{ + public readonly AbsorbLayer Layer; + public readonly float3 Position; + public readonly float3 Direction; + public readonly float Intensity; + public readonly float Shake; + + public ImpactCue(AbsorbLayer layer, float3 position, float3 direction, float intensity, float shake) + { + Layer = layer; + Position = position; + Direction = direction; + Intensity = intensity; + Shake = shake; + } +} + +public static class Feedback +{ + // Intensity is the hit's share of what the receiver's hull can take, scaled by the presenter and saturated to + // 0..1; a receiver with no hull to measure against reads 0. Shake follows intensity for the player's own ship + // only, scaled by the player's ScreenShake preference. + public static ImpactCue Cue(AbsorbEvent e, float receiverMaxDurability, bool receiverIsPlayer, float shakePreference, float intensityScale) + { + var intensity = receiverMaxDurability > 0f ? saturate(e.Magnitude / receiverMaxDurability * intensityScale) : 0f; + var shake = receiverIsPlayer ? intensity * saturate(shakePreference) : 0f; + return new ImpactCue(e.Layer, e.Position, e.Direction, intensity, shake); + } +} diff --git a/Assets/Scripts/ServerShared/Feedback.cs.meta b/Assets/Scripts/ServerShared/Feedback.cs.meta new file mode 100644 index 000000000..65f57c0d9 --- /dev/null +++ b/Assets/Scripts/ServerShared/Feedback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51efa531176e4871835ae88104c92c85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/FireControl.cs b/Assets/Scripts/ServerShared/FireControl.cs index f90e41ae3..c94caded8 100644 --- a/Assets/Scripts/ServerShared/FireControl.cs +++ b/Assets/Scripts/ServerShared/FireControl.cs @@ -67,24 +67,18 @@ public static class FireControl return blastRadius > 0f ? data.Fuse : null; } - // The one arc gate on the trigger. A fused weapon fires whatever the arc says: a target it cannot bear on is - // no reason to keep it silent, the round flies along the arc-clamped aim and bursts at the target's range - // (Fire; operator ruling 2026-09-30, "the user is hoping that the arc gets the weapon close enough to still - // splash some damage"). A weapon that only hits what it fires at still refuses. Fire reads InArc itself to - // choose that flight, so the two share the one bearing test and differ only in this exemption. - // Mining Cut 3: a chunk target bears through its own position, on the plane the bearing test reads. + // The one gate on the trigger (operator rulings fire-on-solutions, controls-solution-trigger, 2026-10-06). A gun + // fires on its solution without the aim, else free along the aim if the aim is inside its arc, else it holds. + // A fused weapon fires whatever the arc says: a target it cannot bear on is no reason to keep it silent, the + // round flies along the arc-clamped aim and bursts at the target's range (Fire; operator ruling 2026-09-30, + // "the user is hoping that the arc gets the weapon close enough to still splash some damage"). A mine layer + // lays a body, not a round, and is never arc-gated. The price of a free shot at a target that does not bear is + // HitProbability's: zero. public static bool ArcPermitsFire(Weapon weapon, Entity shooter) { - var target = shooter.Target.Value; - if (target.IsNone) return true; - float3 toTarget; - if (target.Chunk is ChunkId chunk) - { - var at = shooter.Zone.ChunkPose(chunk.Field, chunk.Index).xy; - toTarget = float3(at.x, 0, at.y) - shooter.Position; - } - else toTarget = target.Entity.Position - shooter.Position; - return FuseOf(weapon.Item, out _) != null || IsMineLayer(weapon) || InArc(weapon.Item, toTarget); + if (FuseOf(weapon.Item, out _) != null || IsMineLayer(weapon)) return true; + var solution = Solution(weapon, shooter, shooter.Target.Value); + return solution.Bears || solution.Free; } // Whether the shooter's next round from this weapon is refused: the weapons ask before they spend anything, so @@ -132,36 +126,43 @@ public static class FireControl return float2(mount.x * cos(turn) - mount.y * sin(turn), mount.x * sin(turn) + mount.y * cos(turn)); } - // Cut 2, R5: whether `observer` has resolved `item` (which must belong to some entity in the zone) well - // enough to aim at it. Derived fresh from EntityInfoGathered on every call -- nothing caches a reveal - // result, so decay drops it the moment info falls back below tier, with no clearing loop anywhere. - // - // Ranking: the target's own non-hull equipment, hardpoint-mounted gear first (the big obvious things), - // then by size descending, ties broken by equipment order (OrderByDescending is a stable sort, so this - // needs no explicit tie-break key). Item i of N reveals once info crosses - // lerp(TargetArmorInfoThreshold, TargetGearInfoThreshold, i / max(1, N - 1)) -- the first item to reveal - // does so at the armor tier, the last at the gear tier. - public static bool IsRevealed(Entity observer, EquippedItem item) + // The one owner of a gun's solution against its subject (the designated target; ruling controls-solution-subject). + // Bears: the gun can engage the subject, so the player fires on it without the aim. Free: the aim is inside the + // arc, so the gun can fire along it. Direction: where a round from this gun travels and where its barrel points -- + // the subject's intercept when it bears, else the arc-clamped aim. A chunk subject bears through its pose and + // flies the aim, as an untargeted round (Subject is null for it). Derived on every read and never stored: turrets + // traverse instantly in the simulation. Traverse is the weapon's Tracking (ruling mount-arc-gun-traverse), priced in + // TrackingRate; this holds no slew state, and a rig's slew is presentation. It never prices; HitProbability is the one price. + public static GunSolution Solution(Weapon weapon, Entity shooter, TargetRef subject) { - var target = item.Entity; - // Cut 5, 5.5 (Soul finding 10): a destroyed item drops out of the ranking entirely rather than merely - // failing its own tier -- ranked.IndexOf(item) then returns -1 for it (the same "no longer on this - // target" path below), and the survivors' tiers close up over the gap instead of leaving one. - var ranked = target.Equipment - .Where(e => e.Data.HardpointType != HardpointType.Hull && e.EquippableItem.Durability >= .01f) - .OrderByDescending(e => e.Data.HardpointType != HardpointType.Tool) - .ThenByDescending(e => e.Data.Shape.Coordinates.Length) - .ToList(); - var index = ranked.IndexOf(item); - if (index < 0) return false; // the hull itself, or an item that is no longer on this target - - var settings = observer.ItemManager.GameplaySettings; - var info = observer.EntityInfoGathered.TryGetValue(target, out var gathered) ? gathered : 0f; - var tier = lerp(settings.TargetArmorInfoThreshold, settings.TargetGearInfoThreshold, - (float) index / max(1, ranked.Count - 1)); - return info >= tier; + var bears = false; + if (subject.Entity != null) bears = Bears(weapon, shooter, subject.Entity, out _); + else if (subject.Chunk is ChunkId chunk) + { + var at = shooter.Zone.ChunkPose(chunk.Field, chunk.Index).xy; + bears = InArc(weapon.Item, float3(at.x, 0, at.y) - shooter.Position); + } + return new GunSolution + { + Subject = subject.Entity, + Bears = bears, + Free = InArc(weapon.Item, shooter.Aim), + Direction = bears && subject.Entity != null + ? TravelDirection(weapon, shooter, subject.Entity) + : AimDirection(weapon.Item, shooter) + }; } + // The aiming read, and the only reader of live gear beside the book (rulings visibility-per-capability-reveal, + // quiet-gear-identifiable-hull-layout-known, reveal-ends-on-perception): `observer` can aim at `item` when its own + // book holds a reveal of it (Entity.HasReveal: it saw the item act) and the item is still fitted to its ship and + // not destroyed. The book says what was seen; the live item says whether it can still be aimed at. Derived on + // every read, never cached; watching a ship reveals no gear. Any aiming choice that reads an item's class or + // stats (Combat's target-item choice, its dps) asks this; it is the item gate of Entity's aim slot (TrySelectTargetItem, + // ResolvedAim). A mount is aimed by TrySelectMount, which reads no item at all. + public static bool IsRevealed(Entity observer, EquippedItem item) => + !item.EquippableItem.IsDestroyed && item.Entity.Equipment.Contains(item) && observer.HasReveal(item.Entity, item); + // Cut 2, Q4: the stats an entity actually fires with. A working targeting system (equipped, online -- // not destroyed, not shut down) supplies its own resolved stats; anything else falls back to the // authored unaided figures, which make aiming without one a last resort rather than an alternative. @@ -277,21 +278,26 @@ public static class FireControl !(weapon is LockWeapon lockWeapon && !lockWeapon.IsLocked); } - // `designated` is the answer above. `inArc` is the bearing test, asked only once a target is designated. + // Whether this gun can engage this target: designated and inside the arc. The one test of it; PFire prices a shot + // at zero unless it holds, and Solution reads it to decide whether the gun fires on the target. `designated` is + // the answer above, kept apart for Solve's burst flight: a designated target out of arc still sets the burst range. + public static bool Bears(Weapon weapon, Entity source, Entity target, out float range) => + Bears(weapon, source, target, out range, out _); + + private static bool Bears(Weapon weapon, Entity source, Entity target, out float range, out bool designated) + { + designated = Designated(weapon, source, target, out range); + return designated && InArc(weapon.Item, target.Position - source.Position); + } + + // `designated` is the answer above. `inArc` is Bears, asked only once a target is designated. // PFire prices a shot at zero unless both hold. Fire reads them to decide what a fused round flies at // (operator rulings 2026-09-30): without valid data it has no target and bursts at max range; with data but // out of arc it bursts at the target's range, along the aim. The HUD reads Designated and the // arc from Solve and Inspect and decides nothing. private static float PFire(Weapon weapon, Entity source, Entity target, out float range, out bool designated, out bool inArc) { - range = 0f; - designated = false; - inArc = false; - if (target == null) return 0f; - - designated = Designated(weapon, source, target, out range); - if (!designated) return 0f; - inArc = InArc(weapon.Item, target.Position - source.Position); + inArc = Bears(weapon, source, target, out range, out designated); if (!inArc) return 0f; var settings = source.ItemManager.GameplaySettings; @@ -316,8 +322,8 @@ public static class FireControl // GetBehavior calls (Accuracy, Resolution via PSensor, Precision), at ~40 B each -- each // one walks Entity.Equipment, a ReactiveCollection whose enumerator is heap-allocated per foreach. It is // NOT `Behaviors` (the earlier wording here was wrong): EquippedItem.Behaviors is a plain array, allocates - // nothing to enumerate. With an item aimed at, ResolveAimPoint -> CellsOf also allocates (a List, then - // ToArray) -- about 944 B per HitProbability, on top of the three GetBehavior calls. None of this is + // nothing to enumerate. With an item or a mount aimed at, ResolveAimPoint also allocates: CellsOf (a List, then + // ToArray) about 944 B per HitProbability, measured; MountCells (a LINQ Select, then ToArray) not measured. Both are on top of the three GetBehavior calls. None of this is // Silhouette's or this pooling's cost; it predates Cut 12.2 and belongs to Entity's own collection choice // and to CellsOf, out of this cut's scope. Cut 10's own guard is what actually matters // operationally: HitProbability and CommitProbability both bail before Forecast is ever called for the @@ -334,7 +340,8 @@ public static class FireControl Silhouette sil; try { - sil = Silhouette(target, targetHull, source.ResolvedTargetItem, bearing, precision, buffer); + var aim = source.ResolvedAim; + sil = Silhouette(target, targetHull, aim.Item, bearing, precision, buffer, aim.Mount); var settings = source.ItemManager.GameplaySettings; pSpread = PSpread(weapon.Spread, sil.Span, range, settings.SchematicCellSize); } @@ -581,7 +588,8 @@ public static class FireControl // it whether a round is refused before they spend anything -- so a refusal is decided once, by the same // code that would have flown the round, and the HUD cannot forecast a burst the trigger will not fire. // Direct: a round that resolves against its target (a weapon without a fuse). Burst: a fused round, with - // BurstReach the planar distance from the shooter at which it bursts. Refused: a fused round whose blast + // BurstReach the planar distance from the shooter at which the payload is delivered (a direct round's target, a fused + // round's burst point, 0 for an untargeted direct round), which Fire's range factor reads for every outcome. Refused: a fused round whose blast // radius (its arming distance) exceeds the weapon's Range; it cannot be fired. public static FireSolution Solve(Weapon weapon, EquippedItem item, Entity source, Entity target) { @@ -616,7 +624,7 @@ public static class FireControl // burst's later rounds and a power-starved Range included). var engaged = fuse != null && !(designated && inArc) ? null : target; var origin = source.Position; - var travelDirection = engaged != null ? TravelDirection(weapon, source, engaged) : AimDirection(item, source); + var travelDirection = Solution(weapon, source, target).Direction; var arming = fuse != null ? blastRadius : 0f; var burstPosition = engaged != null ? engaged.Position : origin; @@ -712,14 +720,19 @@ public static class FireControl var commitHorizon = source.ItemManager.GameplaySettings.CommitHorizon; + var aim = source.ResolvedAim; var shot = new PendingShot { ShotId = zone.NextShotId(), Source = source, Target = engaged, Weapon = item, - Aimed = source.ResolvedTargetItem, + Aimed = aim.Item, + AimedMount = aim.Mount, Damage = damageOverride ?? weapon.Damage, + FireMinRange = weapon.MinRange, + FireEffectiveRange = weapon.EffectiveRange, + FireDamageAtMaxRange = weapon.WeaponData.DamageAtMaxRange, Penetration = weapon.Penetration, DamageSpread = weapon.DamageSpread, DamageType = weapon.WeaponData.DamageType, @@ -730,6 +743,8 @@ public static class FireControl Spread = weapon.Spread, FireRange = fireRange, FireTime = now, + Speed = weapon.Velocity, + MaxRange = weapon.Range, FireOrigin = origin, FireTargetPosition = targetPosition, FireTargetVelocity = targetVelocity, @@ -743,11 +758,20 @@ public static class FireControl BlastRadius = blastRadius, Committed = false }; + // A round whose delivery point Solve plans reads the falloff here, at that point (BurstReach); a no-lock fused round's + // point is decided at its commit (CommitBurst), which reads it there. Each shot reads it once. + if (!shot.DeliveredAtCommit) Deliver(ref shot, solution.BurstReach); zone.PendingShots.Add(shot); return shot.ShotId; } + // The one place a shot's damage meets range: the weapon's falloff at the planar distance its payload is delivered at, + // over the stats frozen at Fire. A delivery is never farther than the Range it was fired with (a burst is pulled back to + // it), so rounding in its distance must not read as beyond it. + private static void Deliver(ref PendingShot shot, float reach) => + shot.Damage *= WeaponData.RangeFactor(shot.FireMinRange, shot.FireEffectiveRange, shot.MaxRange, shot.FireDamageAtMaxRange, min(reach, shot.MaxRange)); + // Lays a mine for a mine layer: freezes the payload as evaluated now (stats, the item's blast radius, the // layer and its faction) and hands the body to Zone.Lay, the one adder. It launches at the shooter's velocity // plus the mount direction turned by a dice angle within +-Spread/2, times Velocity; the dice are the mine's @@ -779,6 +803,8 @@ public static class FireControl FuseDelay = data.FuseDelay, Lifetime = data.Lifetime, BlastRadius = blastRadius, + // Mines are flat (ruling effective-range-authoring-ruled): a mine layer carries no falloff authoring + // (StatValidation.ValidateMineLayerFlat), so its figure is the AI's and the panel's at every distance it can engage. Damage = weapon.Damage, DamageType = weapon.WeaponData.DamageType, Layer = source, @@ -823,11 +849,13 @@ public static class FireControl if (!shot.Committed && now >= shot.CommitTime) { - shot.Outcome = Commit(zone, shot, now); + shot.Outcome = Commit(zone, ref shot, now); shot.Committed = true; // A contact burst short of max range arrives when the round has flown that far, not at the frozen // max-range time (CommitBurst). Never later than the frozen time. if (shot.Outcome.Result == ShotResult.Burst) shot.ArrivalTime = min(shot.ArrivalTime, now + shot.Outcome.ArrivalIn); + // Written back before ShotCommitted fires: a presenter re-reading the record there (Zone.TryGetShot) sees + // the committed ArrivalTime a contact burst has just shortened. shots[i] = shot; zone.ShotCommitted.OnNext(shot.Outcome); } @@ -873,16 +901,16 @@ public static class FireControl var bearing = Bearing(shot.Target, shot.TravelDirection); var hullData = shot.Target.ItemManager.GetData(shot.Target.Hull) as HullData; - sil = Silhouette(shot.Target, hullData, shot.Aimed, bearing, shot.Precision); + sil = Silhouette(shot.Target, hullData, shot.Aimed, bearing, shot.Precision, null, shot.AimedMount); var settings = shot.Target.ItemManager.GameplaySettings; return p * PSpread(shot.Spread, sil.Span, shot.FireRange, settings.SchematicCellSize) * sil.POnHull; } - private static ShotOutcome Commit(Zone zone, PendingShot shot, float now) + private static ShotOutcome Commit(Zone zone, ref PendingShot shot, float now) { // A fused round with no target rolls nothing: it bursts. Where is decided here, at the commit, from the // poses of this tick (R4); Apply performs it. - if (shot.Fuse != null && shot.Target == null) return CommitBurst(zone, shot, now); + if (shot.DeliveredAtCommit) return CommitBurst(zone, ref shot, now); // Cut 6b, 6.1 (Soul finding 6): a shot's dice belong to the shot, not to whatever else happened to // draw from the engine-wide shared generator first. A pure function of (zone identity, shot id) -- @@ -974,12 +1002,14 @@ public static class FireControl // nothing locked stops on what is in its way), and at the max-range point when the line is clear. The point is // read from this tick's poses and frozen into the outcome (R4, the same timing Commit reads facing at). // Nothing is rolled or drawn, so determinism needs nothing beyond the frozen inputs. - private static ShotOutcome CommitBurst(Zone zone, PendingShot shot, float now) + private static ShotOutcome CommitBurst(Zone zone, ref PendingShot shot, float now) { var outcome = MakeOutcome(shot, ShotResult.Burst, false, false, int2.zero, float2.zero, 0f, now); outcome.HasBurstPoint = true; var reach = length(shot.BurstPosition.xz - shot.FireOrigin.xz); var travelled = min(reach, max(HullDistance(zone, shot, reach), shot.BlastRadius)); + // The delivery point is decided here, so the falloff is read here, at the distance the round travelled to it. + Deliver(ref shot, travelled); if (travelled < reach) { outcome.BurstPoint = shot.FireOrigin.xz + shot.TravelDirection * travelled; @@ -1134,6 +1164,8 @@ public static class FireControl if (shot.Outcome.Shielded) { + Publish(shot.Target, AbsorbLayer.Shield, ImpactPoint(shot.Target, shot.Outcome.Cell), + float3(shot.TravelDirection.x, 0, shot.TravelDirection.y), shot.Damage, shot.DamageType); shot.Target.Shield.TakeHit(shot.DamageType, shot.Damage); return; } @@ -1177,9 +1209,31 @@ public static class FireControl for (var li = 0; li < laneCount; li++) ArrayPool.Shared.Return(buffers[li]); + Publish(target, AbsorbLayer.Hull, ImpactPoint(target, shot.Outcome.Cell), + float3(shot.TravelDirection.x, 0, shot.TravelDirection.y), shot.Damage, shot.DamageType); target.DamageHull(hullDamage); } + // Where a landed direct hit meets the receiver: the impact cell's world point on its sim pose, at its height. + private static float3 ImpactPoint(Entity target, int2 cell) + { + var world = target.ToWorldPoint((float2) cell); + return float3(world.x, target.Position.y, world.y); + } + + // The one publisher of an absorbed impact: once per receiver, on its Capabilities, before the damage it reports. + private static void Publish(Entity receiver, AbsorbLayer layer, float3 position, float3 direction, float magnitude, DamageType damageType) => + receiver.Capabilities.PublishAbsorb(new AbsorbEvent(position, direction, magnitude, damageType, layer)); + + // A blast's impact on one entity: at the blast point (on the entity's height), travelling from the blast out through + // the entity's centre, or zero when they coincide. + private static void PublishBlast(Entity entity, float2 blast, AbsorbLayer layer, float magnitude, DamageType damageType) + { + var away = entity.Position.xz - blast; + var direction = lengthsq(away) > 0f ? normalize(away) : float2.zero; + Publish(entity, layer, float3(blast.x, entity.Position.y, blast.y), float3(direction.x, 0, direction.y), magnitude, damageType); + } + // Cut 12.4(b) (docs/fire-control-cut.md, "Where P is"): a contact or delayed blast needs a committed hit -- // on a miss nothing happens, exactly like a direct hit's own gate. IncomingHit fires once, for the host, // before the blast is handed to Detonate (which then treats the host like any other entity in the radius: @@ -1562,6 +1616,7 @@ public static class FireControl { if (shield.CanTakeHit(damageType, totalShare)) { + PublishBlast(entity, worldPlanar, AbsorbLayer.Shield, totalShare, damageType); shield.TakeHit(damageType, totalShare); continue; } @@ -1591,6 +1646,7 @@ public static class FireControl for (var i = 0; i < amounts.Length; i++) hullTotal += amounts[i]; } + PublishBlast(entity, worldPlanar, AbsorbLayer.Hull, totalShare, damageType); entity.DamageHull(hullTotal); } } @@ -1712,12 +1768,13 @@ public static class FireControl private const float SigmaFloor = 0.5f; private static float Sigma(float precision) => max(1f / max(precision, 1e-3f), SigmaFloor); - // The aim point a silhouette is centred on (R10/Q6: the same frozen Aimed both HitProbability and Fire - // read) -- the aimed item's own cell centroid when it currently occupies cells on the target, else the - // hull's own centre of mass. One path; the uniform-random branch Cut 6d replaced stays deleted. - private static float2 ResolveAimPoint(Entity target, HullData hullData, EquippedItem aimed) + // The aim point a silhouette is centred on (R10/Q6: the same frozen Aimed and AimedMount both HitProbability and Fire + // read) -- the cells of the mount aimed at when the aim was frozen at a mount (the shooter has not learned what is + // fitted there, so never the fitted item's cells), else the aimed item's own cell centroid when it currently occupies + // cells on the target, else the hull's own centre of mass. One path; the uniform-random branch Cut 6d replaced stays deleted. + private static float2 ResolveAimPoint(Entity target, HullData hullData, EquippedItem aimed, HardpointData mount) { - var aimedCells = aimed != null ? CellsOf(target, aimed) : null; + var aimedCells = mount != null ? MountCells(mount) : aimed == null ? null : CellsOf(target, aimed); if (aimedCells != null && aimedCells.Length > 0) return aimedCells.Aggregate(float2.zero, (total, c) => total + (float2) c) / aimedCells.Length; return hullData.Shape.CenterOfMass; @@ -1737,7 +1794,7 @@ public static class FireControl // call that follows, so it still passes null and gets an owned allocation. A caller-supplied buffer may be // larger than coords.Length (ArrayPool rents "at least"), so every loop below is bounded by coords.Length, // never buffer.Length. - public static Silhouette Silhouette(Entity target, HullData hull, EquippedItem aimed, float2 bearing, float precision, Interval[] buffer = null) + public static Silhouette Silhouette(Entity target, HullData hull, EquippedItem aimed, float2 bearing, float precision, Interval[] buffer = null, HardpointData mount = null) { var ell = Lateral(bearing); var coords = hull.Shape.Coordinates; @@ -1759,7 +1816,7 @@ public static class FireControl } var sigma = Sigma(precision); - var aimPoint = ResolveAimPoint(target, hull, aimed); + var aimPoint = ResolveAimPoint(target, hull, aimed, mount); var a = dot(aimPoint, ell); var pOnHull = 0f; @@ -1914,6 +1971,10 @@ public static class FireControl exit = min(exit, max(t1, t2)); } + // The hull-schematic cells a hardpoint covers, laid as Entity builds its Hardpoints[,] grid. + private static int2[] MountCells(HardpointData hardpoint) => + hardpoint.Shape.Coordinates.Select(c => hardpoint.Position + c).ToArray(); + // The cells of the target's hull schematic actually occupied by `item` -- GearOccupancy is the one source // of truth for where an equipped item's footprint lands, the same table Detonate and ApplyPooled read. private static int2[] CellsOf(Entity target, EquippedItem item) @@ -1938,10 +1999,18 @@ public struct PendingShot public Entity Target; public EquippedItem Weapon; public EquippedItem Aimed; + // The mount the aim was at, when it was at a mount rather than an item (Entity.ResolvedAim at Fire), frozen with Aimed: + // a reveal between Fire and Commit does not move where this shot was aimed. Null for an item aim or none. + public HardpointData AimedMount; // The frozen payload (R10, Q6): the gun's own stats at the instant the trigger was pulled. Nothing // downstream re-evaluates any of these. public float Damage; + // The weapon's falloff stats at Fire (with MaxRange below), frozen like the rest: what the range factor reads, at Fire or + // at commit. + public float FireMinRange; + public float FireEffectiveRange; + public float FireDamageAtMaxRange; public float Penetration; public float DamageSpread; public DamageType DamageType; @@ -1974,11 +2043,20 @@ public struct PendingShot public float3 FireTargetPosition; public float3 FireTargetVelocity; public float FireTime; + // The weapon's Velocity at Fire, frozen with the rest so a presenter draws the same line whatever happens to the stat later. + public float Speed; + // The weapon's Range at Fire, likewise frozen: how far a presenter may draw a round that misses. FireRange above + // is the distance to the engaged target (0 for a round with none), not how far a round that misses flies on. + public float MaxRange; public float CommitTime; public float ArrivalTime; public bool Committed; public ShotOutcome Outcome; + + // A fused round with no target: where it bursts is decided at its commit (the first hull its aim line meets), so its + // damage reads the falloff there rather than at Fire. + public bool DeliveredAtCommit => Fuse != null && Target == null; } // What a round does when fired (FireControl.Solve): Direct resolves against its target, Burst detonates at a @@ -1990,8 +2068,18 @@ public enum FireOutcome Refused } -// Solve's answer. Outcome and BurstReach (planar distance from the shooter to the burst point, read for Burst -// only) are what the HUD shows; the rest is what Fire freezes into the PendingShot. +// A gun's solution against its subject (FireControl.Solution): whether the gun bears on the subject, whether the +// aim is free (inside the arc), and the direction a round from it travels. +public struct GunSolution +{ + public Entity Subject; + public bool Bears; + public bool Free; + public float2 Direction; +} + +// Solve's answer. Outcome and BurstReach (planar distance from the shooter to the burst point; the HUD reads it for +// Burst, Fire's range factor for both outcomes) are what the HUD shows; the rest is what Fire freezes into the PendingShot. public struct FireSolution { public FireOutcome Outcome; @@ -2045,8 +2133,9 @@ public struct FireControlDiagnostic } // What a ship can do at this instant, in its own frame: acceleration along each body axis (m/s^2) and the kinematic -// turn rate each way (rad/s; turning toward the ship's right is Clockwise). Each propulsor reports its share with -// its own Execute arithmetic and Ship sums them; nothing stores it. Zero is the envelope of anything that is not a Ship. +// turn rate each way (rad/s; turning toward the ship's right is Clockwise). Ship derives it each update as the box +// extremes of its thrusters' columns (Ship.RecalculateEnvelope); nothing stores it. Zero is the envelope of anything +// that is not a Ship. public readonly struct ManoeuvreEnvelope { public readonly float Forward, Reverse, Left, Right, Clockwise, CounterClockwise; @@ -2060,10 +2149,6 @@ public readonly struct ManoeuvreEnvelope Clockwise = clockwise; CounterClockwise = counterClockwise; } - - public static ManoeuvreEnvelope operator +(ManoeuvreEnvelope a, ManoeuvreEnvelope b) => new ManoeuvreEnvelope( - a.Forward + b.Forward, a.Reverse + b.Reverse, a.Left + b.Left, a.Right + b.Right, - a.Clockwise + b.Clockwise, a.CounterClockwise + b.CounterClockwise); } // How unpredictably an entity is changing its motion, observed from its measured acceleration. The trend is an diff --git a/Assets/Scripts/ServerShared/FloatingBodies.cs b/Assets/Scripts/ServerShared/FloatingBodies.cs index a5d26ae20..93e470676 100644 --- a/Assets/Scripts/ServerShared/FloatingBodies.cs +++ b/Assets/Scripts/ServerShared/FloatingBodies.cs @@ -40,3 +40,20 @@ public struct KinematicBody Position += (Velocity + Drift) * dt; } } + +// An item adrift in a zone: a death drop or jettisoned cargo. Zone.Release is its only adder; Zone's floating-item +// step (expiry) and TryPickUp are its only removers. Zone.TryHold and Free are the only writers of Holder, the +// entity grabbing it with a tractor beam; a held item is placed by Zone, not drifted. Runtime state, never saved. +public sealed class FloatingItem +{ + public FloatingBodyId Id; + public ItemInstance Item; + public KinematicBody Body; + public double ReleasedAt; + public float Lifetime; + // The entity holding it, or null when it floats free; HeldFrom is where it was claimed and HeldProgress how far + // along its pull to the holder (0..1). + public Entity Holder; + public float2 HeldFrom; + public float HeldProgress; +} diff --git a/Assets/Scripts/ServerShared/FlowField.cs b/Assets/Scripts/ServerShared/FlowField.cs new file mode 100644 index 000000000..29613cd78 --- /dev/null +++ b/Assets/Scripts/ServerShared/FlowField.cs @@ -0,0 +1,78 @@ +using CultMath; +using static CultMath.math; +using float2 = CultMath.float2; +using float3 = CultMath.float3; + +/// +/// The global flow law: the one definition of the drift that stardust and nebula follow and that the sim knows. +/// A pure function of the zone's FlowSettings, a position, a scroll and a downhill gradient; nothing here keeps +/// a clock. Zone.Flow evaluates it at zone time. Assets/Shaders/Volumetric.cginc (globalFlow, slopeFlow) is its +/// HLSL lowering, driven by VolumeSampling.LowerFlow and pinned to it by Aetheria.EditorTools.FlowFieldParityVerify. +/// +public static class FlowField +{ + // The second octave of the noise samples at position * Golden (Volumetric.cginc Tri3D). + const float Golden = 1.61803398875f; + + // The scroll of the noise field, in field units: speed times zone time, for each of the two octaves, as a phase. + // Every term of Tri3D reaches the scrolled axis through frac, so a phase is only meaningful modulo 1: the fold + // happens here in double, where zone time is exact, and the float that reaches the shaders is in [0, 1) however + // old the zone is. x is the first octave's phase, y the second's (the second octave's axis is scaled by Golden). + public static float2 Scroll(FlowSettings settings, double zoneTime) + { + var scroll = (double) settings.GlobalScrollSpeed * zoneTime; + return float2(Phase(scroll), Phase(scroll * Golden)); + } + + // A phase in [0, 1) strictly: a double just below an integer rounds up to 1f in the cast, and 1 is 0 modulo 1. + static float Phase(double value) + { + var phase = (float) frac(value); + return phase < 1f ? phase : 0f; + } + + // The phase of a cycle of `period` seconds at zone time, in [0, 1). The nebula's flow-advected noise cycles and + // Stardust's particle lifetimes take their phase from here, so drift follows sim time and stops with the sim. + public static float Cycle(double zoneTime, float period) => period == 0f ? 0f : Phase(zoneTime / period); + + // The procedural term (Volumetric.cginc globalFlow): a Tri3D field of position / scale, scrolled along y. + // Skipped when its amplitude is zero, as the shader's FLOW_GLOBAL keyword skips it. + public static float3 Global(FlowSettings settings, float3 position, float2 scroll) + { + if (settings.GlobalAmplitude == 0f) return float3.zero; + var field = position / settings.GlobalScale; + var sample = Tri3D(field - float3(0f, scroll.x, 0f), field * Golden - float3(0f, scroll.y, 0f)) * settings.GlobalAmplitude; + sample.y *= .5f; + return sample; + } + + // The slope term (Volumetric.cginc slopeFlow): swirl around and slide along the gravity gradient. + // `downhill` is the DOWNHILL gradient, -grad(height) in world xz. The shader's texel gradient is that same + // vector (getUV negates the world x and z axes), and Zone.GetNormal's xz is proportional to it. + // Skipped when both amplitudes are zero (the FLOW_SLOPE keyword), and zero for a zero gradient. + public static float3 Slope(FlowSettings settings, float2 downhill) + { + if (settings.SlopeAmplitude == 0f && settings.SwirlAmplitude == 0f) return float3.zero; + if (dot(downhill, downhill) == 0f) return float3.zero; + var direction = normalize(downhill); + return float3(direction.y, 0f, -direction.x) * settings.SwirlAmplitude + + float3(direction.x, 0f, direction.y) * settings.SlopeAmplitude; + } + + public static float3 At(FlowSettings settings, float3 position, float2 scroll, float2 downhill) => + Global(settings, position, scroll) + Slope(settings, downhill); + + // Volumetric.cginc tri / tri3 / Tri3D, term for term. + static float Tri(float x) => abs(frac(x) - .5f); + + static float3 Tri3(float3 p) => + float3(Tri(p.z + Tri(p.y)), Tri(p.z + Tri(p.x)), Tri(p.y + Tri(p.x))); + + // The two octaves' positions are given already scrolled (see Scroll). + static float3 Tri3D(float3 p, float3 pGolden) + { + var t1 = normalize(Tri3(p)); + var t2 = normalize(Tri3(pGolden)); + return cross(t1, t2); + } +} diff --git a/Assets/Scripts/ServerShared/FlowField.cs.meta b/Assets/Scripts/ServerShared/FlowField.cs.meta new file mode 100644 index 000000000..c0b18d70e --- /dev/null +++ b/Assets/Scripts/ServerShared/FlowField.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 8105a45840c4552459aaf44e6c0e19ce \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Galaxy.cs b/Assets/Scripts/ServerShared/Galaxy.cs index a5660f52e..7026d8a52 100644 --- a/Assets/Scripts/ServerShared/Galaxy.cs +++ b/Assets/Scripts/ServerShared/Galaxy.cs @@ -24,7 +24,7 @@ public class Galaxy public Faction[] Factions { get; } public GalaxyZone[] Zones { get; } public GalaxyZone Entrance { get; } - public GalaxyZone Exit { get; } + public GalaxyZone Exit { get; private set; } public Dictionary FactionRelationships { get; } = new Dictionary(); private Action Log { get; } public bool IsPrelude { get; } @@ -33,7 +33,6 @@ public class Galaxy // restored from a save. public uint Seed { get; } - private HashSet _containedFactions; private GalaxyZone[] _exitPath; private Dictionary _nameGenerators = new Dictionary(); private readonly CultCache _cache; @@ -143,6 +142,18 @@ public class Galaxy return _cache.GetAll().FirstOrDefault(f => f.Name.StartsWith(name, StringComparison.InvariantCultureIgnoreCase)); } + // A cast member of a prelude galaxy, by name. A name the catalog does not hold refuses the galaxy, naming the field. + private Faction ResolveCast(string field, string name) => + ResolveFaction(name) ?? throw new InvalidOperationException($"cast faction {name} ({field}) is not in the catalog"); + + // Gives a prelude galaxy its gate: the antagonist's home is the boss zone and the exit. The only writer of Exit + // besides the constructors. + public void PlaceGate(Faction antagonist) + { + BossZones[antagonist] = HomeZones[antagonist]; + Exit = HomeZones[antagonist]; + } + // How many jumps a faction's influence reaches in this galaxy: its authored distance, halved (rounding up) in a // prelude. Derived, never written back to the catalog's Faction, so one galaxy's generation cannot change the next. public int InfluenceOf(Faction faction) => @@ -169,20 +180,23 @@ public class Galaxy var factions = new List(); - var protagonistFaction = ResolveFaction(settings.ProtagonistFaction); + var protagonistFaction = ResolveCast(nameof(settings.ProtagonistFaction), settings.ProtagonistFaction); factions.Add(protagonistFaction); - var antagonistFaction = ResolveFaction(settings.AntagonistFaction); + var antagonistFaction = ResolveCast(nameof(settings.AntagonistFaction), settings.AntagonistFaction); factions.Add(antagonistFaction); - var bufferFaction = ResolveFaction(settings.BufferFaction); + var bufferFaction = ResolveCast(nameof(settings.BufferFaction), settings.BufferFaction); factions.Add(bufferFaction); - var questFaction = ResolveFaction(settings.QuestFaction); - factions.Add(questFaction); + // A cast without a quest faction places no quest zone. + var questFaction = string.IsNullOrEmpty(settings.QuestFaction) + ? null + : ResolveCast(nameof(settings.QuestFaction), settings.QuestFaction); + if (questFaction != null) factions.Add(questFaction); var neutralFactions = settings.NeutralFactions - .Select(ResolveFaction) + .Select(name => ResolveCast(nameof(settings.NeutralFactions), name)) .ToArray(); factions.AddRange(neutralFactions); @@ -223,17 +237,20 @@ public class Galaxy CalculateFactionInfluence(progressCallback); - var potentialQuestZones = Zones - .Where(z => z.Factions.Contains(antagonistFaction) && z.Factions.Contains(bufferFaction)); - if (potentialQuestZones.Any()) - HomeZones[questFaction] = potentialQuestZones - .MaxBy(z => z.Distance[HomeZones[antagonistFaction]] * ConnectedRegion(z, InfluenceOf(questFaction)).Count); - else - HomeZones[questFaction] = Zones - .Where(z => z.Factions.Contains(antagonistFaction)) - .MinBy(z=>z.Distance[HomeZones[bufferFaction]]); - - CalculateFactionInfluence(progressCallback); + if (questFaction != null) + { + var potentialQuestZones = Zones + .Where(z => z.Factions.Contains(antagonistFaction) && z.Factions.Contains(bufferFaction)); + if (potentialQuestZones.Any()) + HomeZones[questFaction] = potentialQuestZones + .MaxBy(z => z.Distance[HomeZones[antagonistFaction]] * ConnectedRegion(z, InfluenceOf(questFaction)).Count); + else + HomeZones[questFaction] = Zones + .Where(z => z.Factions.Contains(antagonistFaction)) + .MinBy(z=>z.Distance[HomeZones[bufferFaction]]); + + CalculateFactionInfluence(progressCallback); + } Entrance = Zones.Where(z => z.Owner == null).MinBy(z => z.Distance[HomeZones[protagonistFaction]]); @@ -432,12 +449,6 @@ public class Galaxy } } - public bool ContainsFaction(CultRecordRef faction) - { - _containedFactions ??= new HashSet(Factions.Select(f => _cache.RefOf(f).Key)); - return _containedFactions.Contains(faction.Key); - } - class DijkstraVertex { public float Cost; diff --git a/Assets/Scripts/ServerShared/GalaxyStage.cs b/Assets/Scripts/ServerShared/GalaxyStage.cs index f4ac7d5f8..8b6e5a1a6 100644 --- a/Assets/Scripts/ServerShared/GalaxyStage.cs +++ b/Assets/Scripts/ServerShared/GalaxyStage.cs @@ -68,7 +68,10 @@ public sealed class GalaxyStage } // A prelude galaxy: the tutorial settings and their fixed factions, centred in dense cloud. - public Galaxy Prelude() + public Galaxy Prelude() => Prelude(_prelude); + + // A prelude galaxy of the given fixed cast, centred in dense cloud. + public Galaxy Prelude(TutorialGenerationSettings cast) { var background = Copy(_preludeBackground); var random = new Random(Seed); @@ -78,7 +81,7 @@ public sealed class GalaxyStage background.NoisePosition = random.NextFloat() * 1000; _progress?.Invoke($"Finding Galaxy Position: iteration {iteration++}"); } while (background.CloudDensity(float2(.5f)) < .5f); - return new Galaxy(_prelude, background, _names, _cache, _playerSettings, _narrativeDirectory, _log, _progress, Seed); + return new Galaxy(cast, background, _names, _cache, _playerSettings, _narrativeDirectory, _log, _progress, Seed); } private static SectorBackgroundSettings Copy(SectorBackgroundSettings settings) => diff --git a/Assets/Scripts/ServerShared/GravityField.cs b/Assets/Scripts/ServerShared/GravityField.cs new file mode 100644 index 000000000..01a070e9d --- /dev/null +++ b/Assets/Scripts/ServerShared/GravityField.cs @@ -0,0 +1,32 @@ +using CultMath; +using static CultMath.math; +using float2 = CultMath.float2; + +/// +/// The law of one gravity well: a 2D point mass with a softened core. Outside the core radius the potential is +/// logarithmic and the pull is c / r; inside it the pull falls linearly to zero at the centre and meets the tail in +/// value and slope at the core radius. c is the well's strength (u^2/s^2), R its core radius (u). No threshold +/// anywhere: a well pulls at every distance. Zone.GetForce and Zone.GetHeight sum this over a zone's bodies. +/// +public static class GravityField +{ + // The tail's additive constant: it makes the tail meet the core in value at the core radius. Gravity.cginc is generated from it. + public const float TailOffset = .5f; + + // The potential at distance r from the body, defined up to a constant (callers subtract their reference). + // A well of no strength (a body whose curves are unauthored, so c = 0 and R = 0) digs nothing. + public static float Potential(float c, float coreRadius, float r) => + c == 0f ? 0f : + r < coreRadius + ? c * r * r / (2 * coreRadius * coreRadius) + : c * (log(r / coreRadius) + TailOffset); + + // The acceleration at `offsetFromBody`, toward the body: zero at the body itself. + public static float2 Acceleration(float c, float coreRadius, float2 offsetFromBody) + { + var r = length(offsetFromBody); + if (r == 0f) return float2.zero; + var pull = r < coreRadius ? c * r / (coreRadius * coreRadius) : c / r; + return -offsetFromBody / r * pull; + } +} diff --git a/Assets/Scripts/ServerShared/GravityField.cs.meta b/Assets/Scripts/ServerShared/GravityField.cs.meta new file mode 100644 index 000000000..929e64b6d --- /dev/null +++ b/Assets/Scripts/ServerShared/GravityField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b0c7d3e9a1f4e2c8d6a7f1b3c9e0a42 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/GravityShader.cs b/Assets/Scripts/ServerShared/GravityShader.cs new file mode 100644 index 000000000..ad163e26d --- /dev/null +++ b/Assets/Scripts/ServerShared/GravityShader.cs @@ -0,0 +1,63 @@ +using System.Globalization; + +/// +/// The single author of Assets/Shaders/Gravity.cginc, the GPU lowering of the zone's potential. The law is +/// GravityField's (its constants are read here, not respelled) and the height is Zone.GetHeight: each well's +/// potential minus its reference, summed, divided by the exaggeration. Unity does not run C# when it imports a +/// shader, so the committed cginc is this output; GravityShaderTests fails unless it equals Source() exactly. +/// To change the shader, change this file and regenerate: AETHERIA_REGENERATE_GRAVITY_CGINC=1 dotnet test --filter GravityShaderTests. +/// +public static class GravityShader +{ + public const string Path = "Assets/Shaders/Gravity.cginc"; + + /// The whole file, with LF line ends. + public static string Source() => (Template + .Replace("@TAIL@", GravityField.TailOffset.ToString("R", CultureInfo.InvariantCulture))) + .Replace("\r\n", "\n"); + + private const string Template = @"#ifndef AETHERIA_GRAVITY_INCLUDED +#define AETHERIA_GRAVITY_INCLUDED + +// GENERATED by ServerShared/GravityShader.cs from GravityField; do not edit (GravityShaderTests fails on any difference). +// The lowering of the zone's potential (aetheria-gravity, cut grid-lowering). The law is ServerShared's GravityField +// and the height is Zone.GetHeight; this file decides nothing. GravityLowering.Lower fills the buffer and the globals +// from the zone (positions from Orbit.Position, reference from Zone.WellReference) each frame. +// GravityFieldParityVerify renders it and compares every texel with -Zone.GetHeight. + +struct GravityWell +{ + float2 position; + float strength; + float coreRadius; + float reference; +}; + +StructuredBuffer _GravityWells; +int _GravityWellCount; +float _HeightExaggeration; + +// GravityField.Potential: c is the well's strength, R its core radius, r the distance. +float gravityPotential(float c, float R, float r) +{ + return c == 0 ? 0 : + r < R + ? c * r * r / (2 * R * R) + : c * (log(r / R) + @TAIL@); +} + +// Zone.GetHeight at world xz: each well's potential minus its own reference, summed, divided by the exaggeration. +float gravityHeight(float2 p) +{ + float result = 0; + for (int i = 0; i < _GravityWellCount; i++) + { + GravityWell well = _GravityWells[i]; + result += gravityPotential(well.strength, well.coreRadius, length(p - well.position)) - well.reference; + } + return result / _HeightExaggeration; +} + +#endif +"; +} diff --git a/Assets/Scripts/ServerShared/GravityShader.cs.meta b/Assets/Scripts/ServerShared/GravityShader.cs.meta new file mode 100644 index 000000000..e241df3ba --- /dev/null +++ b/Assets/Scripts/ServerShared/GravityShader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a3fa1e9df764459b709270e58e79974 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/ItemData.cs b/Assets/Scripts/ServerShared/ItemData.cs index 40ec27532..9fad4cfd0 100644 --- a/Assets/Scripts/ServerShared/ItemData.cs +++ b/Assets/Scripts/ServerShared/ItemData.cs @@ -519,8 +519,7 @@ public class HullData : EquippableItemData [Inspectable, JsonProperty("hullType"), Key(25)] public HullType HullType; - [Inspectable, JsonProperty("gridOffset"), Key(26)] - public float GridOffset; + // Key(26) retired 2026-10-16 (per-hull GridOffset; the layer is the kind's, GameplaySettings). Do not reuse. [Inspectable, JsonProperty("armor"), Key(27)] public float Armor; @@ -536,6 +535,19 @@ public class HullData : EquippableItemData [Inspectable, JsonProperty("visual"), Key(32)] public CultRecordRef Visual; + // The farthest corner of any occupied hull cell from the centre of mass the schematic frame uses, in world + // units: a true bound on how far the hull reaches from its position (the half-diagonal of the bounding box is not, + // as FireControl.Detonate's comment records). A cell at (x, y) spans x +/- .5 and y +/- .5. + public float Reach(float cellSize) + { + var com = Shape.CenterOfMass; + var far = 0f; + foreach (var c in Shape.Coordinates) + foreach (var (dx, dy) in new[] { (-.5f, -.5f), (.5f, -.5f), (-.5f, .5f), (.5f, .5f) }) + far = max(far, length(float2(c.x + dx, c.y + dy) - com)); + return far * cellSize; + } + [IgnoreMember] public Shape InteriorCells { @@ -566,7 +578,12 @@ public class HardpointData [Inspectable, JsonProperty("armor"), Key(5)] public float Armor; // Full arc width in degrees a weapon on this hardpoint may bear across; 0 means "use // GameplaySettings.FiringArc" (docs/fire-control-cut.md R6). Turrets author 360 (Q1). + // On a Thruster hardpoint it is the full gimbal width: the row swings +-FiringArc/2 about Rotation, 0 is a + // fixed thruster, and there is no GameplaySettings fallback. [Inspectable, JsonProperty("firingArc"), Key(6)] public float FiringArc; + // Thruster hardpoints sharing a non-empty Row swing as one row; a Thruster hardpoint with FiringArc > 0 and no Row + // is a row of one. Only a Thruster hardpoint may state one. + [Inspectable, JsonProperty("row"), Key(7)] public string Row; public override string ToString() { @@ -720,7 +737,10 @@ public class PerformanceStat _ => throw new ArgumentOutOfRangeException(nameof(term.Source), term.Source, $"Unknown StatSource on {Min}-{Max} stat") }; } - return (lerp(Min, Max, factor) * context.ScaleModifier(this) + context.ConstantModifier(this)) * powerMultiplier; + // A stat whose span is a single value has nothing to interpolate: an unauthored stat is +infinity at both ends + // (Tracking, EffectiveRange), and lerp(+inf, +inf, f) is NaN. + var interpolated = Min == Max ? Min : lerp(Min, Max, factor); + return (interpolated * context.ScaleModifier(this) + context.ConstantModifier(this)) * powerMultiplier; } } @@ -815,6 +835,38 @@ public static class StatValidation } } + // Ruling missile-stats-now-gear-later: a munition design (a LauncherData or GuidedWeaponData behaviour) carries exactly + // one of each of the five munition parts, and any other design carries none. Runs wherever ValidateStatModifiers runs, + // so a launcher missing a part is named at catalog load and Upsert rather than at its first launch. + public static void ValidateMunitionParts(string ownerName, IEnumerable behaviors) + { + var all = (behaviors ?? Enumerable.Empty()).Where(b => b != null).ToArray(); + var isMunition = all.Any(b => b is LauncherData || b is GuidedWeaponData); + foreach (var part in new[] { typeof(MunitionHullData), typeof(MunitionThrusterData), typeof(MunitionSeekerData), typeof(MunitionControlData), typeof(MunitionFuelData) }) + { + var count = all.Count(b => b.GetType() == part); + var expected = isMunition ? 1 : 0; + if (count != expected) + throw new InvalidOperationException( + $"{ownerName}: carries {count} {part.Name}, but a {(isMunition ? "munition" : "non-munition")} design carries {expected}"); + } + } + + // Ruling effective-range-authoring-ruled: mines are flat. A mine layer's Range and MinRange gate where it may lay; its + // damage meets no range, so it carries no falloff authoring, and WeaponData.RangeFactor reads 1 inside the gate for the + // mine, the AI and the panel alike. Refused here, with the other catalog rules, wherever those run. + public static void ValidateMineLayerFlat(string ownerName, IEnumerable behaviors) + { + foreach (var layer in (behaviors ?? Enumerable.Empty()).OfType()) + { + var effective = layer.EffectiveRange; + if (effective == null || !float.IsPositiveInfinity(effective.Min) || !float.IsPositiveInfinity(effective.Max) || (effective.Terms != null && effective.Terms.Count > 0)) + throw new InvalidOperationException($"{ownerName}: {nameof(MineLayerData)}.{nameof(WeaponData.EffectiveRange)} is authored, but a mine layer carries no damage falloff"); + if (layer.DamageAtMaxRange != 0f) + throw new InvalidOperationException($"{ownerName}: {nameof(MineLayerData)}.{nameof(WeaponData.DamageAtMaxRange)} is authored, but a mine layer carries no damage falloff"); + } + } + // Cut 7 (docs/stats-and-power-cut.md): "a stat naming a role its design lacks" must be refused, not silently // fall back to the lot's own workmanship (Lot.QualityForRole already falls back for a role a lot never rolled // -- that is the intended forward-compat path for an old lot meeting a newly-authored role. This is the other @@ -855,8 +907,7 @@ public static class StatValidation // // F6 (docs/stats-and-power-cut.md, Soul pass 2026-09-19) named every field a PowerRequest implementation // actually reads, not just each consumer's top-level request field: Radiator.PowerRequest also reads - // PumpedHeat and WasteHeat, AetherDrive.PowerRequest also reads Torque, LambdaMultiplier, MaximumRpm and - // PassiveCoupling, Shield.PowerRequest (via RefreshReserve) also reads RefillDuration and RestoreDuration, + // PumpedHeat and WasteHeat, Shield.PowerRequest (via RefreshReserve) also reads RefillDuration and RestoreDuration, // InstantWeapon.PowerRequest (via RefreshInputCapacitor) also reads Cooldown and Count, and Sensor. // PowerRequest (via RefreshInputCapacitor) also reads PingCooldown. Audited directly against each // PowerRequest method's own body (and RefreshReserve/RefreshInputCapacitor, which PowerRequest calls into) @@ -892,11 +943,6 @@ public static class StatValidation (typeof(RadiatorData), nameof(RadiatorData.EnergyUsage)), (typeof(RadiatorData), nameof(RadiatorData.PumpedHeat)), (typeof(RadiatorData), nameof(RadiatorData.WasteHeat)), - (typeof(AetherDriveData), nameof(AetherDriveData.EnergyDraw)), - (typeof(AetherDriveData), nameof(AetherDriveData.Torque)), - (typeof(AetherDriveData), nameof(AetherDriveData.LambdaMultiplier)), - (typeof(AetherDriveData), nameof(AetherDriveData.MaximumRpm)), - (typeof(AetherDriveData), nameof(AetherDriveData.PassiveCoupling)), }; // Whether `stat` is the request stat of some IPowerConsumer behaviour on `data` -- used by StatModifier's diff --git a/Assets/Scripts/ServerShared/ItemInstance.cs b/Assets/Scripts/ServerShared/ItemInstance.cs index d4e7d9d89..80a891666 100644 --- a/Assets/Scripts/ServerShared/ItemInstance.cs +++ b/Assets/Scripts/ServerShared/ItemInstance.cs @@ -53,6 +53,9 @@ public class EquippableItem : CraftedItemInstance [JsonProperty("durability"), Key(7)] public float Durability; [JsonProperty("override"), Key(8)] public bool OverrideShutdown; + // The one rule for a destroyed item: its wear is spent. + [IgnoreMember] public bool IsDestroyed => Durability < .01f; + // Cut 5 (docs/stats-and-power-cut.md §1.3, §0b "A power tier"): a player choice, stored on the unit rather // than the design, so two units of the same design can be prioritized differently. PowerTiers.Unassigned // until the first equip seeds a behaviour-kind default (EquippedItem's constructor) or the player overrides diff --git a/Assets/Scripts/ServerShared/ItemManager.cs b/Assets/Scripts/ServerShared/ItemManager.cs index 281228165..884179e4e 100644 --- a/Assets/Scripts/ServerShared/ItemManager.cs +++ b/Assets/Scripts/ServerShared/ItemManager.cs @@ -140,6 +140,7 @@ public class ItemManager { Design = ItemData.RefOf(design), Origin = new Attributed { Faction = product.Manufacturer }, + Product = ItemData.RefOf(product), Quality = RollQuality(), Roles = new List() }; @@ -182,6 +183,9 @@ public class ItemManager }; } + if (design is ConsumableItemData) + return new ConsumableItem { Data = l.Design, Lot = lot }; + return new CompoundCommodity { Data = l.Design, Lot = lot @@ -200,9 +204,10 @@ public class ItemManager return CreateInstance(CreateLot(product)); } - // Who made an item and what it is branded as, derived from its lot's provenance. Null maker (an unset faction, - // or an Extracted lot with none) means no brand at all; a set maker with no matching product still shows the - // maker, with no product name or flavour text. + // Who made an item and what it is branded as. The maker derives from its lot's provenance and the product is the + // one its lot records; nothing re-derives it. Null maker (an unset faction, or an Extracted lot with none) means + // no brand at all; a set maker whose lot records no product (or one the catalog no longer holds) still shows + // the maker, with no product name or flavour text. public (Faction Maker, FactionProductData Product) Brand(CraftedItemInstance item) { var lot = GetLot(item); @@ -214,13 +219,15 @@ public class ItemManager }; if (!maker.IsSet()) return (null, null); - var product = ItemData.GetAll() - .Where(p => p.Manufacturer.Key.Equals(maker.Key) && p.Design.Key.Equals(item.Data.Key)) - .OrderBy(p => ItemData.RefOf(p).Key.Value, StringComparer.Ordinal) - .FirstOrDefault(); + var product = ItemData.Get(lot.Product); return (ItemData.Get(maker), product); } + // What the player reads an item as: its lot's product name when it records one, + // otherwise the design's own name (unbranded, console-given and extracted lots, and commodities). + public string Title(ItemInstance item) => + (item is CraftedItemInstance crafted ? Brand(crafted).Product?.Name : null) ?? GetData(item).Name; + public (RarityTier tier, int upgrades) GetTier(CraftedItemInstance item) { var quality = GetLot(item).Quality; diff --git a/Assets/Scripts/ServerShared/Loadout.cs b/Assets/Scripts/ServerShared/Loadout.cs index 0c445a100..0e60a544e 100644 --- a/Assets/Scripts/ServerShared/Loadout.cs +++ b/Assets/Scripts/ServerShared/Loadout.cs @@ -190,7 +190,7 @@ public static class Loadouts return () => (EquippableItem) itemManager.CreateInstance(product); } - private static FactionProductData[] ProductsInKeyOrder(CultCache cache) => + internal static FactionProductData[] ProductsInKeyOrder(CultCache cache) => cache.GetAll().OrderBy(p => cache.RefOf(p).Key.Value, StringComparer.Ordinal).ToArray(); private static string Cell(LoadoutSlot slot) => $"slot {slot.Position.x},{slot.Position.y}"; diff --git a/Assets/Scripts/ServerShared/LoadoutGenerator.cs b/Assets/Scripts/ServerShared/LoadoutGenerator.cs index 2fb2a69f9..46bd5bc33 100644 --- a/Assets/Scripts/ServerShared/LoadoutGenerator.cs +++ b/Assets/Scripts/ServerShared/LoadoutGenerator.cs @@ -16,6 +16,14 @@ public class LoadoutGenerator public Faction Faction { get; } public float PriceExponent { get; } + // Consumables are scarce (operator, 2026-10-09): a quarter of stations stock one product, one ship in ten carries + // one unit, and a carried consumable becomes loot when its ship dies. The units are the most a roll can stock; a + // station draws 1 to the maximum. + public const float StationConsumableChance = .25f; + public const int StationConsumableUnits = 2; + public const float ShipConsumableChance = .1f; + public const int ShipConsumableUnits = 1; + public LoadoutGenerator( ref Random random, ItemManager itemManager, @@ -46,6 +54,8 @@ public class LoadoutGenerator var entity = new Ship(ItemManager, null, hull, ItemManager.GameplaySettings.DefaultEntitySettings); entity.Faction = Faction; OutfitEntity(entity); + EquipPickup(entity); + StockConsumables(entity, ShipConsumableChance, ShipConsumableUnits); return EntitySerializer.Pack(entity); } @@ -107,6 +117,11 @@ public class LoadoutGenerator FillInterior(entity); + // The consumable goes in before the gear stock: sixteen gear picks drawn with replacement can fill a real hold, + // and a roll that hit must leave the entity holding one (the ruled rate is the rule). With no consumable on + // offer nothing is drawn here, so the gear draws are exactly what they were. + StockConsumables(entity, StationConsumableChance, StationConsumableUnits); + var cargo = entity.CargoBays.First(); var inventory = RandomProducts(16, 1, data => !(data is HullData hull && hull.HullType != HullType.Ship) && !(data is CargoBayData)) @@ -122,6 +137,25 @@ public class LoadoutGenerator return EntitySerializer.Pack(entity) as OrbitalEntityPack; } + // A loadout's one consumable step. With no consumable on offer, or no hold to put one in, nothing is drawn, so a + // catalog without consumables generates exactly what it did before them. Otherwise one roll decides whether the + // entity has any, and a hit stocks 1 to maxUnits instances of one product, stopping when no hold takes another. + private void StockConsumables(Entity entity, float chance, int maxUnits) + { + var (available, _) = AvailableProducts(null, false); + if (available.Length == 0 || !entity.CargoBays.Any()) return; + if (Random.NextFloat() >= chance) return; + + var (product, design) = RandomProducts(1, 0).FirstOrDefault(); + if (design == null) return; + var units = Random.NextInt(1, maxUnits + 1); + for (var i = 0; i < units; i++) + { + var instance = ItemManager.CreateInstance(product); + if (!entity.CargoBays.Any(bay => bay.TryStore(instance))) break; + } + } + private static bool IsHeater(GearData item) => item.HardpointType == HardpointType.Tool && item.Behaviors.Any(b => b is ThermotoggleData { HighPass: false }) && @@ -139,16 +173,28 @@ public class LoadoutGenerator // Products normally come only from manufacturers present in the galaxy and known to the zone's faction; a // required item falls back to any manufacturer when none of those make one, which means the product table // lacks variety, so it is logged rather than hidden. - public (FactionProductData product, T design)[] RandomProducts(int count, float sizeExponent, Predicate filter = null, bool required = false) where T : EquippableItemData + public (FactionProductData product, T design)[] RandomProducts(int count, float sizeExponent, Predicate filter = null, bool required = false) where T : CraftedItemData { - var hulls = ItemManager.ItemData.GetAll().ToArray(); + var (available, preferManufacturers) = AvailableProducts(filter, required); + return available.WeightedRandomElements(ref Random, entry => + (preferManufacturers ? ManufacturerPreference(entry.product.Manufacturer) : 1) * + pow(entry.design.Shape.Coordinates.Length, sizeExponent) / // Prioritize larger items + pow(entry.design.Price, PriceExponent), // Penalize item price to a controllable degree + count); + } + + // The products this faction can be offered for a design kind (only gear needs a home), and whether manufacturer preference applies (it does + // not once a required item has fallen back to any manufacturer). The one availability rule for every selection. + private ((FactionProductData product, T design)[] available, bool preferManufacturers) AvailableProducts(Predicate filter, bool required) where T : CraftedItemData + { + var hulls = SoldHulls(ItemManager.ItemData); var candidates = ItemManager.ItemData.GetAll() .Select(product => (product, design: ItemManager.ItemData.Get(product.Design) as T)) .Where(entry => entry.design != null && entry.design.Price > 0 && entry.product.Manufacturer.IsSet() && - HasHome(entry.design, hulls) && + (!(entry.design is EquippableItemData equippable) || HasHome(equippable, hulls)) && (filter?.Invoke(entry.design) ?? true)) .ToArray(); var available = candidates.Where(entry => IsAvailable(entry.product)).ToArray(); @@ -160,40 +206,65 @@ public class LoadoutGenerator preferManufacturers = false; } - return available.WeightedRandomElements(ref Random, entry => - (preferManufacturers ? ManufacturerPreference(entry.product.Manufacturer) : 1) * - pow(entry.design.Shape.Coordinates.Length, sizeExponent) / // Prioritize larger items - pow(entry.design.Price, PriceExponent), // Penalize item price to a controllable degree - count); + return (available, preferManufacturers); + } + + // A faction's boss: its BossHull when the faction sets one and a product sells it, else the most expensive ship hull + // the faction can be offered, with the gap logged. Null only when no ship hull is on offer at all. + public EntityPack GenerateBossLoadout() + { + var bossHull = Faction != null && Faction.BossHull.IsSet() ? ItemManager.ItemData.Get(Faction.BossHull) : null; + if (bossHull != null) + { + var boss = GenerateShipLoadout(hull => hull == bossHull); + if (boss != null) return boss; + ItemManager.Log($"{Faction.Name}'s BossHull {bossHull.Name} is not sold by any product; its boss flies the most expensive ship hull instead."); + } + else + ItemManager.Log($"{Faction?.Name ?? "This faction"} has no BossHull; its boss flies the most expensive ship hull instead."); + + var (available, _) = AvailableProducts(hull => hull.HullType == HullType.Ship, required: true); + if (available.Length == 0) return null; + var priciest = available.OrderByDescending(entry => entry.design.Price).ThenBy(entry => entry.design.Name, StringComparer.Ordinal).First().design; + return GenerateShipLoadout(hull => hull == priciest); } // Hardpoint gear that no hull in the catalog can mount has no home (operator, 2026-09-30: "we'll need to author a // bunch more hulls before all the gear variety in the game has a home"): generation never offers it, so no station // stocks it. It gains one the moment a hull with a hardpoint that takes it exists. Tool gear goes in any interior. - private static bool HasHome(EquippableItemData design, HullData[] hulls) => + // Only a hull some product sells gives gear a home: a hull no faction builds (the Smoke Test Hull) is a test fixture, so its + // hardpoints never put gear on a shelf. The one definition of the hulls HasHome considers. + public static HullData[] SoldHulls(CultCache items) => + items.GetAll().Select(product => items.Get(product.Design)).OfType().Distinct().ToArray(); + + public static bool HasHome(EquippableItemData design, HullData[] hulls) => design.HardpointType == HardpointType.Tool || design.HardpointType == HardpointType.Hull || hulls.Any(hull => hull.Hardpoints.Any(hardpoint => hardpoint.Takes(design))); - // No galaxy means no availability to filter by: every product is on offer. A fixture generates loadouts that - // way, so a test can exercise placement and products without standing up a whole galaxy; no game path does. - // Loadouts.Materialize takes availability as a predicate; RunStart, the game's one preset spawner, passes this, so - // presets and generation share one availability rule. In a galaxy, a faction always reaches its own manufacturer's - // gear, and otherwise gear made by a manufacturer in that galaxy that its allegiance names (operator, 2026-09-30: - // allegiance lists only other factions). + // No galaxy, or no faction, means no allegiance to filter by: every product is on offer. A fixture generates + // loadouts that way, so a test can exercise placement and products without standing up a whole galaxy; a scenario + // stage has no faction and reaches every maker. Loadouts.Materialize takes availability as a predicate; RunStart, + // the game's one preset spawner, passes this, so presets and generation share one availability rule. A faction + // always reaches its own manufacturer's gear, and otherwise gear made by a manufacturer its allegiance names + // (operator, 2026-09-30: allegiance lists only other factions). Whether that manufacturer is present in the galaxy + // does not matter (operator, 2026-10-06: a faction need not be present for its gear to be available). public bool IsAvailable(FactionProductData product) => - Galaxy == null || Galaxy.IsPrelude || - Faction != null && ItemManager.ItemData.Get(product.Manufacturer) == Faction || - Galaxy.ContainsFaction(product.Manufacturer) && (Faction == null || Faction.Allegiance.ContainsKey(product.Manufacturer)); + Galaxy == null || Faction == null || + ItemManager.ItemData.Get(product.Manufacturer) == Faction || Faction.Allegiance.ContainsKey(product.Manufacturer); - // Prioritize products from the zone faction and its allies, penalizing distance to the manufacturer's headquarters - private float ManufacturerPreference(CultRecordRef manufacturer) + // Prioritize products from the zone faction and its allies, penalizing distance to the manufacturer's headquarters. + // A manufacturer with no home zone in this galaxy weighs as if its headquarters lay one jump beyond the farthest + // zone this zone reaches: reachable through allegiance, least preferred. + public float ManufacturerPreference(CultRecordRef manufacturer) { if (Faction == null || Galaxy == null) return 1; var maker = ItemManager.ItemData.Get(manufacturer); var allegiance = maker == Faction ? 1 : Faction.Allegiance.TryGetValue(manufacturer, out var a) ? a : 0; var home = maker != null && Galaxy.HomeZones.TryGetValue(maker, out var h) ? h : null; - var distance = home != null && Zone?.Distance != null && Zone.Distance.TryGetValue(home, out var d) ? d : 0; + var distance = Zone?.Distance == null ? 0 : + home != null && Zone.Distance.TryGetValue(home, out var d) ? d : + home == null && Zone.Distance.Count > 0 ? Zone.Distance.Values.Max() + 1 : 0; return allegiance / (1 + distance); } @@ -217,6 +288,24 @@ public class LoadoutGenerator FillInterior(entity); } + // Every ship carries a tractor beam: picking up needs a pickup behaviour (scenarios ruling, "everyone gets tractor + // beams"). It goes in after the shared outfitting, which stations and turrets also run and which adds none, into + // whatever interior the hull has left; a hull with no cell for one cannot be generated. + private void EquipPickup(Entity entity) + { + var emptyShape = entity.UnoccupiedSpace; + var (product, design) = RandomProduct(2, item => + item.Behaviors.Any(b => b is PickupData) && + item.Shape.FitsWithin(emptyShape, out _, out _), required: true); + if (design == null) throw new InvalidLoadoutException("No compatible tractor beam found for ship!"); + + design.Shape.FitsWithin(emptyShape, out var rotation, out var position); + var beam = ItemManager.CreateInstance(product) as EquippableItem; + beam.Rotation = rotation; + if (!entity.TryEquip(beam, position)) + throw new InvalidLoadoutException("Failed to equip selected tractor beam!"); + } + private void EquipHardpoints(Entity entity) { var hullData = ItemManager.GetData(entity.Hull) as HullData; diff --git a/Assets/Scripts/ServerShared/OrbitalEntity.cs b/Assets/Scripts/ServerShared/OrbitalEntity.cs index 93f055804..a2c511ba7 100644 --- a/Assets/Scripts/ServerShared/OrbitalEntity.cs +++ b/Assets/Scripts/ServerShared/OrbitalEntity.cs @@ -23,6 +23,8 @@ public class OrbitalEntity : Entity OrbitData = orbit; } + public override float LayerHeight => ItemManager.GameplaySettings.OrbitalLayerHeight; + public override void Update(float delta) { if (OrbitData.IsSet()) diff --git a/Assets/Scripts/ServerShared/PlayerSettings.cs b/Assets/Scripts/ServerShared/PlayerSettings.cs index 2566dcf59..f46bbad22 100644 --- a/Assets/Scripts/ServerShared/PlayerSettings.cs +++ b/Assets/Scripts/ServerShared/PlayerSettings.cs @@ -64,6 +64,8 @@ public class PlayerGraphicsSettings { [Key(0)] public Quality NebulaQuality = Quality.Normal; [Key(1)] public bool ShowAsteroidsInMinimap; + // How hard the camera shakes when the player's ship takes an impact: 0 off, 1 full (Feedback.Cue). + [Key(2)] public float ScreenShake = 1f; } [MessagePackObject] diff --git a/Assets/Scripts/ServerShared/PowerTiers.cs b/Assets/Scripts/ServerShared/PowerTiers.cs index e6bf90d89..c7c88233b 100644 --- a/Assets/Scripts/ServerShared/PowerTiers.cs +++ b/Assets/Scripts/ServerShared/PowerTiers.cs @@ -13,7 +13,7 @@ // every other item on the hull (EquippedItem.UpdatePerformance). Feed it first or lose the rest anyway. // - High: Shield. Hull survival the player is actively trading power for; not a life-support constant, so it // sits below Radiator rather than beside it. -// - Medium: Thruster, AetherDrive. Mobility -- needed to hold position, evade, or disengage, but a ship that +// - Medium: Thruster. Mobility -- needed to hold position, evade, or disengage, but a ship that // loses thrust for a tick under brownout is inconvenienced, not dead the way an overheating hull is. // - Low: ConstantWeapon, InstantWeapon. Offense. The ruling's own framing ("low-priority subsystems starve // first") names weapons as the default example of what a reactor throttle should sacrifice first. diff --git a/Assets/Scripts/ServerShared/Provenance.cs b/Assets/Scripts/ServerShared/Provenance.cs index b04a4aeeb..80e8e31f0 100644 --- a/Assets/Scripts/ServerShared/Provenance.cs +++ b/Assets/Scripts/ServerShared/Provenance.cs @@ -58,8 +58,8 @@ public class ProvenanceLedger } } -// One lot: the design it built, who made it and from what, its rolled workmanship, and how well each design role -// was filled. Immutable once minted; instances carry a LotId, never a copy. +// One lot: the design it built, who made it and from what, its rolled workmanship, how well each design role +// was filled, and the branded product it was made as. Immutable once minted; instances carry a LotId, never a copy. [MessagePackObject] public class Lot { @@ -68,6 +68,10 @@ public class Lot [Key(2)] public float Quality; [Key(3)] public List Roles; + // The product the lot was made as: the one owner of which product names its units. Unset for unbranded lots + // (console give, presets, extracted), which brand their maker only. + [Key(4)] public CultRecordRef Product; + // The quality a stat reads for one of the design's roles. An unnamed role, a design without roles, and a lot // minted before roles existed all fall back to the lot's own workmanship. public float QualityForRole(string role) diff --git a/Assets/Scripts/ServerShared/RunGoal.cs b/Assets/Scripts/ServerShared/RunGoal.cs new file mode 100644 index 000000000..ee34b1563 --- /dev/null +++ b/Assets/Scripts/ServerShared/RunGoal.cs @@ -0,0 +1,42 @@ +using System.Linq; +using CultMath; +using static CultMath.math; + +// The run's goal: whether a zone's boss lives, and so whether the exit gate is open. Engine-free and stateless; the +// answer is derived from Zone.Entities (the death path removes the dead, Zone.cs), so no "boss defeated" flag exists to +// disagree with it, and no presentation decides it. +public static class RunGoal +{ + public static Entity Boss(Zone zone) => zone.Entities.FirstOrDefault(entity => entity.IsBoss); + + public static bool BossAlive(Zone zone) => Boss(zone) != null; + + // The exit gate fails closed: it is open only in the galaxy's exit zone, once a boss was spawned there and no living + // boss remains. An exit zone that never got a boss stays sealed, so a missing boss can never read as a dead one. + public static bool ExitOpen(Zone zone) => + zone.Galaxy?.Exit != null && zone.GalaxyZone == zone.Galaxy.Exit && zone.Pack.BossSpawned && !BossAlive(zone); + + // Where the exit gate sits: at the adjacency wormholes' radius (the zone's radius times the ratio), in the middle of + // the widest angular gap between them, so it shares a point with none. A zone with no neighbours gets the +x axis. + public static float2 ExitGatePosition(Zone zone, float wormholeDistanceRatio) + { + var radius = zone.Pack.Radius * wormholeDistanceRatio; + var angles = zone.GalaxyZone.AdjacentZones + .Select(adjacent => normalize(adjacent.Position - zone.GalaxyZone.Position)) + .Select(direction => atan2(direction.y, direction.x)) + .OrderBy(angle => angle) + .ToArray(); + if (angles.Length == 0) return float2(radius, 0); + + var bestAngle = 0f; + var bestGap = -1f; + for (var i = 0; i < angles.Length; i++) + { + var next = i + 1 < angles.Length ? angles[i + 1] : angles[0] + 2 * PI; + if (next - angles[i] <= bestGap) continue; + bestGap = next - angles[i]; + bestAngle = angles[i] + bestGap / 2; + } + return float2(cos(bestAngle), sin(bestAngle)) * radius; + } +} diff --git a/Assets/Scripts/ServerShared/RunGoal.cs.meta b/Assets/Scripts/ServerShared/RunGoal.cs.meta new file mode 100644 index 000000000..2e3839fad --- /dev/null +++ b/Assets/Scripts/ServerShared/RunGoal.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: de03c3545cb04ce38bf85b713dc5df74 diff --git a/Assets/Scripts/ServerShared/ScenarioStage.cs b/Assets/Scripts/ServerShared/ScenarioStage.cs index 2fa28dc1f..159504292 100644 --- a/Assets/Scripts/ServerShared/ScenarioStage.cs +++ b/Assets/Scripts/ServerShared/ScenarioStage.cs @@ -105,18 +105,23 @@ public sealed class ScenarioStage } // Anything else in the arena. A stance holds both ways between it and the player. A piloted ship gets the zone's - // pilot; an unpiloted entity has none and goes nowhere on its own. A turret hull stays where it is put. - public Entity Place(ScenarioFit fit, float2 at, float2 facing = default, ScenarioStance stance = ScenarioStance.Neutral, bool piloted = false) + // pilot; an unpiloted entity has none and goes nowhere on its own unless it is placed moving: velocity is the planar + // velocity it starts with, and the sim carries it from there. A turret hull stays where it is put. + public Entity Place(ScenarioFit fit, float2 at, float2 facing = default, ScenarioStance stance = ScenarioStance.Neutral, bool piloted = false, + float2 velocity = default) { var where = $"entity {_placements++}"; var entity = Build(fit, where, at, facing); if (entity == null) return null; + entity.Velocity = velocity; if (piloted && !(entity is Ship)) _failures.Add($"{where}: {entity.Name} is not a ship hull, so it cannot be piloted"); _placed.Add(new Placement { Entity = entity, Stance = stance, Piloted = piloted }); return entity; } - // Items in the entity's first cargo bay, one per design named. + // Items in the entity's first cargo bay, one per design named. A name is an equippable design (built as a fit + // builds it) or a consumable design (built from its first available product in key order, as a generated hold is + // stocked); a name that is neither is a failure. public void Cargo(Entity entity, params string[] designs) { if (entity == null) return; @@ -124,10 +129,27 @@ public sealed class ScenarioStage var bay = entity.CargoBays.FirstOrDefault(); foreach (var design in designs) { - var data = Named(design, where); + var data = Named(design, where, found => found is EquippableItemData || found is ConsumableItemData); if (data == null) continue; - var build = Loadouts.Resolve(_items, _items.ItemData.RefOf(data), _available, where, _failures); - if (build != null && (bay == null || !bay.TryStore(build()))) + Func build; + if (data is ConsumableItemData) + { + var key = _items.ItemData.RefOf(data).Key; + var product = Loadouts.ProductsInKeyOrder(_items.ItemData).Where(p => p.Design.Key.Equals(key)).FirstOrDefault(p => _available(p)); + if (product == null) + { + _failures.Add($"{where}: no product offers {design}"); + continue; + } + build = () => _items.CreateInstance(product); + } + else + { + var equippable = Loadouts.Resolve(_items, _items.ItemData.RefOf((EquippableItemData) data), _available, where, _failures); + if (equippable == null) continue; + build = equippable; + } + if (bay == null || !bay.TryStore(build())) _failures.Add($"{where}: no room for {design}"); } } @@ -151,9 +173,9 @@ public sealed class ScenarioStage return entity; } - private T Named(string name, string where) where T : EquippableItemData + private T Named(string name, string where, Func among = null) where T : CraftedItemData { - var named = _items.ItemData.GetAll().Where(data => data.Name == name).Take(2).ToArray(); + var named = _items.ItemData.GetAll().Where(data => data.Name == name && (among == null || among(data))).Take(2).ToArray(); if (named.Length == 1) return named[0]; _failures.Add(named.Length == 0 ? $"{where}: no design named {name}" : $"{where}: more than one design is named {name}"); return null; diff --git a/Assets/Scripts/ServerShared/Scenarios/AiFusedDiscipline.cs b/Assets/Scripts/ServerShared/Scenarios/AiFusedDiscipline.cs new file mode 100644 index 000000000..eb8ecab18 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/AiFusedDiscipline.cs @@ -0,0 +1,36 @@ +using static CultMath.math; +using static ItemRotation; + +public sealed class AiFusedDiscipline : Scenario +{ + public override string Name => "AI Fused Discipline"; + public override string Brief => "A Djinni; a piloted neutral Longinus carrying a Smoke Proximity and a piloted hostile Longinus whose only weapon is " + + "Smoke Refused. Verify: the hostile closes on you and never fires its refused weapon; the neutral never fires its " + + "fused one."; + public override uint Seed => 110; + public override bool Ambient => false; + + public static readonly CultMath.float2 Hostile = float2(0, 700), Neutral = float2(500, 300); + + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast); + + public override void Stage(ScenarioStage stage) + { + ScenarioFit Armed(string weapon) => stage.Fit("Longinus", + ("Cockpit 2x2", int2(2, 6), None), + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Compact Reactor", int2(2, 4), None), + (weapon, int2(1, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Fire Control Array", int2(1, 6), Clockwise)); + + stage.Player(stage.Generated("Djinni"), float2(0, 0)); + stage.Place(Armed("Smoke Refused"), Hostile, facing: float2(0, -1), stance: ScenarioStance.Hostile, piloted: true); + stage.Place(Armed("Smoke Proximity"), Neutral, facing: float2(-1, 0), piloted: true); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/AiFusedDiscipline.cs.meta b/Assets/Scripts/ServerShared/Scenarios/AiFusedDiscipline.cs.meta new file mode 100644 index 000000000..5994a43a7 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/AiFusedDiscipline.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d71dbf0ab5847a6ab58f96a50678ac7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Scenarios/Arcs.cs b/Assets/Scripts/ServerShared/Scenarios/Arcs.cs index d1ceb61e0..da2983267 100644 --- a/Assets/Scripts/ServerShared/Scenarios/Arcs.cs +++ b/Assets/Scripts/ServerShared/Scenarios/Arcs.cs @@ -4,43 +4,57 @@ using static ItemRotation; public sealed class Arcs : Scenario { public override string Name => "Arcs"; - public override string Brief => "Forward mounts, a bare hull off the bow, one off the stern, a hostile turret. Verify: the bow " + - "hull can be hit, nothing fires at the stern one through the ship, the turret tracks you all the way round."; + public override string Brief => "The Smoke Test Hull with forward mounts and a side mount on each flank; a bare hull off the bow, one off " + + "the stern, one abeam to port, one abeam to starboard, and a hostile turret. Verify: the hull keeps its " + + "heading while you aim at the stern hull, and the forward guns hold. Designate the bow hull and fire with the " + + "aim anywhere: the forward guns fire on it and hit. The side guns fire at their beam hull and never through " + + "the hull. Designate the starboard hull, aim ahead and fire its group: it fires on the hull without the aim " + + "and the port group holds; undesignate and aim to port: the port group fires free. The turret tracks you " + + "all the way round."; public override uint Seed => 103; public override bool Ambient => false; - // Where the targets sit: the player is at the origin facing +z, and every mount fires forward. - public static readonly CultMath.float2 Bow = float2(0, 400), Stern = float2(0, -400), Turret = float2(600, 0); + // Where the targets sit: the player is at the origin facing +z. The forward mounts fire forward, the starboard mount + // (Clockwise) along +x and the port mount (CounterClockwise) along -x. + public static readonly CultMath.float2 Bow = float2(0, 400), Stern = float2(0, -400), Turret = float2(600, 300), + Port = float2(-400, 0), Starboard = float2(400, 0); public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(); public override void Stage(ScenarioStage stage) { - var fighter = stage.Fit("LonginusX", - ("Cockpit 2x2", int2(2, 6), None), - ("Traction", int2(2, 3), None), - ("Core Power", int2(2, 1), None), - ("GT 3K", int2(0, 5), None), - ("GT 3K", int2(5, 5), None), - ("FastBlast+-", int2(1, 8), None), - ("FastBlast+-", int2(4, 8), None), - ("Iapyx", int2(1, 2), CounterClockwise), - ("Iapyx", int2(4, 2), Clockwise), - ("not if i see you first", int2(3, 10), None), - ("Fire Control Array", int2(2, 5), None)); + var fighter = stage.Fit("Smoke Test Hull", + ("Cockpit 2x2", int2(4, 6), None), + ("Large Drive", int2(3, 0), Reversed), + ("Large Drive", int2(5, 0), Reversed), + ("Rugged Drive", int2(4, 14), CounterClockwise), + ("Rugged Drive", int2(5, 14), Clockwise), + ("Compact Reactor", int2(4, 4), None), + ("Guided Missile Launcher", int2(2, 5), None), + ("Guided Missile Launcher", int2(7, 5), None), + ("Cell Blaster", int2(3, 8), None), + ("Cell Blaster", int2(6, 8), None), + ("Radiator", int2(4, 2), CounterClockwise), + ("Radiator", int2(5, 2), Clockwise), + ("Compact Sensor", int2(5, 10), None), + ("Fire Control Array", int2(3, 6), Clockwise), + ("Autocannon", int2(8, 4), Clockwise), + ("Charged Scatter Blaster", int2(0, 4), CounterClockwise)); var turret = stage.Fit("Turret", - ("ClearPath", int2(1, 2), None), - ("ClearPath", int2(5, 2), None), - ("Skiron", int2(0, 2), CounterClockwise), - ("Skiron", int2(7, 2), Clockwise), - ("Core Power", int2(3, 3), None), + ("Light Machine Gun", int2(1, 2), None), + ("Light Machine Gun", int2(5, 2), None), + ("Long Radiator", int2(0, 2), CounterClockwise), + ("Long Radiator", int2(7, 2), Clockwise), + ("Compact Reactor", int2(3, 3), None), ("Turret Control Module", int2(3, 5), None), - ("not if i see you first", int2(4, 5), None), + ("Compact Sensor", int2(4, 5), None), ("Fire Control Array", int2(3, 6), None)); stage.Player(fighter, float2(0, 0), facing: float2(0, 1)); - stage.Place(stage.Bare("LonginusX"), Bow); - stage.Place(stage.Bare("LonginusX"), Stern); + stage.Place(stage.Bare("Longinus"), Bow); + stage.Place(stage.Bare("Longinus"), Stern); stage.Place(turret, Turret, stance: ScenarioStance.Hostile); + stage.Place(stage.Bare("Longinus"), Port); + stage.Place(stage.Bare("Longinus"), Starboard); } } diff --git a/Assets/Scripts/ServerShared/Scenarios/Belt.cs b/Assets/Scripts/ServerShared/Scenarios/Belt.cs new file mode 100644 index 000000000..efab34db7 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/Belt.cs @@ -0,0 +1,48 @@ +using System.Linq; +using static CultMath.math; +using static ItemRotation; + +public sealed class Belt : Scenario +{ + public override string Name => "Belt"; + public override string Brief => "The biggest asteroid belt the generator made, with the Longinus parked 100 m outside its ring, facing along it, " + + "and nothing else in the arena. Verify: next and previous target step through the rocks and the reticle sweeps " + + "across the belt without a hitch; Previous with nothing targeted takes the farthest rock; the target indicator " + + "sits on the rock it names."; + + // Seeds 1-256 scanned for the arena whose entrance zone holds the belt with the most asteroids: seed 24, a belt of + // 615 rocks. The next four: 179 (553), 251 (548), 221 (532), 29 (515). + public override uint Seed => 24; + public override bool Ambient => false; + + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast); + + public override void Stage(ScenarioStage stage) + { + var fighter = stage.Fit("Longinus", + ("Cockpit 2x2", int2(2, 6), None), + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Compact Reactor", int2(2, 4), None), + ("Guided Missile Launcher", int2(0, 5), None), + ("Guided Missile Launcher", int2(5, 5), None), + ("Lightning Projector", int2(1, 8), None), + ("Cell Blaster", int2(4, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Fire Control Array", int2(1, 6), Clockwise)); + + // The belt is a ring about its parent's position at the belt orbit's distance. The player stands 100 m outside + // it, at the point nearest the origin, facing along the ring. + var arena = stage.Arena; + var belt = arena.Planets.Values.OfType().OrderByDescending(candidate => candidate.Asteroids.Length).First(); + var orbit = arena.Orbits[belt.Orbit.Key].Data; + var centre = arena.GetOrbitPosition(orbit.Parent.Key); + var outward = lengthsq(centre) > 0f ? normalize(-centre) : float2(1, 0); + var at = centre + outward * (orbit.Distance + 100f); + stage.Player(fighter, at, facing: float2(-outward.y, outward.x)); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/Belt.cs.meta b/Assets/Scripts/ServerShared/Scenarios/Belt.cs.meta new file mode 100644 index 000000000..375ec1cb9 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/Belt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6177c598b87544d6bb0cefdfb4f01acc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Scenarios/Crossing.cs b/Assets/Scripts/ServerShared/Scenarios/Crossing.cs new file mode 100644 index 000000000..f0e91be00 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/Crossing.cs @@ -0,0 +1,52 @@ +using static CultMath.math; +using static ItemRotation; + +public sealed class Crossing : Scenario +{ + public override string Name => "Crossing"; + public override string Brief => "A Lightning Projector at the starboard gun and a Cell Blaster at the port gun, an unpiloted Djinni coasting across the bow " + + "close ahead and an unpiloted one waiting at range. The crosser is launched to port at 50 m/s and only coasts: nothing steers it, " + + "its hull drag slows it to about 25 m/s at the bow line, and it does not shoot back. Make the pass coasting: give no throttle until the Djinni has crossed the bow, then fly freely " + + "(thrusting from the start carries you past it). Verify: as the Djinni crosses close, FastBlast lands some and projector " + + "almost none; against the Djinni at range both land. Fly it again without the Fire Control Array: " + + "with it the small gun lands more."; + public override uint Seed => 112; + public override bool Ambient => false; + + // Where the Djinni sit: the player is at Origin facing +z. Origin is 250 m or more from every body, where the zone's + // pull is weakest (about 1.4 u/s^2; the sum of the wells never drops to nothing, and at the old origin the player sat on the star). + // The crosser is unpiloted and placed moving at the Djinni's 50 m/s cap, so its pass is ballistic: bent by the field and slowed + // by hull drag (it reaches the bow line at about 25 m/s relative to the player, 3.6 s in), and nothing steers it. + // CrosserAt is the centre of the start window in which the pass holds: shifting it by 10 m along either axis keeps the pass + // inside the test's time and distance windows (CrossingHoldsAcrossTheStartWindow). + // The waiting Djinni sits inside the Lightning Projector's arc at 80% of its Range. + public static readonly CultMath.float2 Origin = float2(724, 124); + public static readonly CultMath.float2 CrosserAt = Origin + float2(-128, 45), CrosserFacing = float2(1, 0), CrosserVelocity = float2(50, 0); + public const float ProjectorRange = 1216f; // the Lightning Projector's Range in metres, 1216.4 as the fit stands settled at rest + public static readonly CultMath.float2 Waiting = Origin + float2(0, ProjectorRange * .8f); + + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast); + + public override void Stage(ScenarioStage stage) + { + var fighter = stage.Fit("Longinus", + ("Cockpit 2x2", int2(2, 6), None), + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Compact Reactor", int2(2, 4), None), + ("Guided Missile Launcher", int2(0, 5), None), + ("Guided Missile Launcher", int2(5, 5), None), + ("Lightning Projector", int2(1, 8), None), + ("Cell Blaster", int2(4, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Fire Control Array", int2(1, 6), Clockwise)); + + stage.Player(fighter, Origin, facing: float2(0, 1)); + stage.Place(stage.Generated("Djinni"), CrosserAt, facing: CrosserFacing, stance: ScenarioStance.Hostile, velocity: CrosserVelocity); + stage.Place(stage.Bare("Djinni"), Waiting); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/Crossing.cs.meta b/Assets/Scripts/ServerShared/Scenarios/Crossing.cs.meta new file mode 100644 index 000000000..2787758ab --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/Crossing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0cc3edfb4b0e4ea485cce71354f41748 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Scenarios/DemoTerminus.cs b/Assets/Scripts/ServerShared/Scenarios/DemoTerminus.cs new file mode 100644 index 000000000..8cda7c600 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/DemoTerminus.cs @@ -0,0 +1,41 @@ +using float2 = CultMath.float2; + +// The demo: one gate, one region and one boss, with a fixed cast. The Pirates are the protagonist's ostensible +// employer, Zhestokost the antagonist whose home is the boss zone and the exit, Lucent Media and Aeronautics Unlimited +// the neutrals. A prelude galaxy of that cast; the player, who is not a Pirate, flies the base Longinus. +public sealed class DemoTerminus : Scenario +{ + public static readonly TutorialGenerationSettings Cast = new TutorialGenerationSettings + { + ProtagonistFaction = "Pirates", + AntagonistFaction = "Zhe", + BufferFaction = "Luc", + NeutralFactions = new[] { "Aero" }, + QuestFaction = null, + ZoneCount = 64, + LinkDensity = .5f + }; + + public override string Name => "Terminus (Demo)"; + public override string Brief => "One gate, one region, one boss. Allied: the Pirates. Opposed: Zhestokost. " + + "Neutral: Lucent Media and Aeronautics Unlimited."; + + public override Galaxy Generate(GalaxyStage stage) + { + var galaxy = stage.Prelude(Cast); + galaxy.PlaceGate(galaxy.ResolveFaction(Cast.AntagonistFaction)); + return galaxy; + } + + public override void Stage(ScenarioStage stage) + { + var galaxy = stage.Galaxy; + var pirates = galaxy.ResolveFaction(Cast.ProtagonistFaction); + galaxy.FactionRelationships[pirates] = FactionRelationship.Friendly; + galaxy.FactionRelationships[galaxy.ResolveFaction(Cast.AntagonistFaction)] = FactionRelationship.Hated; + galaxy.FactionRelationships[galaxy.ResolveFaction(Cast.BufferFaction)] = FactionRelationship.Neutral; + foreach (var neutral in Cast.NeutralFactions) + galaxy.FactionRelationships[galaxy.ResolveFaction(neutral)] = FactionRelationship.Neutral; + stage.Player(stage.Generated("Longinus"), float2.zero); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/DemoTerminus.cs.meta b/Assets/Scripts/ServerShared/Scenarios/DemoTerminus.cs.meta new file mode 100644 index 000000000..706f1bf0e --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/DemoTerminus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ba7152d3c8b46a98924a4148be550db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Scenarios/DjinniShakedown.cs b/Assets/Scripts/ServerShared/Scenarios/DjinniShakedown.cs index 720fa2d08..7cbec5630 100644 --- a/Assets/Scripts/ServerShared/Scenarios/DjinniShakedown.cs +++ b/Assets/Scripts/ServerShared/Scenarios/DjinniShakedown.cs @@ -3,13 +3,22 @@ using float2 = CultMath.float2; public sealed class DjinniShakedown : Scenario { public override string Name => "Djinni Shakedown"; - public override string Brief => "A fitted Djinni in empty space. Verify: its thrusters move and turn it; with the hull " + - "offline and thrusters firing, its speed does not run away."; + public override string Brief => "A fitted Djinni in empty space, facing +z, with a bare hull dead ahead and one abeam. Verify: its thrusters " + + "move and turn it; with the hull offline and thrusters firing, its speed does not run away. Its " + + "articulated ballistic barrel points at the hull ahead when it bears, and rests at the arc edge while you " + + "aim at the hull abeam."; public override uint Seed => 101; public override bool Ambient => false; + // Where the targets sit: the ballistic mount faces +z, so Ahead is inside its arc and Abeam outside it. + public static readonly float2 Ahead = new float2(0, 400), Abeam = new float2(400, 0); + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(); - public override void Stage(ScenarioStage stage) => + public override void Stage(ScenarioStage stage) + { stage.Player(stage.Generated("Djinni"), float2.zero); + stage.Place(stage.Bare("Longinus"), Ahead); + stage.Place(stage.Bare("Longinus"), Abeam); + } } diff --git a/Assets/Scripts/ServerShared/Scenarios/Duel.cs b/Assets/Scripts/ServerShared/Scenarios/Duel.cs index fa270a4bd..510d60147 100644 --- a/Assets/Scripts/ServerShared/Scenarios/Duel.cs +++ b/Assets/Scripts/ServerShared/Scenarios/Duel.cs @@ -4,7 +4,7 @@ using static ItemRotation; public sealed class Duel : Scenario { public override string Name => "Duel"; - public override string Brief => "One piloted, hostile LonginusX with slow GT 3K missiles and a Spectra in its hold. Verify: rolled " + + public override string Brief => "One piloted, hostile Longinus with slow guided missiles and a Light Laser in its hold. Verify: rolled " + "hits and near-misses, subsystem aim, beam reads above bow, armour takes the missile, loot keeps its brand."; public override uint Seed => 104; public override bool Ambient => false; @@ -13,23 +13,26 @@ public sealed class Duel : Scenario public override void Stage(ScenarioStage stage) { - var fighter = stage.Fit("LonginusX", + var fighter = stage.Fit("Longinus", ("Cockpit 2x2", int2(2, 6), None), - ("Traction", int2(2, 3), None), - ("Core Power", int2(2, 1), None), - ("GT 3K", int2(0, 5), None), - ("GT 3K", int2(5, 5), None), - ("FastBlast+-", int2(1, 8), None), - ("FastBlast+-", int2(4, 8), None), - ("Iapyx", int2(1, 2), CounterClockwise), - ("Iapyx", int2(4, 2), Clockwise), - ("not if i see you first", int2(3, 10), None), - ("PotaT+-", int2(1, 5), None), - ("Fire Control Array", int2(2, 5), None), - ("Store-All Plus", int2(2, 8), None)); + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Compact Reactor", int2(2, 4), None), + ("Guided Missile Launcher", int2(0, 5), None), + ("Guided Missile Launcher", int2(5, 5), None), + ("Cell Blaster", int2(1, 8), None), + ("Cell Blaster", int2(4, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Capacitor", int2(1, 5), None), + ("Fire Control Array", int2(1, 6), Clockwise), + ("Cargo Bay", int2(2, 8), None)); stage.Player(fighter, float2(0, 0)); var rival = stage.Place(fighter, float2(0, 900), facing: float2(0, -1), stance: ScenarioStance.Hostile, piloted: true); - stage.Cargo(rival, "Spectra"); + stage.Cargo(rival, "Light Laser"); } } diff --git a/Assets/Scripts/ServerShared/Scenarios/FusedRounds.cs b/Assets/Scripts/ServerShared/Scenarios/FusedRounds.cs new file mode 100644 index 000000000..ca9011bee --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/FusedRounds.cs @@ -0,0 +1,51 @@ +using static CultMath.math; +using static ItemRotation; + +public sealed class FusedRounds : Scenario +{ + public override string Name => "Fused Rounds"; + public override string Brief => "The Smoke Test Hull with Smoke Proximity, Smoke Delayed and a Cluster Cannon; a hostile bare Longinus at mid range, a bare " + + "hull dead ahead, a fragile one to starboard, a close one inside the proximity blast radius, and one astern. " + + "Verify with nothing selected: aim past every hull and the round bursts at max range along the aim; aim at the hull " + + "ahead and it stops and bursts on it; fire the Cluster Cannon at the fragile hull and, once it is hurt, a Smoke " + + "Proximity round at it: the hull dies before the round lands, no burst. Select the astern hull: the round fires and bursts at its range along the arc edge. Select the " + + "close hull: the burst is pushed out to the blast radius from your centre. A Smoke Proximity burst beside the " + + "Longinus damages where the model shows the blast; a Smoke Delayed round into its nose bursts inside. The HUD " + + "reads Direct, Burst at N m or Refused for the fused weapons and a percentage for the Cluster Cannon, and the " + + "smoke weapons show no Manufacturer row."; + public override uint Seed => 108; + public override bool Ambient => false; + + // Where everything sits: the player is at the origin facing +z. Ahead lies on the initial aim line, inside every forward + // mount's arc. Fragile is a bare Longinus inside the Cluster Cannon's effective range (full damage; the scenario test reads the bound from the weapon); Close is inside Smoke Proximity's blast radius + // (8 m from the ship's centre) and beside the aim line, not across it; Stern is outside every mount's arc. + public static readonly CultMath.float2 Mid = float2(-200, 600), Ahead = float2(0, 300), Fragile = float2(80, 240), + Close = float2(6.4f, 4f), Stern = float2(0, -400); + + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast); + + public override void Stage(ScenarioStage stage) + { + var shooter = stage.Fit("Smoke Test Hull", + ("Cockpit 2x2", int2(4, 6), None), + ("Large Drive", int2(3, 0), Reversed), + ("Large Drive", int2(5, 0), Reversed), + ("Rugged Drive", int2(4, 14), CounterClockwise), + ("Rugged Drive", int2(5, 14), Clockwise), + ("Compact Reactor", int2(4, 4), None), + ("Smoke Proximity", int2(3, 8), None), + ("Smoke Delayed", int2(6, 8), None), + ("Cluster Cannon", int2(5, 17), None), + ("Radiator", int2(4, 2), CounterClockwise), + ("Radiator", int2(5, 2), Clockwise), + ("Compact Sensor", int2(5, 10), None), + ("Fire Control Array", int2(3, 6), Clockwise)); + + stage.Player(shooter, float2(0, 0), facing: float2(0, 1)); + stage.Place(stage.Bare("Longinus"), Mid, stance: ScenarioStance.Hostile); + stage.Place(stage.Bare("Longinus"), Ahead); + stage.Place(stage.Bare("Longinus"), Fragile); + stage.Place(stage.Bare("Longinus"), Close); + stage.Place(stage.Bare("Longinus"), Stern); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/FusedRounds.cs.meta b/Assets/Scripts/ServerShared/Scenarios/FusedRounds.cs.meta new file mode 100644 index 000000000..0e96bab70 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/FusedRounds.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4afe22415e8546849f2366c39a40fd8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Scenarios/LauncherAngles.cs b/Assets/Scripts/ServerShared/Scenarios/LauncherAngles.cs index a734be6e1..7c5fc669c 100644 --- a/Assets/Scripts/ServerShared/Scenarios/LauncherAngles.cs +++ b/Assets/Scripts/ServerShared/Scenarios/LauncherAngles.cs @@ -4,8 +4,8 @@ using static ItemRotation; public sealed class LauncherAngles : Scenario { public override string Name => "Launcher Angles"; - public override string Brief => "A GT 3K, a pswarm and two FastBlasts; a hostile LonginusX broadside on, a bare Longinus beside it. " + - "Verify: hits pulse only the facing edge; a pswarm round whose target dies fades unexploded."; + public override string Brief => "A Guided Missile Launcher, a Swarm Rocket Pod and two Cell Blasters; a hostile bare Longinus broadside on, another beside it. " + + "Verify: hits pulse only the facing edge; a Swarm Rocket Pod round whose target dies fades unexploded."; public override uint Seed => 105; public override bool Ambient => false; @@ -13,21 +13,24 @@ public sealed class LauncherAngles : Scenario public override void Stage(ScenarioStage stage) { - var launcher = stage.Fit("LonginusX", + var launcher = stage.Fit("Longinus", ("Cockpit 2x2", int2(2, 6), None), - ("Traction", int2(2, 3), None), - ("Core Power", int2(2, 1), None), - ("GT 3K", int2(0, 5), None), - ("pswarm", int2(5, 5), None), - ("FastBlast+-", int2(1, 8), None), - ("FastBlast+-", int2(4, 8), None), - ("Iapyx", int2(1, 2), CounterClockwise), - ("Iapyx", int2(4, 2), Clockwise), - ("not if i see you first", int2(3, 10), None), - ("Fire Control Array", int2(2, 5), None)); + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Compact Reactor", int2(2, 4), None), + ("Guided Missile Launcher", int2(0, 5), None), + ("Swarm Rocket Pod", int2(5, 5), None), + ("Cell Blaster", int2(1, 8), None), + ("Cell Blaster", int2(4, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Fire Control Array", int2(1, 6), Clockwise)); stage.Player(launcher, float2(0, 0)); - stage.Place(stage.Bare("LonginusX"), float2(0, 900), facing: float2(1, 0), stance: ScenarioStance.Hostile); + stage.Place(stage.Bare("Longinus"), float2(0, 900), facing: float2(1, 0), stance: ScenarioStance.Hostile); stage.Place(stage.Bare("Longinus"), float2(300, 700)); } } diff --git a/Assets/Scripts/ServerShared/Scenarios/LockOn.cs b/Assets/Scripts/ServerShared/Scenarios/LockOn.cs new file mode 100644 index 000000000..87e5de829 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/LockOn.cs @@ -0,0 +1,46 @@ +using static CultMath.math; +using static ItemRotation; + +public sealed class LockOn : Scenario +{ + public override string Name => "Lock On"; + public override string Brief => "A hostile closes from out of sight, finds you and locks. Verify: no warning at first; once it locks, one " + + "indicator appears toward it and tightens as the lock grows; break line of sight or range and it vanishes; " + + "your own ping shows no incoming paint on its side, only the lock does."; + public override uint Seed => 113; + public override bool Ambient => false; + + // The hostile starts about 4000 m off, ahead and to port of the player, facing the player. At that range its passive + // sensors hold no track of the player (the test asks the sim's own PassiveInfo against the detection threshold). The + // hostile closes, sees the player some fourteen seconds in and locks. The zone's pull bends the hostile's run and moves the + // player, and the warning must still point at where the hostile was staged to within 5 degrees at the lock: this side keeps + // the bend under one degree (on the far side it is more than seven). At Duel's 900 m (and at 600 m) it sees and locks + // within a second. + public static readonly CultMath.float2 HostileAt = float2(-2000, 3450); + + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast); + + public override void Stage(ScenarioStage stage) + { + var fighter = stage.Fit("Longinus", + ("Cockpit 2x2", int2(2, 6), None), + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Compact Reactor", int2(2, 4), None), + ("Guided Missile Launcher", int2(0, 5), None), + ("Guided Missile Launcher", int2(5, 5), None), + ("Cell Blaster", int2(1, 8), None), + ("Cell Blaster", int2(4, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Capacitor", int2(1, 5), None), + ("Fire Control Array", int2(1, 6), Clockwise), + ("Cargo Bay", int2(2, 8), None)); + + stage.Player(fighter, float2(0, 0), facing: float2(0, 1)); + stage.Place(fighter, HostileAt, facing: normalize(-HostileAt), stance: ScenarioStance.Hostile, piloted: true); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/LockOn.cs.meta b/Assets/Scripts/ServerShared/Scenarios/LockOn.cs.meta new file mode 100644 index 000000000..1512201c0 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/LockOn.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f0b6d2a9c7e4a1b8d5e2c6f7a9b0c14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Scenarios/Pursuit.cs b/Assets/Scripts/ServerShared/Scenarios/Pursuit.cs new file mode 100644 index 000000000..75a803b18 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/Pursuit.cs @@ -0,0 +1,60 @@ +using static CultMath.math; +using static ItemRotation; + +public sealed class Pursuit : Scenario +{ + // The pursuer starts astern, inside the 400 at which VapourCloudTests.ACloudBreaksALockAtRange shows a fresh vent + // cloud breaking a sensor's lock, and well outside the 40 at which AStrongCloseSensorBurnsThrough shows a close + // sensor burning through. + private const float Astern = 300; + + public override string Name => "Pursuit"; + public override string Brief => "A hostile Longinus on your tail; a Mine Launcher fitted, three Coolant Vents and two Thruster " + + "Overdrives aboard. Verify: lay mines in its path, the mine pulses slowly after 2 s, fast when " + + "the hostile is near, explodes 2 s later; vent and coast to lose it; overdrive away."; + public override uint Seed => 111; + public override bool Ambient => false; + + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast); + + public override void Stage(ScenarioStage stage) + { + var layer = stage.Fit("Longinus", + ("Cockpit 2x2", int2(2, 6), None), + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Compact Reactor", int2(2, 4), None), + ("Mine Launcher", int2(0, 5), None), + ("Swarm Rocket Pod", int2(5, 5), None), + ("Cell Blaster", int2(1, 8), None), + ("Cell Blaster", int2(4, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Fire Control Array", int2(1, 6), Clockwise), + ("Cargo Bay", int2(2, 8), None)); + var pursuer = stage.Fit("Longinus", + ("Cockpit 2x2", int2(2, 6), None), + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Compact Reactor", int2(2, 4), None), + ("Guided Missile Launcher", int2(0, 5), None), + ("Guided Missile Launcher", int2(5, 5), None), + ("Cell Blaster", int2(1, 8), None), + ("Cell Blaster", int2(4, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Capacitor", int2(1, 5), None), + ("Fire Control Array", int2(1, 6), Clockwise), + ("Cargo Bay", int2(2, 8), None)); + + var player = stage.Player(layer, float2(0, 0), facing: float2(0, 1)); + stage.Cargo(player, "Coolant Vent", "Coolant Vent", "Coolant Vent", "Thruster Overdrive", "Thruster Overdrive"); + stage.Place(pursuer, float2(0, -Astern), facing: float2(0, 1), stance: ScenarioStance.Hostile, piloted: true); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/Pursuit.cs.meta b/Assets/Scripts/ServerShared/Scenarios/Pursuit.cs.meta new file mode 100644 index 000000000..375cb139b --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/Pursuit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b0587057e6a4618bf63944364298870 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Scenarios/RefusedRounds.cs b/Assets/Scripts/ServerShared/Scenarios/RefusedRounds.cs new file mode 100644 index 000000000..557812197 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/RefusedRounds.cs @@ -0,0 +1,40 @@ +using static CultMath.math; +using static ItemRotation; + +public sealed class RefusedRounds : Scenario +{ + public override string Name => "Refused Rounds"; + public override string Brief => "The Smoke Test Hull with Smoke Refused, Smoke Refused Beam, Smoke Refused Charge and an Autocannon; a bare Longinus " + + "dead ahead. Each smoke weapon's blast radius is wider than its range, so it can never be fired. Verify: pull each " + + "trigger and a refused shot costs no ammo, energy, heat, sound, visibility or cooldown, the beam never starts and " + + "the charged weapon never starts charging; the Autocannon fires normally."; + public override uint Seed => 109; + public override bool Ambient => false; + + // The one target, ahead of the nose: inside every forward mount's arc. + public static readonly CultMath.float2 Target = float2(0, 300); + + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast); + + public override void Stage(ScenarioStage stage) + { + var shooter = stage.Fit("Smoke Test Hull", + ("Cockpit 2x2", int2(4, 6), None), + ("Large Drive", int2(3, 0), Reversed), + ("Large Drive", int2(5, 0), Reversed), + ("Rugged Drive", int2(4, 14), CounterClockwise), + ("Rugged Drive", int2(5, 14), Clockwise), + ("Compact Reactor", int2(4, 4), None), + ("Smoke Refused", int2(3, 8), None), + ("Smoke Refused Beam", int2(6, 8), None), + ("Smoke Refused Charge", int2(3, 17), None), + ("Autocannon", int2(5, 17), None), + ("Radiator", int2(4, 2), CounterClockwise), + ("Radiator", int2(5, 2), Clockwise), + ("Compact Sensor", int2(5, 10), None), + ("Fire Control Array", int2(3, 6), Clockwise)); + + stage.Player(shooter, float2(0, 0), facing: float2(0, 1)); + stage.Place(stage.Bare("Longinus"), Target); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/RefusedRounds.cs.meta b/Assets/Scripts/ServerShared/Scenarios/RefusedRounds.cs.meta new file mode 100644 index 000000000..45c0cde82 --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/RefusedRounds.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c72528ae3b7144989483462543f2de88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Scenarios/Scenarios.cs b/Assets/Scripts/ServerShared/Scenarios/Scenarios.cs index 31890d789..752b33e28 100644 --- a/Assets/Scripts/ServerShared/Scenarios/Scenarios.cs +++ b/Assets/Scripts/ServerShared/Scenarios/Scenarios.cs @@ -1,11 +1,14 @@ -// Every way to set up a new run, in the order New Game lists them. Modes are the game; Tests are arenas built to check -// one system each, listed only in editor and development builds. +// Every way to set up a new run, in the order New Game lists them. Modes are what a release build lists; Development +// are the other ways the game sets up a run and Tests are arenas built to check one system each, both listed only in +// editor and development builds. public static class Scenarios { - public static readonly Scenario[] Modes = { new TutorialGalaxy(), new MainGalaxy() }; + public static readonly Scenario[] Modes = { new DemoTerminus() }; + + public static readonly Scenario[] Development = { new TutorialGalaxy(), new MainGalaxy() }; public static readonly Scenario[] Tests = { - new DjinniShakedown(), new StarvedReactor(), new Arcs(), new Duel(), new LauncherAngles(), new LongHaul() + new DjinniShakedown(), new StarvedReactor(), new Arcs(), new Duel(), new LauncherAngles(), new WeaponFeel(), new FusedRounds(), new RefusedRounds(), new AiFusedDiscipline(), new LongHaul(), new Pursuit(), new Crossing(), new Belt(), new LockOn() }; } diff --git a/Assets/Scripts/ServerShared/Scenarios/StarvedReactor.cs b/Assets/Scripts/ServerShared/Scenarios/StarvedReactor.cs index ccbf9baa8..3a23b164a 100644 --- a/Assets/Scripts/ServerShared/Scenarios/StarvedReactor.cs +++ b/Assets/Scripts/ServerShared/Scenarios/StarvedReactor.cs @@ -4,7 +4,7 @@ using static ItemRotation; public sealed class StarvedReactor : Scenario { public override string Name => "Starved Reactor"; - public override string Brief => "Two Spectras on a MoveOnPro, which can fall to a quarter of Core Power's charge, and a bare hull " + + public override string Brief => "Two Light Lasers on a Muon Fusion Reactor, which can fall to a quarter of the Compact Reactor's charge, and a bare hull " + "to shoot. Verify: starvation reads as starvation, brownout degrades, refills stutter."; public override uint Seed => 102; public override bool Ambient => false; @@ -13,17 +13,20 @@ public sealed class StarvedReactor : Scenario public override void Stage(ScenarioStage stage) { - var starved = stage.Fit("LonginusX", + var starved = stage.Fit("Longinus", ("Cockpit 2x2", int2(2, 6), None), - ("Traction", int2(2, 3), None), - ("MoveOnPro", int2(2, 1), None), - ("Spectra", int2(1, 8), None), - ("Spectra", int2(4, 8), None), - ("Iapyx", int2(1, 2), CounterClockwise), - ("Iapyx", int2(4, 2), Clockwise), - ("not if i see you first", int2(3, 10), None), - ("Fire Control Array", int2(2, 5), None)); + ("Large Drive", int2(1, 0), Reversed), + ("Large Drive", int2(3, 0), Reversed), + ("Rugged Drive", int2(2, 14), CounterClockwise), + ("Rugged Drive", int2(3, 14), Clockwise), + ("Muon Fusion Reactor", int2(2, 4), None), + ("Light Laser", int2(1, 8), None), + ("Light Laser", int2(4, 8), None), + ("Radiator", int2(2, 2), CounterClockwise), + ("Radiator", int2(3, 2), Clockwise), + ("Compact Sensor", int2(3, 10), None), + ("Fire Control Array", int2(1, 6), Clockwise)); stage.Player(starved, float2(0, 0)); - stage.Place(stage.Bare("LonginusX"), float2(0, 400)); + stage.Place(stage.Bare("Longinus"), float2(0, 400)); } } diff --git a/Assets/Scripts/ServerShared/Scenarios/WeaponFeel.cs b/Assets/Scripts/ServerShared/Scenarios/WeaponFeel.cs new file mode 100644 index 000000000..43d4097ae --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/WeaponFeel.cs @@ -0,0 +1,38 @@ +using static CultMath.math; +using static ItemRotation; + +public sealed class WeaponFeel : Scenario +{ + public override string Name => "Weapon Feel"; + public override string Brief => "The Smoke Test Hull with a Charged Scatter Blaster, an Autocannon and a Cell Blaster burst weapon; a bare Longinus dead ahead. " + + "Verify: Charged Scatter Blaster and Autocannon fire with effects, particles and action-bar icons; the burst weapon's " + + "cadence is as before; a fast release-and-press on the Charged Scatter Blaster starts no second charge."; + public override uint Seed => 107; + public override bool Ambient => false; + + // The one target, ahead of the nose: inside every forward mount's arc. + public static readonly CultMath.float2 Target = float2(0, 400); + + public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast); + + public override void Stage(ScenarioStage stage) + { + var shooter = stage.Fit("Smoke Test Hull", + ("Cockpit 2x2", int2(4, 6), None), + ("Large Drive", int2(3, 0), Reversed), + ("Large Drive", int2(5, 0), Reversed), + ("Rugged Drive", int2(4, 14), CounterClockwise), + ("Rugged Drive", int2(5, 14), Clockwise), + ("Compact Reactor", int2(4, 4), None), + ("Charged Scatter Blaster", int2(3, 17), None), + ("Autocannon", int2(5, 17), None), + ("Cell Blaster", int2(3, 8), None), + ("Radiator", int2(4, 2), CounterClockwise), + ("Radiator", int2(5, 2), Clockwise), + ("Compact Sensor", int2(5, 10), None), + ("Fire Control Array", int2(3, 6), Clockwise)); + + stage.Player(shooter, float2(0, 0), facing: float2(0, 1)); + stage.Place(stage.Bare("Longinus"), Target); + } +} diff --git a/Assets/Scripts/ServerShared/Scenarios/WeaponFeel.cs.meta b/Assets/Scripts/ServerShared/Scenarios/WeaponFeel.cs.meta new file mode 100644 index 000000000..6ea88923e --- /dev/null +++ b/Assets/Scripts/ServerShared/Scenarios/WeaponFeel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 74c554ab5a6a4ac5ad0334a29135dc7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Sensing.cs b/Assets/Scripts/ServerShared/Sensing.cs new file mode 100644 index 000000000..3a678fde9 --- /dev/null +++ b/Assets/Scripts/ServerShared/Sensing.cs @@ -0,0 +1,224 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System.Linq; +using CultMath; + +// Light signatures split by channel (ruling visibility-per-capability-reveal): an observer learns what a ship +// is by which channel carries the light. Append-only: values are serialized in VisibilityData. +public enum SignatureChannel +{ + Thermal, + Reflection, + DrivePlume, + LaunchFlash, + Emission +} + +public readonly struct Signature +{ + public readonly SignatureChannel Channel; + public readonly float Strength; + public readonly EquippedItem Item; + // The class this act claims: the true item's Data unless its ship's EW claims otherwise (aetheria-ew, + // classify-from-belief). Stamped by Entity.SetSignature from the ship's claim. + public readonly EquippableItemData Claimed; + + public Signature(SignatureChannel channel, float strength, EquippedItem item, EquippableItemData claimed) + { + Channel = channel; + Strength = strength; + Item = item; + Claimed = claimed; + } + + public Signature WithStrength(float strength) => new Signature(Channel, strength, Item, Claimed); +} + +// What a painted ship learns of a beam on it (ruling sensor-stat-set item 4): a Search paint is a ping sweeping +// it (Strength 0); a Track paint is a lock (Strength is the emitter's own lock progress, 0..1, ruling +// lock-warning-strength). A Scan paint is a held scanner: Strength is its scan progress 0..1 (ruling scan-is-an-act). +// Never summed. +public enum PaintMode +{ + Search, + Track, + Scan +} + +// An ally's ping crossed `Subject` at `IlluminatedRange` through `IlluminatedObscuration`; `MaxRange` is that +// sensor's PingRange. Posted on the crossing tick and read for one tick by the receiving ship's own sensors. +public readonly struct PingReturn +{ + public readonly Entity Subject; + public readonly float IlluminatedRange; + public readonly float IlluminatedObscuration; + public readonly float MaxRange; + + public PingReturn(Entity subject, float illuminatedRange, float illuminatedObscuration, float maxRange) + { + Subject = subject; + IlluminatedRange = illuminatedRange; + IlluminatedObscuration = illuminatedObscuration; + MaxRange = maxRange; + } +} + +// An item's emission this tick, heard by another ship's Sense within `HearRange` x its HearingMultiple x obscuration; +// it decides nothing by itself. +public readonly struct ActiveEmission +{ + public readonly EquippedItem Item; + public readonly float HearRange; + // The class this emission claims (see Signature.Claimed); stamped by Entity.Emit. + public readonly EquippableItemData Claimed; + + public ActiveEmission(EquippedItem item, float hearRange, EquippableItemData claimed) + { + Item = item; + HearRange = hearRange; + Claimed = claimed; + } +} + +public readonly struct PaintWarning +{ + public readonly float2 Bearing; + public readonly EquippableItemData EmitterClass; + public readonly PaintMode Mode; + public readonly float Strength; + + public PaintWarning(float2 bearing, EquippableItemData emitterClass, PaintMode mode, float strength) + { + Bearing = bearing; + EmitterClass = emitterClass; + Mode = mode; + Strength = strength; + } +} + +// What an observer has seen `Item` do (ruling visibility-per-capability-reveal): the channel it showed on, the +// bearing at that act and the zone clock then. Held per (subject, item) in the observer's Entity; the latest act +// replaces the earlier one. Position is never carried: only the track gives it. `Item` stays the true item: it is the +// book's key and what aim reads. `Claimed` is the class the act claimed, and is what every classifying reader reads +// (aetheria-ew, classify-from-belief). A null `Channel` is a reveal by the observer's own scan (Entity.RecordInspection), +// whose `Claimed` is the subject's claim for the item. +public readonly struct Reveal +{ + public readonly EquippedItem Item; + public readonly EquippableItemData Claimed; + public readonly SignatureChannel? Channel; + public readonly float2 Bearing; + public readonly float Time; + + public Reveal(EquippedItem item, SignatureChannel? channel, float2 bearing, float time, EquippableItemData claimed) + { + Item = item; + Claimed = claimed; + Channel = channel; + Bearing = bearing; + Time = time; + } +} + +// What an observer aims at on its target (Entity.AimedAt): exactly one of a revealed item or a mount of the hull the observer +// believes the target to be (Entity.LayoutOf), or nothing. A mount is a believed position, never the true item on it. +public readonly struct AimTarget +{ + public readonly EquippedItem Item; + public readonly HardpointData Mount; + + private AimTarget(EquippedItem item, HardpointData mount) + { + Item = item; + Mount = mount; + } + + public static AimTarget None => default; + public static AimTarget OfItem(EquippedItem item) => new AimTarget(item, null); + public static AimTarget OfMount(HardpointData mount) => new AimTarget(null, mount); +} + +// One weapon or gear row of a ship's schematic as its viewer is entitled to read it (aetheria-ew, classify-from-belief; ruling +// ew-claim-weapon-measure-ruled). Made only by Entity.SchematicRows. `Item` is the true item: the selection mark's key and, +// on the viewer's own ship, the live gear. `Claimed` is the class the row shows. The range label is the live range on +// the viewer's own ship and the claimed design's rated range on any other; a row whose claimed class is not a weapon has +// no range. The viewer never sees a target item's quality, wear or power. A renderer shows these and decides nothing. +// A mount row (`Mount` set, `Item` and `Claimed` null) is a hardpoint of the hull the viewer believes the ship to be, with +// nothing of the ship's claimed on it: where something is, not what. +public readonly struct SchematicRow +{ + public readonly EquippedItem Item; + public readonly EquippableItemData Claimed; + public readonly HardpointData Mount; + private readonly bool _own; + + internal SchematicRow(EquippedItem item, EquippableItemData claimed, bool own) + { + Item = item; + Claimed = claimed; + Mount = null; + _own = own; + } + + internal SchematicRow(HardpointData mount) : this() + { + Mount = mount; + } + + // What a renderer compares to know the rows changed. Range is a reading, not part of the key. + public (EquippedItem, EquippableItemData, HardpointData) Key => (Item, Claimed, Mount); + + // Whether this row is the one `aim` points at: a claimed-item row by its item, a mount row by its mount. + public bool Marks(AimTarget aim) => Item != null ? aim.Item == Item : aim.Mount != null && aim.Mount == Mount; + + public float? Range => _own + ? Item.Behaviors.OfType().First().Range + : Claimed?.Behaviors.OfType().FirstOrDefault()?.RatedRange; +} + +// A subject's removal from a zone as the zone recorded it (death, dock, warp, any removal): where it was and how +// bright its light was (its Visibility at removal). Judged by each observer's Sense under the +// light-act gate; notification only, one tick long, it decides nothing. +public readonly struct Departure +{ + public readonly Entity Subject; + public readonly float2 Position; + public readonly float Signature; + + public Departure(Entity subject, float2 position, float signature) + { + Subject = subject; + Position = position; + Signature = signature; + } +} + +// How much an observer holds of one subject, derived on read by Entity.ContactOf from its track, its reveals and +// the zone clock. Detected: tracked, or a reveal younger than GameplaySettings.BearingMemory. Tracked: exactly +// membership of VisibleEntities. Classified: detected, with any reveal in the book. Identified: the track has reached +// TargetGearInfoThreshold, and holds a hull belief: Profile, the hull class this observer believes the subject is (null +// below Identified; aetheria-ew, classify-from-belief; seen-through arrives with the judge). Bearing is the true +// bearing while tracked, else the freshest reveal's. +public readonly struct Contact +{ + public readonly bool Detected; + public readonly bool Tracked; + public readonly bool Classified; + public readonly bool Identified; + public readonly float2 Bearing; + public readonly float Info; + public readonly HullData Profile; + + public Contact(bool detected, bool tracked, bool classified, bool identified, float2 bearing, float info, HullData profile) + { + Profile = profile; + Detected = detected; + Tracked = tracked; + Classified = classified; + Identified = identified; + Bearing = bearing; + Info = info; + } +} diff --git a/Assets/Scripts/ServerShared/Sensing.cs.meta b/Assets/Scripts/ServerShared/Sensing.cs.meta new file mode 100644 index 000000000..0cffdf792 --- /dev/null +++ b/Assets/Scripts/ServerShared/Sensing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3c91e5d7b2f4086b1d4e9f07c6a2358 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Settings.cs b/Assets/Scripts/ServerShared/Settings.cs index 9ab2928fd..cda5e1623 100644 --- a/Assets/Scripts/ServerShared/Settings.cs +++ b/Assets/Scripts/ServerShared/Settings.cs @@ -13,25 +13,27 @@ using static CultMath.math; [Serializable, MessagePackObject(keyAsPropertyName:true), JsonObject] public class PlanetSettings { - public float ZoneDepthExponent; - public float ZoneDepth; - public float ZoneBoundaryFog; - public ExponentialCurve GravityDepth; - public ExponentialCurve GravityRadius; - public ExponentialCurve WaveDepth; - public ExponentialCurve WaveRadius; - public ExponentialCurve WaveFrequency; - public ExponentialCurve WaveSpeed; public ExponentialCurve LightRadius; public ExponentialCurve BodyRadius; + + // The closest a child may orbit its parent, in u, by the parent's mass, and the softened core radius of the parent's + // well (the steepest drawn slope sits at the Roche limit). Authored like BodyRadius, never per body. + public ExponentialCurve RocheLimit = new ExponentialCurve(); + + // A body's well strength by its mass (GravityField): c in u^2/s^2 (the pull is c / r beyond the core, which is the Roche limit). + public ExponentialCurve WellStrength = new ExponentialCurve(); + + // The one global exaggeration of gravity height: height = potential / K, in u/s^2 per unit of height. + public float HeightExaggeration = 1f; public float AsteroidVerticalOffset = -5f; public ExponentialLerp AsteroidSize; public ExponentialLerp AsteroidHitpoints; public ExponentialLerp AsteroidRespawnTime; - public float GravityStrength; public float SecureAreaRadiusMultiplier = .45f; - public ExponentialCurve OrbitPeriod; + + // The global flow stardust and nebula follow and the sim knows (FlowField). Zero flow by default. + public FlowSettings Flow = new FlowSettings(); } [Serializable, MessagePackObject(keyAsPropertyName:true), JsonObject] @@ -178,6 +180,11 @@ public class GameplaySettings public float FloatingBodyDrag = .05f; public float FloatingBodyLaunchDrag = .2f; public float FloatingBodyGravity = 1f; + // Loot: the chance each equipped item (the hull excepted) drops when its carrier dies, the launch speed of a + // dropped item, and how many seconds a floating item lasts. + public float LootDropProbability = .25f; + public float LootDropVelocity = 25f; + public float FloatingItemLifetime = 30f; public float SevereHeatstrokeRiskThreshold = .25f; public float WormholeDepth = 1000; public float WormholeExitVelocity = 20; @@ -211,14 +218,13 @@ public class GameplaySettings public float LockIndicatorNoiseAmplitude = 50f; public ExponentialLerp LockIndicatorFrequency; public ExponentialLerp LockSpinSpeed; - public float TorqueFloor; public float TorqueMultiplier; - public float AetherTorqueMultiplier; - public float AetherHeatMultiplier; public float VisibilityDecay; + // Seconds a reveal's bearing keeps a ship Detected after its last act with no track (Entity.ContactOf). + public float BearingMemory = 6; public float TargetInfoDecay; public float TargetDetectionInfoThreshold; - public float TargetArmorInfoThreshold; + // Also the Identified threshold: the track level at which a ship's hull class, and with it its layout, is known. public float TargetGearInfoThreshold; public float ConvergenceMinimumDistance; public float FiringArc = 120; @@ -240,7 +246,7 @@ public class GameplaySettings // UnaidedTracking above -- FireControl.Precision falls back to this the same way it already falls back to // UnaidedAccuracy/UnaidedTracking. Precision is now a grouping tightness (FireControl.Sigma = 1/Precision, // in hull-schematic cell units), not the old coin-flip probability, so the unaided floor has to be - // authored on that scale. .3 -> sigma 3.33 cells: against the live catalog's own hulls (LonginusX 6x17, + // authored on that scale. .3 -> sigma 3.33 cells: against the live catalog's own hulls (Longinus 6x17, // Zenith 12x12, Turret 8x8) that puts pOnHull at the hull's own centre of mass around .5-.84 -- broadly // sprayed across the whole silhouette (sigma is a large fraction of the hull's own width) while still // landing on the ship more often than not. A tighter floor (e.g. .1, sigma 10) was tried first and @@ -268,6 +274,17 @@ public class GameplaySettings // (pSpread) to turn a hull's cell footprint into a real-world silhouette size at range. public float SchematicCellSize = 2f; + // Restitution of a hull striking a hull (Contacts.Step): the speed at which a pair separates along the contact + // normal is this times the speed at which it closed. 0 is perfectly inelastic, 1 perfectly elastic. + public float ContactRestitution = .5f; + + // Heights above the field of the ship plane, the orbital layer (stations, turrets: every OrbitalEntity) and the floater + // layer (loot, mines): orbitals above ships and floaters below them, so no ship ever touches either (ruling + // aetheria-gravity:orbitals-above-floaters-below). + public float ShipLayerHeight = 3f; + public float OrbitalLayerHeight = 15f; + public float FloaterLayerHeight = 0f; + // The floor an AI's own predicted hit probability (FireControl.HitProbability) must clear before it counts // a firing solution worth taking (Combat.cs, TurretController.cs). Player fire is gated on arc alone // (Weapon.ArcAllowsFire, Q2) -- this threshold is an AI fire-discipline heuristic, not part of the roll. diff --git a/Assets/Scripts/ServerShared/Ship.cs b/Assets/Scripts/ServerShared/Ship.cs index 1ec9fff27..4d621e2f9 100644 --- a/Assets/Scripts/ServerShared/Ship.cs +++ b/Assets/Scripts/ServerShared/Ship.cs @@ -9,7 +9,6 @@ using System.Linq; using System.Reflection; using MessagePack; using Newtonsoft.Json; -using UniRx; using CultMath; using static CultMath.math; using quaternion = CultMath.quaternion; @@ -17,6 +16,8 @@ using quaternion = CultMath.quaternion; [MessagePackObject] public class Ship : Entity { + public override float LayerHeight => ItemManager.GameplaySettings.ShipLayerHeight; + // [Key("bindings")] public Dictionary Bindings = new Dictionary(); //[IgnoreMember] public int HullHardpointCount; @@ -30,16 +31,11 @@ public class Ship : Entity public float Turn; public bool IsPlayerShip; - private HashSet _thrusterItems; private Thruster[] _allThrusters; - private HashSet _forwardThrusters; - private HashSet _reverseThrusters; - private HashSet _rightThrusters; - private HashSet _leftThrusters; - private HashSet _clockwiseThrusters; - private HashSet _counterClockwiseThrusters; - private HashSet _aetherDriveItems; - private HashSet _aetherDrives; + // One column per thruster (its effect per unit throttle, in the body frame) and the throttles the allocator answers with. + private float3[] _columns; + private float[] _throttles; + private readonly ThrustAllocator _allocator = new ThrustAllocator(); private bool _exitingWormhole = false; private bool _enteringWormhole = false; @@ -50,23 +46,6 @@ public class Ship : Entity private float2 _wormholeExitVelocity; public bool WormholeAnimationInProgress => _enteringWormhole || _exitingWormhole; - public float ForwardThrust { get; private set; } - public float ReverseThrust { get; private set; } - public float LeftStrafeThrust { get; private set; } - public float RightStrafeThrust { get; private set; } - public float ClockwiseTorque { get; private set; } - public float CounterClockwiseTorque { get; private set; } - public float LeftStrafeTotalTorque { get; private set; } - private List LeftStrafeTorqueThrusters = new List(); - public float RightStrafeTotalTorque { get; private set; } - private List RightStrafeTorqueThrusters = new List(); - - public float TurnTime(float2 direction) - { - var angleDiff = Direction.Angle(normalize(direction)); - var clockwise = dot(direction, Direction.Rotate(ItemRotation.Clockwise)) > 0; - return angleDiff / ((clockwise ? ClockwiseTorque : CounterClockwiseTorque) / Mass); - } public event Action OnExitedWormhole; public event Action OnEnteredWormhole; @@ -96,217 +75,65 @@ public class Ship : Entity { base.Activate(); - _aetherDrives = new HashSet(GetBehaviors()); - _aetherDriveItems = new HashSet(_aetherDrives.Select(x => x.Item)); - _allThrusters = GetBehaviors().ToArray(); - _thrusterItems = new HashSet(_allThrusters.Select(x=>x.Item)); - - _forwardThrusters = new HashSet(_allThrusters - .Where(x => x.Item.EquippableItem.Rotation == ItemRotation.Reversed)); - - _reverseThrusters = new HashSet(_allThrusters - .Where(x => x.Item.EquippableItem.Rotation == ItemRotation.None)); - - _rightThrusters = new HashSet(_allThrusters - .Where(x => x.Item.EquippableItem.Rotation == ItemRotation.CounterClockwise)); - - _leftThrusters = new HashSet(_allThrusters - .Where(x => x.Item.EquippableItem.Rotation == ItemRotation.Clockwise)); - - _counterClockwiseThrusters = new HashSet(_allThrusters - .Where(x => x.Torque < -ItemManager.GameplaySettings.TorqueFloor)); - - _clockwiseThrusters = new HashSet(_allThrusters - .Where(x => x.Torque > ItemManager.GameplaySettings.TorqueFloor)); + _columns = new float3[_allThrusters.Length]; + _throttles = new float[_allThrusters.Length]; } public Ship(ItemManager itemManager, Zone zone, EquippableItem hull, EntitySettings settings) : base(itemManager, zone, hull, settings) { - ItemDestroyed.Where(item=>_thrusterItems.Contains(item)).Subscribe(RemoveThruster); - ItemDestroyed.Where(item=>_aetherDriveItems.Contains(item)).Subscribe(RemoveAetherDrive); - } - - private void RemoveAetherDrive(EquippedItem item) - { - _aetherDriveItems.Remove(item); - _aetherDrives.Remove(item.GetBehavior()); - } - - private void RemoveThruster(EquippedItem item) - { - _thrusterItems.Remove(item); - var thruster = item.GetBehavior(); - if (_forwardThrusters.Contains(thruster)) _forwardThrusters.Remove(thruster); - if (_reverseThrusters.Contains(thruster)) _reverseThrusters.Remove(thruster); - if (_rightThrusters.Contains(thruster)) _rightThrusters.Remove(thruster); - if (_leftThrusters.Contains(thruster)) _leftThrusters.Remove(thruster); - if (_clockwiseThrusters.Contains(thruster)) _clockwiseThrusters.Remove(thruster); - if (_counterClockwiseThrusters.Contains(thruster)) _counterClockwiseThrusters.Remove(thruster); } #region ThrustCalculation - // What this ship can do at this instant (see ManoeuvreEnvelope): the sum of what each live propulsor reports with - // its own Execute arithmetic; thrusters are its only propulsors. Derived each update, never saved. The aggregates above are not an envelope (they - // mix units and cancel a lone off-axis strafer), so nothing in it reads them. + // What this ship can do at this instant (see ManoeuvreEnvelope): the box extremes of the thrusters' columns at their + // live thrust (zero when unpowered or not Active), because it reports what the ship can do now. The allocator solves + // with Column(NominalThrust), the full-grant column, because a column promises what a thruster does at a full grant + // and the allocator must not reshape its answer as the grant moves. Same geometry (Thruster.Column), different thrust. + // Derived each update, never saved. public ManoeuvreEnvelope Envelope { get; private set; } private void RecalculateEnvelope() { - var envelope = default(ManoeuvreEnvelope); - foreach (var thruster in _allThrusters) envelope += thruster.Manoeuvre(); - Envelope = envelope; - } - - private void RecalculateThrust() - { - RecalculateEnvelope(); - RecalculateForwardThrust(); - RecalculateReverseThrust(); - RecalculateLeftStrafeThrust(); - RecalculateRightStrafeThrust(); - RecalculateClockwiseTorque(); - RecalculateCounterClockwiseTorque(); - } - - private void RecalculateForwardThrust() - { - ForwardThrust = 0; - foreach (var thruster in _forwardThrusters) - if (thruster.Item.Active.Value) - ForwardThrust += thruster.Thrust; - - foreach (var drive in _aetherDrives) - if (drive.Item.Active.Value) - ForwardThrust += drive.Thrust.x; - } - - private void RecalculateReverseThrust() - { - ReverseThrust = 0; - foreach (var thruster in _reverseThrusters) - if (thruster.Item.Active.Value) - ReverseThrust += thruster.Thrust; - - foreach (var drive in _aetherDrives) - if (drive.Item.Active.Value) - ReverseThrust += drive.Thrust.x; - } - - private void RecalculateLeftStrafeThrust() - { - LeftStrafeThrust = 0; - LeftStrafeTotalTorque = 0; - foreach (var thruster in _leftThrusters) + float forward = 0, back = 0, left = 0, right = 0, clockwise = 0, counterClockwise = 0; + foreach (var thruster in _allThrusters) { - if(thruster.Item.Active.Value) - { - LeftStrafeThrust += thruster.Thrust; - LeftStrafeTotalTorque += thruster.Torque * thruster.Thrust; - } + var column = thruster.Column(thruster.Item != null && thruster.Item.PowerSupply > 1e-4f ? thruster.Thrust : 0f); + forward += max(column.y, 0f); + back += max(-column.y, 0f); + left += max(-column.x, 0f); + right += max(column.x, 0f); + clockwise += max(column.z, 0f); + counterClockwise += max(-column.z, 0f); } - LeftStrafeTorqueThrusters.Clear(); - foreach(var thruster in _leftThrusters) - if (abs(sign(thruster.Torque) - sign(LeftStrafeTotalTorque)) < .01f) - LeftStrafeTorqueThrusters.Add(thruster); - - foreach (var drive in _aetherDrives) - if (drive.Item.Active.Value) - LeftStrafeThrust += drive.Thrust.y; - } - - private void RecalculateRightStrafeThrust() - { - RightStrafeThrust = 0; - RightStrafeTotalTorque = 0; - foreach (var thruster in _rightThrusters) - { - if(thruster.Item.Active.Value) - { - RightStrafeThrust += thruster.Thrust; - RightStrafeTotalTorque += thruster.Torque * thruster.Thrust; - } - } - RightStrafeTorqueThrusters.Clear(); - foreach(var thruster in _rightThrusters) - if (abs(sign(thruster.Torque) - sign(RightStrafeTotalTorque)) < .01f) - RightStrafeTorqueThrusters.Add(thruster); - - foreach (var drive in _aetherDrives) - if (drive.Item.Active.Value) - RightStrafeThrust += drive.Thrust.y; - } - - private void RecalculateClockwiseTorque() - { - ClockwiseTorque = 0; - foreach (var thruster in _clockwiseThrusters) - if (thruster.Item.Active.Value) - ClockwiseTorque += thruster.Torque; - - foreach (var drive in _aetherDrives) - if (drive.Item.Active.Value) - ClockwiseTorque += drive.Thrust.z; - } - - private void RecalculateCounterClockwiseTorque() - { - CounterClockwiseTorque = 0; - foreach (var thruster in _counterClockwiseThrusters) - if (thruster.Item.Active.Value) - CounterClockwiseTorque -= thruster.Torque; - - foreach (var drive in _aetherDrives) - if (drive.Item.Active.Value) - CounterClockwiseTorque += drive.Thrust.z; + Envelope = new ManoeuvreEnvelope(forward, back, left, right, clockwise, counterClockwise); } #endregion + // Called by Entity.Update once the items' performance is current and before the power bus is stepped and the items + // execute: liveness, thrust and the throttles they decide are one phase, the one Execute acts on. The lock is a + // bound on the allocator's solve; intent reaches the allocator here and nowhere else. + protected override void UpdateThrottles() + { + if (_exitingWormhole || _enteringWormhole) return; + RecalculateEnvelope(); + for (var i = 0; i < _allThrusters.Length; i++) + _columns[i] = _allThrusters[i].Column(_allThrusters[i].NominalThrust); + _allocator.Allocate(_columns, MovementDirection, Turn, _throttles, ThrottleLocked); + for (var i = 0; i < _allThrusters.Length; i++) _allThrusters[i].Axis = _throttles[i]; + } + public override void Update(float delta) { - if (_active && !_exitingWormhole && !_enteringWormhole) - { - RecalculateThrust(); - foreach (var thruster in _allThrusters) thruster.Axis = 0; - var rightThrusterTorqueCompensation = abs(RightStrafeTotalTorque) / RightStrafeTorqueThrusters.Count; - foreach (var thruster in _rightThrusters) - { - var thrust = 0f; - thrust += MovementDirection.x; - if (RightStrafeTorqueThrusters.Contains(thruster)) - thrust -= MovementDirection.x * (rightThrusterTorqueCompensation / (abs(thruster.Torque) * thruster.Thrust)); - thruster.Axis = thrust; - } - var leftThrusterTorqueCompensation = abs(LeftStrafeTotalTorque) / LeftStrafeTorqueThrusters.Count; - foreach (var thruster in _leftThrusters) - { - var thrust = 0f; - thrust += -MovementDirection.x; - if (LeftStrafeTorqueThrusters.Contains(thruster)) - thrust += MovementDirection.x * (leftThrusterTorqueCompensation / (abs(thruster.Torque) * thruster.Thrust)); - thruster.Axis = thrust; - } - foreach (var thruster in _forwardThrusters) thruster.Axis += MovementDirection.y; - foreach (var thruster in _reverseThrusters) thruster.Axis += -MovementDirection.y; - - foreach (var thruster in _clockwiseThrusters) thruster.Axis += Turn; - foreach (var thruster in _counterClockwiseThrusters) thruster.Axis += -Turn; - - foreach (var drive in _aetherDrives) - drive.Axis = float3(MovementDirection.y, MovementDirection.x, Turn); - } - var velocityMagnitude = length(Velocity); if(velocityMagnitude > .01f) Velocity = normalize(Velocity) * decay(velocityMagnitude, HullData.Drag, delta); Position.xz += Velocity * delta; + Velocity += Zone.GetForce(Position.xz) * delta; var normal = Zone.GetNormal(Position.xz); - var force = new float2(normal.x, normal.z); - Velocity += Zone.GravityAcceleration(force, Zone.Settings.GravityStrength) * delta; var shipRight = Direction.Rotate(ItemRotation.Clockwise); var forward = cross(float3(shipRight.x, 0, shipRight.y), normal); Rotation = quaternion.LookRotation(forward, normal); diff --git a/Assets/Scripts/ServerShared/ShipAuthoring.cs b/Assets/Scripts/ServerShared/ShipAuthoring.cs index ec5f2a3c2..eafbacd2d 100644 --- a/Assets/Scripts/ServerShared/ShipAuthoring.cs +++ b/Assets/Scripts/ServerShared/ShipAuthoring.cs @@ -17,6 +17,22 @@ public sealed class ShipAuthoring [Key(2)] public string ModelAsset; [Key(3)] public List Anchors = new List(); [Key(4)] public List SchematicLines = new List(); + // The moving parts of the rig, presentation only (ruling rig-is-presentation): no joint value feeds the simulation. + [Key(5)] public List Joints = new List(); +} + +// A rig joint: a bone of the model's armature. Axes are three floats per degree of freedom, a unit vector in Ship Root +// space at rest (glTF axes, +Y up); Min and Max are that degree of freedom's limits in degrees. +[MessagePackObject] +public sealed class ShipJoint +{ + // The bone's aetheria.id, which is also its GLB node id. + [Key(0)] public string Id; + // The nearest joint above this one in the model, or null for a root joint. + [Key(1)] public string Parent; + [Key(2)] public float[] Axes; + [Key(3)] public float[] Min; + [Key(4)] public float[] Max; } [MessagePackObject] @@ -25,13 +41,15 @@ public sealed class ShipAnchor // Stable semantic identity. HullData.Hardpoints[].Transform names this ID for mounts. [Key(0)] public string Id; // One of: map-icon, hull-collider, shield, tractor, thruster-emitter, weapon-mount, - // weapon-muzzle, radiator-mesh, or articulation (a pivot, never a mount). + // weapon-muzzle, or radiator-mesh. [Key(1)] public string Role; // Stable node ID in the compiled model, never a Blender display name. [Key(2)] public string ModelNodeId; // Only child roles use ParentId; e.g. a muzzle names its weapon hardpoint. [Key(3)] public string ParentId; [Key(4)] public int Order; + // On a weapon-mount anchor: the id of the nearest joint above its node in the model; null or empty is a fixed mount. + [Key(5)] public string Joint; } // Evaluated or baked Grease Pencil stroke coordinates in Blender's right-handed Z-up @@ -53,8 +71,7 @@ public static class ShipAuthoringStore // ShipAnchor.Role's vocabulary. private static readonly HashSet Roles = new HashSet(StringComparer.Ordinal) { - "map-icon", "hull-collider", "shield", "tractor", "thruster-emitter", "weapon-mount", "weapon-muzzle", "radiator-mesh", - "articulation" + "map-icon", "hull-collider", "shield", "tractor", "thruster-emitter", "weapon-mount", "weapon-muzzle", "radiator-mesh" }; // The anchor role a visible hardpoint's mount plays, or null for an internal hardpoint, which has no anchor. @@ -71,7 +88,7 @@ public static class ShipAuthoringStore var cache = new CultCache(); try { - cache.AddBackingStore(new SingleFileMessagePackBackingStore(path, !writable), new[] { typeof(HullData), typeof(ShipAuthoring) }); + cache.AddBackingStore(new SingleFileMessagePackBackingStore(path, !writable), new[] { typeof(HullData), typeof(ShipAuthoring), typeof(FactionProductData) }); return cache; } catch @@ -88,6 +105,14 @@ public static class ShipAuthoringStore cache.UpsertAsync(typeof(ShipAuthoring), visual, ShipModCatalog.AuthoringKey(visual.Id)).GetAwaiter().GetResult(); } + // A package's product by one maker. These two are the only product writers; the key is the ship and the maker, so a + // maker has at most one product of the hull and writing again replaces it. + public static void WriteProduct(CultCache cache, string shipId, FactionProductData product) => + cache.UpsertAsync(typeof(FactionProductData), product, ShipModCatalog.ProductKey(shipId, product.Manufacturer.Key)).GetAwaiter().GetResult(); + + public static bool DeleteProduct(CultCache cache, string shipId, CultRecordKey maker) => + cache.Remove(ShipModCatalog.ProductKey(shipId, maker)); + // A new mod hull that flies like a shipped one. Every member of the reference is copied through the type's own // MessagePack round trip, so a member added to HullData later is copied too; then the six that are the shipped ship's // own body and layout are reset: Name, Shape (one occupied cell, so the record loads), Hardpoints, Prefab, Schematic, @@ -106,8 +131,8 @@ public static class ShipAuthoringStore } // The structure of a ship file, without judging its content (drafts load): exactly one hull and one visual, each at - // its deterministic key, the hull naming that visual by its typed ref. - public static (HullData Hull, ShipAuthoring Visual) Load(string path) + // its deterministic key, the hull naming that visual by its typed ref, and the hull's products, each at its maker's key. + public static (HullData Hull, ShipAuthoring Visual, FactionProductData[] Products) Load(string path) { RefuseLegacyEmbeddedHull(path); try { return LoadRecords(path); } @@ -150,7 +175,7 @@ public static class ShipAuthoringStore private const int RetiredHullKey = 1; - private static (HullData Hull, ShipAuthoring Visual) LoadRecords(string path) + private static (HullData Hull, ShipAuthoring Visual, FactionProductData[] Products) LoadRecords(string path) { using var cache = Open(path); var hulls = cache.GetAll().ToArray(); @@ -163,14 +188,44 @@ public static class ShipAuthoringStore if (!cache.TryGetHandle(hull).Value.Key.Equals(ShipModCatalog.HullKey(visual.Id)) || !cache.TryGetHandle(visual).Value.Key.Equals(ShipModCatalog.AuthoringKey(visual.Id))) throw new InvalidOperationException($"{path}: {visual.Id}: records must be stored under {ShipModCatalog.HullKey(visual.Id).Value} and {ShipModCatalog.AuthoringKey(visual.Id).Value}."); - return (hull, visual); + var products = cache.GetAll().ToArray(); + foreach (var product in products) + { + if (!product.Manufacturer.IsSet() || ShipModCatalog.IsModKey(product.Manufacturer.Key)) + throw new InvalidOperationException($"{path}: {visual.Id}: a product needs a manufacturer that is a shipped faction."); + var productKey = ShipModCatalog.ProductKey(visual.Id, product.Manufacturer.Key); + if (!cache.TryGetHandle(product).Value.Key.Equals(productKey)) + throw new InvalidOperationException($"{path}: {visual.Id}: a product must be stored at {productKey.Value}."); + if (!product.Design.IsSet() || !product.Design.Key.Equals(ShipModCatalog.HullKey(visual.Id))) + throw new InvalidOperationException($"{path}: {visual.Id}: a product must name the package hull {ShipModCatalog.HullKey(visual.Id).Value} as its design."); + } + return (hull, visual, products); } - public static (HullData Hull, ShipAuthoring Visual) Read(string path) + public static (HullData Hull, ShipAuthoring Visual, FactionProductData[] Products) Read(string path) + { + var (hull, visual, products) = Load(path); + ValidateLoaded(hull, visual, products); + return (hull, visual, products); + } + + // Every judgement a loaded package's records face, in one place: Read, and validate on a draft with no model yet, call it. + public static void ValidateLoaded(HullData hull, ShipAuthoring visual, FactionProductData[] products) { - var (hull, visual) = Load(path); Validate(hull, visual); - return (hull, visual); + ValidateProducts(hull, visual, products); + } + + // What a package may sell: every product named, no name twice, and a price above 0, because generation skips price 0. + private static void ValidateProducts(HullData hull, ShipAuthoring visual, FactionProductData[] products) + { + if (products.Length == 0) return; + if (products.Any(product => string.IsNullOrWhiteSpace(product.Name))) + throw new InvalidOperationException($"{visual.Id}: every product needs a name."); + if (products.Select(product => product.Name).Distinct(StringComparer.Ordinal).Count() != products.Length) + throw new InvalidOperationException($"{visual.Id}: product names must be unique within the package."); + if (hull.Price <= 0) + throw new InvalidOperationException($"{visual.Id}: a hull with products needs a price above 0 (generation skips price 0)."); } // A hull names one body: a Unity prefab (shipped hulls) or a ShipAuthoring record (mod ships), never both, so no @@ -182,19 +237,33 @@ public static class ShipAuthoringStore throw new InvalidOperationException($"{label}: a hull names one body, but this one names both a Unity prefab and a visual record."); } + // The one ship-ID rule, shared by Validate and ship-authoring create. The ID becomes a folder name on every platform, so + // Windows device names (alone or before a dot) and a trailing dot are refused too. The messages name the rule, never the value. + public static void RequireShipId(string id) + { + if (string.IsNullOrWhiteSpace(id)) throw new InvalidOperationException("Ship ID is required."); + if (!(id[0] >= 'a' && id[0] <= 'z' || id[0] >= '0' && id[0] <= '9') || id.Any(c => + !(c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '.' || c == '_' || c == '-'))) + throw new InvalidOperationException("Ship ID must use lower-case ASCII letters, digits, dots, underscores, or hyphens."); + if (id[id.Length - 1] == '.') throw new InvalidOperationException("Ship ID must not end with a dot."); + var stem = id.Split('.')[0]; + if (stem is "con" or "prn" or "aux" or "nul" + || stem.Length == 4 && (stem.StartsWith("com") || stem.StartsWith("lpt")) && stem[3] >= '1' && stem[3] <= '9') + throw new InvalidOperationException("Ship ID must not be a Windows device name."); + } + // The one semantic check every path shares: the hull and its visual, judged together. public static void Validate(HullData hull, ShipAuthoring ship) { if (ship == null) throw new InvalidOperationException("Ship authoring record is null."); - if (string.IsNullOrWhiteSpace(ship.Id)) throw new InvalidOperationException("Ship ID is required."); - if (!(ship.Id[0] >= 'a' && ship.Id[0] <= 'z' || ship.Id[0] >= '0' && ship.Id[0] <= '9') || ship.Id.Any(c => - !(c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '.' || c == '_' || c == '-'))) - throw new InvalidOperationException($"{ship.Id}: ship ID must use lower-case ASCII letters, digits, dots, underscores, or hyphens."); + RequireShipId(ship.Id); if (hull == null) throw new InvalidOperationException($"{ship.Id}: hull data is required."); if (string.IsNullOrWhiteSpace(hull.Name)) throw new InvalidOperationException($"{ship.Id}: hull name is required."); if (hull.Shape?.Cells == null || !hull.Shape.Cells.Cast().Any(occupied => occupied)) throw new InvalidOperationException($"{ship.Id}: schematic must contain at least one cell."); RequireOneBody(hull, ship.Id); + if (hull.HullType == HullType.Ship && !(hull.Behaviors ?? new List()).Any(behavior => behavior is VelocityLimitData)) + throw new InvalidOperationException($"{ship.Id}: a ship hull needs a top speed (VelocityLimit)."); if (!hull.Visual.Key.Equals(ShipModCatalog.AuthoringKey(ship.Id))) throw new InvalidOperationException($"{ship.Id}: the hull must name its visual record {ShipModCatalog.AuthoringKey(ship.Id).Value}."); if (string.IsNullOrWhiteSpace(ship.ModelAsset) || Path.IsPathRooted(ship.ModelAsset) || @@ -233,6 +302,11 @@ public static class ShipAuthoringStore throw new InvalidOperationException($"{ship.Id}: hardpoint {hardpoint.Transform} has an unknown rotation {(int)hardpoint.Rotation}."); if (!float.IsFinite(hardpoint.Armor) || hardpoint.Armor < 0 || !float.IsFinite(hardpoint.FiringArc) || hardpoint.FiringArc < 0) throw new InvalidOperationException($"{ship.Id}: hardpoint {hardpoint.Transform} armor and firing arc must be finite and not negative."); + // A thruster's gimbal range is the judge's alone, a row of one included: no thruster swings further than a turn. + if (hardpoint.Type == HardpointType.Thruster && hardpoint.FiringArc > 360f) + throw new InvalidOperationException($"{ship.Id}: thruster hardpoint {hardpoint.Transform} firing arc may be at most 360 degrees."); + if (!string.IsNullOrEmpty(hardpoint.Row) && hardpoint.Type != HardpointType.Thruster) + throw new InvalidOperationException($"{ship.Id}: hardpoint {hardpoint.Transform} is a {hardpoint.Type} hardpoint, and only a Thruster hardpoint may state a row."); if (hardpoint.Shape?.Cells == null || !hardpoint.Shape.Cells.Cast().Any(occupied => occupied)) throw new InvalidOperationException($"{ship.Id}: hardpoint {hardpoint.Transform} has no cells."); for (var cellX = 0; cellX < hardpoint.Shape.Width; cellX++) @@ -256,14 +330,23 @@ public static class ShipAuthoringStore if (mountRole != null && mountAnchor.Role != mountRole) throw new InvalidOperationException($"{ship.Id}: {hardpoint.Type} hardpoint {hardpoint.Transform} needs a {mountRole} anchor of that id."); } + foreach (var row in mounts.Values.Where(hardpoint => hardpoint.Type == HardpointType.Thruster && !string.IsNullOrEmpty(hardpoint.Row)) + .GroupBy(hardpoint => hardpoint.Row, StringComparer.Ordinal)) + { + var lead = row.First(); + foreach (var hardpoint in row) + if (hardpoint.Rotation != lead.Rotation || hardpoint.FiringArc != lead.FiringArc) + throw new InvalidOperationException($"{ship.Id}: thruster hardpoints {lead.Transform} and {hardpoint.Transform} are in row {row.Key} and must share Rotation and FiringArc."); + if (!(lead.FiringArc > 0f)) + throw new InvalidOperationException($"{ship.Id}: thruster row {row.Key} must state a gimbal FiringArc above 0."); + } foreach (var anchor in anchors) { if (!string.IsNullOrEmpty(anchor.ParentId) && !mounts.ContainsKey(anchor.ParentId)) throw new InvalidOperationException($"{ship.Id}: anchor {anchor.Id} has unknown hardpoint parent {anchor.ParentId}."); // A mount-role anchor is the mount of a hardpoint of its type, never a loose node. The hardpoint loop above has // already refused one whose id names a hardpoint of another type, so here it only has to name a hardpoint. - if ((anchor.Role == "thruster-emitter" || anchor.Role == "radiator-mesh" || anchor.Role == "weapon-mount") && - !mounts.ContainsKey(anchor.Id)) + if ((RigChains.Actuates(anchor.Role) || anchor.Role == "radiator-mesh") && !mounts.ContainsKey(anchor.Id)) throw new InvalidOperationException($"{ship.Id}: {anchor.Role} anchor {anchor.Id} must be the mount of a hardpoint of its type."); if (anchor.Role == "weapon-muzzle" && (string.IsNullOrEmpty(anchor.ParentId) || !IsWeapon(mounts[anchor.ParentId].Type))) @@ -272,6 +355,7 @@ public static class ShipAuthoringStore foreach (var hardpoint in mounts.Values.Where(hardpoint => IsWeapon(hardpoint.Type))) if (!anchors.Any(anchor => anchor.Role == "weapon-muzzle" && anchor.ParentId == hardpoint.Transform)) throw new InvalidOperationException($"{ship.Id}: weapon hardpoint {hardpoint.Transform} needs at least one muzzle anchor."); + ValidateRig(ship, anchors, mounts, nodeIds); foreach (var line in ship.SchematicLines ?? new List()) { @@ -291,4 +375,158 @@ public static class ShipAuthoringStore throw new InvalidOperationException($"{ship.Id}: schematic line color must be finite RGBA."); } } + + // A degree of freedom counts as yaw when its axis lies within 5 degrees of Ship Root up (glTF +Y). + private static readonly float YawAxisCos = MathF.Cos(5f * MathF.PI / 180f); + + // The joints, which anchors ride them, and whether each driven joint's chain can sweep the arc its guns state. The + // joints are presentation, so this judges only that the rig could point the gun where the hardpoint says it may fire. + private static void ValidateRig(ShipAuthoring ship, List anchors, Dictionary mounts, HashSet nodeIds) + { + var joints = ship.Joints ?? new List(); + var byId = new Dictionary(StringComparer.Ordinal); + foreach (var joint in joints) + { + if (joint == null || string.IsNullOrWhiteSpace(joint.Id) || byId.ContainsKey(joint.Id)) + throw new InvalidOperationException($"{ship.Id}: joint IDs must be present and unique."); + if (nodeIds.Contains(joint.Id)) + throw new InvalidOperationException($"{ship.Id}: joint {joint.Id} is also an anchor's model node."); + byId.Add(joint.Id, joint); + } + foreach (var joint in joints) + { + var dofs = joint.Min?.Length ?? 0; + if (dofs < 1 || joint.Max?.Length != dofs || joint.Axes?.Length != 3 * dofs) + throw new InvalidOperationException($"{ship.Id}: joint {joint.Id} needs one or more degrees of freedom: Axes holds three values each, Min and Max one each."); + for (var dof = 0; dof < dofs; dof++) + { + var (x, y, z) = (joint.Axes[3 * dof], joint.Axes[3 * dof + 1], joint.Axes[3 * dof + 2]); + var (min, max) = (joint.Min[dof], joint.Max[dof]); + if (!float.IsFinite(x) || !float.IsFinite(y) || !float.IsFinite(z) || !float.IsFinite(min) || !float.IsFinite(max)) + throw new InvalidOperationException($"{ship.Id}: joint {joint.Id} axes and limits must be finite."); + if (MathF.Abs(MathF.Sqrt(x * x + y * y + z * z) - 1f) > 1e-3f) + throw new InvalidOperationException($"{ship.Id}: joint {joint.Id} axis {dof} must be a unit vector."); + if (min < -180f || max > 180f || min > max) + throw new InvalidOperationException($"{ship.Id}: joint {joint.Id} limits {dof} must satisfy -180 <= Min <= Max <= 180."); + } + if (!string.IsNullOrEmpty(joint.Parent) && !byId.ContainsKey(joint.Parent)) + throw new InvalidOperationException($"{ship.Id}: joint {joint.Id} has an unknown parent joint."); + } + foreach (var joint in joints) + { + var step = joint; + for (var depth = 0; !string.IsNullOrEmpty(step.Parent); depth++) + { + if (depth >= joints.Count) + throw new InvalidOperationException($"{ship.Id}: joint {joint.Id} is on a parent cycle."); + step = byId[step.Parent]; + } + } + + foreach (var anchor in anchors.Where(anchor => !string.IsNullOrEmpty(anchor.Joint))) + { + if (anchor.Role == "radiator-mesh") + throw new InvalidOperationException($"{ship.Id}: {anchor.Role} anchor {anchor.Id} may not ride a joint."); + if (!RigChains.Actuates(anchor.Role)) + throw new InvalidOperationException($"{ship.Id}: {anchor.Role} anchor {anchor.Id} may not name a joint; only a weapon mount or a thruster emitter rides one."); + if (!byId.ContainsKey(anchor.Joint)) + throw new InvalidOperationException($"{ship.Id}: {anchor.Role} anchor {anchor.Id} names an unknown joint."); + } + + // A joint has one actuator (ruling one-joint-one-actuator), and RigChains.Drives is the only place that says what drives a + // joint: a joint carrying two actuators, or whose reach passes through a joint another actuator drives, is refused here, + // whatever the two actuators are. + var drives = RigChains.Drives(ship).Select(drive => (drive.Joint, Hardpoint: mounts[drive.Anchor.Id])).ToArray(); + foreach (var onJoint in drives.GroupBy(drive => drive.Joint, StringComparer.Ordinal)) + { + var lead = onJoint.First().Hardpoint; + var other = onJoint.Select(drive => drive.Hardpoint).FirstOrDefault(hardpoint => RigChains.Actuator(hardpoint) != RigChains.Actuator(lead)); + if (other != null) + throw new InvalidOperationException($"{ship.Id}: joint {onJoint.Key} carries more than one actuator ({lead.Transform} and {other.Transform}); a joint has one actuator."); + } + var driven = RigChains.Driven(ship); + foreach (var joint in driven) + { + var through = RigChains.Chain(ship, joint).SkipLast(1).FirstOrDefault(driven.Contains); + if (through != null) + throw new InvalidOperationException($"{ship.Id}: joint {joint} reaches through joint {through}, which another actuator drives; a joint has one actuator."); + } + + var ridden = drives.Where(drive => IsWeapon(drive.Hardpoint.Type)).ToArray(); + foreach (var (_, hardpoint) in ridden) + if (!(hardpoint.FiringArc > 0f)) + throw new InvalidOperationException($"{ship.Id}: weapon hardpoint {hardpoint.Transform} rides a joint, so it must state its firing arc above 0."); + foreach (var group in ridden.GroupBy(mount => mount.Joint, StringComparer.Ordinal)) + { + var lead = group.First().Hardpoint; + foreach (var (_, hardpoint) in group) + if (hardpoint.Rotation != lead.Rotation || hardpoint.FiringArc != lead.FiringArc) + throw new InvalidOperationException($"{ship.Id}: weapon hardpoints {lead.Transform} and {hardpoint.Transform} ride joint {group.Key} and must share Rotation and FiringArc."); + var reach = YawReach(ship, group.Key); + if (reach < lead.FiringArc) + throw new InvalidOperationException($"{ship.Id}: joint {group.Key} chain reaches {reach} degrees of yaw, short of the {lead.FiringArc} degree firing arc of {lead.Transform}."); + } + + // A thruster row is a gimbal: its hardpoints' stated FiringArc is how far the row swings, so a row on a joint rides it + // whole, and the joint's chain must be able to sweep that arc. A hardpoint with no Row is a row of one. + var thrusters = mounts.Values.Where(hardpoint => hardpoint.Type == HardpointType.Thruster).ToArray(); + var tilted = drives.Where(drive => drive.Hardpoint.Type == HardpointType.Thruster).ToArray(); + foreach (var (_, hardpoint) in tilted) + if (!(hardpoint.FiringArc > 0f)) + throw new InvalidOperationException($"{ship.Id}: thruster hardpoint {hardpoint.Transform} rides a joint, so it must state its firing arc above 0; a fixed thruster may not ride a joint."); + foreach (var onJoint in tilted.GroupBy(drive => drive.Joint, StringComparer.Ordinal)) + { + var lead = onJoint.First().Hardpoint; + var members = string.IsNullOrEmpty(lead.Row) ? new[] { lead } : thrusters.Where(hardpoint => hardpoint.Row == lead.Row).ToArray(); + foreach (var member in members) + if (!tilted.Any(drive => drive.Hardpoint == member && drive.Joint == onJoint.Key)) + throw new InvalidOperationException($"{ship.Id}: thruster hardpoint {member.Transform} is in the row of {lead.Transform} on joint {onJoint.Key} and must ride it too; a row rides one joint whole."); + var reach = YawReach(ship, onJoint.Key); + if (reach < lead.FiringArc) + throw new InvalidOperationException($"{ship.Id}: joint {onJoint.Key} chain reaches {reach} degrees of yaw, short of the {lead.FiringArc} degree gimbal arc of {lead.Transform}."); + } + } + + // The yaw a driven joint's chain can sweep: the summed range of every degree of freedom whose axis is yaw, capped at a turn. + private static float YawReach(ShipAuthoring ship, string jointId) + { + var joints = ship.Joints.ToDictionary(joint => joint.Id, StringComparer.Ordinal); + var reach = 0f; + foreach (var joint in RigChains.Chain(ship, jointId).Select(id => joints[id])) + for (var dof = 0; dof < joint.Min.Length; dof++) + if (MathF.Abs(joint.Axes[3 * dof + 1]) >= YawAxisCos) + reach += joint.Max[dof] - joint.Min[dof]; + return MathF.Min(reach, 360f); + } +} + +// A rig's actuators and the joints they drive. An actuator is a weapon mount or a thruster emitter that names a joint; a gun +// group (every gun on a joint) or a thruster row is one actuator, and a joint has at most one (ruling one-joint-one-actuator). +// This is the only place that says which anchors are actuators, so the judge, the binder and the plan all follow it. +public static class RigChains +{ + public static bool Actuates(string role) => role == "weapon-mount" || role == "thruster-emitter"; + + // Every actuator anchor that names a joint, with the joint it drives. + public static IEnumerable<(string Joint, ShipAnchor Anchor)> Drives(ShipAuthoring ship) => + ship.Anchors.Where(anchor => Actuates(anchor.Role) && !string.IsNullOrEmpty(anchor.Joint)).Select(anchor => (anchor.Joint, anchor)); + + public static HashSet Driven(ShipAuthoring ship) => + new HashSet(Drives(ship).Select(drive => drive.Joint), StringComparer.Ordinal); + + // The actuator a mount belongs to: all guns on a joint are one, a thruster is its row, and a thruster of no row is its own. + public static string Actuator(HardpointData hardpoint) => + ShipAuthoringStore.IsWeapon(hardpoint.Type) ? "weapon" : string.IsNullOrEmpty(hardpoint.Row) ? "thruster:" + hardpoint.Transform : "row:" + hardpoint.Row; + + // The joint and its ancestors, root-first. The judge refuses a driven joint whose ancestors another actuator drives, + // so for an accepted ship this is the whole chain the actuator's reach is summed over. + public static string[] Chain(ShipAuthoring ship, string jointId) + { + var joints = ship.Joints.ToDictionary(joint => joint.Id, StringComparer.Ordinal); + var chain = new List { jointId }; + for (var parent = joints[jointId].Parent; !string.IsNullOrEmpty(parent); parent = joints[parent].Parent) + chain.Add(parent); + chain.Reverse(); + return chain.ToArray(); + } } diff --git a/Assets/Scripts/ServerShared/ShipModCatalog.cs b/Assets/Scripts/ServerShared/ShipModCatalog.cs index 38216f481..52d383ce8 100644 --- a/Assets/Scripts/ServerShared/ShipModCatalog.cs +++ b/Assets/Scripts/ServerShared/ShipModCatalog.cs @@ -16,14 +16,18 @@ public static class ShipModCatalog public ShipAuthoring Visual; public string ModelPath; public Dictionary NodeIndices; + // The package's own products, read from its ship.cc; empty for a package taken from the catalog, where gameplay reads products. + public FactionProductData[] Products = Array.Empty(); } public static CultRecordKey HullKey(string id) => new CultRecordKey("mod-hull:" + id); public static CultRecordKey AuthoringKey(string id) => new CultRecordKey("mod-ship:" + id); + public static CultRecordKey ProductKey(string id, CultRecordKey maker) => new CultRecordKey("mod-product:" + id + ":" + maker.Value); + // A key the mods own. The shipped catalog and its authored records never reference one: a mod may be uninstalled. public static bool IsModKey(CultRecordKey key) => - key.IsSet() && (key.Value.StartsWith("mod-hull:", StringComparison.Ordinal) || key.Value.StartsWith("mod-ship:", StringComparison.Ordinal)); + key.IsSet() && (key.Value.StartsWith("mod-hull:", StringComparison.Ordinal) || key.Value.StartsWith("mod-ship:", StringComparison.Ordinal) || key.Value.StartsWith("mod-product:", StringComparison.Ordinal)); // A package left out of the composition, named by its directory, with every reason it was left out. public sealed class Exclusion @@ -45,7 +49,7 @@ public static class ShipModCatalog // named. A collision (with the shipped catalog, or with another package's hull name) excludes every package involved, // since neither has a claim to the name. The derived catalog holds the shipped catalog plus the included packages. // Unsafe inputs and outputs (a missing catalog, a derived file that would replace a source) still throw: nothing is composed. - public static Composition Compose(string shippedCatalog, string outputCatalog, string modsRoot) + public static Composition Compose(string shippedCatalog, string outputCatalog, string modsRoot, CultDocumentRegistry registry = null) { var source = Path.GetFullPath(shippedCatalog); var output = Path.GetFullPath(outputCatalog); @@ -84,7 +88,7 @@ public static class ShipModCatalog Directory.CreateDirectory(workspace); File.Copy(source, temporary); Composition composition; - using (var cache = AetheriaStores.Open(temporary, catalogWritable: true)) + using (var cache = AetheriaStores.Open(temporary, catalogWritable: true, registry: registry)) { // Collisions are judged against the shipped records alone, before any package is written, so the // verdict does not depend on directory order. CultCache indexes names per concrete type and lets the @@ -93,6 +97,8 @@ public static class ShipModCatalog var keys = new HashSet(cache.AllStoredDocuments.Select(record => record.Key)); var itemNames = new HashSet(cache.GetAll().Select(item => item.Name), StringComparer.Ordinal); var shipIds = new HashSet(cache.GetAll().Select(existing => existing.Id), StringComparer.Ordinal); + var factionKeys = new HashSet(cache.GetAll().Select(faction => cache.TryGetHandle(faction).Value.Key)); + var productNames = new HashSet(cache.GetAll().Select(product => product.Name), StringComparer.Ordinal); foreach (var (directory, package) in packages) { var (hull, ship) = (package.Hull, package.Visual); @@ -102,16 +108,33 @@ public static class ShipModCatalog Exclude(directory, $"hull name '{hull.Name}' collides with an existing catalog item."); if (shipIds.Contains(ship.Id)) Exclude(directory, $"ship ID collides with an existing catalog ship authoring record."); + foreach (var product in package.Products) + { + if (!factionKeys.Contains(product.Manufacturer.Key)) + Exclude(directory, $"product '{product.Name}' names a manufacturer the shipped catalog holds no faction for."); + if (keys.Contains(ProductKey(ship.Id, product.Manufacturer.Key))) + Exclude(directory, $"a mod product key collides with an existing catalog record."); + if (productNames.Contains(product.Name)) + Exclude(directory, $"product name '{product.Name}' collides with an existing catalog product."); + } } foreach (var claim in packages.GroupBy(package => package.Package.Hull.Name, StringComparer.Ordinal).Where(group => group.Count() > 1)) foreach (var (directory, package) in claim) Exclude(directory, $"hull name '{claim.Key}' is also claimed by " + string.Join(", ", claim.Where(other => other.Directory != directory).Select(other => other.Directory)) + "."); + foreach (var claim in packages.SelectMany(package => package.Package.Products.Select(product => (package.Directory, product.Name))) + .GroupBy(entry => entry.Name, StringComparer.Ordinal).Where(group => group.Select(entry => entry.Directory).Distinct().Count() > 1)) + foreach (var directory in claim.Select(entry => entry.Directory).Distinct()) + Exclude(directory, $"product name '{claim.Key}' is also claimed by " + + string.Join(", ", claim.Select(entry => entry.Directory).Where(other => other != directory).Distinct()) + "."); var included = packages.Where(package => !reasons.ContainsKey(package.Directory)).Select(package => package.Package).ToArray(); foreach (var package in included) - // Verbatim: the mod store's own two records, under the keys it already holds them at. + { + // Verbatim: the mod store's own records, under the keys it already holds them at. ShipAuthoringStore.Write(cache, package.Hull, package.Visual); + foreach (var product in package.Products) ShipAuthoringStore.WriteProduct(cache, package.Visual.Id, product); + } // Shipped hulls too: the derived catalog must not hold a hull that names two bodies. foreach (var hull in cache.GetAll()) ShipAuthoringStore.RequireOneBody(hull, hull.Name); @@ -135,8 +158,8 @@ public static class ShipModCatalog public static Package ReadPackage(string shipPath) { var path = Path.GetFullPath(shipPath); - var (hull, ship) = ShipAuthoringStore.Read(path); - return Bind(hull, ship, Path.GetDirectoryName(path), path); + var (hull, ship, products) = ShipAuthoringStore.Read(path); + return Bind(hull, ship, products, Path.GetDirectoryName(path), path); } // The package a catalog hull names: its two records come from the catalog, and only the GLB comes from the mod @@ -147,31 +170,32 @@ public static class ShipModCatalog throw new InvalidOperationException($"{hull.Name}: the catalog holds no visual record {hull.Visual.Key.Value}."); ShipAuthoringStore.Validate(hull, ship); var directory = Path.Combine(Path.GetFullPath(modsRoot), ship.Id); - return Bind(hull, ship, directory, Path.Combine(directory, "ship.cc")); + return Bind(hull, ship, Array.Empty(), directory, Path.Combine(directory, "ship.cc")); } // The one game-side choice of catalog: the shipped file when no package is installed or none survives composition, // otherwise the derived file, composed afresh from the shipped one and the surviving packages. Recomposed every // call, so the derived file is never stale and never an authority. Excluded packages come back named, for the menu. - public static (string Catalog, Exclusion[] Excluded) ResolveCatalog(string shippedCatalog, string derivedCatalog, string modsRoot) + public static (string Catalog, Exclusion[] Excluded) ResolveCatalog(string shippedCatalog, string derivedCatalog, string modsRoot, + CultDocumentRegistry registry = null) { if (!Directory.Exists(modsRoot) || !Directory.GetDirectories(modsRoot).Any(directory => File.Exists(Path.Combine(directory, "ship.cc")))) return (shippedCatalog, Array.Empty()); Composition composition; // A failure of the composition itself (an unwritable derived path, say) is still a mod problem, never a reason not to boot. - try { composition = Compose(shippedCatalog, derivedCatalog, modsRoot); } + try { composition = Compose(shippedCatalog, derivedCatalog, modsRoot, registry); } catch (Exception error) { return (shippedCatalog, new[] { new Exclusion { Package = "(all mods)", Reason = error.Message } }); } return (composition.Included.Length == 0 ? shippedCatalog : derivedCatalog, composition.Excluded); } - private static Package Bind(HullData hull, ShipAuthoring ship, string directory, string path) + private static Package Bind(HullData hull, ShipAuthoring ship, FactionProductData[] products, string directory, string path) { if (!string.Equals(Path.GetFileName(directory), ship.Id, StringComparison.Ordinal)) throw new InvalidOperationException($"{path}: ship ID must match its package directory name."); var modelPath = Path.GetFullPath(Path.Combine(directory, ship.ModelAsset)); // Containment is ShipAuthoringStore.Validate's job: it refuses rooted and `..` model paths before this line. - if (!File.Exists(modelPath) || !string.Equals(Path.GetExtension(modelPath), ".glb", StringComparison.OrdinalIgnoreCase)) + if (!File.Exists(modelPath) || !string.Equals(Path.GetExtension(modelPath), ".glb", StringComparison.Ordinal)) throw new InvalidOperationException($"{ship.Id}: model asset must name an existing GLB inside its package."); var modelNodes = ReadNodeIds(modelPath); foreach (var anchor in ship.Anchors) @@ -182,17 +206,52 @@ public static class ShipModCatalog foreach (var anchor in ship.Anchors) if ((anchor.Role == "thruster-emitter" || anchor.Role == "radiator-mesh") && !modelNodes[anchor.ModelNodeId].HasMesh) throw new InvalidOperationException($"{ship.Id}: {anchor.Role} anchor {anchor.Id} needs a mesh, but model node {anchor.ModelNodeId} has none."); + BindRig(ship, modelNodes); CultRecordRefs.Validate(hull); return new Package { - Hull = hull, Visual = ship, ModelPath = modelPath, + Hull = hull, Visual = ship, Products = products, ModelPath = modelPath, NodeIndices = modelNodes.ToDictionary(node => node.Key, node => node.Value.Index, StringComparer.Ordinal) }; } - // GLB is the xenos asset boundary. Only its node extras, and whether each node names a mesh, are read here; geometry - // belongs to the runtime importer. - public static Dictionary ReadNodeIds(string path) + // The rig the record states must be the rig the model has: every joint is a node, each joint's Parent and each mount's + // Joint is the nearest joint above its node, ancestors without an id being walked through by ReadNodeIds, and a radiator + // mesh sits under no joint. + private static void BindRig(ShipAuthoring ship, Dictionary nodes) + { + var joints = new HashSet((ship.Joints ?? new List()).Select(joint => joint.Id), StringComparer.Ordinal); + var idAt = nodes.ToDictionary(node => (int)node.Value.Index, node => node.Key); + // Parent is already the nearest ancestor that carries an id, so the walk up is the chain of those. + string JointAbove(string nodeId) + { + // glTF forbids cycles; the bound keeps a malformed model from hanging the binder. + var parent = nodes[nodeId].Parent; + for (var steps = 0; parent >= 0 && steps <= nodes.Count; steps++, parent = nodes[idAt[parent]].Parent) + if (joints.Contains(idAt[parent])) return idAt[parent]; + return null; + } + + foreach (var joint in ship.Joints ?? new List()) + { + if (!nodes.ContainsKey(joint.Id)) + throw new InvalidOperationException($"{ship.Id}: model has no node with aetheria.id={joint.Id} for a joint."); + if (!string.Equals(JointAbove(joint.Id) ?? "", joint.Parent ?? "", StringComparison.Ordinal)) + throw new InvalidOperationException($"{ship.Id}: joint {joint.Id} must name the nearest joint above its model node as its Parent."); + } + foreach (var anchor in ship.Anchors.Where(anchor => RigChains.Actuates(anchor.Role) || anchor.Role == "radiator-mesh")) + { + var above = JointAbove(anchor.ModelNodeId); + if (string.Equals(above ?? "", anchor.Joint ?? "", StringComparison.Ordinal)) continue; + throw new InvalidOperationException(anchor.Role == "radiator-mesh" + ? $"{ship.Id}: {anchor.Role} anchor {anchor.Id} sits under a joint in the model." + : $"{ship.Id}: {(anchor.Role == "weapon-mount" ? "weapon mount" : "thruster emitter")} {anchor.Id} must name the nearest joint above its model node as its Joint."); + } + } + + // GLB is the xenos asset boundary. Only its node extras, whether each node names a mesh, and its nearest identified ancestor's node index + // (-1 for none) are read here; geometry belongs to the runtime importer. + public static Dictionary ReadNodeIds(string path) { using var stream = File.OpenRead(path); using var reader = new BinaryReader(stream); @@ -203,17 +262,29 @@ public static class ShipModCatalog if (reader.ReadUInt32() != 0x4E4F534A || chunkLength > stream.Length - stream.Position) throw new InvalidOperationException($"{path}: missing GLB JSON chunk."); var json = JObject.Parse(Encoding.UTF8.GetString(reader.ReadBytes((int)chunkLength))); - var ids = new Dictionary(StringComparer.Ordinal); - var nodes = json["nodes"]?.OfType() ?? Enumerable.Empty(); + var ids = new Dictionary(StringComparer.Ordinal); + var nodes = (json["nodes"]?.OfType() ?? Enumerable.Empty()).ToArray(); + var parents = Enumerable.Repeat(-1, nodes.Length).ToArray(); + for (var parent = 0; parent < nodes.Length; parent++) + foreach (var child in nodes[parent]["children"]?.Select(token => (int)token) ?? Enumerable.Empty()) + if (child >= 0 && child < nodes.Length) parents[child] = parent; uint index = 0; foreach (var node in nodes) { var id = (string)node["extras"]?["aetheria.id"]; if (string.IsNullOrEmpty(id)) { index++; continue; } - if (!ids.TryAdd(id, (index, node["mesh"] != null && node["mesh"].Type != JTokenType.Null))) + if (!ids.TryAdd(id, (index, node["mesh"] != null && node["mesh"].Type != JTokenType.Null, IdentifiedAncestor(parents, nodes, (int)index)))) throw new InvalidOperationException($"{path}: duplicate GLB node aetheria.id={id}."); index++; } return ids; } + + private static int IdentifiedAncestor(int[] parents, JObject[] nodes, int index) + { + var parent = parents[index]; + for (var steps = 0; parent >= 0 && steps <= nodes.Length; steps++, parent = parents[parent]) + if (!string.IsNullOrEmpty((string)nodes[parent]["extras"]?["aetheria.id"])) return parent; + return -1; + } } diff --git a/Assets/Scripts/ServerShared/ShipModPlan.cs b/Assets/Scripts/ServerShared/ShipModPlan.cs index bb80647a1..6f659edac 100644 --- a/Assets/Scripts/ServerShared/ShipModPlan.cs +++ b/Assets/Scripts/ServerShared/ShipModPlan.cs @@ -15,6 +15,10 @@ public sealed class ShipModPlan public string[] Radiators; // Each weapon mount (role weapon-mount) and its muzzle anchors, by Order then id. public (string Mount, string[] Muzzles)[] Weapons; + // One entry per driven joint (one a weapon mount names), by its first weapon in hull order: the joint, its chain + // root-first (RigChains), and the lead mount (the joint's first weapon in hull order) with that mount's first muzzle. + // Presentation only: the assembler rigs these and nothing here reaches the simulation. + public (string Joint, string[] Chain, string LeadMount, string LeadMuzzle)[] Rigs; // Maps a pair Validate accepts; every rule about which anchor may play which part is Validate's, so this refuses nothing. public static ShipModPlan Build(HullData hull, ShipAuthoring visual) @@ -26,6 +30,12 @@ public sealed class ShipModPlan var muzzles = visual.Anchors.Where(anchor => anchor.Role == "weapon-muzzle") .OrderBy(anchor => anchor.Order).ThenBy(anchor => anchor.Id, StringComparer.Ordinal).ToArray(); + var weapons = hardpoints.Where(hardpoint => ShipAuthoringStore.IsWeapon(hardpoint.Type)).Select(hardpoint => hardpoint.Transform).ToHashSet(StringComparer.Ordinal); + var jointOf = RigChains.Drives(visual).Where(drive => weapons.Contains(drive.Anchor.Id)) + .ToDictionary(drive => drive.Anchor.Id, drive => drive.Joint, StringComparer.Ordinal); + var leads = hardpoints.Where(hardpoint => jointOf.ContainsKey(hardpoint.Transform)).GroupBy(hardpoint => jointOf[hardpoint.Transform], StringComparer.Ordinal) + .Select(group => (Joint: group.Key, Lead: group.First().Transform)); + return new ShipModPlan { MapIcon = Only("map-icon"), @@ -36,7 +46,9 @@ public sealed class ShipModPlan Radiators = Mounts(HardpointType.Radiator), Weapons = hardpoints.Where(hardpoint => ShipAuthoringStore.IsWeapon(hardpoint.Type)).Select(hardpoint => ( hardpoint.Transform, - muzzles.Where(muzzle => muzzle.ParentId == hardpoint.Transform).Select(muzzle => muzzle.Id).ToArray())).ToArray() + muzzles.Where(muzzle => muzzle.ParentId == hardpoint.Transform).Select(muzzle => muzzle.Id).ToArray())).ToArray(), + Rigs = leads.Select(rig => (rig.Joint, RigChains.Chain(visual, rig.Joint), rig.Lead, + muzzles.First(muzzle => muzzle.ParentId == rig.Lead).Id)).ToArray() }; } } diff --git a/Assets/Scripts/ServerShared/SimClock.cs b/Assets/Scripts/ServerShared/SimClock.cs new file mode 100644 index 000000000..6d00c46d0 --- /dev/null +++ b/Assets/Scripts/ServerShared/SimClock.cs @@ -0,0 +1,68 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System; + +// The one relation between simulation time and real time. Real seconds go in; whole fixed steps come out, each +// handed to the caller's step action with the same Step. Nothing else in the game converts frame time to sim time, +// and nothing integrates a sim quantity on this clock: presenters read Lead to draw ahead of the latest step +// (DrawAhead) and decide no sim fact. +public sealed class SimClock +{ + // The longest real time one frame may feed. A hitch (a load, a breakpoint) is a slow frame, not a burst of + // catch-up steps. + public const float MaxFrameSeconds = .1f; + + private readonly double _period; + private double _accumulator; + private bool _advancing; + + public SimClock(float step, float stepsPerRealSecond = 60) + { + if (!(step > 0)) throw new ArgumentOutOfRangeException(nameof(step)); + if (!(stepsPerRealSecond > 0)) throw new ArgumentOutOfRangeException(nameof(stepsPerRealSecond)); + Step = step; + StepsPerRealSecond = stepsPerRealSecond; + _period = 1.0 / stepsPerRealSecond; + } + + // Sim seconds per step, fixed for the clock's life. + public float Step { get; } + + public float StepsPerRealSecond { get; } + + public long Steps { get; private set; } + + // Sim seconds since the last step, 0 <= Lead < Step. + public float Lead => (float) (_accumulator * StepsPerRealSecond * Step); + + // Forgets the real time paid toward the next step (a new zone starts between steps). A step cannot do this to the + // clock that is running it. + public void Reset() + { + if (_advancing) throw new InvalidOperationException("A step cannot reset the clock that is running it."); + _accumulator = 0; + } + + // Feeds real seconds (negative counts as none, one frame counts at most MaxFrameSeconds) and runs the whole + // steps they pay for. Returns how many ran. + public int Advance(float realSeconds, Action step) + { + _accumulator += Math.Min(Math.Max(realSeconds, 0f), MaxFrameSeconds); + var ran = 0; + _advancing = true; + try + { + while (_accumulator >= _period) + { + _accumulator -= _period; + step(Step); + Steps++; + ran++; + } + } + finally { _advancing = false; } + return ran; + } +} diff --git a/Assets/Scripts/ServerShared/SimClock.cs.meta b/Assets/Scripts/ServerShared/SimClock.cs.meta new file mode 100644 index 000000000..30e06c489 --- /dev/null +++ b/Assets/Scripts/ServerShared/SimClock.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a9e3edac65f4a8e8313bdbfe69ccebd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/StatResolver.cs b/Assets/Scripts/ServerShared/StatResolver.cs index bbd3ea542..7062fbd9e 100644 --- a/Assets/Scripts/ServerShared/StatResolver.cs +++ b/Assets/Scripts/ServerShared/StatResolver.cs @@ -141,6 +141,9 @@ public class StatResolver { set.Scale.Remove(modifierKey); set.Constant.Remove(modifierKey); + // An entry with nothing attached is no entry: a modifier that is gone leaves no trace in the resolver. + if (set.Scale.Count == 0 && set.Constant.Count == 0) + _modifiers.Remove(entry); } _cache.Remove(entry); } diff --git a/Assets/Scripts/ServerShared/Targeting/BeltTargets.cs b/Assets/Scripts/ServerShared/Targeting/BeltTargets.cs index cba7ea628..3e12536c3 100644 --- a/Assets/Scripts/ServerShared/Targeting/BeltTargets.cs +++ b/Assets/Scripts/ServerShared/Targeting/BeltTargets.cs @@ -59,8 +59,8 @@ public sealed class BeltTargets : ITargetProvider { order[i] = i; distances[i] = data.Asteroids[i].Distance; - // Pose divides by the float period the curve returns; the keys must use the same one. - _periods[i] = settings.OrbitPeriod.Evaluate(distances[i]); + // The belt's own periods (Zone.PeriodAround), the very floats Pose divides by. + _periods[i] = zone.AsteroidBelts[field].Periods[i]; } Array.Sort(distances, order); _bands = new Band[(count + RocksPerBand - 1) / RocksPerBand]; diff --git a/Assets/Scripts/ServerShared/ThrustAllocator.cs b/Assets/Scripts/ServerShared/ThrustAllocator.cs new file mode 100644 index 000000000..148b98d29 --- /dev/null +++ b/Assets/Scripts/ServerShared/ThrustAllocator.cs @@ -0,0 +1,112 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System; +using CultMath; + +/// +/// Turns intent (which way to go, which way to turn) into every thruster's throttle, whatever the thrusters' actual +/// strength and position. One per ship. A column is one thruster's effect per unit throttle: x starboard acceleration, +/// y forward acceleration, z clockwise yaw rate in rad/s. Throttles are bounded to [0,1]. +/// +/// One solve per call over the n throttles and four error variables (the unwanted or +/// missing translation on each half-axis, paid for linearly). Yaw is a heavily weighted row, so a hold is exact and a +/// turn is served first; the linear translation cost means the actuator with the least translation per unit of turn +/// serves first and the next joins only as it saturates. Nothing classifies a column as attitude or drive: the onset +/// at which a second actuator joins a turn falls out of the columns. +/// +public sealed class ThrustAllocator +{ + const float TranslationWeight = 100f; + const float YawWeight = 1000f; + const float ErrorCostWeight = .3f; + const float ErrorCostOffset = 10f; + const float Ridge = .1f; + const float ErrorMax = 2f; + const double KktRelativeTolerance = 1e-12; + const int ErrorVariables = 4; + const int FixedRows = 3 + ErrorVariables; + + int _columns = -1; + float[] _a, _b, _lo, _hi, _x, _workspace; + + /// + /// Solves the throttles for the intent. is the throttle lock: every thruster whose + /// column pushes forward is bounded below at full, the stick is ignored (forward is the only translation asked, so + /// nothing fires against the floored drives), and the turn is served by what remains. + /// + public void Allocate(ReadOnlySpan columns, float2 move, float turn, Span throttle, bool forwardFloor = false) + { + var n = columns.Length; + if (n != _columns) Resize(n); + for (var i = 0; i < n; i++) throttle[i] = 0; + if (forwardFloor) move = new float2(0, 1); + for (var i = 0; i < n; i++) _lo[i] = forwardFloor && columns[i].y > 0 ? 1f : 0f; + + // Nothing asked, nothing fired: that is a fact about the intent, decided before the solve. The solver's warm + // start is left as the last solved point, which is where the next non-zero call resumes. + if (Intent(move, turn, 0) == 0 && Intent(move, turn, 1) == 0 && Intent(move, turn, 2) == 0) return; + + var vars = n + ErrorVariables; + var rows = FixedRows + n; + + // Rows 0 and 1 are the translation axes (starboard, forward), row 2 the yaw. + for (var axis = 0; axis < 3; axis++) + { + float plus = 0, minus = 0; + for (var i = 0; i < n; i++) + { + var c = Component(columns[i], axis); + if (c > 0) plus += c; + else if (c < 0) minus -= c; + } + var extreme = Math.Max(plus, minus); + var intent = Intent(move, turn, axis); + var weight = axis == 2 ? YawWeight : TranslationWeight; + // Intent is a fraction of the half-axis extreme it points into. + var demand = intent >= 0 ? intent * plus : intent * minus; + var scale = extreme > 0 ? weight / extreme : 0f; + var row = axis * vars; + for (var i = 0; i < n; i++) _a[row + i] = Component(columns[i], axis) * scale; + _b[axis] = demand * scale; + if (axis < 2) + { + var errorWeight = extreme > 0 ? weight : 0f; + _a[row + n + 2 * axis] = -errorWeight; + _a[row + n + 2 * axis + 1] = errorWeight; + } + } + + // A linear cost on each error variable, as w*e = -w*kappa, and a ridge on each throttle. + for (var k = 0; k < ErrorVariables; k++) + { + _a[(3 + k) * vars + n + k] = ErrorCostWeight; + _b[3 + k] = -ErrorCostWeight * ErrorCostOffset; + } + for (var i = 0; i < n; i++) _a[(FixedRows + i) * vars + i] = Ridge; + + var status = BoundedLeastSquares.Solve(rows, vars, _a, _b, _lo, _hi, _x, _workspace, out _, KktRelativeTolerance); + if (status == BoundedLeastSquaresStatus.InvalidInput) return; + for (var i = 0; i < n; i++) throttle[i] = _x[i]; + } + + static float Intent(float2 move, float turn, int axis) => + Math.Min(Math.Max(axis == 0 ? move.x : axis == 1 ? move.y : turn, -1f), 1f); + + static float Component(float3 c, int axis) => axis == 0 ? c.x : axis == 1 ? c.y : c.z; + + void Resize(int n) + { + _columns = n; + var vars = n + ErrorVariables; + var rows = FixedRows + n; + _a = new float[rows * vars]; + _b = new float[rows]; + _lo = new float[vars]; + _hi = new float[vars]; + _x = new float[vars]; + _workspace = new float[BoundedLeastSquares.WorkspaceLength(vars)]; + for (var i = 0; i < vars; i++) _hi[i] = i < n ? 1f : ErrorMax; + } +} diff --git a/Assets/Scripts/ServerShared/ThrustAllocator.cs.meta b/Assets/Scripts/ServerShared/ThrustAllocator.cs.meta new file mode 100644 index 000000000..d7b82c1b3 --- /dev/null +++ b/Assets/Scripts/ServerShared/ThrustAllocator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b0e3f7a9c2d4e61a8f4d3c7b1e90a26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/VapourClouds.cs b/Assets/Scripts/ServerShared/VapourClouds.cs new file mode 100644 index 000000000..9f4a44603 --- /dev/null +++ b/Assets/Scripts/ServerShared/VapourClouds.cs @@ -0,0 +1,32 @@ +using CultMath; +using static CultMath.math; +using float2 = CultMath.float2; + +// A vented vapour cloud: a free-floating disc that thins every sensor sight line through it. Not an Entity, +// never priced or rolled, never saved. Zone.Vent is the only adder and Zone's cloud step the only remover; +// Zone.Obscuration is the one reader detection uses. +public sealed class VapourCloud +{ + public FloatingBodyId Id; + public KinematicBody Body; + public double VentedAt; + public float Lifetime; + public float Radius; + // The opacity at the moment of venting; it fades linearly to nothing over Lifetime. + public float Opacity; + public Entity Venter; + + // A cloud with no lifetime divides by zero; saturate maps the NaN and the infinity to nothing left. + public float OpacityAt(double now) => + saturate(Opacity) * saturate(1f - (float) (now - VentedAt) / Lifetime); + + // Whether the segment a-b reaches the disc: the closest point of the segment to the centre lies within the + // radius. A cloud past either end of the segment touches it only if it is near that end. + public bool Touches(float2 a, float2 b) + { + var ab = b - a; + var length2 = lengthsq(ab); + var t = length2 > 0f ? saturate(dot(Body.Position - a, ab) / length2) : 0f; + return lengthsq(Body.Position - (a + ab * t)) <= Radius * Radius; + } +} diff --git a/Assets/Scripts/ServerShared/VapourClouds.cs.meta b/Assets/Scripts/ServerShared/VapourClouds.cs.meta new file mode 100644 index 000000000..cdaa4b80d --- /dev/null +++ b/Assets/Scripts/ServerShared/VapourClouds.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ced45a9738974452b0065b57ee527e8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/VerseGrammar.cs b/Assets/Scripts/ServerShared/VerseGrammar.cs new file mode 100644 index 000000000..00e24833d --- /dev/null +++ b/Assets/Scripts/ServerShared/VerseGrammar.cs @@ -0,0 +1,108 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System; +using System.Collections.Generic; +using GameCult.Caching; +using MessagePack; + +// The verse grammar (aetheria-release, cut verse-grammar; ghostlight-verse rulings verse-grammar-home-ruled and +// verse-verbs-two-render-paths): the verbs a Ghostlight-simulated Aetheria world may use, each rendering by exactly one +// path the game already has, with typed participant roles. Aetheria owns which verbs exist and how each renders; +// Ghostlight owns what each does to world state. Nothing in the game runtime reads these documents. +[CultDocument("aetheria.verse_grammar", "1"), CultGlobal, MessagePackObject] +public class VerseGrammar +{ + [Key(1)] public int Revision; + [Key(2)] public string Description; +} + +// How a verb is shown: filmed in-engine as a ship action, or presented as an Aetheria conversation. +public enum VerseRenderPath +{ + ShipAction = 1, + Conversation = 2, +} + +// What kind of thing a role binds. +public enum VerseReferentKind +{ + Person = 1, + Faction = 2, + Population = 3, + Place = 4, + Cargo = 5, +} + +[MessagePackObject] +public class VerseRole +{ + [Key(1)] public string Name; + [Key(2)] public VerseReferentKind Binds; +} + +// The actor is the invoking subject and is never a role. +[CultDocument("aetheria.verse_verb", "1"), MessagePackObject] +public class VerseVerb +{ + [CultName, Key(1)] public string Name; + [Key(2)] public VerseRenderPath RenderPath; + [Key(3)] public VerseRole[] Roles = Array.Empty(); + [Key(4)] public string Description; +} + +public static class VerseGrammarValidation +{ + public const int VerbNameMaxLength = 48; + public const int RoleNameMaxLength = 32; + + // The invoking subject, never a role (Ghostlight refuses a world affordance that names it: ReservedRole). + public const string ActorRole = "actor"; + + // Canonical: a lower-case letter, then lower-case letters, digits and underscores, at most maxLength characters. + private static bool Canonical(string name, int maxLength) + { + if (name == null || name.Length == 0 || name.Length > maxLength) return false; + if (name[0] < 'a' || name[0] > 'z') return false; + foreach (var c in name) + if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_')) return false; + return true; + } + + // Every verb valid and no two sharing a name: a verb is found by name (Ghostlight refuses DuplicateAffordanceKind). + public static void ValidateAll(IEnumerable verbs) + { + var seen = new HashSet(StringComparer.Ordinal); + foreach (var verb in verbs) + { + Validate(verb); + if (!seen.Add(verb.Name)) + throw new InvalidOperationException($"VerseVerb \"{verb.Name}\": duplicate verb name."); + } + } + + // Canonical names, unique role names, defined enum values. A failure names the field and the rule, and the verb once + // its name is known canonical; it never prints a value the author wrote that is itself the fault. + public static void Validate(VerseVerb verb) + { + if (!Canonical(verb.Name, VerbNameMaxLength)) + throw new InvalidOperationException($"VerseVerb.Name: not a canonical verb name ([a-z][a-z0-9_], 1 to {VerbNameMaxLength} characters)."); + if (!Enum.IsDefined(typeof(VerseRenderPath), verb.RenderPath)) + throw new InvalidOperationException($"VerseVerb \"{verb.Name}\" RenderPath: not a defined render path."); + if (verb.Roles == null) + throw new InvalidOperationException($"VerseVerb \"{verb.Name}\" Roles: missing."); + var seen = new HashSet(StringComparer.Ordinal); + foreach (var role in verb.Roles) + { + if (role == null || !Canonical(role.Name, RoleNameMaxLength)) + throw new InvalidOperationException($"VerseVerb \"{verb.Name}\" Roles.Name: not a canonical role name ([a-z][a-z0-9_], 1 to {RoleNameMaxLength} characters)."); + if (role.Name == ActorRole) + throw new InvalidOperationException($"VerseVerb \"{verb.Name}\" Roles.Name: reserved for the invoking subject, never a role."); + if (!seen.Add(role.Name)) + throw new InvalidOperationException($"VerseVerb \"{verb.Name}\" Roles.Name: duplicate role name."); + if (!Enum.IsDefined(typeof(VerseReferentKind), role.Binds)) + throw new InvalidOperationException($"VerseVerb \"{verb.Name}\" Roles.Binds: not a defined referent kind."); + } + } +} diff --git a/Assets/Scripts/ServerShared/VerseGrammar.cs.meta b/Assets/Scripts/ServerShared/VerseGrammar.cs.meta new file mode 100644 index 000000000..084f027cb --- /dev/null +++ b/Assets/Scripts/ServerShared/VerseGrammar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f1a7c52d9e84b6aa0c15e7b2d4f8a91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Wormhole.cs b/Assets/Scripts/ServerShared/Wormhole.cs index bad43b9fd..fd93e51ca 100644 --- a/Assets/Scripts/ServerShared/Wormhole.cs +++ b/Assets/Scripts/ServerShared/Wormhole.cs @@ -4,4 +4,6 @@ public class Wormhole { public float2 Position; public GalaxyZone Target; + // The run's exit gate: it leads nowhere (Target is null) and ends the run when RunGoal.ExitOpen. + public bool Exit; } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/WwiseMetadata.cs b/Assets/Scripts/ServerShared/WwiseMetadata.cs deleted file mode 100644 index 30b88ad29..000000000 --- a/Assets/Scripts/ServerShared/WwiseMetadata.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; - -[JsonObject] -public class WwiseMetadataFile -{ - public WwiseMetaSoundBanksInfo SoundBanksInfo; -} - -[JsonObject] -public class WwiseMetaSoundBanksInfo -{ - public WwiseMetaSoundBank[] SoundBanks; - - private Dictionary _soundBanks; - public WwiseMetaSoundBank GetSoundBank(uint id) - { - if (_soundBanks == null) _soundBanks = SoundBanks.ToDictionary(sb => sb.Id); - return _soundBanks[id]; - } - - private Dictionary _soundBankNames; - public WwiseMetaSoundBank GetSoundBank(string name) - { - if (_soundBankNames == null) _soundBankNames = SoundBanks.ToDictionary(sb => sb.ShortName); - return _soundBankNames[name]; - } -} - -[JsonObject] -public class WwiseMetaSoundBank -{ - public uint Id; - public string ShortName; - public string ObjectPath; - public WwiseMetaObject[] IncludedEvents; - public WwiseMetaObject[] GameParameters; - - public WwiseMetaObject GetEvent(WeaponAudioEvent weaponAudioEvent) - { - return weaponAudioEvent switch - { - WeaponAudioEvent.Fire => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_fire")), - WeaponAudioEvent.Hit => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_hit")), - WeaponAudioEvent.Miss => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_miss")), - _ => throw new ArgumentOutOfRangeException(nameof(weaponAudioEvent), weaponAudioEvent, null) - }; - } - - public WwiseMetaObject GetEvent(ChargedWeaponAudioEvent chargedWeaponAudioEvent) - { - return chargedWeaponAudioEvent switch - { - ChargedWeaponAudioEvent.Start => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_charge_play")), - ChargedWeaponAudioEvent.Stop => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_charge_stop")), - ChargedWeaponAudioEvent.Fail => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_fail")), - _ => throw new ArgumentOutOfRangeException(nameof(chargedWeaponAudioEvent), chargedWeaponAudioEvent, null) - }; - } - - public WwiseMetaObject GetEvent(LoopingAudioEvent loopingAudioEvent) - { - return loopingAudioEvent switch - { - LoopingAudioEvent.Play => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_play")), - LoopingAudioEvent.Stop => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_stop")), - _ => throw new ArgumentOutOfRangeException(nameof(loopingAudioEvent), loopingAudioEvent, null) - }; - } - - public WwiseMetaObject GetParameter(SpecialAudioParameter audioParameter) - { - return audioParameter switch - { - SpecialAudioParameter.ShipVelocity => GameParameters?.FirstOrDefault(p => p.Name == "ship_velocity"), - SpecialAudioParameter.ChargeLevel => GameParameters?.FirstOrDefault(p => p.Name == "charge_level"), - SpecialAudioParameter.TargetLock => GameParameters?.FirstOrDefault(p => p.Name == "target_locking"), - SpecialAudioParameter.Intensity => GameParameters?.FirstOrDefault(p => p.Name == "sfx_shared_intensity"), - _ => throw new ArgumentOutOfRangeException(nameof(audioParameter), audioParameter, null) - }; - } -} - -[JsonObject] -public class WwiseMetaObject -{ - public uint Id; - public string Name; - public string ObjectPath; -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/WwiseMetadata.cs.meta b/Assets/Scripts/ServerShared/WwiseMetadata.cs.meta deleted file mode 100644 index d9deda43b..000000000 --- a/Assets/Scripts/ServerShared/WwiseMetadata.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0a12363ee8ef43b399bf91ca099947a9 -timeCreated: 1619664281 \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/WwiseSoundBinding.cs b/Assets/Scripts/ServerShared/WwiseSoundBinding.cs deleted file mode 100644 index da7a97548..000000000 --- a/Assets/Scripts/ServerShared/WwiseSoundBinding.cs +++ /dev/null @@ -1,22 +0,0 @@ -using MessagePack; -using Newtonsoft.Json; - -[MessagePackObject, JsonObject(MemberSerialization.OptIn)] -public class WwiseSoundBinding -{ - [Key(0), JsonProperty("playEvent")] - public uint PlayEvent; -} - -[MessagePackObject, JsonObject(MemberSerialization.OptIn)] -public class WwiseLoopingSoundBinding : WwiseSoundBinding -{ - [Key(1), JsonProperty("stopEvent")] - public uint StopEvent; -} - -// public class WwiseParameterBinding -// { -// [Key(0), JsonProperty("parameter")] -// public uint Parameter; -// } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/WwiseSoundBinding.cs.meta b/Assets/Scripts/ServerShared/WwiseSoundBinding.cs.meta deleted file mode 100644 index b996ffa72..000000000 --- a/Assets/Scripts/ServerShared/WwiseSoundBinding.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2e128c1cb68f481c9a846344e8283014 -timeCreated: 1619729875 \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Zone.cs b/Assets/Scripts/ServerShared/Zone.cs index 1ad7888fb..48b7517c9 100644 --- a/Assets/Scripts/ServerShared/Zone.cs +++ b/Assets/Scripts/ServerShared/Zone.cs @@ -15,11 +15,42 @@ using float2 = CultMath.float2; public class Zone { public Action Log; - public ReactiveCollection Entities = new ReactiveCollection(); + + // Membership, in admission order. Admit and Remove are the only writers; everyone else reads this view, which has + // no mutating member, so the death watch below follows membership by construction. + private readonly ReactiveCollection _entities = new ReactiveCollection(); + public MemberView Entities { get; } + + public sealed class MemberView : IReadOnlyReactiveCollection + { + private readonly ReactiveCollection _members; + internal MemberView(ReactiveCollection members) => _members = members; + public int Count => _members.Count; + public Entity this[int index] => _members[index]; + public int IndexOf(Entity entity) => _members.IndexOf(entity); + public bool Contains(Entity entity) => _members.Contains(entity); + public IEnumerator GetEnumerator() => _members.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public UniRx.IObservable> ObserveAdd() => _members.ObserveAdd(); + public UniRx.IObservable ObserveCountChanged(bool notifyCurrentCount = false) => _members.ObserveCountChanged(notifyCurrentCount); + public UniRx.IObservable> ObserveMove() => _members.ObserveMove(); + public UniRx.IObservable> ObserveRemove() => _members.ObserveRemove(); + public UniRx.IObservable> ObserveReplace() => _members.ObserveReplace(); + public UniRx.IObservable ObserveReset() => _members.ObserveReset(); + } // Laid mines, in lay order. Zone owns their existence: Lay is the one adder, the mine step the one remover, // and every removal is a blast. Runtime state, never saved. public ReactiveCollection Mines = new ReactiveCollection(); + + // Vented vapour clouds, in vent order. Zone owns their existence: Vent is the one adder, StepClouds the one + // remover, and Obscuration the one reader that detection uses. Runtime state, never saved. + public ReactiveCollection Clouds = new ReactiveCollection(); + + // Floating items (death drops, jettisoned cargo), in release order. Zone owns their existence: Release is the one + // adder; StepFloatingItems (expiry) and TryPickUp are the only removers. TryHold, Free and Remove-of-the-holder + // are the only writers of FloatingItem.Holder. Runtime state, never saved. + public ReactiveCollection FloatingItems = new ReactiveCollection(); public Dictionary Planets = new Dictionary(); public Dictionary PlanetInstances = new Dictionary(); @@ -55,6 +86,8 @@ public class Zone public List PendingShots = new List(); public Subject ShotCommitted = new Subject(); public Subject ShotResolved = new Subject(); + // Contacts.Step publishes each hull-on-hull contact it resolves; presentations are the only readers. + public Subject Contacted = new Subject(); private int _nextShotId; public int NextShotId() => ++_nextShotId; @@ -73,13 +106,16 @@ public class Zone return false; } + private readonly List _departures = new List(); + internal IReadOnlyList Departures => _departures; + public float Time { get => (float) _time; } // Zone time at full precision, for the index's orbital keys, which must agree with ChunkPose's own. - internal double ExactTime => _time; + public double ExactTime => _time; public ZonePack Pack { get; } public GalaxyZone GalaxyZone { get; } public Galaxy Galaxy { get; } @@ -94,8 +130,16 @@ public class Zone private uint _lastBodyId; public FloatingBodyId NextBodyId() => new FloatingBodyId(++_lastBodyId); + // The death ordinal of the loot dice: the nth death in this zone rolls on SimulationDice.For(CombatSeed, LootStream, n). + private uint _deaths; + + // One death subscription per member entity: Admit creates it together with the membership, Remove disposes it + // together with the membership, and nothing else touches either. + private readonly Dictionary _deathWatches = new Dictionary(); + public Zone(ItemManager itemManager, PlanetSettings settings, ZonePack pack, GalaxyZone galaxyZone, Galaxy galaxy) { + Entities = new MemberView(_entities); _time = pack.Time; GalaxyZone = galaxyZone; Galaxy = galaxy; @@ -109,7 +153,11 @@ public class Zone // in the simulation, not only in Unity's own loot-drop subscription. One subscription point covers // every join, whichever caller admits the entity (deserialization below, a jump, a spawned turret) -- // ObserveAdd fires for all of them. Forbidden writer: no presentation may remove an entity from Zone. - Entities.ObserveAdd().Subscribe(add => add.Value.Death.Subscribe(_ => { Entities.Remove(add.Value); add.Value.Deactivate(); })); + // The death watch lives exactly as long as the entity's membership in this zone: installed on admission, + // disposed on removal (death, dock, jump), so an entity admitted again never holds a second one. + // The one record of a removal for observers (ruling reveal-ends-on-perception): read by the next Sense pass. + _entities.ObserveRemove().Subscribe(remove => _departures.Add(new Departure(remove.Value, remove.Value.Position.xz, + remove.Value.Visibility))); // Leaving Entities, by death, docking or a transfer, is leaving the zone's pilots: the agent and its flight // membership go with the ship, so nothing keeps flying a hull that is not here. @@ -125,7 +173,7 @@ public class Zone foreach (var orbit in pack.Orbits) { - Orbits.Add(orbit.Key, new Orbit(Settings, cache.Get(orbit))); + Orbits.Add(orbit.Key, new Orbit(cache.Get(orbit))); } foreach (var body in pack.Planets) @@ -139,7 +187,6 @@ public class Zone // the rule generation uses, and keeps it. FieldKinds.Ensure(body.Key, belt, cache); AsteroidBelts[body.Key] = new AsteroidBelt(belt); - Targets.Add(new BeltTargets(this, body.Key, belt, settings, _time)); break; case SunData sun: var sunInstance = new Sun(settings, sun, Orbits[planet.Orbit.Key]); @@ -155,6 +202,42 @@ public class Zone } } + // Orbits, bodies and belts exist: every rail's period is derived once, from the field it orbits in. + foreach (var orbit in Orbits) + { + var parent = orbit.Value.Data.Parent; + if (!parent.IsSet()) continue; + if (!_childOrbits.TryGetValue(parent.Key, out var siblings)) + _childOrbits[parent.Key] = siblings = new List(); + siblings.Add(orbit.Key); + } + foreach (var body in PlanetInstances) + if (body.Value.WellStrength > 0) + _wellOn.TryAdd(Planets[body.Key].Orbit.Key, body.Value); + foreach (var orbit in Orbits) + orbit.Value.Period = orbit.Value.Data.Parent.IsSet() + ? PeriodAround(orbit.Value.Data.Parent.Key, orbit.Value.Data.Distance, orbit.Key) + : float.PositiveInfinity; + foreach (var belt in AsteroidBelts) + { + var beltOrbit = Planets[belt.Key].Orbit.Key; + var beltParent = Orbits[beltOrbit].Data.Parent.Key; + for (var i = 0; i < belt.Value.Periods.Length; i++) + belt.Value.Periods[i] = PeriodAround(beltParent, belt.Value.Data.Asteroids[i].Distance, beltOrbit); + } + + PopulatedRadius = ComputePopulatedRadius(); + + // Aetheria gravity (target invariant zone-valid-before-tick): every orbit is placed at the pack's time + // when the zone is built, so each well, light and body pose read before the first Update is where the + // body is. Velocity stays zero until the first Update differences two placed positions. + foreach (var orbit in Orbits) + GetOrbitPosition(orbit.Key); + + // BeltTargets copies the belts' periods, so it is built after them. + foreach (var belt in AsteroidBelts) + Targets.Add(new BeltTargets(this, belt.Key, belt.Value.Data, settings, _time)); + // Cut 2 (docs/mining-cut.md): read after belts are built so a later ChunkExists/ChunkRadius call has // Planets/AsteroidBelts populated. A pack from before key 6 existed has ChunkWear == null (nullable // persistence rule); that reads as no wear rather than throwing. @@ -175,17 +258,32 @@ public class Zone // TODO: Associate planets with stored entities for planetary colonies } - // The one admission into this zone (docs/scenarios-cut.md, 2.2): the only writer of Entities.Add and the only + // The one admission into this zone (docs/scenarios-cut.md, 2.2): the only writer of membership and the only // creator of agents. Construction, new-run staging (RunStart), warp arrival, undock and the console's spawned // turret all join through here. A piloted entity gets the zone's Minion; an unpiloted one gets no agent at all. - // Only a ship can be piloted. The Death subscription above covers every join, whichever caller admits it. + // Only a ship can be piloted. The death watch is installed here, for every join, whichever caller admits it. + // An entity that is already a member is refused: it would hold a second watch and a second agent. public void Admit(Entity entity, bool piloted) { - Entities.Add(entity); + if (_entities.Contains(entity)) throw new InvalidOperationException("entity: already a member of this zone"); + _entities.Add(entity); + _deathWatches.Add(entity, entity.Death.Subscribe(_ => { DropLoot(entity); Remove(entity); entity.Deactivate(); })); entity.Activate(); if (piloted) Agents.Add(CreateAgent((Ship) entity)); } + // The one removal from this zone (death, dock, jump): membership and its death watch leave together. False, and + // nothing changes, when the entity is not a member. The caller deactivates; Remove does not. + public bool Remove(Entity entity) + { + if (!_entities.Remove(entity)) return false; + _deathWatches.Remove(entity, out var watch); + watch.Dispose(); + foreach (var floating in FloatingItems) + if (ReferenceEquals(floating.Holder, entity)) Free(floating.Id); + return true; + } + private Agent CreateAgent(Ship ship) { var key = ship.Faction ?? Unaffiliated; @@ -204,10 +302,11 @@ public class Zone { Radius = Pack.Radius, Mass = Pack.Mass, - Entities = Entities.Select(EntitySerializer.Pack).ToList(), + Entities = _entities.Select(EntitySerializer.Pack).ToList(), Orbits = Orbits.Keys.Select(key => new CultRecordRef(key)).ToList(), Planets = Planets.Keys.Select(key => new CultRecordRef(key)).ToList(), Time = _time, + BossSpawned = Pack.BossSpawned, // Cut 2 (docs/mining-cut.md): drop entries that carry no live information -- healed (no damage) and // not currently broken -- so a save never accumulates wear rows for chunks nobody has touched since // they last respawned. @@ -220,18 +319,16 @@ public class Zone private bool IsExpired(ChunkWear wear) => wear.Damage <= 0f && (!wear.BrokenUntil.HasValue || wear.BrokenUntil.Value <= _time); - public void AddOrbit(OrbitData orbit) - { - Orbits.Add(_itemManager.ItemData.RefOf(orbit).Key, new Orbit(Settings, orbit)); - } - public void Update(float deltaTime) { _time += deltaTime; _updatedOrbits.Clear(); + // Every previous position is taken before any orbit is placed: GetOrbitPosition places a parent as a + // side effect of placing its child, so differencing inside one loop would depend on dictionary order. + foreach (var orbit in Orbits) + orbit.Value.PreviousPosition = orbit.Value.Position; foreach (var orbit in Orbits) { - orbit.Value.PreviousPosition = orbit.Value.Position; orbit.Value.Position = GetOrbitPosition(orbit.Key); orbit.Value.Velocity = (orbit.Value.Position - orbit.Value.PreviousPosition) / deltaTime; } @@ -240,9 +337,19 @@ public class Zone foreach(var agent in Agents.ToArray()) agent.Update(deltaTime); - foreach (var entity in Entities.ToArray()) entity.Update(deltaTime); + var entities = Entities.ToArray(); + foreach (var entity in entities) entity.PublishInbox(); + foreach (var entity in entities) entity.Update(deltaTime); + foreach (var entity in entities) entity.Sense(); + _departures.Clear(); StepMines(deltaTime); + StepClouds(deltaTime); + StepFloatingItems(deltaTime); + + // Hull contact (cut sim-contact): after every entity has moved and the mines and clouds have taken + // their toll, so only hulls still in the zone touch, and before shots resolve against the result. + Contacts.Step(this); // Cut 3: after every entity has had its chance to fire this tick, age and resolve the shots that // firing queued. A shot fired this tick with a flight time shorter than CommitHorizon commits and @@ -256,6 +363,134 @@ public class Zone Mines.Add(mine); } + public void Vent(VapourCloud cloud) + { + cloud.Id = NextBodyId(); + cloud.VentedAt = _time; + Clouds.Add(cloud); + } + + // The one adder of floating items: death drops and jettison both come here. The item drifts as a KinematicBody + // launched at `velocity` and expires after FloatingItemLifetime. + public FloatingItem Release(ItemInstance item, float2 position, float2 velocity) + { + var floating = new FloatingItem + { + Id = NextBodyId(), Item = item, Body = new KinematicBody { Position = position, Velocity = velocity }, + ReleasedAt = _time, Lifetime = _itemManager.GameplaySettings.FloatingItemLifetime + }; + FloatingItems.Add(floating); + return floating; + } + + // The one commit of a pickup: the first of the taker's cargo bays that accepts the item stores it and the item + // stops floating. Otherwise nothing changes. + // An item held by another entity is refused: one holder per item holds at the commit as well. + public bool TryPickUp(Entity taker, FloatingBodyId id) + { + var floating = FloatingItems.FirstOrDefault(f => f.Id.Equals(id)); + if (floating == null || (floating.Holder != null && !ReferenceEquals(floating.Holder, taker))) return false; + if (!taker.CargoBays.Any(bay => bay.TryStore(floating.Item))) return false; + FloatingItems.Remove(floating); + return true; + } + + // The tractor beam's claim on a floating item: false if it is absent or already held. The item stays where it is + // until its pull begins; StepFloatingItems places it from then on. + public bool TryHold(Entity holder, FloatingBodyId id) + { + var floating = FloatingItems.FirstOrDefault(f => f.Id.Equals(id)); + if (floating == null || floating.Holder != null) return false; + floating.Holder = holder; + floating.HeldFrom = floating.Body.Position; + floating.HeldProgress = 0; + return true; + } + + // How far along its pull to the holder a held item is, 0..1. + public void SetHeldProgress(FloatingBodyId id, float progress) + { + var floating = FloatingItems.FirstOrDefault(f => f.Id.Equals(id)); + if (floating?.Holder != null) floating.HeldProgress = saturate(progress); + } + + // Lets a held item go: it floats on from where it is with the Velocity and Drift it had. + public void Free(FloatingBodyId id) + { + var floating = FloatingItems.FirstOrDefault(f => f.Id.Equals(id)); + if (floating == null) return; + floating.Holder = null; + floating.HeldProgress = 0; + } + + // Called from the death subscription, before the entity leaves the zone: one generator per death. Each equipped + // item but the hull drops on a LootDropProbability draw; every cargo stack drops whole. Each drop leaves from the + // dead entity's position at a random heading. Draw order: Equipment order (the probability draw, then the heading + // of a dropped item), then each cargo bay's stacks in CargoBays order (a heading each). + private void DropLoot(Entity dead) + { + var settings = _itemManager.GameplaySettings; + var random = SimulationDice.For(CombatSeed, SimulationDice.LootStream, ++_deaths); + var at = new float2(dead.Position.x, dead.Position.z); + float2 Heading() { var angle = random.NextFloat() * 2f * PI; return float2(cos(angle), sin(angle)); } + foreach (var equipped in dead.Equipment.ToArray()) + { + if (equipped == dead.EquippedHull || !(random.NextFloat() < settings.LootDropProbability)) continue; + Release(equipped.EquippableItem, at, Heading() * settings.LootDropVelocity); + } + foreach (var bay in dead.CargoBays.ToArray()) + foreach (var stack in bay.Cargo.Keys.ToArray()) + Release(stack, at, Heading() * settings.LootDropVelocity); + } + + // After StepClouds and before FireControl.Step: each floating item drifts as a KinematicBody on the zone's force + // and is removed once its lifetime has run out. A held item is neither integrated nor expired: it is placed + // between where it was claimed and its holder, now that the entities have moved. + // The curve a held item rides from where it was claimed to its holder: the one owner, which the test scene's + // stand-in sim and tendril call rather than spell again. + public static float HeldPull(float progress) => smoothstep(0f, 1f, progress); + + private void StepFloatingItems(float deltaTime) + { + var settings = _itemManager.GameplaySettings; + foreach (var floating in FloatingItems.ToArray()) + { + if (floating.Holder != null) + { + floating.Body.Position = lerp(floating.HeldFrom, floating.Holder.Position.xz, HeldPull(floating.HeldProgress)); + continue; + } + floating.Body.Step(deltaTime, GetForce(floating.Body.Position), settings); + if (floating.ReleasedAt + floating.Lifetime <= _time) FloatingItems.Remove(floating); + } + } + + // The fraction of a sight line's signal that survives the clouds between `a` and `b`: the product of + // (1 - opacity now) over every cloud whose disc the segment touches, so 1f when none does. Derived from the + // live clouds at each call and stored nowhere; Sensor.Gain is where it enters detection. + public float Obscuration(float2 a, float2 b) + { + var through = 1f; + for (var i = 0; i < Clouds.Count; i++) + { + var cloud = Clouds[i]; + if (cloud.Touches(a, b)) through *= 1f - cloud.OpacityAt(_time); + } + return through; + } + + // After StepMines: each cloud drifts as a KinematicBody on the zone's force, as a mine does, and is removed + // once its lifetime has run out. Nothing else removes a cloud. + private void StepClouds(float deltaTime) + { + var settings = _itemManager.GameplaySettings; + foreach (var cloud in Clouds.ToArray()) + { + cloud.Body.Step(deltaTime, GetForce(cloud.Body.Position), settings); + if (cloud.VentedAt + cloud.Lifetime <= _time) Clouds.Remove(cloud); + } + } + // After the entity loop and before FireControl.Step, in lay order: each mine drifts as a KinematicBody, is // triggered by the first eligible hull its armed disc touches, and detonates through FireControl.Detonate at // its trigger plus fuse delay or at its lifetime, whatever its layer does (ruling mine-owner-leash). The @@ -292,30 +527,120 @@ public class Zone if (!_updatedOrbits.Contains(orbitID)) { - var orbit = Orbits[orbitID]; - float2 pos = float2.zero; - if (orbit.Period > .01f) - { - var phase = (float) frac(_time / orbit.Period); - pos = OrbitData.Evaluate(frac(phase + orbit.Data.Phase)) * orbit.Data.Distance; - - if (float.IsNaN(pos.x)) - { - //_context.Log("Orbit position is NaN, something went very wrong!"); - pos = float2.zero; - } - } - - var parentPosition = !Orbits[orbitID].Data.Parent.IsSet() - ? Orbits[orbitID].Data.FixedPosition : - GetOrbitPosition(orbit.Data.Parent.Key); - Orbits[orbitID].Position = parentPosition + pos; + Orbits[orbitID].Position = RailAt(orbitID, _time); _updatedOrbits.Add(orbitID); } return Orbits[orbitID].Position; } + // The rail law, once: where an orbit sits from its parent's node at a time. An infinite period (a parentless orbit, + // or one with no field to circle in) leaves the orbit at its phase: frac(t / inf) is 0. + private static float2 Offset(Orbit orbit, double time) + { + var pos = float2.zero; + if (orbit.Period > .01f) + { + var phase = (float) frac(time / orbit.Period); + pos = OrbitData.Evaluate(frac(phase + orbit.Data.Phase)) * orbit.Data.Distance; + + if (float.IsNaN(pos.x)) + pos = float2.zero; + } + + return pos; + } + + // The same rail law at any time, with no memo read or written: a parent is its own rail at that time. + private float2 RailAt(CultRecordKey orbitID, double time) + { + if (!orbitID.IsSet()) + return float2.zero; + if (!Orbits.TryGetValue(orbitID, out var orbit)) + { + Log?.Invoke("Requested orbit is not part of this zone!"); + return float2.zero; + } + var parentPosition = !orbit.Data.Parent.IsSet() ? orbit.Data.FixedPosition : RailAt(orbit.Data.Parent.Key, time); + return parentPosition + Offset(orbit, time); + } + + // Where an orbit is at a time: pure, writes nothing. At the step's own time it is the step's memo (GetOrbitPosition); + // at any other time (a presenter's drawn time) it is the rail law evaluated there. + public float2 OrbitPositionAt(CultRecordKey orbitID, double time) + { + if (!orbitID.IsSet()) + return float2.zero; + if (!Orbits.ContainsKey(orbitID)) + { + Log?.Invoke("Requested orbit is not part of this zone!"); + return float2.zero; + } + + return time == _time ? GetOrbitPosition(orbitID) : RailAt(orbitID, time); + } + + // orbit -> the well-bearing body on it, and orbit -> the orbits whose parent it is. Derived from the pack in the + // constructor, read only by PeriodAround and Strength. + private readonly Dictionary _wellOn = new Dictionary(); + private readonly Dictionary> _childOrbits = new Dictionary>(); + private readonly Dictionary _strengths = new Dictionary(); + + // The one owner of a rail's period (Orbit.Period, AsteroidBelt.Periods): 2 pi sqrt(d / a), a being the pull the + // field gives at distance d from the node being orbited. Round a body, that is the body's own well through + // GravityField. Round a bodyless node it is the ring law: the strength of the node's orbits inside d, plus the + // ring term for the orbits on d itself (within RingWindow of it), taken as a point at the node. A bodied self + // feels half the strength of its ring partners (as a binary does); a strengthless self (a station, a turret) + // takes the period its bodied ring partners have, the mean of what each of them feels. No pull gives an + // infinite period. + private const float RingWindow = 0.1f; + + private float PeriodAround(CultRecordKey parentOrbit, float distance, CultRecordKey self) + { + float a; + if (_wellOn.TryGetValue(parentOrbit, out var body)) + a = length(GravityField.Acceleration(body.WellStrength, body.RocheLimit, float2(distance, 0))); + else + { + var inside = 0f; + var ring = new List<(CultRecordKey Orbit, float Strength)>(); + if (_childOrbits.TryGetValue(parentOrbit, out var children)) + foreach (var child in children) + { + var childDistance = Orbits[child].Data.Distance; + var childStrength = Strength(child); + if (childDistance < distance - RingWindow) inside += childStrength; + else if (childDistance <= distance + RingWindow && childStrength > 0) ring.Add((child, childStrength)); + } + // Whose pull self feels: its own if it has strength, else each bodied member of the ring. + var ringSum = 0f; + foreach (var member in ring) ringSum += member.Strength; + var selfBodied = Strength(self) > 0; + var feelings = 0f; + var feelers = 0; + foreach (var member in ring) + if (!selfBodied || member.Orbit.Equals(self)) + { + feelings += (ringSum - member.Strength) / 2; + feelers++; + } + var strength = inside + (feelers > 0 ? feelings / feelers : 0f); + a = length(GravityField.Acceleration(strength, 0f, float2(distance, 0))); + } + return a > 0 && distance > 0 ? 2 * PI * sqrt(distance / a) : float.PositiveInfinity; + } + + // The well strength an orbit carries as a node: its own body's plus every orbit round it, recursively. + private float Strength(CultRecordKey orbit) + { + if (_strengths.TryGetValue(orbit, out var known)) return known; + var strength = _wellOn.TryGetValue(orbit, out var body) ? body.WellStrength : 0f; + if (_childOrbits.TryGetValue(orbit, out var children)) + foreach (var child in children) + strength += Strength(child); + return _strengths[orbit] = strength; + } + public float2 GetOrbitVelocity(CultRecordKey orbit) { if (Orbits.ContainsKey(orbit)) @@ -379,12 +704,15 @@ public class Zone // Cut 1 (docs/mining-cut.md): a chunk's pose is a pure function of zone time, computed when asked. No stored // pose survives a tick; the sim and the renderer both read it fresh through here. - public float4 ChunkPose(CultRecordKey belt, int index) + public float4 ChunkPose(CultRecordKey belt, int index) => ChunkPose(belt, index, _time); + + // The same pose at any time: the sim reads it at _time, a presenter at the drawn time (DrawAhead.Time). + public float4 ChunkPose(CultRecordKey belt, int index, double time) { var beltData = Planets[belt] as AsteroidBeltData; - var parentPosition = GetOrbitPosition(Orbits[beltData.Orbit.Key].Data.Parent.Key); + var parentPosition = OrbitPositionAt(Orbits[beltData.Orbit.Key].Data.Parent.Key, time); var size = ChunkRadius(new ChunkId(belt, index)); - return AsteroidBelts[belt].Pose(index, _time, parentPosition, Settings, size); + return AsteroidBelts[belt].Pose(index, time, parentPosition, size); } // Mining Cut 3 (docs/mining-cut-refresh.md): how bright a chunk is -- Reflector's rule (cross-section × the light @@ -399,33 +727,13 @@ public class Zone return kind.CrossSection * PI * cells * cells * GetLight(ChunkPose(chunk.Field, chunk.Index).xy); } - public void EvaluateBelt(CultRecordKey belt, Span into) + public void EvaluateBelt(CultRecordKey belt, Span into, double time) { var beltData = Planets[belt] as AsteroidBeltData; - var parentPosition = GetOrbitPosition(Orbits[beltData.Orbit.Key].Data.Parent.Key); + var parentPosition = OrbitPositionAt(Orbits[beltData.Orbit.Key].Data.Parent.Key, time); var beltInstance = AsteroidBelts[belt]; for (var i = 0; i < beltData.Asteroids.Length; i++) - into[i] = beltInstance.Pose(i, _time, parentPosition, Settings, ChunkRadius(new ChunkId(belt, i))); - } - - public OrbitData CreateOrbit(CultRecordKey parent, float2 position) - { - var parentPosition = GetOrbitPosition(parent); - var delta = position - parentPosition; - var distance = length(delta); - var period = Settings.OrbitPeriod.Evaluate(distance); - var phase = atan2(delta.y, delta.x) / (PI * 2); - var currentPhase = frac(_time / period); - var storedPhase = (float) frac(phase - currentPhase); - - var orbit = new OrbitData - { - Distance = distance, - Parent = new CultRecordRef(parent), - Phase = storedPhase - }; - Orbits.Add(_itemManager.ItemData.Upsert(orbit).Key, new Orbit(Settings, orbit)); - return orbit; + into[i] = beltInstance.Pose(i, time, parentPosition, ChunkRadius(new ChunkId(belt, i))); } public SecurityLevel GetSecurityLevel(float2 pos) @@ -445,34 +753,53 @@ public class Zone return security; } - public float GetHeight(float2 position) + // The potential of a body's well at the zone's edge, subtracted so every well is zero there: the one owner of the + // reference. GetHeight sums with it and the renderer's lowering (GravityLowering) hands it to the shader unchanged. + public float WellReference(Planet body) => GravityField.Potential(body.WellStrength, body.RocheLimit, Pack.Radius); + + // The extent of the populated area, from the zone's origin: owned here; presenters read it, nothing authors it. A static + // bound on where anything can be, so it holds at every time and reads nothing the pack's Radius decides: for each body, + // its orbit chain's reach plus its Roche limit; for each belt, the chain's reach to the orbit its asteroids circle (the + // belt orbit's parent) plus the belt's own Radius, its largest asteroid Distance. + public float PopulatedRadius { get; } + + private float ComputePopulatedRadius() { - var result = -PowerPulse(length(position)/(Pack.Radius*2), Settings.ZoneDepthExponent) * Settings.ZoneDepth; + var radius = 0f; + foreach (var body in PlanetInstances.Values) + radius = max(radius, ChainReach(body.BodyData.Orbit.Key) + body.RocheLimit); + foreach (var belt in AsteroidBelts) + radius = max(radius, ChainReach(Orbits[Planets[belt.Key].Orbit.Key].Data.Parent.Key) + belt.Value.Radius); + return radius; + } + + // The most an orbit can lie from the origin: the root's offset plus every orbit Distance down the chain to it. + private float ChainReach(CultRecordKey key) + { + var reach = 0f; + while (key.IsSet() && Orbits.TryGetValue(key, out var orbit)) + { + if (orbit.Data.Parent.IsSet()) reach += orbit.Data.Distance; + else reach += length(orbit.Data.FixedPosition); + key = orbit.Data.Parent.Key; + } + return reach; + } + + public float GetHeight(float2 position) => GetHeight(position, _time); + + // The field at a time: each well sits where its body's rail puts it then. The sim reads it at _time, a presenter at + // the drawn time, so a ship rides the same slope the drawn planet's well makes. + public float GetHeight(float2 position, double time) + { + var result = 0f; foreach (var body in PlanetInstances.Values) { - var p = position - body.Orbit.Position; //GetOrbitPosition(body.BodyData.Orbit) - var distSqr = lengthsq(p); - var gravityRadius = body.GravityWellRadius; - if (distSqr < gravityRadius*gravityRadius) - { - var depth = body.GravityWellDepth; - result -= PowerPulse(sqrt(distSqr) / gravityRadius, body.BodyData.GravityDepthExponent) * depth; - } - - if (body is GasGiant gas) - { - var waveRadius = gas.GravityWavesRadius; - if(distSqr < waveRadius*waveRadius) - { - var depth = gas.GravityWavesDepth; - var frequency = Settings.WaveFrequency.Evaluate(body.BodyData.Mass); - var speed = gas.GravityWavesSpeed; - result -= RadialWaves(sqrt(distSqr) / waveRadius, 8, 1.25f, frequency, (float) (_time * speed)) * depth; - } - } + var offset = position - OrbitPositionAt(body.BodyData.Orbit.Key, time); + result += GravityField.Potential(body.WellStrength, body.RocheLimit, length(offset)) - WellReference(body); } - return result; + return result / Settings.HeightExaggeration; } public float GetLight(float2 position) @@ -492,26 +819,28 @@ public class Zone internal float SchematicCellSize => _itemManager.GameplaySettings.SchematicCellSize; internal float FieldCrossSection(AsteroidBeltData belt) => _itemManager.ItemData.Get(belt.Kind)?.CrossSection ?? 0f; - // The one law of how a gravity well pushes anything: ships, floating items and mines all read it. The shape is - // the one ships have always felt, normalize(f) * strength * (1 / (1 - |f|^2) - 1), gated off below |f|^2 = .001. - // It is an acceleration, per second: the legacy law added that amount once per 60 fps frame with no dt, so - // GravityReferenceRate (60) restates it and `acceleration * dt` gives the legacy push at 60 fps. - public const float GravityReferenceRate = 60f; - - public static float2 GravityAcceleration(float2 normalXz, float strength) - { - var magnitude = lengthsq(normalXz); - if (magnitude <= .001f) return float2.zero; - return normalize(normalXz) * strength * (1 / (1 - magnitude) - 1) * GravityReferenceRate; - } - - // The acceleration the well exerts at `position`. + // The one source of gravitational acceleration (u/s^2): the sum of every body's well (GravityField). Ships, + // floating items, clouds and mines all read it, and so does Flow. It is the gradient of the potential GetHeight + // draws, so the two cannot disagree. public float2 GetForce(float2 position) { - var normal = GetNormal(position); - return GravityAcceleration(new float2(normal.x, normal.z), Settings.GravityStrength); + var force = float2.zero; + foreach (var body in PlanetInstances.Values) + force += GravityField.Acceleration(body.WellStrength, body.RocheLimit, position - body.Orbit.Position); + return force; } + // The global flow velocity at `position` in zone time, in u/s (FlowField is the law). The slope term reads the + // downhill direction, which is the force. + public float3 Flow(float3 position) => + FlowField.At(Settings.Flow, position, FlowScroll, GetForce(position.xz)); + + // The flow's noise scroll at zone time (Zone.Flow evaluates at exactly this); lowered to the shaders' _FlowScroll. + public float2 FlowScroll => FlowField.Scroll(Settings.Flow, _time); + + // The phase of a cycle of `period` seconds at zone time, for presenters that animate on the flow. + public float CyclePhase(float period) => FlowField.Cycle(_time, period); + public static float PowerPulse(float x, float exponent) { x *= 2; @@ -519,22 +848,12 @@ public class Zone return pow((x + 1) * (1 - x), exponent); } - public static float RadialWaves(float x, float maskExponent, float sineExponent, float frequency, float phase) + // The surface normal of the drawn height (potential / K), derived from the force. Display only (ship tilt): the + // sim never reads it as a force. + public float3 GetNormal(float2 pos) { - //x *= 2; - return PowerPulse(x, maskExponent) * cos(pow(x*2, sineExponent) * frequency + phase); - } - - public float3 GetNormal(float2 pos, float step = .1f, float mul = 1) - { - float hL = GetHeight(new float2(pos.x - step, pos.y)) * mul; - float hR = GetHeight(new float2(pos.x + step, pos.y)) * mul; - float hD = GetHeight(new float2(pos.x, pos.y - step)) * mul; - float hU = GetHeight(new float2(pos.x, pos.y + step)) * mul; - - // Deduce terrain normal - float3 normal = new float3((hL - hR), (hD - hU), step*2); - return normalize(normal).xzy; + var slope = GetForce(pos) / Settings.HeightExaggeration; + return normalize(new float3(slope.x, 1f, slope.y)); } } @@ -543,10 +862,13 @@ public class Planet public Orbit Orbit; protected readonly PlanetSettings Settings; public BodyData BodyData; - public float GravityWellDepth; - public float GravityWellRadius; public float BodyRadius; + // The well (GravityField): strength c by mass, and the Roche limit, which is both the closest a child may orbit and + // the well's softened core radius R (one curve of mass, never per body). Both are authored PlanetSettings curves. + public float WellStrength; + public float RocheLimit; + public Planet(PlanetSettings settings, BodyData data, Orbit orbit) { Settings = settings; @@ -558,30 +880,22 @@ public class Planet public void CalculateProperties() { BodyRadius = Settings.BodyRadius.Evaluate(BodyData.Mass) * BodyData.BodyRadiusMultiplier; - GravityWellRadius = Settings.GravityRadius.Evaluate(BodyData.Mass) * BodyData.GravityRadiusMultiplier; - GravityWellDepth = Settings.GravityDepth.Evaluate(BodyData.Mass) * BodyData.GravityDepthMultiplier; + WellStrength = Settings.WellStrength.Evaluate(BodyData.Mass); + RocheLimit = Settings.RocheLimit.Evaluate(BodyData.Mass); + if (!(WellStrength >= 0f) || float.IsInfinity(WellStrength)) + throw new InvalidOperationException("A body's well strength must be finite and not negative (PlanetSettings.WellStrength)."); + if (WellStrength > 0 && !(RocheLimit > 0f && !float.IsInfinity(RocheLimit))) + throw new InvalidOperationException("A body's Roche limit, which is its core radius, must be positive and finite (PlanetSettings.RocheLimit)."); } } public class GasGiant : Planet { public GasGiantData GasGiantData; - public float GravityWavesDepth; - public float GravityWavesRadius; - public float GravityWavesSpeed; public GasGiant(PlanetSettings settings, GasGiantData data, Orbit orbit) : base(settings, data, orbit) { GasGiantData = data; - CalculateProperties(); - } - - public new void CalculateProperties() - { - base.CalculateProperties(); - GravityWavesDepth = Settings.WaveDepth.Evaluate(BodyData.Mass) * GasGiantData.WaveDepthMultiplier; - GravityWavesRadius = Settings.WaveRadius.Evaluate(BodyData.Mass) * GasGiantData.WaveRadiusMultiplier; - GravityWavesSpeed = Settings.WaveSpeed.Evaluate(BodyData.Mass) * GasGiantData.WaveSpeedMultiplier; } } @@ -608,9 +922,14 @@ public class AsteroidBelt public AsteroidBeltData Data; public float Radius { get; } + // Each asteroid's orbital period, in seconds: derived once at zone build by Zone.PeriodAround (the field at the + // asteroid's own distance from the belt's parent), the only period Pose and BeltTargets divide by. + public float[] Periods { get; } + public AsteroidBelt(AsteroidBeltData data) { Data = data; + Periods = new float[data.Asteroids.Length]; Radius = data.Asteroids.Max(a => a.Distance); } @@ -618,12 +937,11 @@ public class AsteroidBelt // The only place a chunk pose is computed; no per-tick copy survives it. Cut 2: size is no longer read from // per-belt storage -- Zone owns wear now, so the caller (Zone.ChunkPose/EvaluateBelt) computes it through // Zone.ChunkRadius and passes it in. - public float4 Pose(int index, double time, float2 parentPosition, PlanetSettings settings, float size) + public float4 Pose(int index, double time, float2 parentPosition, float size) { var asteroid = Data.Asteroids[index]; var rot = (float) (time * asteroid.RotationSpeed % (PI * 2)); - var pos = OrbitData.Evaluate((float) frac(time / settings.OrbitPeriod.Evaluate(asteroid.Distance) + - asteroid.Phase)) * asteroid.Distance + parentPosition; + var pos = OrbitData.Evaluate((float) frac(time / Periods[index] + asteroid.Phase)) * asteroid.Distance + parentPosition; return float4(pos.x, pos.y, rot, size); } @@ -705,11 +1023,13 @@ public class Orbit public float2 Velocity = float2.zero; public float2 Position = float2.zero; public float2 PreviousPosition = float2.zero; - public float Period; - public Orbit(PlanetSettings settings, OrbitData data) + // Seconds per turn, written only by the Zone constructor (Zone.PeriodAround); infinite when the orbit has no + // field to circle in. + public float Period { get; internal set; } + + public Orbit(OrbitData data) { Data = data; - Period = settings.OrbitPeriod.Evaluate(data.Distance); } } diff --git a/Assets/Scripts/ServerShared/ZoneData.cs b/Assets/Scripts/ServerShared/ZoneData.cs index 2216355d6..dd098862f 100644 --- a/Assets/Scripts/ServerShared/ZoneData.cs +++ b/Assets/Scripts/ServerShared/ZoneData.cs @@ -43,6 +43,11 @@ public class ZonePack // default instance. [JsonProperty("chunkWear"), Key(6)] public List ChunkWear; + + // True once this zone's boss has been spawned. The dead boss leaves no entity, so this is the one fact that tells a + // slain boss from one that never existed; RunGoal.ExitOpen reads it. Written only by ZoneGenerator, carried by PackZone. + [JsonProperty("bossSpawned"), Key(7)] + public bool BossSpawned; } // Cut 2 (docs/mining-cut.md): one packed wear entry for one chunk. "Field" names the body that owns the chunk @@ -81,15 +86,6 @@ public abstract class BodyData [JsonProperty("bodyRadiusMul")] [Key(5)] public float BodyRadiusMultiplier = 1; - - [JsonProperty("gravRadiusMul")] [Key(6)] - public float GravityRadiusMultiplier = 1; - - [JsonProperty("depthMul")] [Key(7)] - public float GravityDepthMultiplier = 1; - - [JsonProperty("depthExp")] [Key(8)] - public float GravityDepthExponent = 16; } [CultDocument("aetheria.planetdata", "1"), MessagePackObject, JsonObject(MemberSerialization.OptIn)] @@ -181,18 +177,6 @@ public class GasGiantData : BodyData [JsonProperty("albedoRotationSpeed"), Key(13)] public float AlbedoRotationSpeed = 1; - [JsonProperty("gravRadiusMul")] [Key(14)] - public float WaveRadiusMultiplier = 1; - - [JsonProperty("depthMul")] [Key(15)] - public float WaveDepthMultiplier = 1; - - [JsonProperty("depthExp")] [Key(16)] - public float WaveDepthExponent = 8; - - [JsonProperty("depthExp")] [Key(17)] - public float WaveSpeedMultiplier = 8; - [JsonProperty("materialOverrides"), Key(18)] public List MaterialOverrides = new List(); diff --git a/Assets/Scripts/ServerShared/ZoneGenerator.cs b/Assets/Scripts/ServerShared/ZoneGenerator.cs index 2ff4fe005..202e5e4e9 100644 --- a/Assets/Scripts/ServerShared/ZoneGenerator.cs +++ b/Assets/Scripts/ServerShared/ZoneGenerator.cs @@ -256,45 +256,60 @@ public static class ZoneGenerator return loadoutGenerators[faction]; } + // L4 or L5: 60 degrees (one sixth of a turn) ahead of or behind the planet on its orbit. Phase is in turns. OrbitData CreateLagrangeOrbit(OrbitData baseOrbit) { var lagrangeOrbit = new OrbitData { Parent = baseOrbit.Parent, Distance = baseOrbit.Distance, - Phase = baseOrbit.Phase + PI / 3 * sign(random.NextFloat() - .5f), + Phase = baseOrbit.Phase + sign(random.NextFloat() - .5f) / 6f, }; pack.Orbits.Add(cache.Upsert(lagrangeOrbit)); return lagrangeOrbit; } - void PlaceTurret(OrbitData orbit, LoadoutGenerator loadoutGenerator, int distanceMultiplier) + // A turret co-orbits with its station, on one side of it (side is -1 behind, +1 ahead), clear of the body inside + // it on that side by one of the turret's own radii: its centre sits innerReach + 2 turretReach beyond that + // body's. Every body's reach counts, so turrets of differing reach clear each other. Phase is in turns, so the + // arc length divides by the orbit's circumference. Returns where the turret sits (signed arc from the station) + // and its reach, or null when there is no turret hull to generate, before any orbit is created. + (float arc, float reach)? PlaceTurret(OrbitData orbit, LoadoutGenerator loadoutGenerator, float side, float innerArc, float innerReach) { - var phase = 20f * distanceMultiplier / orbit.Distance; + var turret = loadoutGenerator.GenerateTurretLoadout(); + if (turret == null) return null; + var turretReach = (itemManager.GetData(turret.Hull) as HullData).Reach(itemManager.GameplaySettings.SchematicCellSize); + var arc = innerArc + side * (innerReach + 2 * turretReach); var turretOrbit = new OrbitData { Parent = orbit.Parent, Distance = orbit.Distance, - Phase = orbit.Phase + phase + Phase = orbit.Phase + arc / (2 * PI * orbit.Distance) }; pack.Orbits.Add(cache.Upsert(turretOrbit)); - var turret = loadoutGenerator.GenerateTurretLoadout(); - if (turret == null) return; turret.Orbit = cache.RefOf(turretOrbit); pack.Entities.Add(turret); + return (arc, turretReach); } - void PlaceTurrets(OrbitData orbit, LoadoutGenerator loadoutGenerator, int count) + // Turrets flank the station alternately, behind then ahead, each side growing outward from the station. + void PlaceTurrets(OrbitData orbit, LoadoutGenerator loadoutGenerator, int count, float stationReach) { + var arcs = new float[2]; + var reaches = new[] { stationReach, stationReach }; for(int t=0; t + (itemManager.GetData(station.Hull) as HullData).Reach(itemManager.GameplaySettings.SchematicCellSize); + for (var i = 0; i < storyStations.Length; i++) { var story = storyStations[i]; @@ -312,7 +327,7 @@ public static class ZoneGenerator station.Story = i; pack.Entities.Add(station); - if (ambient) PlaceTurrets(lagrangeOrbit, GetLoadoutGenerator(story.Faction), story.Turrets); + if (ambient) PlaceTurrets(lagrangeOrbit, GetLoadoutGenerator(story.Faction), story.Turrets, StationReach(station)); } for (var i = storyStations.Length; i < selectedStationOrbits.Length; i++) @@ -334,9 +349,27 @@ public static class ZoneGenerator station.SecurityRadius = pack.Radius; pack.Entities.Add(station); - if (ambient) PlaceTurrets(lagrangeOrbit, GetLoadoutGenerator(nearestFaction), 2); + if (ambient) PlaceTurrets(lagrangeOrbit, GetLoadoutGenerator(nearestFaction), 2, StationReach(station)); } + // A boss zone gets its faction's boss whether or not the zone is ambient: the boss is the run's goal, not + // wandering traffic. RunGoal reads the mark; nothing else decides whether a boss lives. + foreach (var bossFaction in galaxy.BossZones.Where(entry => entry.Value == galaxyZone).Select(entry => entry.Key)) + { + var boss = GetLoadoutGenerator(bossFaction).GenerateBossLoadout(); + if (boss == null) + { + itemManager.Log($"No boss could be generated for {bossFaction.Name}; its boss zone has no boss to kill!"); + continue; + } + boss.Boss = true; + pack.Entities.Add(boss); + pack.BossSpawned = true; + } + + if (galaxyZone == galaxy.Exit && !pack.BossSpawned) + itemManager.Log("Galaxy.Exit has no boss: Galaxy.BossZones does not map a boss faction to the exit zone, or its boss could not be generated (ZoneGenerator exit-without-boss). The exit gate stays sealed."); + if (!ambient) return pack; var enemyCount = (int)(random.NextFloat() * factionPresence * 2) + baseStationCount; @@ -513,7 +546,6 @@ public class GeneratorPlanet public float Distance; public float Phase; public float Mass; - //public float Period; public float ChildDistanceMinimum; public float ChildDistanceMaximum; public bool Empty = false; @@ -568,7 +600,6 @@ public class GeneratorPlanet ChildDistanceMaximum = (i % 2 == 0 ? p0ChildDist : p1ChildDist) }; child.ChildDistanceMinimum = Settings.PlanetSafetyRadius.Evaluate(child.Mass) * 2; - //child.Period = Settings..Evaluate(child.Distance); Children.Add(child); } @@ -629,7 +660,6 @@ public class GeneratorPlanet Distance = distances[i], Phase = random.NextFloat() }; - //child.Period = Context.GlobalData.OrbitalPeriod(child.Distance); child.ChildDistanceMinimum = Settings.PlanetSafetyRadius.Evaluate(child.Mass) * 2; // Maximum child distance of child is the smallest distance to either of its neighbors child.ChildDistanceMaximum = min(i == 0 ? child.Distance - ChildDistanceMinimum : child.Distance - distances[i - 1], diff --git a/Assets/Scripts/UI/FieldTester.cs b/Assets/Scripts/UI/FieldTester.cs index 0e955e3f5..493b0b60e 100644 --- a/Assets/Scripts/UI/FieldTester.cs +++ b/Assets/Scripts/UI/FieldTester.cs @@ -26,6 +26,10 @@ public class FieldTester : MonoBehaviour public Camera Camera; public FieldDriver TestField; public PropertiesPanel Properties; + // The scene's slow viewing timings for a grab, published as the events' phase durations. + public float GrabExtendTime; + public float GrabEnvelopTime; + public float GrabPullTime; private AetheriaInput _input; private bool _forceThrust; @@ -49,6 +53,14 @@ public class FieldTester : MonoBehaviour private List<(float lerp, float time, Transform transform)> _pickups = new List<(float lerp, float time, Transform transform)>(); + // This scene stands in for the simulation, so it owns its pickup's grab timeline and pose: one grab at a time. + private bool _grabbing; + private int _grabIndex; + private float _grabElapsed; + private float3 _grabStart; + private bool _envelopPublished; + private bool _pullPublished; + private void Start() { _input = new AetheriaInput(); @@ -59,10 +71,7 @@ public class FieldTester : MonoBehaviour if (binder == null) Debug.LogError("FieldTester expects a CapabilityPresentationBinder on TestField's GameObject; no capability events will reach the field."); else - binder.Bind(_capabilityEvents, - grabTargetResolver: handle => handle >= 0 && handle < _pickups.Count ? _pickups[handle].transform : null, - grabInitialVelocityResolver: handle => Vector3.forward * - (PickupTravelDistance / lerp(PickupTravelTimeMin, PickupTravelTimeMax, _pickups[handle].lerp))); + binder.Bind(_capabilityEvents); // Impact absorption (fork L): what used to be FieldDriver's own click handler is now this // scene's stand-in for whatever will eventually detect a hit and publish AbsorbEvent. @@ -73,7 +82,7 @@ public class FieldTester : MonoBehaviour { var damageType = DamageTypeCycle[_nextDamageTypeIndex]; _nextDamageTypeIndex = (_nextDamageTypeIndex + 1) % DamageTypeCycle.Length; - _capabilityEvents.PublishAbsorb(new AbsorbEvent(hit.point.ToCultMath(), ray.direction.ToCultMath(), TestField.TestMagnitude, damageType)); + _capabilityEvents.PublishAbsorb(new AbsorbEvent(hit.point.ToCultMath(), ray.direction.ToCultMath(), TestField.TestMagnitude, damageType, AbsorbLayer.Shield)); }; } @@ -99,12 +108,16 @@ public class FieldTester : MonoBehaviour var click = pickup.GetComponent(); click.OnClick += (collider, data, ray, hit) => { - if (!TestField.CanGrab) return; + if (_grabbing) return; click.Clear(); - var p = _pickups[i1]; - _capabilityEvents.PublishGrab(new GrabEvent(i1, GrabPhase.Started, p.transform.position.ToCultMath(), 0)); - p.transform = null; - _pickups[i1] = p; + _grabbing = true; + _grabIndex = i1; + _grabElapsed = 0; + _envelopPublished = _pullPublished = false; + _grabStart = _pickups[i1].transform.position.ToCultMath(); + var id = new FloatingBodyId((uint) i1); + _capabilityEvents.PublishGrab(new GrabEvent(id, GrabPhase.Started, _grabStart, 0)); + _capabilityEvents.PublishGrab(new GrabEvent(id, GrabPhase.Extend, _grabStart, GrabExtendTime)); }; pickup.ScanLabelContainer.gameObject.SetActive(false); @@ -117,6 +130,45 @@ public class FieldTester : MonoBehaviour } } + // Publishes Envelop and Pull once each at their cumulative boundaries, holds the pickup still until the pull and + // then moves it along the same smoothstep as Zone's held pose, and ends with Completed and the pickup's removal. + private void AdvanceGrab() + { + _grabElapsed += Time.deltaTime; + var id = new FloatingBodyId((uint) _grabIndex); + var pullStart = GrabExtendTime + GrabEnvelopTime; + if (!_envelopPublished && _grabElapsed >= GrabExtendTime) + { + _envelopPublished = true; + _capabilityEvents.PublishGrab(new GrabEvent(id, GrabPhase.Envelop, _grabStart, GrabEnvelopTime)); + } + if (!_pullPublished && _grabElapsed >= pullStart) + { + _pullPublished = true; + _capabilityEvents.PublishGrab(new GrabEvent(id, GrabPhase.Pull, _grabStart, GrabPullTime)); + } + var pickup = _pickups[_grabIndex].transform; + pickup.position = PulledPosition(_grabStart, TestField.transform.position.ToCultMath(), _grabElapsed, + GrabExtendTime, GrabEnvelopTime, GrabPullTime).ToUnity(); + if (_pullPublished && PullProgress(_grabElapsed, GrabExtendTime, GrabEnvelopTime, GrabPullTime) >= 1) + { + _capabilityEvents.PublishGrab(new GrabEvent(id, GrabPhase.Completed, pickup.position.ToCultMath(), 0)); + Destroy(pickup.gameObject); + var p = _pickups[_grabIndex]; + p.transform = null; + _pickups[_grabIndex] = p; + _grabbing = false; + } + } + + // How far along the pull a grab is `elapsed` seconds in: 0 through Extend and Envelop, then 0..1 over the pull. + public static float PullProgress(float elapsed, float extend, float envelop, float pull) => + saturate((elapsed - extend - envelop) / max(pull, 1e-4f)); + + // Where the stand-in sim holds its pickup: still through Extend and Envelop, then along Zone's held-pose curve. + public static float3 PulledPosition(float3 start, float3 holder, float elapsed, float extend, float envelop, float pull) => + lerp(start, holder, Zone.HeldPull(PullProgress(elapsed, extend, envelop, pull))); + private void Update() { var move = _forceThrust ? float2(0,1) : _input.Player.Move.ReadValue().ToCultMath(); @@ -144,10 +196,12 @@ public class FieldTester : MonoBehaviour _capabilityEvents.PublishThrust(new ThrustEvent(_push, min(length(_push), 1), float2(_frontTwist, _rearTwist))); + if (_grabbing) AdvanceGrab(); + for (var i = 0; i < _pickups.Count; i++) { var (l, time, t) = _pickups[i]; - if (t == null) continue; + if (t == null || (_grabbing && i == _grabIndex)) continue; time = frac(time + Time.deltaTime / lerp(PickupTravelTimeMin, PickupTravelTimeMax, l)); t.localScale = Vector3.one * lerp(PickupSizeMin, PickupSizeMax, l) * Zone.PowerPulse(time - .5f, ScaleExponent); t.position = new Vector3(t.position.x, t.position.y, (time - .5f) * PickupTravelDistance); diff --git a/Assets/Scripts/UI/HUD/SchematicDisplay.cs b/Assets/Scripts/UI/HUD/SchematicDisplay.cs index e2eb764f7..57f545960 100644 --- a/Assets/Scripts/UI/HUD/SchematicDisplay.cs +++ b/Assets/Scripts/UI/HUD/SchematicDisplay.cs @@ -22,8 +22,6 @@ public class SchematicDisplay : MonoBehaviour public GameObject ShieldIcon; public Image HeatsinkBackground; - public GameObject AetherDriveUi; - public TextMeshProUGUI EnergyLabel; public TextMeshProUGUI CockpitTemperatureLabel; public TextMeshProUGUI RadiatorTemperatureLabel; @@ -32,9 +30,6 @@ public class SchematicDisplay : MonoBehaviour public TextMeshProUGUI VisibilityLabel; public TextMeshProUGUI HullDurabilityLabel; public TextMeshProUGUI DistanceLabel; - public TextMeshProUGUI ForwardRPMLabel; - public TextMeshProUGUI StrafeRPMLabel; - public TextMeshProUGUI TurnRPMLabel; public RectTransform SensorCooldownFill; public RectTransform EnergyFill; @@ -42,9 +37,6 @@ public class SchematicDisplay : MonoBehaviour public RectTransform HeatstrokeMeterFill; public RectTransform HypothermiaMeterFill; public RectTransform HeatstrokeLimitFill; - public RectTransform ForwardRPMFill; - public RectTransform StrafeRPMFill; - public RectTransform TurnRPMFill; private Entity _entity; private EquippableItem _hull; @@ -55,7 +47,6 @@ public class SchematicDisplay : MonoBehaviour private HeatStorage[] _heatStorages; private EquippedCargoBay[] _cargoBays; private SchematicDisplayItem[] _schematicItems; - private AetherDrive _aetherDrive; private bool _enemy; private Entity _player; @@ -67,7 +58,8 @@ public class SchematicDisplay : MonoBehaviour public class SchematicDisplayItem { - public EquippedItem Item; + // The row Entity.SchematicRows derived: which item, which class and which range it shows. + public SchematicRow Row; public SchematicListElement ListElement; public IProgressBehavior Cooldown; // public ItemUsage ItemUsage; @@ -78,20 +70,16 @@ public class SchematicDisplay : MonoBehaviour { _enemy = player != null; _player = player; - if (_schematicItems != null) - foreach (var item in _schematicItems) - { - item.ListElement.GetComponent().ReturnToPool(); - } + ReturnRows(); _entity = entity; + if (VisibilityLabel) + VisibilityLabel.gameObject.SetActive(!_enemy); if (!_enemy) { _cockpit = entity.GetBehavior(); _reactor = entity.GetBehavior(); _capacitors = entity.GetBehaviors().ToArray(); - _aetherDrive = entity.GetBehavior(); - AetherDriveUi.SetActive(_aetherDrive != null); _radiators = entity.GetBehaviors().ToArray(); if (_radiators.Length == 0) @@ -106,24 +94,41 @@ public class SchematicDisplay : MonoBehaviour CargoTemperatureLabel.text = "N/A"; } - // Cut 2 (docs/fire-control-cut.md): an enemy schematic shows only what `player` has actually - // resolved (FireControl.IsRevealed) -- the same predicate the selection writer and the AI use. The - // player's own schematic is unfiltered; there is nothing to reveal about your own ship. - _schematicItems = entity.Equipment - .Where(x => x.Behaviors.Any(b => b.Data is WeaponData) && (!_enemy || FireControl.IsRevealed(player, x))) + BuildRows(Rows()); + } + + // Which rows, which class and which range label are Entity.SchematicRows' decision (aetheria-ew, classify-from-belief); + // this display only renders them. + private IEnumerable Rows() => (_player ?? _entity).SchematicRows(_entity); + + private void ReturnRows() + { + if (_schematicItems == null) return; + foreach (var item in _schematicItems) + item.ListElement.GetComponent().ReturnToPool(); + _schematicItems = null; + } + + private void BuildRows(IEnumerable rows) + { + _schematicItems = rows .Select(x => new SchematicDisplayItem { - Item = x, + Row = x, ListElement = ListElementPrototype.Instantiate(), - Cooldown = _enemy ? null : (IProgressBehavior) x.Behaviors.FirstOrDefault(b=> b is IProgressBehavior), + Cooldown = _enemy ? null : (IProgressBehavior) x.Item.Behaviors.FirstOrDefault(b=> b is IProgressBehavior), // ItemUsage = _enemy ? null : (ItemUsage) x.Behaviors.FirstOrDefault(b=> b is ItemUsage), - Weapon = (Weapon) x.Behaviors.FirstOrDefault(b=>b is Weapon) + Weapon = _enemy ? null : (Weapon) x.Item.Behaviors.FirstOrDefault(b=>b is Weapon) }) .ToArray(); foreach (var x in _schematicItems) { - if(x.Item.Data is WeaponItemData weaponItemData) + if (x.Row.Mount != null) + x.ListElement.ShowGear(x.Row.Mount.Type, null); + else if(x.Row.Claimed is WeaponItemData weaponItemData) x.ListElement.ShowWeapon(weaponItemData); + else + x.ListElement.ShowGear(x.Row.Claimed.HardpointType, x.Row.Claimed.Name); //x.ListElement.Label.text = x.Item.EquippableItem.Name; if (!_enemy) { @@ -186,32 +191,28 @@ public class SchematicDisplay : MonoBehaviour EnergyFill.anchorMax = new Vector2(charge / maxCharge, 1); EnergyLabel.text = $"{((int)charge).ToString()}/{((int)maxCharge).ToString()} + ({((int)_reactor.Draw).ToString()})"; } - - if (_aetherDrive != null) - { - ForwardRPMLabel.text = ActionGameManager.PlayerSettings.Format(_aetherDrive.Rpm.x); - ForwardRPMFill.anchorMax = new Vector2(_aetherDrive.Rpm.x / _aetherDrive.MaximumRpm, 1); - - StrafeRPMLabel.text = ActionGameManager.PlayerSettings.Format(_aetherDrive.Rpm.y); - StrafeRPMFill.anchorMax = new Vector2(_aetherDrive.Rpm.y / _aetherDrive.MaximumRpm, 1); - - TurnRPMLabel.text = ActionGameManager.PlayerSettings.Format(_aetherDrive.Rpm.z); - TurnRPMFill.anchorMax = new Vector2(_aetherDrive.Rpm.z / _aetherDrive.MaximumRpm, 1); - } } // else // { // DistanceLabel.text = $"{(int)length(_entity.Position - _player.Position)}"; // } + // A reveal gained or ended after selection changes the rows with no event to hook: rebuild when the + // revealed set differs from the rows' items. + if (_enemy && !Rows().Select(r => r.Key).SequenceEqual(_schematicItems.Select(x => x.Row.Key))) + { + ReturnRows(); + BuildRows(Rows()); + } + // Cut 2 (docs/fire-control-cut.md): marks whichever row is the player's current aim point. - // Re-checked every frame (not just on ShowShip) because ResolvedTargetItem can drop on its own + // Re-checked every frame (not just on ShowShip) because ResolvedAim can drop on its own // as info decays, with no event to hook. if (_enemy && _schematicItems != null) foreach (var x in _schematicItems) - x.ListElement.SetSelected(x.Item == _player.ResolvedTargetItem); + x.ListElement.SetSelected(x.Row.Marks(_player.ResolvedAim)); - if(VisibilityLabel) + if(VisibilityLabel && !_enemy) VisibilityLabel.text = ((int)_entity.Visibility).ToString(); if(HullDurabilityFill) @@ -227,11 +228,11 @@ public class SchematicDisplay : MonoBehaviour { if (!_enemy) { - var itemData = _entity.ItemManager.GetData(x.Item.EquippableItem); - x.ListElement.HeatFill.anchorMax = new Vector2(unlerp(itemData.MinimumTemperature, itemData.MaximumTemperature, x.Item.Temperature), 0); + var itemData = _entity.ItemManager.GetData(x.Row.Item.EquippableItem); + x.ListElement.HeatFill.anchorMax = new Vector2(unlerp(itemData.MinimumTemperature, itemData.MaximumTemperature, x.Row.Item.Temperature), 0); if (x.Cooldown != null) x.ListElement.CooldownFill.anchorMax = new Vector2(x.Cooldown.Progress, 1); - x.ListElement.DurabilityLabel.text = $"{(int)(x.Item.EquippableItem.Durability / itemData.Durability * 100)}%"; + x.ListElement.DurabilityLabel.text = $"{(int)(x.Row.Item.EquippableItem.Durability / itemData.Durability * 100)}%"; if (x.Weapon.WeaponData.AmmoType.IsSet()) { if(x.Weapon.WeaponData.MagazineSize > 1) @@ -241,10 +242,11 @@ public class SchematicDisplay : MonoBehaviour } } - if (x.Weapon.WeaponData != null) + if (x.ListElement.RangeLabel) { - if(x.ListElement.RangeLabel) - x.ListElement.RangeLabel.text = ((int) x.Weapon.Range).ToString(); + var range = x.Row.Range; + x.ListElement.RangeLabel.gameObject.SetActive(range.HasValue); + if (range.HasValue) x.ListElement.RangeLabel.text = ((int) range.Value).ToString(); } } } diff --git a/Assets/Scripts/UI/HUD/SchematicListElement.cs b/Assets/Scripts/UI/HUD/SchematicListElement.cs index 5603e927e..b42bf4632 100644 --- a/Assets/Scripts/UI/HUD/SchematicListElement.cs +++ b/Assets/Scripts/UI/HUD/SchematicListElement.cs @@ -15,13 +15,56 @@ public class SchematicListElement : MonoBehaviour public RectTransform CooldownFill; public RectTransform HeatFill; - // Cut 2 (docs/fire-control-cut.md): marks this row as the current aim point (Entity.ResolvedTargetItem) + // Cut 2 (docs/fire-control-cut.md): marks this row as the current aim point (Entity.ResolvedAim) // on an enemy schematic. Unassigned in a prefab that has not been wired up in the Unity editor yet // (unavailable in this pass) -- SetSelected below is a no-op until then, not a null reference. public GameObject SelectedIndicator; private List _iconInstances = new List(); + // A gear row names its class; created on first use as VisibleTargetIndicator.ShowLabel creates its own (no scene or + // prefab edit) and hidden by every other row kind, because pools are shared. + private TextMeshProUGUI _nameLabel; + + private void ClearIcons() + { + foreach(var prototype in _iconInstances) prototype.ReturnToPool(); + _iconInstances.Clear(); + } + + private void SetName(string name) + { + var show = !string.IsNullOrEmpty(name); + if (_nameLabel == null) + { + if (!show) return; + var child = new GameObject("Name", typeof(RectTransform)); + child.transform.SetParent(transform, false); + _nameLabel = child.AddComponent(); + _nameLabel.fontSize = 14; + _nameLabel.alignment = TextAlignmentOptions.Left; + _nameLabel.raycastTarget = false; + var rect = _nameLabel.rectTransform; + rect.anchorMin = new Vector2(0, 0); + rect.anchorMax = new Vector2(1, 1); + rect.offsetMin = new Vector2(40, 0); + rect.offsetMax = Vector2.zero; + } + _nameLabel.gameObject.SetActive(show); + if (show && _nameLabel.text != name) _nameLabel.text = name; + } + + // A revealed item that is not a weapon: its hardpoint's icon and, when given, its class name. Layout-aim reuses this with + // a null name for mount rows. + public void ShowGear(HardpointType type, string name) + { + ClearIcons(); + var icon = IconPrototype.Instantiate(); + _iconInstances.Add(icon.GetComponent()); + icon.sprite = Settings.GetIcon(type); + SetName(name); + } + public void SetSelected(bool selected) { if (SelectedIndicator != null) SelectedIndicator.SetActive(selected); @@ -29,8 +72,8 @@ public class SchematicListElement : MonoBehaviour public void ShowWeapon(WeaponItemData weapon) { - foreach(var prototype in _iconInstances) prototype.ReturnToPool(); - _iconInstances.Clear(); + ClearIcons(); + SetName(null); var caliberIcon = IconPrototype.Instantiate(); _iconInstances.Add(caliberIcon.GetComponent()); diff --git a/Assets/Scripts/UI/HUD/VisibleTargetIndicator.cs b/Assets/Scripts/UI/HUD/VisibleTargetIndicator.cs index f12220bd7..db512492e 100644 --- a/Assets/Scripts/UI/HUD/VisibleTargetIndicator.cs +++ b/Assets/Scripts/UI/HUD/VisibleTargetIndicator.cs @@ -2,10 +2,35 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; +using TMPro; public class VisibleTargetIndicator : MonoBehaviour { public RectTransform Transform; public Image Fill; public PlaceUIElementWorldspace Place; + public TextMeshProUGUI Label; + + // Null or empty hides the label; the first non-empty text creates it as a child (no scene or prefab edit) and keeps it. + // Pools are shared, so hide the label before the indicator returns to its pool. + public void ShowLabel(string text) + { + var show = !string.IsNullOrEmpty(text); + if (Label == null) + { + if (!show) return; + var child = new GameObject("Label", typeof(RectTransform)); + child.transform.SetParent(transform, false); + Label = child.AddComponent(); + Label.fontSize = 14; + Label.alignment = TextAlignmentOptions.Top; + Label.raycastTarget = false; + var rect = Label.rectTransform; + rect.anchorMin = rect.anchorMax = new Vector2(.5f, 0); + rect.pivot = new Vector2(.5f, 1); + rect.sizeDelta = new Vector2(200, 24); + } + Label.gameObject.SetActive(show); + if (show && Label.text != text) Label.text = text; + } } diff --git a/Assets/Scripts/UI/MainMenu.cs b/Assets/Scripts/UI/MainMenu.cs index f20208ff7..bd019ab21 100644 --- a/Assets/Scripts/UI/MainMenu.cs +++ b/Assets/Scripts/UI/MainMenu.cs @@ -127,8 +127,8 @@ public class MainMenu : MonoBehaviour _nextMenu.panel.AddButton("Quit", Application.Quit); } - // New Game: every way to set up a run, each with its brief. The test arenas are listed only in editor and - // development builds. + // New Game: every way to set up a run, each with its brief. A release build lists only the modes; the other ways + // to set up a run and the test arenas are listed only in editor and development builds. private void ShowScenarios() { _nextMenu.panel.Clear(); @@ -136,6 +136,8 @@ public class MainMenu : MonoBehaviour AddScenarios(Scenarios.Modes); if (Debug.isDebugBuild) { + _nextMenu.panel.AddSection("development"); + AddScenarios(Scenarios.Development); _nextMenu.panel.AddSection("test arenas"); AddScenarios(Scenarios.Tests); } @@ -297,9 +299,14 @@ public class MainMenu : MonoBehaviour _nextMenu.panel.AddField("Show Asteroids in Minimap", () => ActionGameManager.PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap, b => ActionGameManager.PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap = b); + _nextMenu.panel.AddField("Screen Shake", + () => ActionGameManager.PlayerSettings.GraphicsSettings.ScreenShake, + f => ActionGameManager.PlayerSettings.GraphicsSettings.ScreenShake = f, + 0, 1); _nextMenu.panel.AddButton("Back", () => { + ActionGameManager.SavePlayerSettings(); ShowSettings(); Fade(false); }); diff --git a/Assets/Scripts/UI/Menu/TradeMenu.cs b/Assets/Scripts/UI/Menu/TradeMenu.cs index 5c3245907..1adadcf15 100644 --- a/Assets/Scripts/UI/Menu/TradeMenu.cs +++ b/Assets/Scripts/UI/Menu/TradeMenu.cs @@ -192,9 +192,9 @@ public class TradeMenu : MonoBehaviour columns.Add(("Name", 3, x => () => x.item is CraftedItemInstance craftedItemInstance ? - $"{x.data.Name}" : - x.data.Name, - x => x.data.Name)); + $"{GameManager.ItemManager.Title(x.item)}" : + GameManager.ItemManager.Title(x.item), + x => GameManager.ItemManager.Title(x.item))); if(_hardpointFilter.filter==null) columns.Add(("Type", 2, x => () => @@ -352,7 +352,7 @@ public class TradeMenu : MonoBehaviour { int quantity = 1; Dialog.Clear(); - Dialog.Title.text = $"Buying {i.data.Name}"; + Dialog.Title.text = $"Buying {GameManager.ItemManager.Title(i.item)}"; Dialog.AddField("Quantity", () => quantity, q => quantity = min(min(q, GameManager.Credits / StationServices.BuyPrice(GameManager.ItemManager, s)), s.Quantity)); diff --git a/Assets/Scripts/UI/Properties Panel/CurveField.cs b/Assets/Scripts/UI/Properties Panel/CurveField.cs index 48c992890..d2e8b43e0 100644 --- a/Assets/Scripts/UI/Properties Panel/CurveField.cs +++ b/Assets/Scripts/UI/Properties Panel/CurveField.cs @@ -20,8 +20,7 @@ public class CurveField : MonoBehaviour public Image CurrentX; public Image CurrentY; - private BezierCurve _curve; - //private Func _xFunc; + private Func _y; public void SetCurrent(float x) { @@ -29,46 +28,33 @@ public class CurveField : MonoBehaviour CurrentY.gameObject.SetActive(true); var xrect = CurrentX.GetComponent(); var yrect = CurrentY.GetComponent(); - var y = _curve.Evaluate(x); + var y = _y(x); xrect.anchorMin = new Vector2(x, 0); xrect.anchorMax = new Vector2(x, y); yrect.anchorMin = new Vector2(x, y); yrect.anchorMax = new Vector2(x, y); } - public void Show(string label, BezierCurve curve, Func xFunc, bool showMax = false) + // Segments + 1 uniform samples of y over [0, 1], labelled by xFunc; the middle label sits at midX. + public void Show(string label, Func y, Func xFunc, float midX = .5f) { - _curve = curve; - //_xFunc = xFunc; + _y = y; CurrentX.gameObject.SetActive(false); CurrentY.gameObject.SetActive(false); Title.text = label; var points = new List(); - var keys = curve.Keys.Select(v => new Vector2(v.x, v.y)); - if (curve.Keys[0].x > .01f) keys = keys.Prepend(new Vector2(0, curve.Keys[0].y)); - if (curve.Keys[curve.Keys.Length-1].x < .99f) keys = keys.Append(new Vector2(1, curve.Keys[curve.Keys.Length-1].y)); - var keysArray = keys.ToArray(); - for (int i = 0; i < keysArray.Length - 1; i++) + for (int j = 0; j <= Segments; j++) { - for (int j = 0; j < Segments; j++) - { - var x = lerp(keysArray[i].x, keysArray[i + 1].x, (float) j / Segments); - points.Add(new Vector2(x, curve.Evaluate(x))); - } + var x = (float) j / Segments; + points.Add(new Vector2(x, y(x))); } - points.Add(new Vector2(1, curve.Evaluate(1))); Line.Points = points.ToArray(); MinLabel.text = xFunc(0); MaxLabel.text = xFunc(1); - if (showMax) - { - var midX = curve.Maximum; - MidLabel.text = xFunc(midX); - var rect = MidLabel.GetComponent(); - rect.anchorMin = new Vector2(midX, rect.anchorMin.y); - rect.anchorMax = new Vector2(midX, rect.anchorMax.y); - } - else MidLabel.text = xFunc(.5f); + MidLabel.text = xFunc(midX); + var rect = MidLabel.GetComponent(); + rect.anchorMin = new Vector2(midX, rect.anchorMin.y); + rect.anchorMax = new Vector2(midX, rect.anchorMax.y); } } diff --git a/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs b/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs index 3e8a3c5ae..053e148b8 100644 --- a/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs +++ b/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs @@ -376,7 +376,6 @@ public class PropertiesPanel : MonoBehaviour sheet.AddStat("Manufacturer", () => maker.Name); if (product != null) { - AddProperty(product.Name); AddProperty(product.Description); } } @@ -387,7 +386,7 @@ public class PropertiesPanel : MonoBehaviour private void AddEquippableItemProperties(EquippableItem item, Func statValueFunction) { - if (item.Durability < .01f) + if (item.IsDestroyed) { return; } @@ -424,16 +423,21 @@ public class PropertiesPanel : MonoBehaviour if (gearData.Behaviors.FirstOrDefault(b => b is WeaponData) is WeaponData weapon) { var range = AddCurveField(); - range.Show("Damage Range", weapon.DamageCurve, t => ActionGameManager.PlayerSettings.Format(lerp(statValueFunction(weapon.MinRange), statValueFunction(weapon.Range), t))); + var min = statValueFunction(weapon.MinRange); + var effective = statValueFunction(weapon.EffectiveRange); + var max = statValueFunction(weapon.Range); + range.Show("Damage Range", + t => WeaponData.RangeFactor(min, effective, max, weapon.DamageAtMaxRange, lerp(min, max, t)), + t => ActionGameManager.PlayerSettings.Format(lerp(min, max, t)), + effective < max ? saturate(unlerp(min, max, effective)) : .5f); } } private string GetTitle(EquippableItem item) { - var data = GameManager.ItemManager.GetData(item); var (tier, upgrades) = GameManager.ItemManager.GetTier(item); return - $"{data.Name} ({tier.Name}{new string('+', upgrades)})"; + $"{GameManager.ItemManager.Title(item)} ({tier.Name}{new string('+', upgrades)})"; } public void Inspect(EquippedItem item) @@ -475,7 +479,7 @@ public class PropertiesPanel : MonoBehaviour var gearData = GameManager.ItemManager.GetData(item.EquippableItem); var statusSheet = AddStatSheet(); - if (item.EquippableItem.Durability < .01f) + if (item.EquippableItem.IsDestroyed) statusSheet.AddStat("Durability", () => "Item Destroyed!"); else statusSheet.AddStat("Durability", () => $"{(int)(item.EquippableItem.Durability / gearData.Durability * 100)}%"); statusSheet.AddStat("Temperature", () => ActionGameManager.PlayerSettings.FormatTemperature(item.Temperature)); diff --git a/Assets/Scripts/Zone Display/GasGiantObject.cs b/Assets/Scripts/Zone Display/GasGiantObject.cs index 81fb45a1d..927513648 100644 --- a/Assets/Scripts/Zone Display/GasGiantObject.cs +++ b/Assets/Scripts/Zone Display/GasGiantObject.cs @@ -9,5 +9,4 @@ using UnityEngine; public class GasGiantObject : PlanetObject { public SunMaterial SunMaterial; - public MeshRenderer GravityWaves; } diff --git a/Assets/Scripts/Zone Display/GravityLowering.cs b/Assets/Scripts/Zone Display/GravityLowering.cs new file mode 100644 index 000000000..b4ea1e34c --- /dev/null +++ b/Assets/Scripts/Zone Display/GravityLowering.cs @@ -0,0 +1,82 @@ +using System.Runtime.InteropServices; +using UnityEngine; + +/// +/// The renderer's lowering of the zone's potential (aetheria-gravity, cut grid-lowering). Zone.GetHeight owns the drawn +/// height: this hands its inputs (each well's position, strength, core radius and reference, and the exaggeration) to +/// Assets/Shaders/Gravity.cginc, which sums them per texel, and makes the one quad that carries the sum into every +/// camera that culls layer 9. Nothing here decides a height. +/// +public static class GravityLowering +{ + /// The layer the gravity cameras cull; nothing but the run-time field sits on it. + public const int FieldLayer = 9; + /// The quad's side in u: larger than any zone (10000) plus any view (4096); texels outside a camera cost nothing. + public const float FieldExtent = 100000f; + + // Mirrors the well record of Gravity.cginc: float2 position, strength, coreRadius, reference. + [StructLayout(LayoutKind.Sequential)] + struct WellRecord + { + public Vector2 Position; + public float Strength; + public float CoreRadius; + public float Reference; + } + + static readonly int Stride = Marshal.SizeOf(); + static readonly int WellsId = Shader.PropertyToID("_GravityWells"); + static readonly int CountId = Shader.PropertyToID("_GravityWellCount"); + static readonly int ExaggerationId = Shader.PropertyToID("_HeightExaggeration"); + static WellRecord[] _records = new WellRecord[0]; + + /// + /// Fills one record per body of the zone (a null zone has none) and sets the shader globals. The buffer is the + /// caller's, (re)allocated to the body count (at least one, so the global is always bound). Wells are lowered at the + /// drawn time (DrawAhead.Time), the same T the planets and a ship's ride height use. + /// + public static void Lower(Zone zone, float lead, ref ComputeBuffer wells) + { + var count = zone?.PlanetInstances.Count ?? 0; + var capacity = Mathf.Max(count, 1); + if (wells == null || wells.count != capacity) + { + wells?.Release(); + wells = new ComputeBuffer(capacity, Stride); + } + + if (_records.Length != capacity) _records = new WellRecord[capacity]; + var i = 0; + if (zone != null) + foreach (var body in zone.PlanetInstances.Values) + { + var well = DrawAhead.Well(zone, body, lead); + _records[i++] = new WellRecord + { + Position = new Vector2(well.Position.x, well.Position.y), + Strength = well.Strength, + CoreRadius = well.CoreRadius, + Reference = well.Reference + }; + } + wells.SetData(_records); + + Shader.SetGlobalBuffer(WellsId, wells); + Shader.SetGlobalInt(CountId, count); + Shader.SetGlobalFloat(ExaggerationId, zone?.Settings.HeightExaggeration ?? 1f); + } + + /// The one quad of the field: flat in xz at y 0 on layer 9, drawn with the Gravity Field material. + public static GameObject CreateField(Material material) + { + var field = new GameObject("Gravity Field") { layer = FieldLayer }; + field.transform.rotation = Quaternion.Euler(90f, 0f, 0f); + field.transform.localScale = FieldExtent * Vector3.one; + field.AddComponent().sharedMesh = Resources.GetBuiltinResource("Quad.fbx"); + var renderer = field.AddComponent(); + renderer.sharedMaterial = material; + renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; + renderer.receiveShadows = false; + return field; + } +} diff --git a/Assets/Scripts/Zone Display/GravityLowering.cs.meta b/Assets/Scripts/Zone Display/GravityLowering.cs.meta new file mode 100644 index 000000000..725a49896 --- /dev/null +++ b/Assets/Scripts/Zone Display/GravityLowering.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1a5e08474b514e509ed1477b3ac06e94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Zone Display/PlanetObject.cs b/Assets/Scripts/Zone Display/PlanetObject.cs index 9e4a80358..21b49262f 100644 --- a/Assets/Scripts/Zone Display/PlanetObject.cs +++ b/Assets/Scripts/Zone Display/PlanetObject.cs @@ -9,7 +9,6 @@ using UnityEngine; public class PlanetObject : MonoBehaviour { public MeshRenderer Body; - public MeshRenderer GravityWell; public MeshRenderer Icon; public CelestialBodyGenerator Generator; } diff --git a/Assets/Scripts/Zone Display/VapourCloudInstance.cs b/Assets/Scripts/Zone Display/VapourCloudInstance.cs new file mode 100644 index 000000000..594221332 --- /dev/null +++ b/Assets/Scripts/Zone Display/VapourCloudInstance.cs @@ -0,0 +1,44 @@ +using CultMath; +using CultMath.UnityBridge; +using UnityEngine; + +// How one vented vapour cloud looks: a fog-bank brush painted into the Patch layer, which the volumetric pass reads as +// patch thickness. Zone owns every cloud fact (existence, body, radius, opacity); this reads them and draws, and writes +// nothing back (rulings vapour-cloud-obscuration, unity-presents-only-r3). The brush's depth scales with the sim's OpacityAt, so the bank fades to nothing at the cloud's lifetime. +public class VapourCloudInstance : MonoBehaviour +{ + // The world height the scene's patch brushes sit at (Depth Micro), inside the Patch camera's clip range. + public float PatchHeight = -5f; + + private static readonly int Depth = Shader.PropertyToID("_Depth"); + + private Zone _zone; + private VapourCloud _cloud; + private MeshRenderer _renderer; + private MaterialPropertyBlock _block; + private float _authoredDepth; + + public void Bind(Zone zone, VapourCloud cloud) + { + _zone = zone; + _cloud = cloud; + _renderer = GetComponent(); + _block = new MaterialPropertyBlock(); + _authoredDepth = _renderer.sharedMaterial.GetFloat(Depth); + Place(); + } + + private void Update() => Place(); + + private void Place() + { + var p = DrawAhead.Position(_cloud.Body, ActionGameManager.Clock.Lead); + transform.position = new Vector3(p.x, PatchHeight, p.y); + transform.localScale = Vector3.one * (2f * _cloud.Radius); + + // The sim's own opacity, already saturated to 0..1 (VapourCloud.OpacityAt); the presenter adds no rule of its own. + _renderer.GetPropertyBlock(_block); + _block.SetFloat(Depth, _authoredDepth * _cloud.OpacityAt(_zone.Time)); + _renderer.SetPropertyBlock(_block); + } +} diff --git a/Assets/Scripts/Zone Display/VapourCloudInstance.cs.meta b/Assets/Scripts/Zone Display/VapourCloudInstance.cs.meta new file mode 100644 index 000000000..9c645e059 --- /dev/null +++ b/Assets/Scripts/Zone Display/VapourCloudInstance.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a792b8f456004d04997a26557b338d1c \ No newline at end of file diff --git a/Assets/Scripts/Zone Display/VolumeSampling.cs b/Assets/Scripts/Zone Display/VolumeSampling.cs index fd9d9f1e9..72c5e269b 100644 --- a/Assets/Scripts/Zone Display/VolumeSampling.cs +++ b/Assets/Scripts/Zone Display/VolumeSampling.cs @@ -27,16 +27,11 @@ public class VolumeSampling : MonoBehaviour public RenderTexture NebulaTint; private MeshRenderer _gridMeshRenderer; - private float _flowScroll; private Transform _gridTransform; - private GlobalKeyword _keywordFlowGlobal; - private GlobalKeyword _keywordFlowSlope; private GlobalKeyword _keywordNoiseSlope; private void Start() { - _keywordFlowGlobal = GlobalKeyword.Create("FLOW_GLOBAL"); - _keywordFlowSlope = GlobalKeyword.Create("FLOW_SLOPE"); _keywordNoiseSlope = GlobalKeyword.Create("NOISE_SLOPE"); if (GridMesh != null) @@ -52,6 +47,7 @@ public class VolumeSampling : MonoBehaviour Shader.SetGlobalVector("_GridTransform", new Vector4(_gridTransform.position.x,_gridTransform.position.z,GridCamera.orthographicSize*2)); var environment = ActionGameManager.Instance?.CurrentEnvironment ?? Settings.DefaultEnvironment; + var clock = FlowClock; if (GridMesh != null) { @@ -91,18 +87,48 @@ public class VolumeSampling : MonoBehaviour Shader.SetGlobalFloat("_NebulaNoiseExponent", environment.Noise.Exponent); Shader.SetGlobalFloat("_NebulaNoiseAmplitude", environment.Noise.Amplitude); Shader.SetGlobalFloat("_NebulaNoiseSpeed", environment.Noise.Speed); + // The noise the flow advects evolves on the flow's clock too: it pauses with the sim. + Shader.SetGlobalFloat("_NebulaNoiseTime", (float) clock); Shader.SetGlobalFloat("_NebulaNoiseSlopeExponent", environment.Noise.SlopeExponent); - Shader.SetGlobalFloat("_FlowScale", environment.Flow.GlobalScale); - Shader.SetGlobalFloat("_FlowAmplitude", environment.Flow.GlobalAmplitude); - Shader.SetGlobalFloat("_FlowSlopeAmplitude", environment.Flow.SlopeAmplitude); - Shader.SetGlobalFloat("_FlowSwirlAmplitude", environment.Flow.SwirlAmplitude); - _flowScroll += environment.Flow.GlobalScrollSpeed * Time.deltaTime; - Shader.SetGlobalFloat("_FlowScroll", _flowScroll); - Shader.SetGlobalFloat("_FlowPeriod", environment.Flow.Period); - - Shader.SetKeyword(_keywordFlowGlobal, environment.Flow.GlobalAmplitude != 0); - Shader.SetKeyword(_keywordFlowSlope, environment.Flow.SlopeAmplitude != 0 || environment.Flow.SwirlAmplitude != 0); + // The flow is the zone's: its settings and its time. Without a zone (menus) the same law runs on the presentation clock. + LowerFlow(ActionGameManager.Instance?.Zone?.Settings.Flow ?? Settings.PlanetSettings.Flow, clock); Shader.SetKeyword(_keywordNoiseSlope, environment.Noise.SlopeExponent != 0); } + + // GlobalKeyword's constructor only looks a keyword up; Create registers it. The shaders' pragmas and this owner + // agree on the names. Unity refuses Create inside a MonoBehaviour's construction, and a scene constructing the + // first VolumeSampling runs this type's static initializer there, so the keywords are created on first use, from + // LowerFlow, never in a field initializer. + static GlobalKeyword? _keywordFlowGlobal; + static GlobalKeyword? _keywordFlowSlope; + static GlobalKeyword KeywordFlowGlobal => _keywordFlowGlobal ??= GlobalKeyword.Create("FLOW_GLOBAL"); + static GlobalKeyword KeywordFlowSlope => _keywordFlowSlope ??= GlobalKeyword.Create("FLOW_SLOPE"); + + /// + /// The time the flow runs on: the zone's drawn time (DrawAhead.Time, so drift stops with the sim and follows sim + /// speed), or on menus, where no zone exists, the presentation clock. + /// + public static double FlowClock => ActionGameManager.Instance?.Zone is { } zone + ? DrawAhead.Time(zone, ActionGameManager.Clock.Lead) + : Time.timeSinceLevelLoad; + + /// + /// The one place that sets the flow uniforms and keywords: every shader flow term derives from FlowSettings and + /// the flow clock through FlowField, so no presenter keeps its own flow clock. + /// + public static void LowerFlow(FlowSettings flow, double flowClock) + { + Shader.SetGlobalFloat("_FlowScale", flow.GlobalScale); + Shader.SetGlobalFloat("_FlowAmplitude", flow.GlobalAmplitude); + Shader.SetGlobalFloat("_FlowSlopeAmplitude", flow.SlopeAmplitude); + Shader.SetGlobalFloat("_FlowSwirlAmplitude", flow.SwirlAmplitude); + var scroll = FlowField.Scroll(flow, flowClock); + Shader.SetGlobalVector("_FlowScroll", new Vector4(scroll.x, scroll.y)); + Shader.SetGlobalFloat("_FlowPeriod", flow.Period); + Shader.SetGlobalFloat("_FlowCycle", FlowField.Cycle(flowClock, flow.Period)); + + Shader.SetKeyword(KeywordFlowGlobal, flow.GlobalAmplitude != 0); + Shader.SetKeyword(KeywordFlowSlope, flow.SlopeAmplitude != 0 || flow.SwirlAmplitude != 0); + } } diff --git a/Assets/Scripts/Zone Display/ZoneRenderer.cs b/Assets/Scripts/Zone Display/ZoneRenderer.cs index 5ef289cde..8126eb096 100644 --- a/Assets/Scripts/Zone Display/ZoneRenderer.cs +++ b/Assets/Scripts/Zone Display/ZoneRenderer.cs @@ -27,12 +27,11 @@ public class ZoneRenderer : MonoBehaviour public GameSettings Settings; public Transform ZoneRoot; public Transform SectorBrushes; - public MeshRenderer SectorBoundaryBrush; + // The ambient tint quad, sized from the zone's populated radius, never under SectorBrushes: FitAmbientLight. + public Transform AmbientLight; public CinemachineVirtualCamera SceneCamera; public Camera[] FogCameras; public Camera[] MinimapCameras; - public Material FogMaterial; - public float FogFarFadeFraction = .125f; public float FarPlaneDistanceMultiplier = 2; public InstancedMesh[] AsteroidMeshes; public int AsteroidSpritesheetWidth = 4; @@ -40,11 +39,15 @@ public class ZoneRenderer : MonoBehaviour public LODHandler LODHandler; public Slime SlimeRenderer; public Camera SlimeGravityCamera; - public GridObject SimpleCommodityPickup; - public GridObject CompoundCommodityPickup; - public GridObject GearPickup; - public GridObject WeaponPickup; + public ItemPickup SimpleCommodityPickup; + public ItemPickup CompoundCommodityPickup; + public ItemPickup GearPickup; + public ItemPickup WeaponPickup; + public MineInstance MinePrefab; + public VapourCloudInstance CloudPrefab; public Material[] MapGravityMaterials; + // The gravity field's material (Brushes/Gravity Field): GravityLowering makes the one quad that draws it. + public Material GravityField; [Header("Tour")] public bool Tour; public float TourSwitchTime = 5f; @@ -76,7 +79,8 @@ public class ZoneRenderer : MonoBehaviour // is stored on AsteroidBelt any more. private Dictionary _beltTransforms = new Dictionary(); private float _viewDistance; - //private float _maxDepth; + private GameObject _gravityField; + private ComputeBuffer _gravityWells; private float _minimapDistance; private int _tourIndex = -1; @@ -92,7 +96,9 @@ public class ZoneRenderer : MonoBehaviour private bool _showAsteroidUI; public Dictionary WormholeInstances = new Dictionary(); - private List _loot = new List(); + private Dictionary _floatingItems = new Dictionary(); + private Dictionary _mines = new Dictionary(); + private Dictionary _clouds = new Dictionary(); public Zone Zone { get; private set; } public ItemManager ItemManager { get; set; } @@ -135,8 +141,6 @@ public class ZoneRenderer : MonoBehaviour foreach (var camera in FogCameras) camera.orthographicSize = value; SceneCamera.m_Lens.FarClipPlane = value * FarPlaneDistanceMultiplier; - FogMaterial.SetFloat("_DepthCeiling", value); - FogMaterial.SetFloat("_DepthBlend", FogFarFadeFraction * value); } } @@ -185,13 +189,38 @@ public class ZoneRenderer : MonoBehaviour _transposer = SceneCamera.GetCinemachineComponent(); } + // The ambient is a gaussian: its brightness at the populated edge is the material's _EdgeBrightness (a shape, authored), and + // the quad reaches out to where its brightest channel falls to AmbientFloor. Fog Tint is B10G11R11_UFloatPack32 and cannot + // follow a gaussian into its tail: measured, the drawn value stops following it near 4 floors and holds a plateau of + // about 3.2e-5 before dropping to zero (AmbientEdgeVerify asserts the format and measures it). A quad sized to 1e-5 of the + // centre therefore ended in a plateau and a step to zero; sized to the floor it ends at the last value the format holds, + // so the one step to dark is that value. The one writer of the quad's size and _Reach, and the one place the verify + // reads the sizing from. + public const float AmbientFloor = 1f / (1 << 15); + + public static void FitAmbientLight(Transform light, Zone zone) + { + var renderer = light.GetComponent(); + var material = renderer.sharedMaterial; + var tint = material.GetColor("_Color").linear; + var centre = material.GetFloat("_Depth") * Mathf.Max(tint.r, Mathf.Max(tint.g, tint.b)); + var reach = Mathf.Sqrt(Mathf.Log(centre / AmbientFloor) / Mathf.Log(1f / material.GetFloat("_EdgeBrightness"))); + light.localScale = 2f * reach * zone.PopulatedRadius * Vector3.one; + var block = new MaterialPropertyBlock(); + renderer.GetPropertyBlock(block); + block.SetFloat("_Reach", reach); + renderer.SetPropertyBlock(block); + } + public void LoadZone(Zone zone) { ClearZone(); Zone = zone; SectorBrushes.localScale = zone.Pack.Radius * 2 * Vector3.one; + FitAmbientLight(AmbientLight, zone); SlimeGravityCamera.orthographicSize = zone.Pack.Radius; SlimeRenderer.ZoneRadius = zone.Pack.Radius; + if (_gravityField == null) _gravityField = GravityLowering.CreateField(GravityField); foreach (var p in zone.Planets) LoadPlanet(p.Key, p.Value); @@ -222,6 +251,34 @@ public class ZoneRenderer : MonoBehaviour UnloadEntity(e.Value); })); + // Every mine, whoever laid it, is drawn through this one subscription. A mine leaves Zone.Mines only by + // its blast, so a removal plays the blast; ClearZone below destroys the rest without one. + foreach (var mine in zone.Mines) LoadMine(zone, mine); + _zoneSubscriptions.Add(zone.Mines.ObserveAdd().Subscribe(e => LoadMine(zone, e.Value))); + _zoneSubscriptions.Add(zone.Mines.ObserveRemove().Subscribe(e => + { + if (!_mines.Remove(e.Value, out var instance)) return; + instance.Blast(); + })); + + // Every floating item, whoever released it (a death drop, jettisoned cargo), is drawn through this one + // subscription. An item leaves Zone.FloatingItems by expiry or by pickup, and either way its pickup is gone. + foreach (var floating in zone.FloatingItems) LoadFloatingItem(zone, floating); + _zoneSubscriptions.Add(zone.FloatingItems.ObserveAdd().Subscribe(e => LoadFloatingItem(zone, e.Value))); + _zoneSubscriptions.Add(zone.FloatingItems.ObserveRemove().Subscribe(e => + { + if (_floatingItems.Remove(e.Value, out var pickup) && pickup) Destroy(pickup.gameObject); + })); + + // Every vapour cloud, whoever vented it, is drawn through this one subscription. A cloud leaves Zone.Clouds + // when its opacity has reached nothing, so a removal destroys its fog bank with nothing left to show. + foreach (var cloud in zone.Clouds) LoadCloud(zone, cloud); + _zoneSubscriptions.Add(zone.Clouds.ObserveAdd().Subscribe(e => LoadCloud(zone, e.Value))); + _zoneSubscriptions.Add(zone.Clouds.ObserveRemove().Subscribe(e => + { + if (_clouds.Remove(e.Value, out var instance)) Destroy(instance.gameObject); + })); + if (zone.GalaxyZone != null) { foreach (var adjacentZone in zone.GalaxyZone.AdjacentZones) @@ -233,9 +290,54 @@ public class ZoneRenderer : MonoBehaviour Position = dir * zone.Pack.Radius * Settings.WormholeDistanceRatio }); } + + // The run's exit gate is presentation only: whether it opens is RunGoal.ExitOpen, read when it is used. + if (zone.GalaxyZone == zone.Galaxy.Exit) + AddWormhole(new Wormhole + { + Exit = true, + Position = RunGoal.ExitGatePosition(zone, Settings.WormholeDistanceRatio) + }); } } + private void LoadMine(Zone zone, Mine mine) + { + var instance = Instantiate(MinePrefab); + instance.Bind(zone, mine, ItemManager.GameplaySettings); + _mines.Add(mine, instance); + } + + private void LoadFloatingItem(Zone zone, FloatingItem floating) + { + var prefab = floating.Item switch + { + SimpleCommodity _ => SimpleCommodityPickup, + CompoundCommodity _ => CompoundCommodityPickup, + EquippableItem equippableItem when ItemManager.GetData(equippableItem) is WeaponItemData => WeaponPickup, + EquippableItem _ => GearPickup, + _ => throw new NotImplementedException() + }; + var pickup = Instantiate(prefab, ZoneRoot); + pickup.Bind(zone, floating, ItemManager.GameplaySettings); + pickup.ScanLabel.text = ItemManager.Title(floating.Item); + if (floating.Item is CraftedItemInstance craftedItemInstance) + { + var c = ItemManager.GetTier(craftedItemInstance).tier.Color.ToColor(); + c.a = 0; + pickup.ScanLabel.color = c; + } + else pickup.ScanLabel.color = new Color(.75f, .75f, .75f, 0); + _floatingItems.Add(floating, pickup); + } + + private void LoadCloud(Zone zone, VapourCloud cloud) + { + var instance = Instantiate(CloudPrefab); + instance.Bind(zone, cloud); + _clouds.Add(cloud, instance); + } + public void AddWormhole(Wormhole wormhole) { var instance = Instantiate(WormholePrefab); @@ -245,9 +347,17 @@ public class ZoneRenderer : MonoBehaviour WormholeInstances.Add(wormhole, (instance.gameObject, icon)); } + void OnDestroy() + { + _gravityWells?.Release(); + _gravityWells = null; + } + public void ClearZone() { if (Zone == null) return; + _gravityWells?.Release(); + _gravityWells = null; foreach (var wormhole in WormholeInstances.Values) { Destroy(wormhole.gravity); @@ -259,9 +369,17 @@ public class ZoneRenderer : MonoBehaviour subscription.Dispose(); _zoneSubscriptions.Clear(); - foreach(var gridObject in _loot) - if(gridObject) Destroy(gridObject.gameObject); - _loot.Clear(); + foreach (var instance in _mines.Values) + if (instance) Destroy(instance.gameObject); + _mines.Clear(); + + foreach (var instance in _clouds.Values) + if (instance) Destroy(instance.gameObject); + _clouds.Clear(); + + foreach (var pickup in _floatingItems.Values) + if (pickup) Destroy(pickup.gameObject); + _floatingItems.Clear(); foreach (var entity in Zone.Entities) { @@ -387,17 +505,12 @@ public class ZoneRenderer : MonoBehaviour else planet = Instantiate(GasGiant, ZoneRoot); var gas = (GasGiantObject) planet; - var gasGiant = Zone.PlanetInstances[key] as GasGiant; gas.Body.material.SetTexture("_ColorRamp", gasGiantData.Colors.ToGradient(!(planetData is SunData)).ToTexture()); // gasGiantData.AlbedoRotationSpeed.Subscribe(f => gas.SunMaterial.AlbedoRotationSpeed = f); // gasGiantData.FirstOffsetRotationSpeed.Subscribe(f => gas.SunMaterial.FirstOffsetRotationSpeed = f); // gasGiantData.SecondOffsetRotationSpeed.Subscribe(f => gas.SunMaterial.SecondOffsetRotationSpeed = f); // gasGiantData.FirstOffsetDomainRotationSpeed.Subscribe(f => gas.SunMaterial.FirstOffsetDomainRotationSpeed = f); // gasGiantData.SecondOffsetDomainRotationSpeed.Subscribe(f => gas.SunMaterial.SecondOffsetDomainRotationSpeed = f); - gas.GravityWaves.transform.localScale = gasGiant.GravityWavesRadius * Vector3.one; - gas.GravityWaves.material.SetFloat("_Depth", gasGiant.GravityWavesDepth); - gas.GravityWaves.material.SetFloat("_Frequency", Settings.PlanetSettings.WaveFrequency.Evaluate(planetData.Mass)); - //gas.WaveScroll.Speed = Properties.GravitySettings.WaveSpeed.Evaluate(f); } else { @@ -412,11 +525,6 @@ public class ZoneRenderer : MonoBehaviour var planetInstance = Zone.PlanetInstances[key]; planet.Body.transform.localScale = planetInstance.BodyRadius * Vector3.one; - planet.GravityWell.transform.localScale = planetInstance.GravityWellRadius * Vector3.one; - // var depth = planetInstance.GravityWellDepth; - // if (depth > _maxDepth) _maxDepth = depth; - planet.GravityWell.material.SetFloat("_Depth", planetInstance.GravityWellDepth); - planet.Icon.transform.position = new Vector3(0, -planetInstance.GravityWellDepth, 0); planet.Icon.transform.localScale = Settings.IconSize.Evaluate(planetInstance.BodyData.Mass) * Vector3.one; @@ -434,9 +542,11 @@ public class ZoneRenderer : MonoBehaviour void Update() { var maxDepth = 0f; - foreach (var loot in _loot) + var lead = ActionGameManager.Clock.Lead; + GravityLowering.Lower(Zone, lead, ref _gravityWells); + foreach (var loot in _floatingItems.Values) { - loot.ViewOrigin = PerspectiveEntity.Position; + loot.ViewOrigin = DrawAhead.Position(PerspectiveEntity, lead); loot.ViewDirection = PerspectiveEntity.Aim; } @@ -455,11 +565,11 @@ public class ZoneRenderer : MonoBehaviour foreach (var (key, belt) in Zone.AsteroidBelts) { // Cut 1 (docs/mining-cut.md): belts have no stored pose any more. The renderer fills its own buffer - // from Zone.EvaluateBelt, at the current zone time, every frame. - var orbitPosition = Zone.GetOrbitPosition(Zone.Orbits[belt.Data.Orbit.Key].Data.Parent.Key); - var height = Zone.GetHeight(orbitPosition); + // from Zone.EvaluateBelt, at the drawn time (DrawAhead.Time), every frame. + var orbitPosition = DrawAhead.Orbit(Zone, Zone.Orbits[belt.Data.Orbit.Key].Data.Parent.Key, lead); + var height = DrawAhead.Height(Zone, orbitPosition, lead); var transforms = _beltTransforms[key]; - Zone.EvaluateBelt(key, transforms); + Zone.EvaluateBelt(key, transforms, DrawAhead.Time(Zone, lead)); if(isVisible(new Bounds( new Vector3(orbitPosition.x,height,orbitPosition.y), new Vector3(belt.Radius * 2,100,belt.Radius * 2)))) @@ -492,18 +602,17 @@ public class ZoneRenderer : MonoBehaviour foreach (var planet in Planets) { var planetInstance = Zone.PlanetInstances[planet.Key]; - var p = Zone.GetOrbitPosition(planetInstance.BodyData.Orbit.Key); - var height = Zone.GetHeight(p); + var p = DrawAhead.Orbit(Zone, planetInstance.BodyData.Orbit.Key, lead); + var height = DrawAhead.Height(Zone, p, lead); if (-height > maxDepth) maxDepth = -height; planet.Value.transform.position = new Vector3(p.x, 0, p.y); planet.Value.Body.transform.localPosition = new Vector3(0, height + planetInstance.BodyRadius * 2, 0); + planet.Value.Icon.transform.localPosition = new Vector3(0, height, 0); if (planet.Value is GasGiantObject gasGiantObject) { - gasGiantObject.GravityWaves.material.SetFloat("_Phase", - Zone.Time * ((GasGiant) Zone.PlanetInstances[planet.Key]).GravityWavesSpeed); if (!(planet.Value is SunObject)) { - var toParent = normalize(Zone.GetOrbitPosition(Zone.Orbits[planetInstance.BodyData.Orbit.Key].Data.Parent.Key) - p); + var toParent = normalize(DrawAhead.Orbit(Zone, Zone.Orbits[planetInstance.BodyData.Orbit.Key].Data.Parent.Key, lead) - p); gasGiantObject.SunMaterial.LightingDirection = new Vector3(toParent.x, 0, toParent.y); } } @@ -514,12 +623,11 @@ public class ZoneRenderer : MonoBehaviour { if(entityInstance.CompassIcon) { - var difference = entityInstance.Entity.Position.xz - PerspectiveEntity.Position.xz; + var difference = DrawAhead.Position(entityInstance.Entity, lead).xz - DrawAhead.Position(PerspectiveEntity, lead).xz; var distance = length(difference); entityInstance.CompassIcon.gameObject.SetActive( - PerspectiveEntity.EntityInfoGathered.ContainsKey(entityInstance.Entity) && - PerspectiveEntity.EntityInfoGathered[entityInstance.Entity] > Settings.GameplaySettings.TargetDetectionInfoThreshold && + PerspectiveEntity.ContactOf(entityInstance.Entity).Tracked && distance > _minimapDistance); entityInstance.CompassIcon.transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg - 90); } @@ -527,64 +635,23 @@ public class ZoneRenderer : MonoBehaviour foreach (var wormhole in WormholeInstances.Values) { - var difference = wormhole.gravity.transform.position.Flatland() - PerspectiveEntity.Position.xz.ToUnity(); + var difference = wormhole.gravity.transform.position.Flatland() - DrawAhead.Position(PerspectiveEntity, lead).xz.ToUnity(); var distance = difference.magnitude; wormhole.icon.gameObject.SetActive(distance > _minimapDistance); wormhole.icon.transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg - 90); } //var fogPos = FogCameraParent.position; - SectorBoundaryBrush.material.SetFloat("_Power", Settings.PlanetSettings.ZoneDepthExponent); - SectorBoundaryBrush.material.SetFloat("_Depth", Settings.PlanetSettings.ZoneDepth + Settings.PlanetSettings.ZoneBoundaryFog); - var startDepth = Zone.PowerPulse(Settings.MinimapZoneGravityRange, Settings.PlanetSettings.ZoneDepthExponent) * - Settings.PlanetSettings.ZoneDepth; - var depthRange = Settings.PlanetSettings.ZoneDepth - startDepth + maxDepth; + var depthRange = Mathf.Max(maxDepth, 1f); foreach (var mat in MapGravityMaterials) { - mat.SetFloat("_StartDepth", startDepth); + mat.SetFloat("_StartDepth", 0f); mat.SetFloat("_DepthRange", depthRange); } - //Shader.SetGlobalFloat("_GridOffset", Settings.PlanetSettings.ZoneBoundaryFog); // var gravPos = MinimapGravityQuad.transform.position; - // gravPos.y = -Settings.PlanetSettings.ZoneDepth - _maxDepth; // MinimapGravityQuad.transform.position = gravPos; // MinimapTintQuad.transform.position = gravPos - Vector3.up*10; } - - public void DestroyLoot(ItemPickup loot) - { - _loot.Remove(loot); - } - - public void DropItem(Vector3 position, Vector3 velocity, ItemInstance item) - { - var gridObject = item switch - { - SimpleCommodity _ => Instantiate(SimpleCommodityPickup), - CompoundCommodity _ => Instantiate(CompoundCommodityPickup), - EquippableItem equippableItem when ItemManager.GetData(equippableItem) is WeaponItemData => Instantiate(WeaponPickup), - EquippableItem _ => Instantiate(GearPickup), - _ => throw new NotImplementedException() - }; - var t = gridObject.transform; - t.parent = ZoneRoot; - gridObject.Zone = Zone; - t.position = position; - gridObject.Velocity = velocity; - var itemPickup = gridObject.gameObject.GetComponent(); - itemPickup.Item = item; - itemPickup.ZoneRenderer = this; - itemPickup.ScanLabel.text = ItemManager.GetData(item).Name; - if (item is CraftedItemInstance craftedItemInstance) - { - var c = ItemManager.GetTier(craftedItemInstance).tier.Color.ToColor(); - c.a = 0; - itemPickup.ScanLabel.color = c; - } - else itemPickup.ScanLabel.color = new Color(.75f, .75f, .75f, 0); - gridObject.gameObject.AddComponent().Duration = Settings.PickupLifetime; - _loot.Add(itemPickup); - } } @@ -672,7 +739,7 @@ public class AsteroidBeltUI public void Update(float4[] transforms, float height) { - var parentPosition = _zone.GetOrbitPosition(_orbitParent); + var parentPosition = DrawAhead.Orbit(_zone, _orbitParent, ActionGameManager.Clock.Lead); for (var i = 0; i < transforms.Length; i++) { var transform = transforms[i]; diff --git a/Assets/Shaders/Brushes/AmbientBrush.shader b/Assets/Shaders/Brushes/AmbientBrush.shader new file mode 100644 index 000000000..6c6202d0b --- /dev/null +++ b/Assets/Shaders/Brushes/AmbientBrush.shader @@ -0,0 +1,61 @@ +Shader "Brushes/Ambient Brush" { +Properties { + _Color ("Color", Color) = (1,1,1,1) + _Depth ("Depth", Float) = 0.5 + // The brightness at the populated edge relative to the centre: the shape of the fall, never an extent. + _EdgeBrightness ("Edge Brightness", Range(0.0001, 0.9999)) = .12 + // The quad's radius in units of the populated radius. Written by ZoneRenderer.FitAmbientLight, never authored. + _Reach ("Reach", Float) = 1 +} + +// A gaussian: log-brightness is quadratic in distance from the centre, so the fall is smooth everywhere and +// never reaches an edge or a cliff. x is the distance in units of the zone's populated radius. +Category { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + Blend One One + ColorMask RGB + Cull Off Lighting Off ZWrite Off + + SubShader { + Pass { + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma target 2.0 + + #include "UnityCG.cginc" + + float4 _Color; + float _Depth; + float _EdgeBrightness; + float _Reach; + + struct appdata_t { + float4 vertex : POSITION; + float2 texcoord : TEXCOORD0; + }; + + struct v2f { + float4 vertex : SV_POSITION; + float2 texcoord : TEXCOORD0; + }; + + v2f vert (appdata_t v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.texcoord = v.texcoord; + return o; + } + + float4 frag (v2f i) : SV_Target + { + float x = length(i.texcoord - float2(.5, .5)) * 2 * _Reach; + return _Depth * _Color * exp(-x * x * log(1 / _EdgeBrightness)); + } + ENDCG + } + } +} +} diff --git a/Assets/Shaders/Brushes/RadialWaveBrush.shader.meta b/Assets/Shaders/Brushes/AmbientBrush.shader.meta similarity index 80% rename from Assets/Shaders/Brushes/RadialWaveBrush.shader.meta rename to Assets/Shaders/Brushes/AmbientBrush.shader.meta index 14b474d83..8f80f596b 100644 --- a/Assets/Shaders/Brushes/RadialWaveBrush.shader.meta +++ b/Assets/Shaders/Brushes/AmbientBrush.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8a8e593b17063b54ea02f7ea5363b59d +guid: 782740c1a3d7455ea75dc87fafdc8432 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Assets/Shaders/Brushes/GravityField.shader b/Assets/Shaders/Brushes/GravityField.shader new file mode 100644 index 000000000..857d7c80e --- /dev/null +++ b/Assets/Shaders/Brushes/GravityField.shader @@ -0,0 +1,47 @@ +// Draws the zone's gravity: depth = -Zone.GetHeight at the world xz of every texel, into whichever gravity camera culls +// layer 9 (Surface Displacement, Slime Gravity, both Map Gravity). One quad covers the zone; the +// law lives in Gravity.cginc, which mirrors ServerShared's GravityField. +Shader "Brushes/Gravity Field" { +Category { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + Blend One One + ColorMask RGB + Cull Off Lighting Off ZWrite Off + + SubShader { + Pass { + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma target 4.5 + + #include "UnityCG.cginc" + #include "../Gravity.cginc" + + struct appdata_t { + float4 vertex : POSITION; + }; + + struct v2f { + float4 vertex : SV_POSITION; + float2 world : TEXCOORD0; + }; + + v2f vert (appdata_t v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.world = mul(unity_ObjectToWorld, v.vertex).xz; + return o; + } + + float4 frag (v2f i) : SV_Target + { + return (-gravityHeight(i.world)).xxxx; + } + ENDCG + } + } +} +} diff --git a/Assets/Shaders/Raymarching/VolumeRender.shader.meta b/Assets/Shaders/Brushes/GravityField.shader.meta similarity index 80% rename from Assets/Shaders/Raymarching/VolumeRender.shader.meta rename to Assets/Shaders/Brushes/GravityField.shader.meta index 7ca59e2ad..f98548391 100644 --- a/Assets/Shaders/Raymarching/VolumeRender.shader.meta +++ b/Assets/Shaders/Brushes/GravityField.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7a890b6ceccf53c44bfc54b18b5daa58 +guid: 08d8efa80af84065b54c9bfed784e435 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Assets/Shaders/Brushes/RadialWaveBrush.shader b/Assets/Shaders/Brushes/RadialWaveBrush.shader deleted file mode 100644 index 1828873bc..000000000 --- a/Assets/Shaders/Brushes/RadialWaveBrush.shader +++ /dev/null @@ -1,81 +0,0 @@ -Shader "Brushes/Radial Wave Brush" { -Properties { - _Depth ("Depth", Float) = 0.5 - _Power("Envelope Power", Float) = 1.25 - _Frequency("Frequency", Float) = 6.2832 - _Phase("Phase", Float) = 0 - _SinePower("Sine Power", Float) = 1.25 -} - -Category { - Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } - Blend One One - ColorMask RGB - Cull Off Lighting Off ZWrite Off - - SubShader { - Pass { - - CGPROGRAM - #pragma vertex vert - #pragma fragment frag - #pragma target 2.0 - - #include "UnityCG.cginc" - - float _Depth; - float _Power; - float _Frequency; - float _Phase; - float _SinePower; - - struct appdata_t { - float4 vertex : POSITION; - fixed4 color : COLOR; - float2 texcoord : TEXCOORD0; - }; - - struct v2f { - float4 vertex : SV_POSITION; - fixed4 color : COLOR; - float2 texcoord : TEXCOORD0; - }; - - float4 _MainTex_ST; - - v2f vert (appdata_t v) - { - v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); - o.color = v.color; - o.texcoord = v.texcoord; - return o; - } - - float almostIdentity(float x, float m, float n) - { - if (x>m) return x; - - const float a = 2.0f*n - m; - const float b = 2.0f*m - 3.0f*n; - const float t = x / m; - - return (a*t + b)*t*t + n; - } - - float powerPulse( float x, float power ) - { - x = saturate(abs(x)); - return pow((x + 1.0f) * (1.0f - x), power); - } - - fixed4 frag (v2f i) : SV_Target - { - float dist = length(i.texcoord - float2(.5,.5)) * 2; - return _Depth * powerPulse(dist,_Power) * cos(pow(dist, _SinePower)*_Frequency+_Phase); - } - ENDCG - } - } -} -} diff --git a/Assets/Shaders/Brushes/WormholeBrush.shader b/Assets/Shaders/Brushes/WormholeBrush.shader deleted file mode 100644 index 6d2c8a0ed..000000000 --- a/Assets/Shaders/Brushes/WormholeBrush.shader +++ /dev/null @@ -1,85 +0,0 @@ -Shader "Brushes/Wormhole Brush" { -Properties { - _Depth ("Depth", Float) = 0.5 - _Power("Envelope Power", Float) = 1.25 - _Frequency("Frequency", Float) = 6.2832 - _FrequencyDist("Distance Frequency", Float) = 6.2832 - _Speed("Speed", Float) = 0 - _SinePower("Sine Power", Float) = 1.25 -} - -Category { - Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } - Blend One One - ColorMask RGB - Cull Off Lighting Off ZWrite Off - - SubShader { - Pass { - - CGPROGRAM - #pragma vertex vert - #pragma fragment frag - #pragma target 2.0 - - #include "UnityCG.cginc" - - float _Depth; - float _Power; - float _Frequency; - float _FrequencyDist; - float _Speed; - float _SinePower; - - struct appdata_t { - float4 vertex : POSITION; - fixed4 color : COLOR; - float2 texcoord : TEXCOORD0; - }; - - struct v2f { - float4 vertex : SV_POSITION; - fixed4 color : COLOR; - float2 texcoord : TEXCOORD0; - }; - - float4 _MainTex_ST; - - v2f vert (appdata_t v) - { - v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); - o.color = v.color; - o.texcoord = v.texcoord; - return o; - } - - float almostIdentity(float x, float m, float n) - { - if (x>m) return x; - - const float a = 2.0f*n - m; - const float b = 2.0f*m - 3.0f*n; - const float t = x / m; - - return (a*t + b)*t*t + n; - } - - float powerPulse( float x, float power ) - { - x = saturate(abs(x)); - return pow((x + 1.0f) * (1.0f - x), power); - } - - fixed4 frag (v2f i) : SV_Target - { - float2 uv2 = i.texcoord - float2(.5,.5); - float dist = length(uv2); - float ang = atan2(uv2.y,uv2.x); - return _Depth * powerPulse(dist * 2,_Power) * (cos(ang*_Frequency+pow(dist, _SinePower)*_FrequencyDist+_Time.x*_Speed)+1); - } - ENDCG - } - } -} -} diff --git a/Assets/Shaders/Compute/FlowParity.compute b/Assets/Shaders/Compute/FlowParity.compute new file mode 100644 index 000000000..a431accef --- /dev/null +++ b/Assets/Shaders/Compute/FlowParity.compute @@ -0,0 +1,27 @@ +// Evaluates the shader flow functions for a buffer of positions and gradients, so that +// Aetheria.EditorTools.FlowFieldParityVerify can compare them with FlowField (ServerShared). Reads the same global +// _Flow* uniforms the nebula and stardust read, set by VolumeSampling.LowerFlow. +#pragma kernel Evaluate +// A compute shader declares the global keywords itself (as Stardust.compute does); the flow() it calls is keyword-gated. +#pragma multi_compile __ FLOW_GLOBAL +#pragma multi_compile __ FLOW_SLOPE + +#include "Assets/Shaders/Volumetric.cginc" + +StructuredBuffer positions; +StructuredBuffer gradients; +RWStructuredBuffer globalOut; +RWStructuredBuffer slopeOut; +RWStructuredBuffer gatedOut; // flow(): the keyword-gated function the nebula and stardust call +RWStructuredBuffer noiseOut; // triNoise3d: the nebula noise the flow advects +uint count; + +[numthreads(64, 1, 1)] +void Evaluate(uint3 id : SV_DispatchThreadID) +{ + if (id.x >= count) return; + globalOut[id.x] = globalFlow(positions[id.x]); + slopeOut[id.x] = slopeFlow(gradients[id.x]); + gatedOut[id.x] = flow(positions[id.x]); + noiseOut[id.x] = triNoise3d(positions[id.x] / 512); +} diff --git a/Assets/Shaders/Compute/FlowParity.compute.meta b/Assets/Shaders/Compute/FlowParity.compute.meta new file mode 100644 index 000000000..30b9beea8 --- /dev/null +++ b/Assets/Shaders/Compute/FlowParity.compute.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fd5f95c7d7c63b243aadd16f6e9dc702 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Shaders/Compute/Stardust/Stardust.compute b/Assets/Shaders/Compute/Stardust/Stardust.compute index c2698f766..1188cb237 100644 --- a/Assets/Shaders/Compute/Stardust/Stardust.compute +++ b/Assets/Shaders/Compute/Stardust/Stardust.compute @@ -25,7 +25,7 @@ Texture2D HueTexture; SamplerState samplerHueTexture; float period; -float time; +float phase; // the cycle phase from zone time (FlowField.Cycle), in [0, 1) float spacing; float ceilingHeight; float floorHeight; @@ -125,7 +125,7 @@ void UpdateParticles(uint3 id : SV_DispatchThreadID, int3 groupID : SV_GroupThre uint xp = x + xt + offset; uint yp = y + yt + offset; - const float lifetime = frac(time / period + RandomFirst(xp, yp)); + const float lifetime = frac(phase + RandomFirst(xp, yp)); particles[id.x].position = float3( x * spacing + xt * spacing + perlinNoise1D(RandomValue()*1024)*spacing, 0, diff --git a/Assets/Shaders/Compute/Stardust/Stardust.cs b/Assets/Shaders/Compute/Stardust/Stardust.cs index d75b18f99..fd4ada9c0 100644 --- a/Assets/Shaders/Compute/Stardust/Stardust.cs +++ b/Assets/Shaders/Compute/Stardust/Stardust.cs @@ -34,9 +34,7 @@ public class Stardust : MonoBehaviour public Texture Heightmap; public Texture2D ParticleColors; //public Transform TargetTransform; - public Camera GravityCamera; - private float _flowScroll; private const int GROUP_SIZE = 128; private int _updateParticlesKernel; #endregion @@ -58,6 +56,12 @@ public class Stardust : MonoBehaviour private ComputeBuffer _quadPoints; private const int QUAD_STRIDE = 12; + // The dust is drawn by a command buffer on TargetCamera: a camera replays its buffers at their event and never culls them, + // so the draw needs no bounds and no extent can fall short of how deep the field is. + private CommandBuffer _draw; + // Before the [ImageEffectOpaque] nebula, so its march fogs the dust; a deferred camera skips the forward-opaque events when nothing forward-opaque is drawn (B46, B49). + private const CameraEvent DrawEvent = CameraEvent.BeforeImageEffectsOpaque; + #endregion #region setup @@ -92,6 +96,33 @@ public class Stardust : MonoBehaviour new Vector3(-.5f, -.5f), new Vector3(-.5f, .5f) }); + + //The buffers never change after this, so the material is bound once + ParticleMaterial.SetBuffer("particles", _particlesBuffer); + ParticleMaterial.SetBuffer("quadPoints", _quadPoints); + + //Start may run again (the scene harness calls it by hand): drop the previous draw before building the next + DetachDraw(); + _draw?.Release(); + _draw = new CommandBuffer { name = "Stardust" }; + _draw.DrawProcedural(Matrix4x4.identity, ParticleMaterial, 0, MeshTopology.Triangles, 6, Span * Span); + AttachDraw(); + } + + void OnEnable() => AttachDraw(); + + void OnDisable() => DetachDraw(); + + void AttachDraw() + { + if (_draw != null && TargetCamera != null) + TargetCamera.AddCommandBuffer(DrawEvent, _draw); + } + + void DetachDraw() + { + if (_draw != null && TargetCamera != null) + TargetCamera.RemoveCommandBuffer(DrawEvent, _draw); } #endregion @@ -102,9 +133,9 @@ public class Stardust : MonoBehaviour //Bind resources to compute shader ParticleCalculation.SetBuffer(_updateParticlesKernel, "particles", _particlesBuffer); - ParticleCalculation.SetFloat("time", Time.time); + // Particle lifetimes cycle on the flow clock (zone time), so the dust stops with the sim like everything the flow moves. + ParticleCalculation.SetFloat("phase", FlowField.Cycle(VolumeSampling.FlowClock, Period)); - var pos = GravityCamera.transform.position; ParticleCalculation.SetFloat("period", Period); ParticleCalculation.SetFloat("spacing", Spacing); ParticleCalculation.SetFloat("ceilingHeight", Ceiling); @@ -121,38 +152,17 @@ public class Stardust : MonoBehaviour //Dispatch, launch threads on GPU int numberOfGroups = Mathf.CeilToInt((float)Span * Span / GROUP_SIZE); ParticleCalculation.Dispatch(_updateParticlesKernel, numberOfGroups, 1, 1); - - ParticleMaterial.SetBuffer("particles", _particlesBuffer); - ParticleMaterial.SetBuffer("quadPoints", _quadPoints); - Graphics.DrawProcedural(ParticleMaterial, new Bounds(pos, new Vector3(Spacing * Span, 2048, Spacing * Span)), MeshTopology.Triangles, 6, Span * Span, TargetCamera, null, ShadowCastingMode.Off, false, 0); } #endregion - #region rendering - // void OnRenderObject() - // { - // if (Camera.current == TargetCamera || Camera.current.name == "SceneCamera") - // { - // //Bind resources to material - // ParticleMaterial.SetBuffer("particles", _particlesBuffer); - // ParticleMaterial.SetBuffer("quadPoints", _quadPoints); - // // ParticleMaterial.SetFloat("velocityStretch", ParticleVelocityStretch); - // // ParticleMaterial.SetVector("velocity", PlayerVelocity); - // - // //Set the pass - // ParticleMaterial.SetPass(0); - // - // //Draw - // Graphics.DrawProceduralNow(MeshTopology.Triangles, 6, Span * Span); - // } - // } - #endregion - #region cleanup void OnDestroy() { // m_emitterProxies.Release(); // _temperature.Release(); + DetachDraw(); + _draw?.Release(); + _draw = null; if(_particlesBuffer!=null) { _particlesBuffer.Release(); diff --git a/Assets/Shaders/Gravity.cginc b/Assets/Shaders/Gravity.cginc new file mode 100644 index 000000000..47a419518 --- /dev/null +++ b/Assets/Shaders/Gravity.cginc @@ -0,0 +1,43 @@ +#ifndef AETHERIA_GRAVITY_INCLUDED +#define AETHERIA_GRAVITY_INCLUDED + +// GENERATED by ServerShared/GravityShader.cs from GravityField; do not edit (GravityShaderTests fails on any difference). +// The lowering of the zone's potential (aetheria-gravity, cut grid-lowering). The law is ServerShared's GravityField +// and the height is Zone.GetHeight; this file decides nothing. GravityLowering.Lower fills the buffer and the globals +// from the zone (positions from Orbit.Position, reference from Zone.WellReference) each frame. +// GravityFieldParityVerify renders it and compares every texel with -Zone.GetHeight. + +struct GravityWell +{ + float2 position; + float strength; + float coreRadius; + float reference; +}; + +StructuredBuffer _GravityWells; +int _GravityWellCount; +float _HeightExaggeration; + +// GravityField.Potential: c is the well's strength, R its core radius, r the distance. +float gravityPotential(float c, float R, float r) +{ + return c == 0 ? 0 : + r < R + ? c * r * r / (2 * R * R) + : c * (log(r / R) + 0.5); +} + +// Zone.GetHeight at world xz: each well's potential minus its own reference, summed, divided by the exaggeration. +float gravityHeight(float2 p) +{ + float result = 0; + for (int i = 0; i < _GravityWellCount; i++) + { + GravityWell well = _GravityWells[i]; + result += gravityPotential(well.strength, well.coreRadius, length(p - well.position)) - well.reference; + } + return result / _HeightExaggeration; +} + +#endif diff --git a/Assets/Shaders/Brushes/WormholeBrush.shader.meta b/Assets/Shaders/Gravity.cginc.meta similarity index 71% rename from Assets/Shaders/Brushes/WormholeBrush.shader.meta rename to Assets/Shaders/Gravity.cginc.meta index 6bccf4a95..61a1a4c96 100644 --- a/Assets/Shaders/Brushes/WormholeBrush.shader.meta +++ b/Assets/Shaders/Gravity.cginc.meta @@ -1,10 +1,9 @@ fileFormatVersion: 2 -guid: 8681ac064d59d15458d16cc9b884262c +guid: b8f69df89fde433c8263115c25267a10 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] - preprocessorOverride: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Shaders/Raymarching/VolumeRender.shader b/Assets/Shaders/Raymarching/VolumeRender.shader deleted file mode 100644 index a6e5b4fc2..000000000 --- a/Assets/Shaders/Raymarching/VolumeRender.shader +++ /dev/null @@ -1,217 +0,0 @@ -Shader "VolSample/Volume Render Auto" { - Properties { - _MainTex( "", 2D ) = "white" {} - _StepExponent("Step Exponent", float) = 1 - //_GridTransform("Grid Transform", Vector) = (0,0,0,0) - _Exposure("Exposure", float) = 1 - _Gamma("Gamma", float) = .5 - _TintExponent("Tint Exponent", float) = .5 - _DepthCeiling("Depth Ceiling", float) = 1000 - _DepthBlend("Depth Blend", float) = 100 - _SafetyDistance("Safety Distance", float) = 20 - _Scattering("Scattering", float) = 1 - _ScatteringMinDist("ScatteringMinDist", float) = 1 - _ScatteringDistExponent("ScatteringDistExponent", float) = 1 - _ScatteringDensityExponent("ScatteringDensityExponent", float) = 1 - } - - CGINCLUDE; - - uniform sampler2D _MainTex; - uniform sampler2D _CameraDepthTexture; - - #include "UnityCG.cginc" - #include "Assets/Shaders/Volumetric.cginc" - - // the number of volume samples to take - #define SAMPLE_COUNT 96 - - // Shared shader code for pixel view rays, given screen pos and camera frame vectors. - // Camera vectors are passed in as this shader is run from a post proc camera, so the unity built-in values are not useful. - uniform float4x4 _CamProj; - uniform float4x4 _CamInvProj; - uniform float3 _CamPos; - uniform float3 _CamForward; - uniform float3 _CamRight; - uniform float _HalfFov; - uniform int _FrameNumber; - - uniform float _StepExponent; - - uniform half _Gamma, - _Exposure, - _DepthCeiling, - _DepthBlend, - _Scattering, - _ScatteringDensityExponent, - _ScatteringDistExponent, - _ScatteringMinDist; - - // Dithering - sampler2D _DitheringTex; - float4 _DitheringCoords; - - inline float nrand(float2 ScreenUVs) - { - return frac(sin(ScreenUVs.x * 12.9898 + ScreenUVs.y * 78.233) * 43758.5453); - } - - void RaymarchStep( in float3 pos, in float stepSize, in float weight, inout float4 sum, in float scatter, inout float scatterSum) - { - float4 col = VolumeSampleColor( pos ); - col.a *= stepSize * weight; - sum.rgb += col.rgb * col.a * (1.0 - sum.a); - sum.a += col.a; - scatterSum += pow(sum.a, _ScatteringDensityExponent) * scatter; - } - - float4 RayMarch( in float3 origin, in float3 direction, in float zbuf, in float2 screenUV, out float scatterSum ) - { - scatterSum = 0; - float blue = tex2D(_DitheringTex, screenUV * _DitheringCoords.xy + _DitheringCoords.zw).r; - //float rand = frac(blue + _FrameNumber * 1.61803398875); - //return float4(rand, rand, rand, 1); - //half rand = frac(nrand(screenUV) + _FrameNumber * 1.61803398875); - //half rand = nrand(screenUV + frac(_Time.x)); - half rand = blue; - float4 sum = (float4)0.; - scatterSum = 0.; - - // setup sampling - - float rayDist = 0; - for( int i = 0; i < SAMPLE_COUNT; i++ ) - { - float prevRayDist = rayDist; - rayDist = pow((i+rand)/SAMPLE_COUNT,_StepExponent) * _DepthCeiling + 1; - float distToSurf = zbuf - rayDist; - if( distToSurf <= 0.001 || sum.a > .99) break; - - float step = rayDist - prevRayDist; - //float wt = (distToSurf >= step) ? 1. : distToSurf / step; - - RaymarchStep( origin + rayDist * direction, step, 1-rayDist/_DepthCeiling, sum, _Scattering/pow(max(rayDist,_ScatteringMinDist),_ScatteringDistExponent), scatterSum); - } - - sum.rgb = pow( sum.rgb / pow(100,_TintExponent), 1 / _Gamma ) * _Exposure; - return sum; - } - - struct v2f - { - float4 pos : SV_POSITION; - float4 screenPos : TEXCOORD1; - }; - - v2f vert( appdata_base v ) - { - v2f o; - o.pos = UnityObjectToClipPos( v.vertex ); - o.screenPos = ComputeScreenPos( o.pos ); - return o; - } - - void computeCamera( in float2 q, out float3 rayOrigin, out float3 rayDirection ) - { - rayOrigin = _WorldSpaceCameraPos; - - float2 p = 2.0*(q - 0.5); - float4 d = mul(_CamProj, float4(p, 0, 1)); - d.xyz /= d.w; - //rd = (d - rayOrigin); - rayDirection = normalize(d - rayOrigin); - rayOrigin = d; - //rayOrigin += _ProjectionParams.y * rd; - } - - inline float LinearEyeDepthToOutDepth(float z) - { - return (1 - _ZBufferParams.w * z) / (_ZBufferParams.z * z); - } - - float3 DepthToWorld(float2 uv, float depth) { - float z = (1-depth) * 2.0 - 1.0; - - float4 clipSpacePosition = float4(uv * 2.0 - 1.0, z, 1.0); - - float4 viewSpacePosition = mul(_CamInvProj,clipSpacePosition); - viewSpacePosition /= viewSpacePosition.w; - - float4 worldSpacePosition = mul(unity_ObjectToWorld,viewSpacePosition); - - return worldSpacePosition.xyz; - } - - // MRT shader - struct FragmentOutput - { - half4 dest0 : COLOR0; - half4 dest1 : COLOR1; - }; - - FragmentOutput frag( v2f i ) : SV_Target //out float outDepth : SV_Depth - { - FragmentOutput o; - - float2 q = i.screenPos.xy / i.screenPos.w; - - // camera - float3 rayOrigin, rayDirection; - computeCamera( q, rayOrigin, rayDirection ); - - // z buffer / scene depth for this pixel - float4 screenPos = UNITY_PROJ_COORD( i.screenPos ); - float2 screenUV = screenPos.xy / screenPos.w; - - float depthSample = tex2Dproj( _CameraDepthTexture, screenPos ).r; - //float depthValue = LinearEyeDepth(depthSample); - - float3 worldDepth = DepthToWorld(screenPos, depthSample); - float depthValue = length(worldDepth-rayOrigin); - - // march through volume - float scatter; - float4 clouds = RayMarch( rayOrigin, rayDirection, depthValue, screenUV, scatter ); - o.dest1 = .5 + scatter*.5;//smoothstep(1,.99,clouds.a)*pow(clouds.a,1)*.5; - - float3 bgcol = tex2Dlod( _MainTex, float4(q, 0., 0.) ); - // add in camera render colours, if not zfar (so we exclude skybox) - if(clouds.a < .99 && depthValue < _DepthCeiling) - { - // Blend out camera render when outside marching range - if( depthValue >= _DepthCeiling - _DepthBlend ) - clouds.a = lerp(clouds.a, 1, (depthValue - (_DepthCeiling - _DepthBlend)) / _DepthBlend); - - //clouds.xyz = lerp(clouds.xyz, bgcol, 1-clouds.a); - clouds.xyz += (1. - clouds.a) * bgcol; - // assume zbuffer represents opaque surface - - } - clouds.a = 1.; - - //outDepth = LinearEyeDepthToOutDepth(min(depthValue, rayDist)); - - o.dest0 = clouds; - return o; - } - - - ENDCG - - Subshader - { - Pass - { - ZTest Always Cull Off ZWrite Off - - CGPROGRAM - #pragma target 3.0 - #pragma vertex vert - #pragma fragment frag - ENDCG - } - } - - Fallback off - -} // shader diff --git a/Assets/Shaders/Raymarching/VolumeRenderCustom.shader b/Assets/Shaders/Raymarching/VolumeRenderCustom.shader deleted file mode 100644 index cf0a548b3..000000000 --- a/Assets/Shaders/Raymarching/VolumeRenderCustom.shader +++ /dev/null @@ -1,236 +0,0 @@ -Shader "VolSample/Volume Render" { - Properties { - _MainTex( "", 2D ) = "white" {} - _StepExponent("Step Exponent", float) = 1 - _NebulaSurfaceHeight("Surface Displacement", 2D) = "black" {} - _NebulaPatch("Patch", 2D) = "black" {} - _NebulaPatchHeight("Patch Displacement", 2D) = "black" {} - _NebulaTint("Tint Texture", 2D ) = "white" {} - [HDR]_Tint("Tint Color", Color) = (1,1,1,1) - //_GridTransform("Grid Transform", Vector) = (0,0,0,0) - _NebulaFillDensity("Fill Density", float) = 1 - _NebulaFloorDensity("Floor Density", float) = 1 - _NebulaPatchDensity("Patch Density", float) = 1 - _NebulaFloorOffset("Floor Offset", float) = 1 - _NebulaFloorBlend("Floor Blend", float) = 1 - _NebulaPatchBlend("Patch Blend", float) = 1 - _Exposure("Exposure", float) = 1 - _Gamma("Gamma", float) = .5 - _TintExponent("Tint Exponent", float) = .5 - _DepthCeiling("Depth Ceiling", float) = 1000 - _DepthBlend("Depth Blend", float) = 100 - _NoiseAmplitude("Noise Amplitude", float) = 1 - _NoiseScale("Noise Scale", float) = 100 - _NoiseExponent("Noise Exponent", float) = 2 - _NoiseSpeed("Noise Speed", float) = 1 - _FlowScroll("Flow Scroll", float) = 1 - _FlowScale("Flow Scale", float) = 1 - _FlowAmplitude("Flow Amplitude", float) = 1 - _FlowSpeed("Flow Speed", float) = 1 - _SafetyDistance("Safety Distance", float) = 20 - _Scattering("Scattering", float) = 1 - _ScatteringMinDist("ScatteringMinDist", float) = 1 - _ScatteringDistExponent("ScatteringDistExponent", float) = 1 - _ScatteringDensityExponent("ScatteringDensityExponent", float) = 1 - } - - CGINCLUDE; - - uniform sampler2D _MainTex; - uniform sampler2D _CameraDepthTexture; - - #include "UnityCG.cginc" - #include "Assets/Shaders/Volumetric.cginc" - - // the number of volume samples to take - #define SAMPLE_COUNT 96 - - // Shared shader code for pixel view rays, given screen pos and camera frame vectors. - // Camera vectors are passed in as this shader is run from a post proc camera, so the unity built-in values are not useful. - uniform float4x4 _CamProj; - uniform float4x4 _CamInvProj; - uniform float3 _CamPos; - uniform float3 _CamForward; - uniform float3 _CamRight; - uniform float _HalfFov; - uniform int _FrameNumber; - - uniform float _StepExponent; - - uniform half _Gamma, - _Exposure, - _DepthCeiling, - _DepthBlend, - _Scattering, - _ScatteringDensityExponent, - _ScatteringDistExponent, - _ScatteringMinDist; - - // Dithering - sampler2D _DitheringTex; - float4 _DitheringCoords; - - inline float nrand(float2 ScreenUVs) - { - return frac(sin(ScreenUVs.x * 12.9898 + ScreenUVs.y * 78.233) * 43758.5453); - } - - void RaymarchStep( in float3 pos, in float stepSize, in float weight, inout float4 sum, in float scatter, inout float scatterSum) - { - float4 col = VolumeSampleColor( pos ); - col.a *= stepSize * weight; - sum.rgb += col.rgb * col.a * (1.0 - sum.a); - sum.a += col.a; - scatterSum += pow(col.a, _ScatteringDensityExponent) * scatter; - } - - float4 RayMarch( in float3 origin, in float3 direction, in float zbuf, in float2 screenUV, out float scatterSum ) - { - scatterSum = 0; - float blue = tex2D(_DitheringTex, screenUV * _DitheringCoords.xy + _DitheringCoords.zw).r; - //float rand = frac(blue + _FrameNumber * 1.61803398875); - //return float4(rand, rand, rand, 1); - //half rand = frac(nrand(screenUV) + _FrameNumber * 1.61803398875); - //half rand = nrand(screenUV + frac(_Time.x)); - half rand = blue; - float4 sum = (float4)0.; - scatterSum = 0.; - - // setup sampling - - float rayDist = 0; - for( int i = 0; i < SAMPLE_COUNT; i++ ) - { - float prevRayDist = rayDist; - rayDist = pow((i+rand)/SAMPLE_COUNT,_StepExponent) * _DepthCeiling + 1; - float distToSurf = zbuf - rayDist; - if( distToSurf <= 0.001 || sum.a > .99) break; - - float step = rayDist - prevRayDist; - //float wt = (distToSurf >= step) ? 1. : distToSurf / step; - - RaymarchStep( origin + rayDist * direction, step, 1-rayDist/_DepthCeiling, sum, _Scattering/pow(max(rayDist,_ScatteringMinDist),_ScatteringDistExponent), scatterSum); - } - - sum.rgb = pow( sum.rgb, 1 / _Gamma ) * _Exposure; - return sum; - } - - struct v2f - { - float4 pos : SV_POSITION; - float4 screenPos : TEXCOORD1; - }; - - v2f vert( appdata_base v ) - { - v2f o; - o.pos = UnityObjectToClipPos( v.vertex ); - o.screenPos = ComputeScreenPos( o.pos ); - return o; - } - - void computeCamera( in float2 q, out float3 rayOrigin, out float3 rd ) - { - rayOrigin = _WorldSpaceCameraPos; - - float2 p = 2.0*(q - 0.5); - float4 d = mul(_CamProj, float4(p, 0, 1)); - d.xyz /= d.w; - //rd = (d - rayOrigin); - rd = normalize(d - rayOrigin); - rayOrigin = d; - //rayOrigin += _ProjectionParams.y * rd; - } - - inline float LinearEyeDepthToOutDepth(float z) - { - return (1 - _ZBufferParams.w * z) / (_ZBufferParams.z * z); - } - - float3 DepthToWorld(float2 uv, float depth) { - float z = (1-depth) * 2.0 - 1.0; - - float4 clipSpacePosition = float4(uv * 2.0 - 1.0, z, 1.0); - - float4 viewSpacePosition = mul(_CamInvProj,clipSpacePosition); - viewSpacePosition /= viewSpacePosition.w; - - float4 worldSpacePosition = mul(unity_ObjectToWorld,viewSpacePosition); - - return worldSpacePosition.xyz; - } - - // MRT shader - struct FragmentOutput - { - half4 dest0 : COLOR0; - half4 dest1 : COLOR1; - }; - - FragmentOutput frag( v2f i ) : SV_Target //out float outDepth : SV_Depth - { - FragmentOutput o; - - float2 q = i.screenPos.xy / i.screenPos.w; - - // camera - float3 rayOrigin, rayDirection; - computeCamera( q, rayOrigin, rayDirection ); - - // z buffer / scene depth for this pixel - float4 screenPos = UNITY_PROJ_COORD( i.screenPos ); - float2 screenUV = screenPos.xy / screenPos.w; - - float depthSample = tex2Dproj( _CameraDepthTexture, screenPos ).r; - //float depthValue = LinearEyeDepth(depthSample); - - float3 worldDepth = DepthToWorld(screenPos, depthSample); - float depthValue = length(worldDepth-rayOrigin); - - // march through volume - float scatter; - float4 clouds = RayMarch( rayOrigin, rayDirection, depthValue, screenUV, scatter ); - o.dest1 = .5 + scatter*.5;//smoothstep(1,.99,clouds.a)*pow(clouds.a,1)*.5; - - float3 bgcol = tex2Dlod( _MainTex, float4(q, 0., 0.) ); - // add in camera render colours, if not zfar (so we exclude skybox) - if(clouds.a < .99 && depthValue < _DepthCeiling) - { - // Blend out camera render when outside marching range - if( depthValue >= _DepthCeiling - _DepthBlend ) - clouds.a = lerp(clouds.a, 1, (depthValue - (_DepthCeiling - _DepthBlend)) / _DepthBlend); - - //clouds.xyz = lerp(clouds.xyz, bgcol, 1-clouds.a); - clouds.xyz += (1. - clouds.a) * bgcol; - // assume zbuffer represents opaque surface - - } - clouds.a = 1.; - - //outDepth = LinearEyeDepthToOutDepth(min(depthValue, rayDist)); - - o.dest0 = clouds; - return o; - } - - - ENDCG - - Subshader - { - Pass - { - ZTest Always Cull Off ZWrite Off - - CGPROGRAM - #pragma target 3.0 - #pragma vertex vert - #pragma fragment frag - ENDCG - } - } - - Fallback off - -} // shader diff --git a/Assets/Shaders/Raymarching/VolumeRenderCustom.shader.meta b/Assets/Shaders/Raymarching/VolumeRenderCustom.shader.meta deleted file mode 100644 index a0f8d767f..000000000 --- a/Assets/Shaders/Raymarching/VolumeRenderCustom.shader.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 7940bc6e15d348ff930f4ebb3c475cf2 -timeCreated: 1623409494 \ No newline at end of file diff --git a/Assets/Shaders/Volumetric.cginc b/Assets/Shaders/Volumetric.cginc index 44fad2c06..dd48ddc86 100644 --- a/Assets/Shaders/Volumetric.cginc +++ b/Assets/Shaders/Volumetric.cginc @@ -24,7 +24,6 @@ uniform half _NebulaFillDensity, _NebulaFloorBlend, _NebulaPatchBlend, _NebulaLuminance, - _TintExponent, _TintLodExponent, _NebulaNoiseScale, _NebulaNoiseExponent, @@ -33,7 +32,7 @@ uniform half _NebulaFillDensity, _NebulaNoiseSlopeExponent, _FlowScale, _FlowAmplitude, - _FlowScroll, + _FlowCycle, _FlowPeriod, _FlowSlopeAmplitude, _FlowSwirlAmplitude, @@ -42,6 +41,9 @@ uniform half _NebulaFillDensity, _DynamicLodHigh, _DynamicIntensity, _DynamicSkyBoost; +float2 _FlowScroll; +// The flow clock (zone time, VolumeSampling.FlowClock): the nebula noise evolves on it, never on _Time. +float _NebulaNoiseTime; inline float tri(in float x){return abs(frac(x)-.5);} inline float3 tri3(in float3 p){return float3( tri(p.z+tri(p.y*1.)), tri(p.z+tri(p.x*1.)), tri(p.y+tri(p.x*1.)));} @@ -54,7 +56,7 @@ float triNoise3d(in float3 p) for (float i=0.; i<=1.; i++ ) { float3 dg = tri3(bp * 2.); - p += dg + _Time.y * _NebulaNoiseSpeed; + p += dg + _NebulaNoiseTime * _NebulaNoiseSpeed; bp *= 1.8; z *= 1.5; @@ -66,10 +68,11 @@ float triNoise3d(in float3 p) return rz; } -float3 Tri3D( float3 P ) +// The two octaves' positions arrive already scrolled (FlowField.Scroll folds each octave's phase in double). +float3 Tri3D( float3 P, float3 PGolden ) { float3 t1 = normalize(tri3(P)); - float3 t2 = normalize(tri3(P * 1.61803398875)); + float3 t2 = normalize(tri3(PGolden)); return cross(t1,t2); } @@ -93,7 +96,9 @@ float cloudDensity(float3 pos, float surfaceDisp) float2 uv = getUV(pos.xz); const float dist = pos.y + surfaceDisp - _NebulaFloorOffset; const float patch = tex2Dlod(_NebulaPatch, half4(uv, 0, 0)).r; - const float patchDisp = tex2Dlod(_NebulaPatchHeight, half4(uv, 0, 0)).r; + // Gravity comes from the R32 surface height the caller sampled at this uv; the patch texture carries only the patch + // layers (sector waves, patch brushes), small enough for half floats. + const float patchDisp = surfaceDisp + tex2Dlod(_NebulaPatchHeight, half4(uv, 0, 0)).r; const float patchDensity = saturate((-abs(pos.y+patchDisp - _NebulaFloorOffset)+patch)/_NebulaPatchBlend)*_NebulaPatchDensity; const float floorDist = -dist; @@ -101,16 +106,6 @@ float cloudDensity(float3 pos, float surfaceDisp) return patchDensity + max(0,floorDensity); } -// TODO: Get this working? -float2 texFlow(float3 pos) -{ - const float2 fluidUv = getUVFluid(pos.xz); - if(any(fluidUv<0)||any(fluidUv>1)) return 0; - const float2 fluidSample = tex2Dlod(_FluidVelocity, half4(fluidUv, 0, 0)).xy; - // TODO: remove magic number for fluid texture dimensions - return float3(fluidSample.x,0,fluidSample.y) * (512 / _FluidTransform.z); -} - float2 gravGradient (float2 uv) { return float2( @@ -129,13 +124,15 @@ float3 gravNormal (float2 grad) float3 globalFlow(float3 pos) { - float3 flowSample = Tri3D( pos / _FlowScale - float3(0,_FlowScroll,0) ) * _FlowAmplitude; + const float3 field = pos / _FlowScale; + float3 flowSample = Tri3D( field - float3(0,_FlowScroll.x,0), field * 1.61803398875 - float3(0,_FlowScroll.y,0) ) * _FlowAmplitude; flowSample.y *= .5; return flowSample; } float3 slopeFlow(float2 grad) { + if (dot(grad, grad) == 0) return 0; float2 ngrad = normalize(grad); return float3(ngrad.y, 0, -ngrad.x) * _FlowSwirlAmplitude + float3(ngrad.x, 0, ngrad.y) * _FlowSlopeAmplitude; } @@ -197,13 +194,13 @@ float density(float3 pos) #endif #endif - const float lerp1 = frac(_Time.y / _FlowPeriod); - const float lerp2 = frac(_Time.y / _FlowPeriod + .5); + const float lerp1 = frac(_FlowCycle); + const float lerp2 = frac(_FlowCycle + .5); const float noise1 = pow(triNoise3d((pos+fl.xyz * (lerp1 - .5) * _FlowPeriod) / _NebulaNoiseScale),exponent) * tri2(lerp1); const float noise2 = pow(triNoise3d((pos+fl.xyz * (lerp2 - .5) * _FlowPeriod) / _NebulaNoiseScale),exponent) * tri2(lerp2); pos.y += (noise1 + noise2) * heightFade * _NebulaNoiseAmplitude; - const float lerp3 = frac(_Time.y / _FlowPeriod * 2 + .25); - const float lerp4 = frac(_Time.y / _FlowPeriod * 2 + .75); + const float lerp3 = frac(_FlowCycle * 2 + .25); + const float lerp4 = frac(_FlowCycle * 2 + .75); const float noise3 = pow(triNoise3d((pos+fl.xyz * (lerp3 - .5) * _FlowPeriod / 2) / _NebulaNoiseScale * 8), exponent) * tri2(lerp3); const float noise4 = pow(triNoise3d((pos+fl.xyz * (lerp4 - .5) * _FlowPeriod / 2) / _NebulaNoiseScale * 8), exponent) * tri2(lerp4); pos.y -= (noise3 + noise4) * heightFade * _NebulaNoiseAmplitude / 2; @@ -228,20 +225,11 @@ float4 VolumeSampleColor(float3 pos) return float4(tint, d); } -float2 tintGradient (float2 uv) -{ - return float2( - length(tex2Dlod(_NebulaTint, float4(uv.x + _NebulaTint_TexelSize.x, uv.y, 0, 0))) - length(tex2Dlod(_NebulaTint, float4(uv.x - _NebulaTint_TexelSize.x, uv.y, 0, 0))), - length(tex2Dlod(_NebulaTint, float4(uv.x, uv.y + _NebulaTint_TexelSize.y, 0, 0))) - length(tex2Dlod(_NebulaTint, float4(uv.x, uv.y - _NebulaTint_TexelSize.y, 0, 0))) - ); -} - float3 VolumeSampleColorSimple(float3 pos, float3 normal) { float2 uv = getUV(pos.xz); float3 low = tex2Dlod(_NebulaTint, float4(uv.x, uv.y, 0, _DynamicLodLow)).rgb; float3 high = tex2Dlod(_NebulaTint, float4(uv.x, uv.y, 0, _DynamicLodHigh)).rgb * _DynamicSkyBoost; float upness = dot(normal, float3(0,1,0)); - //float lambert = 2 - dot(normalize(normal.xz), normalize(tintGradient(uv))); return lerp(low,high,sqrt((upness+1)/2)) * _DynamicIntensity / (density(pos)+1); } diff --git a/Assets/TextMesh Pro/Resources/Sprite Assets/EmojiOne.asset b/Assets/TextMesh Pro/Resources/Sprite Assets/EmojiOne.asset deleted file mode 100644 index 8fd3185ec..000000000 --- a/Assets/TextMesh Pro/Resources/Sprite Assets/EmojiOne.asset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:155fff99f467baa93dd2d0886df466bd242cd5e3c8c60c9d43e9cdad269f7f54 -size 13441 diff --git a/Assets/TextMesh Pro/Resources/Sprite Assets/EmojiOne.asset.meta b/Assets/TextMesh Pro/Resources/Sprite Assets/EmojiOne.asset.meta deleted file mode 100644 index c7ac83f4d..000000000 --- a/Assets/TextMesh Pro/Resources/Sprite Assets/EmojiOne.asset.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c41005c129ba4d66911b75229fd70b45 -timeCreated: 1480316912 -licenseType: Pro -NativeFormatImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/TextMesh Pro/Resources/TMP Settings.asset b/Assets/TextMesh Pro/Resources/TMP Settings.asset index 769423630..069416487 100644 --- a/Assets/TextMesh Pro/Resources/TMP Settings.asset +++ b/Assets/TextMesh Pro/Resources/TMP Settings.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:76affcb169f370013c97b08f1d6d3e092a054a2abf970e164cd40400799552a7 -size 1852 +oid sha256:19c9ec14d2e0d0ca31177f52ec0a4a81d945bd9c5ead9f776c5bf51fbc22b344 +size 1938 diff --git a/Assets/TextMesh Pro/Sprites/EmojiOne Attribution.txt b/Assets/TextMesh Pro/Sprites/EmojiOne Attribution.txt deleted file mode 100644 index 384180a92..000000000 --- a/Assets/TextMesh Pro/Sprites/EmojiOne Attribution.txt +++ /dev/null @@ -1,3 +0,0 @@ -This sample of beautiful emojis are provided by EmojiOne https://www.emojione.com/ - -Please visit their website to view the complete set of their emojis and review their licensing terms. \ No newline at end of file diff --git a/Assets/TextMesh Pro/Sprites/EmojiOne.json b/Assets/TextMesh Pro/Sprites/EmojiOne.json deleted file mode 100644 index 6c4e50bc8..000000000 --- a/Assets/TextMesh Pro/Sprites/EmojiOne.json +++ /dev/null @@ -1,156 +0,0 @@ -{"frames": [ - -{ - "filename": "1f60a.png", - "frame": {"x":0,"y":0,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f60b.png", - "frame": {"x":128,"y":0,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f60d.png", - "frame": {"x":256,"y":0,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f60e.png", - "frame": {"x":384,"y":0,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f600.png", - "frame": {"x":0,"y":128,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f601.png", - "frame": {"x":128,"y":128,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f602.png", - "frame": {"x":256,"y":128,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f603.png", - "frame": {"x":384,"y":128,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f604.png", - "frame": {"x":0,"y":256,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f605.png", - "frame": {"x":128,"y":256,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f606.png", - "frame": {"x":256,"y":256,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f609.png", - "frame": {"x":384,"y":256,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f618.png", - "frame": {"x":0,"y":384,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "1f923.png", - "frame": {"x":128,"y":384,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "263a.png", - "frame": {"x":256,"y":384,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}, -{ - "filename": "2639.png", - "frame": {"x":384,"y":384,"w":128,"h":128}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, - "sourceSize": {"w":128,"h":128}, - "pivot": {"x":0.5,"y":0.5} -}], -"meta": { - "app": "http://www.codeandweb.com/texturepacker", - "version": "1.0", - "image": "EmojiOne.png", - "format": "RGBA8888", - "size": {"w":512,"h":512}, - "scale": "1", - "smartupdate": "$TexturePacker:SmartUpdate:196a26a2e149d875b91ffc8fa3581e76:fc928c7e275404b7e0649307410475cb:424723c3774975ddb2053fd5c4b85f6e$" -} -} diff --git a/Assets/TextMesh Pro/Sprites/EmojiOne.png b/Assets/TextMesh Pro/Sprites/EmojiOne.png deleted file mode 100644 index 63e49d095..000000000 --- a/Assets/TextMesh Pro/Sprites/EmojiOne.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a87b965a701de3dc31d7401e542b1fc946587f912c51d7a26e46ade9f098bd1a -size 112319 diff --git a/Assets/TextMesh Pro/Sprites/EmojiOne.png.meta b/Assets/TextMesh Pro/Sprites/EmojiOne.png.meta deleted file mode 100644 index c9fa1a7df..000000000 --- a/Assets/TextMesh Pro/Sprites/EmojiOne.png.meta +++ /dev/null @@ -1,431 +0,0 @@ -fileFormatVersion: 2 -guid: dffef66376be4fa480fb02b19edbe903 -TextureImporter: - fileIDToRecycleName: - 21300000: EmojiOne_0 - 21300002: EmojiOne_1 - 21300004: EmojiOne_2 - 21300006: EmojiOne_3 - 21300008: EmojiOne_4 - 21300010: EmojiOne_6 - 21300012: EmojiOne_7 - 21300014: EmojiOne_8 - 21300016: EmojiOne_9 - 21300018: EmojiOne_10 - 21300020: EmojiOne_11 - 21300022: EmojiOne_12 - 21300024: EmojiOne_13 - 21300026: EmojiOne_5 - 21300028: EmojiOne_14 - 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: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 2 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaUsage: 1 - alphaIsTransparency: 1 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 512 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: Standalone - maxTextureSize: 512 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: iPhone - maxTextureSize: 512 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: Android - maxTextureSize: 512 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: - - serializedVersion: 2 - name: EmojiOne_0 - rect: - serializedVersion: 2 - x: 0 - y: 384 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 4bcc36da2108f2c4ba3de5c921d25c3c - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_1 - rect: - serializedVersion: 2 - x: 128 - y: 384 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: e9eea8093eaeaee4d901c4553f572c22 - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_2 - rect: - serializedVersion: 2 - x: 256 - y: 384 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 49451da35411dcc42a3692e39b0fde70 - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_3 - rect: - serializedVersion: 2 - x: 384 - y: 384 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: f65709664b924904790c850a50ca82bc - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_4 - rect: - serializedVersion: 2 - x: 0 - y: 256 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 5b92c568a5ec9ad4b9ed90e271f1c9a8 - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_6 - rect: - serializedVersion: 2 - x: 256 - y: 256 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: b10f2b48b7281594bb8a24a6511a35af - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_7 - rect: - serializedVersion: 2 - x: 384 - y: 256 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 10a600f9329dc2246a897e89f4d283cd - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_8 - rect: - serializedVersion: 2 - x: 0 - y: 128 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 66cffa363b90ab14787d8a5b90cf4502 - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_9 - rect: - serializedVersion: 2 - x: 128 - y: 128 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 55cf3d409c9b89349b1e1bdc1cc224ad - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_10 - rect: - serializedVersion: 2 - x: 256 - y: 128 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 2a9e58eaf96feef42bcefa1cf257193f - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_11 - rect: - serializedVersion: 2 - x: 384 - y: 128 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 2489120affc155840ae6a7be2e93ce19 - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_12 - rect: - serializedVersion: 2 - x: 0 - y: 0 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: 412349a150598d14da4d7140df5c0286 - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_13 - rect: - serializedVersion: 2 - x: 128 - y: 0 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0.5, y: 0.5} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: a937464b42bb3634782dea34c6becb6c - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_5 - rect: - serializedVersion: 2 - x: 256 - y: 0 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0, y: 0} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: b0f933b217682124dbfc5e6b89abe3d0 - vertices: [] - indices: - edges: [] - weights: [] - - serializedVersion: 2 - name: EmojiOne_14 - rect: - serializedVersion: 2 - x: 128 - y: 256 - width: 128 - height: 128 - alignment: 0 - pivot: {x: 0, y: 0} - border: {x: 0, y: 0, z: 0, w: 0} - outline: [] - physicsShape: [] - tessellationDetail: 0 - bones: [] - spriteID: f7235c763afe4434e8bb666750a41096 - vertices: [] - indices: - edges: [] - weights: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: 3e32d8f5477abfc43b19066e8ad5032e - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Directory.Build.props b/Directory.Build.props index e1f4acc37..190e89780 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,8 +6,8 @@ 45c2f4006f5f7dab357426cabd3197e8d0a17f66 $(CULTMATH_ROOT) $(CultLibRoot) - - 6d5e2096563a320933b64ddfd6ded8f2e846ac91 + + 9c1b06cd703bfa44352050e819b0d0659cf5978a C:\Program Files\Git\cmd\git.exe git diff --git a/Directory.Build.targets b/Directory.Build.targets index c9c079a6c..809f01c86 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -18,7 +18,7 @@ + Condition="'$(SkipCultLibRevisionCheck)' != 'true' and '@(ProjectReference->WithMetadataValue('Filename','CultMath'))' != ''"> ()` (Entity.cs:1618) iterates `Equipment` and each item's `Behaviors`. Consumable-hosted behaviours are not in it, so a suppressor is equipped gear only. | +| H4 | How does a behaviour pay heat into its own cell? | `Behavior.AddHeat` (Behaviors.cs:52) is `Item?.AddHeat`, which splits the heat over the item's `InsetShape` cells through `Entity.AddHeat(cell, heat)` (Entity.cs:2221-2226, :1212). A gear with the fixture's `Shape = new Shape()` has no cells; a test that asserts heat in the item's cell needs a gear with a solid 1x1 shape (probe before use). | +| H5 | What stops an item running when too hot? | `EquippedItem.Active` = `Enabled` and `Online`; `Online` = `ThermalOnline` and `DurabilityOnline` (Entity.cs:2071-2074, :2241-2242). `Radiator.Execute` returns early below its floor (Radiator.cs:103-117). A rated temperature is therefore a behaviour stat compared with `Behavior.Temperature` (the mean of the item's cells, Entity.cs:1968-1974), as the radiator compares its own. | +| H6 | What makes a flash a reveal? | `Entity.Sense` (Entity.cs:996-1000) records a reveal when a signature's `Strength` times the observer's `PassiveInfo` at range exceeds `TargetDetectionInfoThreshold`. Scaling the strength at write therefore decides the reveal with no change to `Sense`. The flash also feeds `Visibility` (the sum of sources), so a suppressed launch thins the ship's track too. | +| H7 | Next free `BehaviorData` union key? | Corrected at 0898725f: `LaunchSuppressorData` landed as 49 (Behaviors.cs:193), because `PickupData` took 48 (:192) first; 50 is the next free key. Never reuse a retired key (12, 26). `BehaviorData.Group` is `Key(0)`; a new data type's own fields start at `Key(1)`. | +| H8 | Where does a new gear design reach the catalog? | `tools/AetherDb/Program.cs`: one-shot authoring commands (`pd-gear`, `consumables-first-set`) write a design plus `FactionProductData` rows per maker with `MakerProfiles` (Program.cs:244-249) giving the quality mean and deviation. Makers are the factions `Zhestokost`, `AU`, `Lightsail`, `R&D`, `Lucent`, `NiteLife`, `Finch`, `Alakrita`, `DME`, `Adrasteia`. | +| H9 | Test fixture that already builds ships, fires guns and observes reveals? | `ContactRevealTests` (ContactRevealTests.cs:27-232, a `partial` class also extended by EmissionTests.cs): its constructor authors catalog gear, `Add` builds a ship, `Fire` fires a gun and ticks until its light shows, `Tick`, `RevealsOf`. Gun visibility 5, `TargetDetectionInfoThreshold` .1, `VisibilityDecay` 100. | + +## Model page: corrections to the target's table + +- **Channel suppression** (target row): not stored. It is derived on every `SetSignature` call by asking the + ship's equipped `LaunchSuppressor` behaviours, in equipment order, for the factor of the channel being written + (H2). There is no `(ship, channel)` factor field to write, order or let go stale. The suppressor's authority + is unchanged: only the suppressor's behaviour decides the factor and pays the heat; weapons and observers do not. +- **Suppressor EW gear stats** (inside the target's "EW gear stats" row): `LaunchSuppressorData` carries the factor, + the heat paid per unit of strength removed, and the rated temperature, all `PerformanceStat`s so quality moves + them like other gear. +- **Contact** and **Belief** (target rows): in cut 2, `Contact.Profile` is derived on read from the subject's + `ClaimedHull` once `Identified` and is null below it; no belief is stored. The Belief row (stored, with + `SeenThrough`) begins in cut 4, when the judge gives it a writer (C5). +- **Ship claim** and **Item claim** (target rows): held on the subject `Entity` as `_hullClaim` and `_itemClaims`, + read through `ClaimedHull` and `ClaimOf(item)` (absent means the truth), written only through `Entity.Claim`. + +## Cut 2 probes at 0681d6f2 + +`ew-claims-in-the-book` is mapped as `cut-ew-claims-in-the-book.r1` (agent imagination-aeth-ew-claims). Probed at +`origin/master` `0681d6f2` (contact-hud and ew-hide-launch merged). + +| # | Question | Result | +|---|---|---| +| C1 | Which consumers read another ship's identity to label, rank or choose? | Two. The enemy schematic: rows are `RevealsOf(...).Select(r => r.Item).Where(IsWeapon)` with `IsWeapon` over the true item's live `Behaviors` (SchematicDisplay.cs:96, 99, 104), the label is `ShowWeapon(x.Item.Data)` (:128), the range label is the true behaviour's `Weapon.Range` (:240-245). `CombatState`'s target-item choice walks `target.Equipment`, keeps items whose live behaviour is a `Weapon` and that `IsRevealed`, and ranks by that behaviour's `RangeDamagePerSecond` (Combat.cs:40-51). | +| C2 | Who chooses by allegiance? | `IsHostileTo`, `VisibleEnemies`/`VisibleFriendlies`, `Faction`: ActionGameManager.cs:419, 629, 1273, 1469; Minion.cs:14 (first enemy added); TurretController.cs:98 (first enemy ship); LockWeapon.cs:98; Weapon.cs:113; Sensor.cs:211 (ally datalink, truth by ruling). None reads a class. All belong to cut 3 (`ew-hostility-from-belief-ruled`). | +| C3 | What else shows another ship's identity? | The target `InventoryPanel` (InventoryPanel.cs:241-330 with `hud`): title `entity.Name`, which is `HullData.Name` (Entity.cs:1057), the true hull shape, true `GearOccupancy` and `Armor`; enemy hull fills (ActionGameManager.cs:1351, SchematicDisplay.cs:216-222). Owned by the aetheria-release follow-up `target-panel-reads-enemy-hull` (an operator design call). Under a hull lie these show the true hull, so cut 4 needs that follow-up settled or folded. | +| C4 | Which reads of truth stay? | Aim and damage: FireControl's `target.Hull` reads (FireControl.cs:359, 392, 882, 931, 1022, 1159, 1231, 1567, 1638, 1954), `IsRevealed` (:160), the player's `CycleTargetItem` (ActionGameManager.cs:438) and Combat's aim height `target.Hull` `GridOffset` (Combat.cs:110-112). | +| C5 | Does cut 2 need a stored belief? | No. Nothing can set `SeenThrough` before the judge (cut 4), so a stored belief would be state with no writer. `Contact.Profile` is derived in `ContactOf` from the subject's `ClaimedHull` at `Identified`. The belief store and `SeenThrough` arrive with the judge in cut 4, which then owns `seen-through-holds-while-tracked`. | +| C6 | Can a claim ride the act? | Yes, one writer each: `Signature` (SetSignature, Entity.cs:106), `ActiveEmission` (Emit, :903), `PaintWarning` (ReceivePaint, :912). `PaintWarning.EmitterClass` is already a class slot; outside tests nothing reads it (LockWarningTests.cs:144, PaintModeTests.cs:195, 269 assert it equals the item's Data, which stays true by default). | +| C7 | Does the 3D view classify? | `ZoneRenderer` instantiates the true hull's prefab once per entity (ZoneRenderer.cs:380-383). Under a hull claim the drawn model is a label; re-instancing on a belief change is cut 4's, since a profile cannot differ from the truth before then. | +| C8 | Point defence and seekers? | No point defence in the Body (grep `pointdefen`: zero). Seekers are data (`MunitionSeekerData`, MunitionParts.cs:76) with no in-flight target choice. Nothing to move. | +| C9 | How do tests set a claim with no EW gear? | Through `Entity.Claim`, internal (Aetheria.Shared.csproj:28 has `InternalsVisibleTo Aetheria.Shared.Tests`). It is the model page's ship-claim slot. Its production writer is cut 4's masquerade behaviour. Because SetSignature stamps `ClaimOf(item)` at write time, cut 4 must make the item claim known before a weapon fires (H2): it can pull from the EW behaviour as the suppressor does, or write before execution order matters. | +| C10 | What can an observer measure of a claimed weapon? | A claim is a design (`EquippableItemData`) with no live stats; today's rank reads the true item's quality, heat, wear and power through its behaviour. Question `ew-claim-weapon-measure`. | + +## Cut 1b probes at 0898725f + +`ew-hide-launch-catalog` is mapped as `cut-ew-hide-launch-catalog.r2` (agent imagination-aeth-ew-catalog-r2; r1 is +superseded). Question `ew-suppressor-strength` is ruled both-as-two-designs (kitchen-sink direction): a strong +Launch Suppressor (NiteLife, Finch, DME, R&D) and a mild sustained one (Lightsail, Alakrita, defaulted). K1-K8 were probed by +a scratch AetherDb command and a scratch test run on Yggdrasil at `0898725f`; K9-K11 by a scratch test on Yggdrasil at +`1746e8bd` (code identical at `1e219e96`). Nothing was pushed to origin; job logs stay in session scratchpads. + +| # | Question | Result | +|---|---|---| +| K1 | Which Tool gear exists to template from? | Five non-weapon Tool designs. `Targeting Computer`: 1x1, mass 60, price 60000, durability 50, SpecificHeat 1, Conductivity 1, temperatures min 200 / max 500 / optimum 276.5 / plateau 36, resilience 1, roles [processor, array]; consumables-first-set already reads it by name as the 1x1 tool template (Program.cs:2134). Tool prices run 25000-150000. | +| K2 | How did a prior catalog cut land? | Command first (`815526ee`), then `GameData/Aetheria.cc` alone with the dry-run text in the message (`7a882b62`), then the command made `public` with a `root` argument so tests drive it on a scratch catalog (`d26b465e`). The .cc is an LFS binary: at merge the command is replayed on master's catalog, never the blob merged (release map SC13). Tests: `ConsumablesFirstSetCommandTests` (dry run, apply, second apply on a scratch copy), `SmokeRoundsCommandTests` (apply writes the shipped design's exact bytes), content tests on the shipped catalog. | +| K3 | What reveals a flash, numerically? | `TargetDetectionInfoThreshold` .1, `TargetInfoDecay` .5. One sensor: revealed while S x g / (.5 x d) > .1, so reach is 20 x S x g, linear in S (Sensor.Gain, Entity.PassiveInfo:440-450). Shipped sensors: `The Bat` sensitivity 1-2, `not if i see you first` .25-1.5, curve hull 0..1, so g is about .7-1.35 at mid quality. | +| K4 | How bright are shipped flashes? | Weapon `Visibility` (Min at quality 0, Max at 1): Spectra 550-150, PD Laser 300-100, PD Gun 400-150, Autocannon 1200-800, LRMM72 1200-800, SRMM72 1500-1000, ChargeBlast 5000-1000, CShot 2000-3000. So an unsuppressed 1000 flash is seen about 20,000 units out against weapon ranges of 300-2,500: hiding a shot from its own target needs Factor about .05. | +| K5 | How fast does a suppressor heat? | Cell thermal mass = the hull's share (mass x SpecificHeat / cells: Longinus 37.88, Djinni 45.18) plus the item's mass x SpecificHeat (Entity.cs:1198, :1533). A 60-mass 1x1 suppressor's cell is 97.9 (Longinus) or 105.2 (Djinni): 224 heat raised it 2.29 K and 2.13 K exactly. Ten seconds of zone updates with no radiator cooled it by under .5 K. Ships start at 280 K. Thermal shutdown (`ShutdownPerformance` .1 on the template's 200/500/276.5/36 shape) is at about 479 K, so a rated temperature of 310-330 K gives out long before the item fails. | +| K6 | Does a 1x1 Tool suppressor fit and work on shipped hulls? | Yes. Built like `BuildThrustedShip` with only the reactor, then the suppressor at `UnoccupiedSpace` via `Shape.FitsWithin` and `TryEquip` before `Admit`: Djinni 104 free cells, Longinus 20. Active at once; at lot quality .5 a draft with Factor .4-.2 evaluated .3 and each `SetSignature(LaunchFlash, 400)` stored 120. | +| K7 | Do new Tool products reach generation? | `HasHome` is true for any Tool design (LoadoutGenerator.cs:240-242), so stations stock it and `FillInterior` may fit it on generated ships by the existing availability rule. Nothing else to wire. | +| K8 | Does adding a Tool design and four products disturb existing tests? | No. The full `Aetheria.Shared.Tests` suite (1665 tests, about 16 minutes) ran green before and after a draft design and four products (NiteLife, Finch, DME, R&D) were applied to the catalog in the same job. CB-R1 (`ShippedCatalogRolesAreLive`) held with two roles, each read by a Quality term of exponent 1. | +| K9 | How far does a flash reach on a shipped observer? (corrects K3's reach) | A Longinus with its first shipped Sensors-hardpoint sensor at lot quality .5 has `PassiveInfo(position, 1)` of 1.89e-3 at 500, 6.31e-4 at 1500, 3.16e-4 at 3000, 1.58e-4 at 6000, 9.5e-5 at 10000: about 0.95 / distance. A flash is revealed while strength x that exceeds .1, so reach is about 9.5 x strength, not K3's 20 x (K3's gain range of .7-1.35 is high for this sensor). Unsuppressed 1000: seen to 9,500, hidden at 10,000. Mild mid (300): seen at 1500 (.19), hidden at 3000 (.095) and 6000. Strong mid (55): hidden at 1500 (.035). | +| K10 | How long does a suppressor last under fire, with the hull ticking? | Probed as a draft design on a shipped Longinus and Djinni with reactor and radiator, one launch per second for 120 s, four .25 s zone updates between launches, from rest at 280 K. Cell thermal mass 97.9 / 105.2. Strong (Factor .08-.03, HeatPerUnit 1.4-.8, rated 310-330) at mid quality, 1000 flash: Longinus 4 suppressed launches (stored 55) then bright, Djinni 5; 300 flash: 14 / 14. After that the cell cools through the rated line and flickers: 10 of 120 launches suppressed (Longinus), 6 (Djinni) at 1000. Mild (Factor .4-.2, HeatPerUnit .8-.5, rated 310-330) at mid, 1000 flash (stored 300): first 10 suppressed on both hulls, 22 / 13 of 120 in all; 300 flash (stored 90): first 36 (Longinus) and 33 (Djinni), 68 / 41 of 120. Quality moves it: mild at quality 1 and 300 flash lasts 60 / 48 launches, strong at quality 0 and 1000 flash only 3. So the mild design is sustained for light weapons (about half a minute at one launch a second) and a dozen autocannon-class launches, not for ever: a hot cell holds the rated line and lets a flash through about every fifth to tenth launch. | +| K11 | Does an opening volley stop for good without cooling? | Direct `SetSignature` calls with no zone update between them (r1's test shape): the cell never cools, so once past the rated temperature every later call is unsuppressed. Strong mid, 1000 flash: removed 945 x 1.1 = 1039 heat per call = 10.6 K (Longinus) / 9.9 K (Djinni); the fifth call on a Longinus (321.7 K > 320) and the sixth on a Djinni are the first bright ones. Margin on the Djinni is under 1 K (319.4 after four calls against a rated 320), so a test must derive its expected count from `ThermalMass` and the authored figures rather than assert a literal. | + +## Cut sequence (not yet mapped; cuts 1, 1b and 2 are mapped as specs) + +Cut 1 is split in two by size: `ew-hide-launch` is the behaviour, the one hook in `SetSignature` and their tests; +the catalog authoring follows it as 1b (two designs, six products), mapped above. + +Cut 2 `ew-claims-in-the-book` is mapped (above). It differs from the target line in one place: `SeenThrough` and the stored belief move to cut 4 with the judge (C5). Cut 4 also takes the drawn hull model (C7) and needs the target panel settled (C3). The remaining cuts are the target doc's cut sequence (3, 4, 4a `ew-jammer`, 5-10). diff --git a/docs/aetheria-ew-target.md b/docs/aetheria-ew-target.md new file mode 100644 index 000000000..ae217fd4b --- /dev/null +++ b/docs/aetheria-ew-target.md @@ -0,0 +1,273 @@ +# Aetheria electronic warfare: target + +Campaign `aetheria-ew`, target revision r2. Repo `GameCult/Aetheria`, working branch `master`, cut branches +`eureka/aetheria-ew-`. Written by Imagination (agent imagination-aeth-ew-target, session +self-2026-10-13-ag) against `origin/master` `e89d38e9`, with `origin/eureka/aetheria-release-reveals-replace-tiers` +read where master lacks it. Revision r2 (agent imagination-aeth-ew-r2, same session) folds the eight operator rulings +of 2026-10-13 (`aetheria-ew:ruling:-ruled`, cited below by `-ruled`); master now holds +reveals-replace-tiers, so probe P1's gap is closed. Prior art and lore: `docs/research/ew-prior-art.md` (cited below as `R:`). +This is the target and the model page. No cut is specified here; the first cut is mapped when it is about to run. + +## Purpose, in the operator's words + +> I think of it as envelope shaping, which is making your emissions tell the wrong story. Masking your signal is +> one thing, but looking like something you're not is another. If you can match your cross section to the +> asteroids you're hiding in, you can be detected and it doesn't matter. When you're hot, EW means those emissions +> lie about your gear, or hide a launch, or make it look like you're somewhere else via heat tenders or space +> magic, I don't know, get creative. What do you think? + +(ruling `aetheria-release:ruling:ew-is-envelope-shaping`, 2026-10-13) + +> Remembered bearing? Does that mean we already have positional ambiguity for detection? That was going to be an EW +> feature. ... Decoys are also EW. How about we just map the EW campaign + +(ruling `aetheria-release:ruling:ew-owns-ambiguity-and-decoys`, 2026-10-13) + +The lore says the same thing from the inside: signature shaping is "not invisibility. It is false classification +bounded by heat capacity, emitter bandwidth, aspect, thrust history ..." (R:86), and in the novella "Every false +signature consumed real heat and closed a later option" (R:90). + +## Self's reading, tested against the Body and the lore + +The operator asked "What do you think?". Each point of Self's reading is adopted, amended or rejected here, with +the reason. The forks that needed the operator are now rulings (listed at the end). + +1. **The lie lives in emissions; each observer's own Sense derives belief; EW never writes an observer's book.** + *Adopted, and sharpened.* The Body already has exactly this shape: a ship's light is written only by its own + `Entity.SetSignature` (Entity.cs:98-103), its active emissions only by `Entity.Emit` (:901), and an observer's + book only by its own `RecordReveal` (:922, callers `Sense` and `PublishInbox`). EW adds a third thing a ship + emits, its *claim*, written by its own EW gear, and a judge inside the observer's `Sense` that decides whether + the claim is believed. Amendment: the judge is one function, used by `Entity.Sense` and later by a missile + seeker's own reading, so a seeker is fooled by the same rules a ship is (follow-up `missile-decoys-signature`). + +2. **A reveal records what the emission claims, not the true item; truth stays in the sim.** *Amended.* The book + keeps the true item as its key, because the key is the sim's handle for aiming and for ending a reveal on + perceived destruction (`PerceivesDestroyed`, Entity.cs:932). What changes is what the book *says*: + - `Reveal` gains `Claimed` (an `EquippableItemData`): the class the act claimed, the true `Item.Data` when the + ship tells no lie about that item. `RecordReveal(subject, item, channel)` takes the claimed class from the + signature or emission that carried the act; `PublishInbox` takes it from the paint. + - `Contact` gains `Profile` (the hull class, or background kind, the observer believes) and `SeenThrough`. + `Identified` keeps its gate (track at `TargetGearInfoThreshold`) but now means "holds a hull belief", and the + believed hull is the claim unless the observer has seen through it. Nothing reads `subject.Hull` to classify. + - `IsRevealed` (the aiming read, reveals-replace-tiers `FireControl.IsRevealed` = live item fitted and whole and + `HasReveal`) is unchanged for a gear lie: the observer aims at the real item that acted, believing it is the + claimed class. The shot lands on what emitted; the lie misleads the choice, not the aim. + - Under a believed *hull* lie, the observer's layout is the claimed hull's, so it cannot place the true item: + ruling `ew-aim-under-hull-lie-ruled`: the observer can target the ship but no gear on it until the hull lie is + seen through. + - `Reveal.Item` stops being a classification source: consumers that label or rank (HUD, schematic, AI threat, + point defence choice) read `Claimed` and `Profile`. `Item` stays for `IsRevealed` and the book's own gates. + +3. **Verbs: blend, masquerade, hide a launch, displace.** *Adopted with three amendments.* + - *Blend* needs a background to blend into. Asteroids are chunks, not entities (Zone.cs:453-527); they are never + contacts. So blend is a claim of a *background kind* (rock, debris), believed only inside a belt where real + chunks are near and only while the ship's light stays inside that kind's envelope (no drive plume, thermal and + reflection no brighter than chunks there, `Zone.ChunkVisibility`). A contact believed to be background is + detected and tracked, but it is clutter: not an enemy, not a target (operator: "you can be detected and it + doesn't matter"). This needs allegiance to come from belief, not truth (ruling `ew-hostility-from-belief-ruled`). A believed + background contact is shown as a faint background marker labelled as the kind, not hostile (ruling + `ew-blend-presentation-ruled`). + - *Masquerade* is two claims: a hull profile (the whole ship claims another hull class, and optionally shows + another faction's telemetry) and item claims (one fitted item's acts claim another item class). The envelope is + checked by each observer against what it perceives: drive plume and acceleration no greater than the claimed + hull can make, thermal and cross-section within the claimed hull's band, a launch or a fired weapon that the + claimed hull could carry. Acting outside the profile breaks the lie for that observer. + - *Hide a launch* is the cheapest verb and needs no claim: a suppressor scales its own ship's `LaunchFlash` + strength down inside `SetSignature`, paying heat. It is also how the pre-Cold-Wake tier hides. + - *Displace* is not a false position. It is a real body somewhere else: a heat tender is an emitter body (an + `Entity`) launched from the ship, carrying heat taken from the ship's cells and a claim that names the ship's + profile, while the ship itself goes cold. A decoy is the same kind with a different load (bright, short-lived, + a claim of whatever it imitates). One kind serves both, and the follow-up `missile-decoys-signature` asks for + exactly this ("a decoy record or entity with Visibility, offered to the seeker scan"). The exotic Cold Wake + imitation ("space magic") stays a later tier: EW lies about what, never where, and phantom positions with no + emitter are their own later campaign (ruling `ew-where-lies-ruled`). + +4. **The envelope bounds every lie and costs heat; lies break on envelope violation, multi-aspect observation, + illumination, or heat exhaustion.** *Adopted; the quantities are mostly ones the Body already owns.* + - *Heat* is not a new EW budget. Every lie adds heat to the EW item's own cell through the existing `AddHeat` + (Entity.cs:1208), as every behaviour already does; that heat conducts, shows later as hull radiation (item-less + Thermal, Entity.cs:1849) and radiator Thermal (Radiator.cs:121). The lore's heat debt (R:86) falls out of the + thermal sim with no second owner. *Exhaustion* is the EW item's rated temperature (a gear stat): above it the + behaviour stops writing its claim, exactly as `Radiator` stops below its floor. + - *Bandwidth* is a gear stat: which profiles the gear can claim, as a window around the true hull (mass and + size ratio) and a list of background kinds; a suppressor's channels and factor. + - *Aspect* is geometry, not state: a masquerade emitter has an arc; an observer outside it sees the truth. This + is how multi-aspect observation breaks a lie (the novella's "Proper Hot", R:90) with no extra rule. + - *Thrust history* is read from what the observer perceives now (plume strength and acceleration while + tracked). Recommended default: instantaneous, no history kept. A short history is a later refinement only if + play shows the instantaneous check is too easy to game. + - *Illumination* (burn-through, R:102, R:127): an observer whose own ping or lock paint crosses the subject with + power over range above the lie's masking strength sees through. The illuminator pays as today: it is heard and + the target is warned (rulings `scan-is-an-act`, `sensor-stat-set`). An illuminator's burn-through is + shared with the allies receiving its ping return; a passive see-through (arc, envelope break) stays with the + observer (ruling `ew-seen-through-sharing-ruled`). + +5. **Noise jamming is in, as a crude loud tier; phantom items deferred.** *Amended by the operator* (ruling + `ew-noise-jamming-ruled`: "sounds like an obvious thing to have"). A jammer adds exactly one term to + `Sensor.Gain`, the one place track gain is computed: inside the jammer's cone, other ships' active-sensor gain is + thinned, as the vapour cloud's obscuration thins it. The term is owned by the jammer's heard emission and cone, so + it is not a second sensor model. The jamming is itself an emission heard far (`Emit`), which reveals its user and + invites home-on-jam (R:130), as an illuminator is revealed. The research warns that games leading with noise + jamming end as lock denial (EVE R:111, Starsector R:109); the loud, heard, cone-bound tier keeps the jammer a + gamble with a signature rather than a switch. Full jamming (spot and barrage, J/S ratios, burn-through ranges) + is not in this campaign unless the operator widens it. Phantom items (claims of gear the ship does not carry) are + deferred: an item claim is always attached to a real fitted item that acts. + +6. **Era tiers from lore.** *Amended: tiers are gear, not an era flag.* The lore's line (R:86: "Before the Cold Wake + metamaterial threshold, actors hide, delay, dump, and throw crude decoys. After it, ships ... imitate") becomes a + gear line. Probe P7 shows most of the early tier already exists: radiators off (`Thermotoggle`), heat held + (`HeatStorage`), vapour dump (`VapourDump`). The early tier EW adds is the launch suppressor and the crude decoy + (an emitter body with no claim). The late tier is masquerade and blend gear. Ruling + `ew-imitation-availability-ruled`: both tiers ship; imitation gear is rare and made by a few makers whose identity + fits, so most fights see hiding, crude decoys and jamming, and a masquerading ship is an event. The early tier + (suppressor, crude decoy, jammer) is not scarce. + +7. **Crew refusals and the political cost of jamming.** The sim has no crew model (Entity.cs:85-86, `Population` + and `Personality` are commented out). Lore only in this campaign, no mechanic (ruling `ew-crew-refusals-ruled`). + +## Design truths (ends, not means) + +- A ship can be seen and still not be understood. Detection, tracking and classification stay separate, and EW + acts on classification (R:86 "Detection is faster than identification"). +- Every lie is a physical act with a price paid in heat, and it buys time, not safety: it ends when the liar acts + outside its story, when someone looks from another side, when someone spends their own signature to illuminate, + or when the heat runs out. +- What a player or an AI believes is what its own instruments told it. No consumer is quietly told the truth. +- Learning the truth is earned the same way capabilities are revealed now: by forcing the target to act + (ruling `visibility-per-capability-reveal`). +- EW is legible to the liar: a ship knows what it is claiming, what it costs per second and what will break it. + +## Invariants (to become the typed target) + +- `belief-one-writer`: An observer's belief about a subject (book, claim belief, seen-through) is written only by + that observer's own sensing (`Entity.Sense` and `PublishInbox`; a seeker's own reading through the same judge). + No EW gear, presenter, AI or other entity writes it. +- `lie-is-own-emission`: EW acts only on what its own ship emits. Light stays written only by `SetSignature`, + emissions only by `Emit`, and a ship's claim only by that ship's EW behaviour. +- `one-judge`: Whether a claim is believed is decided by one function of (claim, what the observer perceives of the + subject, geometry, the observer's own illumination), shared by ships and seekers. +- `what-not-where`: Every position the sim exposes is the true position of a real entity; EW lies about what a + contact is, not where an entity is. Displacement is a real emitter body elsewhere. (Ruling + `ew-where-lies-ruled`.) +- `classify-from-belief`: Every consumer that labels, ranks or chooses (HUD, schematic, AI target choice, point + defence choice, seeker) reads `Contact.Profile` and `Reveal.Claimed`; none reads `subject.Hull`, the true item's + data or the subject's true faction to classify. Physics, damage and aiming keep the truth. +- `envelope-bounds-claim`: An observer believes a claim only while what it perceives of the subject lies inside + the claimed profile's envelope, within the gear's bandwidth, and only from inside the gear's arc. +- `lies-cost-real-heat`: Every lie adds heat to its EW item's cell through `AddHeat`; there is no separate EW + budget; an EW behaviour writes no claim above its rated temperature. +- `illumination-burns-through`: An observer whose own ping or lock paint crosses a subject with power above the + lie's masking strength sees through it; the act reveals the illuminator as it does today. An illuminator's + burn-through is shared with the allies receiving its ping return (ruling `ew-seen-through-sharing-ruled`); a + passive see-through stays with the observer. +- `seen-through-holds-while-tracked`: A seen-through verdict holds while the observer keeps the subject tracked or + remembered (`BearingMemory`), and ends with the contact. A new lie fools a fresh contact, not a held one. +- `decoy-is-emitter-body`: Decoys and heat tenders are one kind, a real `Entity` with its own signatures and a claim; + seekers, point defence and the HUD treat it by belief, with no decoy-specific rule. +- `present-model-stays`: The exact track, bearing-only reveals remembered for `BearingMemory`, and range only where a + channel gives it, are unchanged (ruling `ew-owns-ambiguity-and-decoys`). `Sensor.Gain` gains exactly one jamming + term, owned by the jammer's heard emission and cone like the cloud's obscuration (ruling + `ew-noise-jamming-ruled`); EW adds no other term to it. + +## Not in scope + +- Not EW: the two-listener fix (follow-up `two-listener-fix`) estimates a true position from true bearings; it stays + in faction play. It is consistent with EW because a tender's bearings are a real body's bearings. +- Not EW: lock growth, hit odds and evasion (`FireControl`, `LockWeapon`). A lie about class does not change a + firing solution on a tracked ship; a decoy changes odds only by being the thing chosen. +- Not EW: the vapour cloud's obscuration (ruling `vapour-cloud-obscuration`). The follow-up + `cloud-vs-missiles-in-flight` is satisfied by missile-records' seeker reading through `PassiveRate`, which already + multiplies `Zone.Obscuration` (Sensor.cs PassiveRate); EW owns only the pinning test, in the seeker cut. +- Not a consumer: AetheriaEve/AetheriaThing (archived). +- Not in this campaign: false positions or bearings with no emitter (`ew-where-lies-ruled`), error ellipses, phantom + gear, crew refusals as mechanics (`ew-crew-refusals-ruled`), comms jamming, full jamming (spot and barrage, J/S, + burn-through ranges: only if the operator widens `ew-noise-jamming-ruled`), persistent EW state in saves. + +## Model page: identity, lifecycle, authority + +None of these persist across a save: they are runtime state rebuilt from behaviours each tick, or observer state +cleared by `Deactivate`, except the catalog stats. + +| Kind | Identity (what names it) | Lifecycle (what happens to it) | Authority (who decides; forbidden writers) | +|---|---|---|---| +| **Ship claim** (new) | One per ship, held on the subject `Entity`: a `Profile` (a hull's `HullItemData`, or a `BackgroundKind`) and an optional shown `Faction`. Namespace: the ship. Absent means the truth shows. Injective by construction (one slot per ship). | Written each tick its EW behaviour runs and is under its rated temperature; absent the tick it stops (switched off, too hot, destroyed, unpowered). Never stored, never replayed. | The ship's one active masquerade or blend behaviour. If two are fitted, the first in equipment order that runs (default; a fitting rule may forbid two). Forbidden: any other entity, presenters, the AI of other ships, the observer. | +| **Item claim** (new) | `(subject, item)`, carried inside the act: a `Claimed` class on `Signature` and on `ActiveEmission` and `PaintWarning`'s source. Defaults to `item.Data`. | Exists as long as the signature or emission it rides (one tick for emissions; until the source's next write for light). | The subject's EW behaviour sets the item's claim; `SetSignature` and `Emit` stamp it, so the one writer of light and emission stays the one writer of what they claim. Forbidden: the emitting behaviours choosing their own claim (a gun does not lie by itself). | +| **Channel suppression** (new) | `(ship, channel)` factor, 0..1, on the subject. | Set each tick a suppressor runs; 1 otherwise. Applied inside `SetSignature` to that channel's strength. | The ship's suppressor behaviour. Forbidden: weapons scaling their own flash; observers. | +| **Reveal** (changed) | Unchanged key `(observer, subject, true item)`; gains `Claimed`. | As today: entered by an act, replaced by the item's later act, ended on perceived destruction, departure or memory age, cleared by `Deactivate`. The claimed class is the latest act's. | `RecordReveal` only (callers `Sense`, `PublishInbox`). Readers that classify read `Claimed`; `Item` is read only by `IsRevealed` and the book's gates. | +| **Belief** (new) | `(observer, subject)` in the observer's book beside its reveals: believed `Profile`, believed `Faction` (ruling `ew-hostility-from-belief-ruled`: allies by datalink are truth; any other contact's allegiance is the claim's, unknown when none, background when blending), `SeenThrough`, time. | Created when the observer first identifies the subject or receives its claim; revised each `Sense` from the subject's current claim and the judge; `SeenThrough` set by an envelope break, an out-of-arc view or own illumination; ends with the contact (track lost and `BearingMemory` past), on departure, or on `Deactivate`. A new claim from a seen-through subject is ignored until the contact ends. | `Entity.Sense` through the one judge. Forbidden: EW gear, presenters, AI, allies, except that an illuminator's burn-through reaches its ping-return allies through `PublishInbox` (ruling `ew-seen-through-sharing-ruled`). | +| **Contact** (changed) | Derived `(observer, subject)`, never stored. Gains `Profile`, `SeenThrough` (and allegiance per `ew-hostility-from-belief-ruled`). | Derived on every read. | `Entity.ContactOf` only. | +| **Own illumination** (new, transient) | `(observer, subject)`, this tick: the power over range of the observer's own ping crossing or lock paint on the subject. | One tick: written in `Update`, read by `Sense`, cleared by `PublishInbox`, as `_emissions` is now. | The observer's own `Sensor` and `LockWeapon` write it on their own entity. Forbidden: the subject; other entities. | +| **EW gear stats** (new) | Fields on new `BehaviorData` types with append-only MessagePack keys: masquerade (bandwidth window, background kinds, arc, masking strength, heat per second, rated temperature), suppressor (channels, factor, heat per unit suppressed), deployer (body design, heat drawn, launch speed). | Catalog edits through AetherDb; resolved per item by the entity's stat owner (Cut 2). | The catalog. Forbidden: runtime writes. | +| **Background kind** (new) | Append-only enum (`Rock`, `Debris`, more by ruling) with an envelope per kind in `GameplaySettings`: plume ceiling, light relative to nearby chunks, the belt-proximity radius. | Static data. | `GameplaySettings`. Forbidden: per-zone overrides (default; revisit if a zone needs one). | +| **Emitter body** (new) | An `Entity` instanced from a catalog design, admitted through Zone's one admission (Zone.cs:208); it names its `Parent` (the deploying ship). Its claim defaults to its parent's profile. | Created by a deployer behaviour, carrying heat drawn from the parent's cells; lives on its own heat and fuel; removed through the zone's removal path (a `Departure`, so observers judge its end) when spent or destroyed. Not saved. | Its own behaviours write its signatures (its real heat is its signature); the deployer decides creation; the zone owns admission and removal. Forbidden: observers, the parent after release. | +| **Jammer** (new) | Gear `BehaviorData` (cone half-angle and facing, power, gain factor, heat per second, rated temperature) on a ship; its output is `(ship, cone, power)`, this tick. | Runs each tick under its rated temperature: adds heat to its own cell through `AddHeat`, emits a heard jamming emission through `Emit` (heard far: it reveals the user and invites home-on-jam), and its cone-and-power thins `Sensor.Gain` for other ships' active sensors inside the cone, the one gain term. Silent above rated temperature. Not saved. | The jammer's own behaviour owns the emission and the cone; `Sensor.Gain` only reads them, as it reads `Zone.Obscuration`. Forbidden: any other writer of the jamming term; observers; the jammer writing a sensor's state directly. | +| **Heat** (existing) | Per-cell `Temperature` on the hull grid. | Unchanged. | The thermal sim; EW behaviours are ordinary `AddHeat` writers. No new owner. | + +Recommended defaults, not questions: the emitter body is a `Ship` from a catalog design rather than a new `Entity` +subclass (it reuses hull, thermal grid, radiators and thrusters; the two existing subclasses are `Ship` and +`OrbitalEntity`); thrust history is instantaneous; a seen-through verdict holds for the life of the contact; +background envelopes live in `GameplaySettings`. + +## Probes run + +| # | Question | Result | +|---|---|---| +| P1 | Does master hold reveals-replace-tiers? | No. Master `e89d38e9` holds emissions-heard (`3c628f54`); reveals-replace-tiers is 3 commits ahead on its branch (merge base `642a61eb`), replacing `IsRevealed`'s info tiers with `HasReveal` plus live gear. This doc reads that branch's `IsRevealed`. | +| P2 | Who writes light, emission and the book? | `SetSignature` (Entity.cs:98-103, refuses Emission), `Emit` (:901), `RecordReveal` (:922, callers `PublishInbox` :884 and `Sense` :996, :1007). One writer each, so a claim can ride them. | +| P3 | Does anything read `ContactOf` or `RevealsOf` outside Entity? | No product code; only `ContactRevealTests`. contact-hud r2 moves presenters onto them, so EW lands one read site after it. | +| P4 | Is allegiance of a tracked contact truth? | Yes: `EntityHostility[e] = IsHostileTo(e)` on zone entry (Entity.cs:266, :272), and track entry files the entity into `VisibleEnemies` or `VisibleFriendlies` by it (:313-330). Minion targets the first visible enemy (Agents/Minion.cs:14), TurretController the first visible enemy ship (:98), the HUD draws hostile indicators from `VisibleEnemies` (ActionGameManager.cs:1106). Blend cannot work while this stays truth. | +| P5 | Does FireControl read true positions? | Yes, 19 `.Position` reads (e.g. FireControl.cs:237, :257, :295). Consistent with `what-not-where`; a false position would need a second position owner. | +| P6 | What can be blended into? | Chunks are not entities (Zone.cs:453-527: `ChunkExists`, `ChunkVisibility`, `ChunkPose`); only `Ship` and `OrbitalEntity` are entities. Background must be a claimed kind judged against nearby chunk light. | +| P7 | What of the early tier exists? | `Thermotoggle`, `HeatStorage`, `VapourDump`, `Radiator` are behaviours now; `LaunchFlash` is written only by `InstantWeapon` (:280) and `ConstantWeapon` (:173); no suppressor, decoy, jammer or spoof exists. | +| P8 | Is heat a real cost? | Yes: per-cell `Temperature` and `ThermalMass` (Entity.cs:1165-1213); hull radiation is item-less Thermal from cell temperatures (:1849). An EW `AddHeat` is visible later as thermal with no new state. | +| P9 | Do seekers exist to fool? | No: `MunitionSeekerData` is data only (Behaviors/MunitionParts.cs:60-125); a missile in flight is a Unity `GuidedProjectile`. Seeker EW waits on missile-records. | + +## Follow-ups this campaign takes + +- `missile-decoys-signature`: answered by the emitter body plus `classify-from-belief`; point defence and the HUD + treat a decoy as what they believe it is. The Nebulous "turrets take decoys first" note is second-hand and + unconfirmed (R:106); no decoy-first rule. +- `cloud-vs-missiles-in-flight`: a pinning test in the seeker cut, riding missile-records' reading. +- `two-listener-fix`: stays in faction play (not EW). + +## Prior art that shaped this + +Nebulous: Fleet Command treats jamming as noise against radar with burn-through (R:100, R:102), track quality and +error per sensor (R:101), seekers fooled by decoys matching a ship's signature (R:105, R:106). Star Citizen's +design note has decoys that broadcast another ship's signature but cannot fake cross-section (R:119): a lie bounded +by an envelope, as here. Sea Power gives each seeker a chance to reject a false target and each decoy a tier that +works against it (R:115), the shape of masking strength against illumination. EVE and Starsector make EW an +aggregate lock or range penalty (R:109, R:111), which is the masking end the operator set aside. Real-world +vocabulary: deception jamming and DRFM change apparent range, velocity or angle (R:126, R:128), the false-position +family this target defers; burn-through range (R:127); a self-protecting jammer reveals itself to home-on-jam +(R:130), as an illuminator does here. + +## Rulings folded (campaign aetheria-ew, 2026-10-13) + +`ew-where-lies-ruled`, `ew-hostility-from-belief-ruled`, `ew-blend-presentation-ruled`, +`ew-seen-through-sharing-ruled`, `ew-aim-under-hull-lie-ruled`, `ew-noise-jamming-ruled`, +`ew-imitation-availability-ruled`, `ew-crew-refusals-ruled`. + +## Cut sequence (titles only; each is mapped when it is about to run) + +1. `ew-hide-launch`: a suppressor scales its ship's launch flash inside `SetSignature`, paying heat to its cell. + Waits on: none (master and reveals-replace-tiers are in); early tier, so not scarce + (`ew-imitation-availability-ruled`). +2. `ew-claims-in-the-book`: `Reveal.Claimed`, `Contact.Profile` and `SeenThrough`; classifying consumers read them; + claims default to the truth, so behaviour is unchanged. Waits on: reveals-replace-tiers, contact-hud. +3. `ew-belief-allegiance`: enemies and friendlies derive from belief for non-allies. Waits on: cut 2. +4. `ew-masquerade`: masquerade gear writes ship and item claims; the one judge with envelope and arc checks; heat + and rated temperature; aim under a hull lie. Waits on: cut 3. +4a. `ew-jammer`: the jammer gear: a heard jamming emission, a cone, and the one jamming term in `Sensor.Gain`, heat + to its own cell. Waits on: cut 4 (ruling `ew-noise-jamming-ruled`). +5. `ew-burn-through`: own illumination record; paints and pings above masking strength see through. Waits on: + cut 4. +6. `ew-blend`: background kinds and their envelopes; believed background is clutter. Waits on: cut 4. +7. `ew-emitter-bodies`: the deployer and the emitter body (heat tender, crude decoy). Waits on: cut 2 (claim + defaults); cut 4 for a body that carries its parent's profile. +8. `ew-seekers-read-belief`: missile seekers use the one judge; decoys pull seekers; the cloud pin. Waits on: + missile-records, cut 7. +9. `ew-ai-doctrine`: AI goes cold, launches tenders, masquerades when hunted, illuminates to burn through. Waits on: + faction-play-1, cuts 4 and 7. +10. `ew-own-lie-hud`: the liar's own panel: what it claims, heat per second, which known observers see through. + Waits on: cut 4. diff --git a/docs/aetheria-fauna-map.md b/docs/aetheria-fauna-map.md new file mode 100644 index 000000000..b698baf41 --- /dev/null +++ b/docs/aetheria-fauna-map.md @@ -0,0 +1,496 @@ +# Aetheria spaceborne fauna: map + +Campaign `aetheria-fauna`. Target: `docs/aetheria-fauna-target.md` (content r2). Written by Imagination +(agent imagination-aeth-fauna, session self-2026-10-13-ag2) against `origin/master` `0898725f`. This map holds the +body facts, the questions Self admits together with the campaign, the first cut as a draft spec, and the rest of +the cut sequence. Prior art: `docs/research/2026-10-13-fauna-prior-art.md` (`PA:`). Items tagged `[M]` there +come from memory and are unverified. + +## Body facts + +Probed at `0898725f`. A file:line is a line on that commit. + +| # | Question | Result | +|---|---|---| +| B1 | How does the sim hold things that are not ships? | Three runtime collections on `Zone`, all `ReactiveCollection`s with one adder and one remover: `Mines` (Zone.cs:44, `Lay`/`StepMines`), `Clouds` (:48, `Vent`/`StepClouds`), `FloatingItems` (:53, `Release`/expiry/`TryPickUp`). All three are stepped every tick as a `KinematicBody` (FloatingBodies.cs:25-44) on `Zone.GetForce`, have ids from `NextBodyId` (Zone.cs:131), are never saved and are not `Entity`s. Belts are the fourth kind, and they are not stepped (B3). | +| B2 | What is an `Entity`'s per-tick shape? | `Zone.Update` (Zone.cs:274-305) runs `PublishInbox`, `Update` and `Sense` for every entity, then mines, clouds, floating items, `Contacts.Step` (O(n²) hull pairs, Contacts.cs:57-79) and `FireControl.Step`. Each active `Sensor.Execute` walks every zone entity and calls `Zone.Obscuration` per pair (Sensor.cs:186-234). `Entity.Sense` walks every other entity's signatures (Entity.cs:989-1047). Entity count therefore costs O(n²) per tick, and each entity carries a hull, gear, a thermal grid and Rx subscriptions (Entity.cs:262-330). | +| B3 | How are belt rocks held? | As members of a field: `ChunkId(Field, Index)` (Zone.cs:825-839). The comment there says "Field is deliberate, not belt": the operator's ruling generalizes chunks to other kinds of field. The pose is a pure function of zone time (`AsteroidBelt.Pose`, Zone.cs:800-808: orbit distance, phase, `OrbitPeriod`). Wear is a sparse dictionary read lazily (`_wear`, `ChunkExists`, `ChunkRadius`, `Wear`, Zone.cs:503-555). Visibility is `ChunkVisibility` = kind cross-section × area × light (Zone.cs:570-578). Nothing about a rock is stepped per tick. Members are saved through `AsteroidBeltData.Asteroids` (ZoneData.cs:107-117) and wear through `ZonePack.ChunkWear`. | +| B4 | What is the targeting index's provider seam? | `ITargetProvider.Regions` and `Candidates` (TargetingIndex.cs:65-72). A region carries distance, bearing and visibility bounds that must hold for every member. `Within` and `Best` are best-first over regions (Hjaltason and Samet). Two providers exist: `EntityTargets` (offers only the observer's `VisibleEntities`) and `BeltTargets` (orbit bands of 256, segments of 32, re-keyed lazily, BeltTargets.cs:22-190). `BeltTargets` widens every bound by `slack` (:109) and bounds size by `_largestRadius` (:35, :52, :181). `Zone` adds one `BeltTargets` per `AsteroidBeltData` body (Zone.cs:170-175). | +| B5 | How are non-entities seen? | `Entity.ChunkInfo` → `PassiveInfo(position, visibility)` → each sensor's `PassiveRate` → `Sensor.Gain`, the one gain rule (Entity.cs:427-454, Sensor.cs:242-263). `ChunkVisible` is info above `TargetDetectionInfoThreshold`. Chunks are never contacts: there is no reveal, no track and no `Contact` for a chunk. `ContactOf` and the reveal book are keyed by `Entity` (Entity.cs:232, :963). | +| B6 | How is a non-entity target named? | `TargetRef` holds an `Entity` or a `ChunkId` (Zone.cs:844-870). Chunk-aware sites: Entity.cs (10 reads, e.g. :379, :419, :531, :561-572, :1653-1655), FireControl.cs:139-142 (a chunk bears through its pose), ActionGameManager.cs:1174, :1419, :1453. A new member kind that is a `ChunkId` passes through all of them unchanged. A third `TargetRef` arm would touch every one. | +| B7 | How does presentation bind sim things? | `ZoneRenderer` subscribes to `ObserveAdd`/`ObserveRemove` on `Mines`, `FloatingItems` and `Clouds` and instantiates one prefab per thing (ZoneRenderer.cs:232-314). Belts are drawn every frame from `Zone.EvaluateBelt` into the renderer's own buffer through `Graphics.DrawMeshInstanced` (:536-570). Meshes are picked per belt at load (:431-437). No pose is stored on the sim side. | +| B8 | What is the slime-mold experiment? | `Assets/Shaders/Compute/Slime/Slime.cs` plus `Slime.compute`: a GPU Physarum swarm (agents sense a trail texture, turn and deposit; speed and turn follow the gravity slope; random respawn). It runs live in `Scenes/ARPG.unity` through `Prefabs/RPG/Slime Renderer.prefab`, with 131,072 agents and 32,768 trail particles in the scene override (ARPG.unity:19676-19712). `ZoneRenderer` sets only its radius (:198). Its spawn-at-suns code is commented out (:528-532). It is presentation only: it is nondeterministic, the sim never reads it, and it decides nothing. A Discord note from 2021-03-28 calls the agents "rendered in the actual Aetheria level as wee little trails". | +| B9 | Tick model and dice? | `SimClock` runs fixed steps at 60 per real second, caps catch-up at 0.1 s of real time, and gives presenters `Lead` (SimClock.cs:11-60, ActionGameManager.cs:1363). `SimulationDice.For(zoneSeed, stream, ordinal)` supplies deterministic streams (`LootStream` 1, `MineStream` 2). | +| B10 | What do things cost? (scratch probe, deleted, never committed) | Run on Yggdrasil (dotnet sdk 10, Release, 4 CPUs), a test in `ContactRevealTests`' fixture at `0898725f`. **Entities** with one passive sensor each, ms per `Zone.Update`: 8 → 0.38, 32 → 2.85, 128 → 4.95. The ships' light was zero, so no track ever formed; this is the floor, and JIT warm-up inflates the 32 reading. **Stepped bodies** (`KinematicBody.Step` plus `Zone.GetForce`, a zone with no planets), ms per tick: 1k → 0.99 (includes JIT), 10k → 1.45, 100k → 16.1. Without `GetForce`: 10k → 0.10, 100k → 0.99. `GetHeight` loops every planet 4 times per `GetForce` (Zone.cs:627-717), so a real zone costs more. **PassiveInfo** with one sensor: 0.185 µs per call. Reading: a tick has 16.7 ms. Fauna as entities are unaffordable beyond tens. A stepped body per member is affordable only in the low thousands. Evaluating a member on demand, as chunks are, costs nothing per tick, and a query's cost is bounded by the index. | +| B11 | Is there fauna lore? | No. `Vault/**/*.md` has no krill, whale or microfauna; voidbot over AetheriaLore surfaces nothing; Discord has only the slime-agent remarks. Lore is open. | +| B12 | Where would fauna touch aetheria-ew? | aetheria-ew's `BackgroundKind` row (target: "Append-only enum (Rock, Debris, more by ruling)") and cut 6 `ew-blend` ("believed only inside a belt where real chunks are near ... light relative to nearby chunks"). The ruling `ew-blend-presentation-ruled` shows a believed background contact as "a faint background marker labelled as the kind". The ruling `disguise-held-by-flying` makes the motion test adversarial observation. | +| B13 | Do the in-flight Hands passes overlap? | ew-claims (`origin/eureka/aetheria-ew-ew-claims-in-the-book`) edits Sensing.cs, Entity.cs, Combat.cs, SchematicDisplay.cs, FireControl.cs and tests. loot-3 edits FieldDriver, TractorBeam, ItemPickup, the capability presenters and PickupTests. The first cut below touches ZoneData.cs, Zone.cs (`AsteroidBelt`, its construction), BeltTargets.cs, ZoneGenerator.cs and Settings.cs (`ZoneGenerationSettings`): **no file overlap**. | +| B14 | What else reads every belt body? | `SectorRenderer.cs:84` counts `AsteroidBeltData` bodies as belts in the sector UI, so a fauna field would count as a belt there. `ZoneRenderer.LoadPlanet` draws it with asteroid meshes (:431). Both are presentation, and both are later cuts. | + +## Rationale + +- **Fauna are fields, not entities and not stepped bodies (B2, B3, B10).** The chunk path already does what a swarm + needs. It gives identity without allocation, a pose as a pure function of time, lazy wear and respawn, detection + through the one gain rule, a target slot, an index provider and an instanced draw. Making a member a chunk of a + fauna field reuses every one of those owners. The alternatives each add an owner: an entity per fish costs O(n²) + per tick; a stepped body per member costs O(n) per tick and has no index provider; a third `TargetRef` arm touches about + 15 sites (B6). +- **Krill first.** Krill ride the orbital flow, which is exactly the motion belt rocks already have (B3). One bounded + sway term per kind and a clustered generator give a cloud that moves like krill, and nothing else in the Body has + to change. It is the smallest cut the operator can see run, and its tell ("drifts with the wind", PA:9) is the + one the prior art says observers use first. +- **Sharks and whales need an anchor.** Their tell is moving against the flow, so the field's frame has to move. + `fauna-motion-model` decides whether that is a closed form plus sparse events or a stepped anchor. Either one is + per swarm (a few dozen per zone), not per member. +- **Distance aggregation is a presentation and query question first.** The index already bounds what any query + examines (B4). Whether a school is one return or many is a question of what an observer is shown, so it is asked + rather than built ahead of need. +- **The prop-hunt tax already exists.** Garry's Mod charges hunters health for shooting real props, and Black Ops 4 + makes props whistle (PA:35-36). In Aetheria, shooting a return to test it already shows a launch flash and spends + heat and ammunition (aetheria-ew H1, H6), and a member that is shot breaks through `Zone.Wear` like a rock. No + extra tax is proposed. + +## Questions for the operator (draft; Self admits them with the campaign) + +The prior-art file (`docs/research/2026-10-13-fauna-prior-art.md`) was read before these recommendations were +written. One rule shapes every option below: under `disguise-held-by-flying`, no option offers static hiding or an +automatic mimic, and the only flying aid is a generic orbit sync. + +1. **`fauna-in-sim`: where do fauna live: sim or presentation?** + - Options: + - `sim-perceivable-present-ambient`: anything a sensor can perceive or a shot can hit is in `ServerShared`; sub-detection ambient life (the slime trails) stays presentation and decides nothing. + - `presentation-only`: fauna are drawn only; they cannot be contacts or targets. + - `sim-everything`: the slime agents move into the sim too. + - Recommended: `sim-perceivable-present-ambient`. A prop must be in the sensor picture, and sensing is sim (B5). The slime swarm is 131k nondeterministic GPU agents (B8). + - Depends: everything. + +2. **`fauna-identity`: what names a fauna member?** + - Options: + - `field-member`: a member is a `ChunkId` of a fauna field, and fields gain fauna kinds. + - `fauna-arm`: a third `TargetRef` arm with its own id. + - `entity`: each fauna is an `Entity`. + - Recommended: `field-member`. It reuses every chunk owner (B3, B6), and `ChunkId` was named for this. `entity` is ruled out by cost (B10). + - Depends: cut 1 and every later cut. + +3. **`fauna-motion-model`: how do fauna move?** + - Options: + - `closed-form-plus-events`: each class's law is a pure function of zone time, and reactions (scatter, flee, pursue) are sparse event records that decay lazily, as wear does. + - `stepped-anchor`: each swarm's frame is a `KinematicBody` with a steering law, stepped per tick, and members are closed-form offsets from it. + - `boids`: members are stepped individually with neighbour search (Reynolds; spatial hashing, PA:20-21). + - Recommended: `closed-form-plus-events`. It is deterministic at any step size, costs nothing per tick and saves for free. A law written in closed form is also the clearest thing a player can learn, which `disguise-held-by-flying` needs. `stepped-anchor` is the fallback if a class's law cannot be written in closed form. `boids` costs per member per tick (B10), and the prior art found no deterministic server-side swarm source (PA:24). + - Depends: cuts 2 onward. Cut 1 (krill ride the flow) is closed form under any option except `boids`. + +4. **`fauna-interaction`: do sharks and whales act on ships?** + - Options: + - `props-react`: fauna never harm or block ships; they react (schools scatter, sharks veer, whales sound off), and the reaction is a tell. + - `sharks-bite`: sharks attack ships that come close. + - `whales-block`: whales are hulls in `Contacts.Step`. + - Recommended: `props-react` for this campaign. Danger moves the game from prop hunt to hazard avoidance, and blocking hulls would need entity contact (B2). Either can be a later campaign. + - Depends: the anchor and disturbance cuts. + +5. **`fauna-kill-harvest-lure`: can fauna be killed, harvested or lured?** + - Options: + - `shootable-respawning`: members break and respawn through `Zone.Wear` like rocks; harvest and lures are later. + - `untouchable`: shots pass through fauna. + - `harvest-economy`: fauna yield goods through the mining yield table. + - Recommended: `shootable-respawning`. It comes free with `field-member`, and shooting to test a return is the prop-hunt check, taxed by its own launch flash and heat (PA:35-36). + - Depends: cut 1 (it inherits rock wear unless this is ruled `untouchable`). + +6. **`fauna-habitat`: where do fauna live?** + - Options: + - `hosted-by-bodies`: each class favours host bodies (krill and minnows around planets and in belt orbits, whales around gas giants, sharks wherever minnows are), placed by the zone generator from the zone seed. + - `everywhere`: uniform scatter. + - `authored-only`: fauna appear only in scenario zones. + - Recommended: `hosted-by-bodies`. Fauna then become a readable feature of a zone's bodies, and hiding has a geography. + - Depends: cut 1's generator rule (it places krill on planet orbits by default). + +7. **`fauna-distance-representation`: how does a school read at range?** + - Options: + - `aggregate-far-individual-near`: beyond a class's resolution distance an observer sees one return per school, with summed light at its centroid; near it, it sees members. + - `individuals-always`: every member that passes `ChunkVisible` is its own return. + - `aggregate-only`: a school is always one return. + - Recommended: `aggregate-far-individual-near`. It matches how radar and sonar read layers and flocks (PA:9, PA:14), keeps the HUD legible, and gives a ship near a school a place to hide that ends when the hunter closes in. + - Depends: the contact-presentation cut and aetheria-ew's blend judge. + +8. **`fauna-disguise-path`: how does a ship pass as fauna?** + - Options: + - `returns-alike-plus-blend`: below `Identified`, a ship's return and a fauna return share one marker, so any ship can hide among fauna by how it flies, with no gear; aetheria-ew's blend gear carries the disguise past identification by claiming a fauna `BackgroundKind`, judged by an envelope that includes the class's motion law. + - `blend-only`: only blend gear lets a ship pass as fauna. + - `returns-alike-only`: no gear; identification always ends the disguise. + - Recommended: `returns-alike-plus-blend`. aetheria-ew made imitation gear scarce (`ew-imitation-availability-ruled`), so `blend-only` would make prop hunt a rare event. With `returns-alike-plus-blend`, gearless hiding is the common game and gear is the event. + - Depends: aetheria-ew `ew-blend` (cut 6) and contact presentation. This is a cross-campaign question, and Self may file it in aetheria-ew. + +9. **`fauna-shadowing`: can a ship hide in a whale's return?** + - Options: + - `defer`: whales are bright, separate returns for now. + - `merge-within-resolution`: an observer who cannot resolve two returns sees one. + - Recommended: `defer`. Sensing has no resolution concept today (B5). Adding one is a sensing change, which belongs to aetheria-ew or a sensing campaign, not to fauna. + - Depends: nothing in this campaign. + +## First cut (draft spec): `fauna-krill-swarms` + +**Waits on:** rulings on `fauna-in-sim`, `fauna-identity`, `fauna-habitat` (recommended options assumed) and +`fauna-kill-harvest-lure` (`shootable-respawning` assumed; under `untouchable`, `Wear` refuses fauna fields and +that adds one test). +**Base:** `origin/master`; branch `eureka/aetheria-fauna-krill-swarms`. Overlap with in-flight passes: none (B13). +**Model:** Sonnet Hands. Cap: 100 calls. Estimate: about 7 files, +260/-10 lines, of which about 150 are tests. + +**Objective:** krill clouds exist in generated zones as fields of a fauna kind. They are sensed, targeted, shot and +drawn through the chunk path, and they move by the krill law: they ride the orbital flow, and each member sways +within a bounded radius. + +**Scope:** +1. `FieldKindData` (ZoneData.cs:122-136) gains two append-only keys, `SwayRadius` (`Key(3)`, world units, default 0) + and `SwayPeriod` (`Key(4)`, seconds), and `SwarmWeight` (`Key(5)`, default 0): how often swarm generation picks + this kind. A rock kind has sway 0 and swarm weight 0. A krill kind has belt `GenerationWeight` 0, so belts never + draw it (ZoneData.cs:143-158, "Zero never picks it"). +2. `FieldKinds.Assign` (ZoneData.cs:143) takes the weight to read, so belts and swarms share one weighted pick (one + rule, one path). Add no second picker. +3. `AsteroidBelt` (Zone.cs:785-808) takes the field's resolved sway when `Zone` builds it (Zone.cs:170-175). + `Pose` adds a bounded closed-form offset: `SwayRadius * float2(cos(2π(t/SwayPeriod + h₁(i))), sin(2π(t/(SwayPeriod·φ) + h₂(i))))`. + Here `h₁` and `h₂` are hashes of the member index (`SimulationDice.Mix` of it), and φ is a fixed irrational + ratio so the path is not a circle. The offset's length is at most `SwayRadius·√2`, and that figure is the bound + the provider uses. `Radius` (:791) adds it too. With sway 0, the pose is bit-for-bit today's. +4. `BeltTargets` (BeltTargets.cs:109) adds the field's sway bound to `slack`, so every region's distance and bearing + bounds still hold for every member. No other change to the provider. +5. `ZoneGenerator.GenerateZone` (ZoneGenerator.cs:40-210) places krill swarms after the bodies exist. For each + planet or gas giant body, with a probability from `ZoneGenerationSettings` (Settings.cs:109-135, new fields + `KrillSwarmProbability`, `KrillSwarmCount`, `KrillSwarmArc` (turns) and `KrillSwarmWidth` (world units), with code + defaults), it adds an `AsteroidBeltData` whose orbit is parented to that body. Its members are clustered: phase + within `KrillSwarmArc` of one centre and distance within `KrillSwarmWidth` of one radius. Its `Kind` is picked by + `FieldKinds.Assign` on `SwarmWeight`. Draw from the generator's existing `random` (:52), so the result follows the + zone seed. No kind with positive `SwarmWeight` means no swarms. +6. Out of scope (later cuts): a krill look in the renderer (krill draw through the belt path as small rocks); the + `SectorRenderer` belt count; the catalog authoring of a Krill kind (cut 1b); obscuration. + +**Tests** (new `tests/Aetheria.Shared.Tests/FaunaSwarmTests.cs`, as a `partial class MiningCut3Tests` to reuse +`BuildSceneAt` and `Belt` (MiningCut3Tests.cs:74-130); kinds are authored in the test catalog, never re-derived): +- `SwayIsBoundedAndPure`: for a swaying field, every member's `ChunkPose` at many times lies within the sway bound + of its orbital slot (`AsteroidBelt.Pose` with sway 0). A zone stepped to t by 1/60 and by 1/7 gives equal poses + (`fauna-pose-pure`). +- `RockPosesUnchanged`: a sway-0 kind's poses equal the pre-cut formula. The existing `MiningIndexTests` and + `MiningCut3Tests` stay green. +- `RegionBoundsHoldForEveryMemberOfASwayingField`: the pattern of `BeltRegionBoundsHoldForEveryRock` + (MiningIndexTests.cs:105) over a swaying field at several times (`fauna-bounds-hold`). +- `KrillRideTheFlow`: a swarm's centroid velocity over one sway period equals the orbital velocity at its mean + distance, within the sway bound divided by the interval (`fauna-tell-holds`). +- `KrillAreSeenThroughTheOneGain`: a krill member is `ChunkVisible` exactly when `PassiveInfo` at its pose × + `ChunkVisibility` passes the threshold; its visibility scales with the kind's cross-section (`fauna-one-gain`). +- `KrillBreakAndRespawn`: `Zone.Wear` breaks a krill member and it respawns at zone time, as a rock does. Under + `untouchable`, this test asserts the refusal instead. +- `GeneratedZonesHostKrill`: with a catalog that holds one rock kind (belt weight 1) and one krill kind (belt + weight 0, swarm weight 1), a generated zone has swarms only on planet or gas giant orbits, each with the krill + kind, members inside the arc and width, and no belt with the krill kind. Generating the same galaxy zone twice + gives equal swarms. Use `RestoredHullsTests.TutorialZoneSettings()` with the krill fields set. + +**Hand mutants** (one list to `mutation-table.sh`, each expected to fail its test): +- drop the sway term in `Pose`; +- sway radius × 2 in `Pose` but not in the bound (the bound must catch it); +- omit the sway bound from `slack`; +- `Assign` reads `GenerationWeight` for swarms; +- the generator ignores `KrillSwarmArc` (full ring); +- the generator uses a new `System.Random` instead of the zone's `random`; +- the sway uses `_time` rounded to the frame (a function of dt). + +**Verification:** one Yggdrasil job: build, the full `Aetheria.Shared.Tests`, and the mutant table. Recipe: +`F:\Projects\eureka-handoff-aux-2026-10-12\hands-aetheria-common-ag.md`. + +**Promises for Soul:** `fauna-pose-pure`, `fauna-bounds-hold`, `fauna-tell-holds` (krill), `fauna-one-gain`, +rocks unchanged, no per-tick member loop (grep `Zone.Update` and the step functions for any loop over +`Asteroids`), and generation that is deterministic per zone. + +## Cut sequence r1 (superseded by the r2 sequence below) + +1. `fauna-krill-swarms`: krill fields through the chunk path, with the sway law and generation (drafted above). +1b. `fauna-krill-catalog`: an AetherDb command that authors the Krill field kind (cross-section, sway, swarm weight). +2. `fauna-field-presentation`: fauna kinds pick their own look (instanced sprites or particles per kind, not + asteroid meshes); `SectorRenderer` counts belts only. Waits on 1. +3. `fauna-minnow-schools`: the minnow kind; the sway law gains a fast milling term per kind. Waits on 1. +4. `fauna-anchors`: a field frame that moves across the flow under a class law (shark patrol and sprint, whale arcs), + per `fauna-motion-model`. Waits on that ruling and 1. +5. `fauna-sharks-and-whales`: the two kinds and their generation (sharks near schools, whales around gas giants), + thermal light for whales. Waits on 4, `fauna-habitat`. +6. `fauna-disturbance`: sparse disturbance records; schools scatter from hulls and shots, sharks veer + (`props-react`). Waits on 4, `fauna-interaction`. +7. `fauna-returns`: what an observer is shown of fauna (background markers, aggregate far and individual near), one + marker shared with unidentified ship returns. Waits on `fauna-distance-representation`, `fauna-disguise-path`, + and aetheria-ew's contact presentation. +8. `fauna-in-ew-blend`: fauna `BackgroundKind`s with motion-law envelopes in aetheria-ew's judge. Owned by + aetheria-ew cut 6 or after it, per `fauna-disguise-path`. +9. `fauna-krill-obscure`: dense krill thin sight lines through `Zone.Obscuration`, as vapour clouds do (one gain + term, no second one). Waits on 1, an operator yes. +10. `orbit-sync-helper`: the generic flying aid that holds a ship on the local orbital flow. It is not fauna-specific + and may belong to the flight campaign. Waits on an operator yes. + +## r2: the flow, placement and the content the rulings opened + +Written by Imagination (agent imagination-aeth-fauna-r2, session self-2026-10-13-ag2) against `origin/master` +`1746e8bd`, after the operator ruled on the nine questions above. The questions above are answered; their rulings +are in the mind. This section adds the body facts the flow ruling needs, the forks it opened, and the r2 cut +sequence, which replaces the r1 sequence above. The krill draft above stays as the shape of the krill cut; it is +re-mapped against the flow owner and the placement ruling when it is about to run. + +### Body facts (r2) + +Probed at `1746e8bd`. + +| # | Question | Result | +|---|---|---| +| B15 | What is the flow? | `Volumetric.cginc`: `globalFlow(pos)` = `Tri3D(pos/_FlowScale - (0,_FlowScroll,0)) * _FlowAmplitude` with y halved (:130-135); `Tri3D` is the cross product of two normalised `tri3` folds, the second at the golden ratio (:46-47, :69-74); `slopeFlow(grad)` = `normalize(grad)` turned 90 degrees times `_FlowSwirlAmplitude` plus `normalize(grad)` times `_FlowSlopeAmplitude` (:137-141); `flow(pos)` sums the two under the keywords `FLOW_GLOBAL` and `FLOW_SLOPE` (:148-161). Consumers: `Stardust.compute:139-142` (each particle is placed at `-flow * lifetime * period`, a closed-form advection over a cycle) and the nebula's noise advection (`Volumetric.cginc:185-208`). | +| B16 | Who owns it today? | The renderer. `VolumeSampling.Update` pushes the parameters from `environment.Flow` and accumulates `_flowScroll += GlobalScrollSpeed * Time.deltaTime` on the frame clock (`VolumeSampling.cs:96-106`). `environment` is `ActionGameManager.CurrentEnvironment`, which always returns `Settings.DefaultEnvironment` (`ActionGameManager.cs:222-228`), a field of the presentation `GameSettings` ScriptableObject (`GameSettings.cs:40`). `ZoneEnvironment` and `FlowSettings` are already `ServerShared` MessagePack types (`Environment.cs:8-61`), but no zone holds one. The sim cannot see the flow. | +| B17 | What flow is live? | `Assets/Resources/Settings.asset:396-402` (LFS): `GlobalScale` 512, `GlobalAmplitude` 15, `GlobalScrollSpeed` 0.025, `Period` 8, `SlopeAmplitude` 0, `SwirlAmplitude` 0. Only the global term runs; `FLOW_SLOPE` is off in the shipped game. Probe: the horizontal global flow averages 6.06 u/s (max 12.2) across a zone, the same as the rail speed 2π = 6.28 u/s. | +| B18 | Does the slope term have a sim twin? | It reads `_NebulaSurfaceHeight`, a GPU render of brush meshes (`Assets/Shaders/Brushes/*`), which is a second lowering of the heightfield `Zone.GetHeight` owns (`Zone.cs:627-660`). Its `getUV` negates world position (`Volumetric.cginc:81-84`), so its texel gradient points downhill in world terms. `normalize` of a zero gradient is NaN (:139); today the keyword keeps that from running. | +| B19 | What clock do presenters use? | Zone time: `Zone._time` (double, `Zone.cs:70`). Belts are drawn at it (`ZoneRenderer.cs:543-547`), gas giant wave phase too (:587-588). `Zone.Settings` is the public `PlanetSettings` (`Zone.cs:59`), the world-law block every zone already receives. | +| B20 | Placement prior art and probe | `docs/research/2026-10-13-fauna-placement-prior-art.md`. A CPU transliteration of the operator's `Slime.compute` with her prefab's parameters, fed by `Zone.GetNormal`: bit-identical run to run, 9 s for 40k agents × 600 steps on 256², trail on the shoulders of the wells and in filaments between them (0 % in flat space, 5.7 % in cores), correlation 0.28 with a closed-form slope-suitability map. Adding the flow reshapes the network (correlation 0.34 with the no-flow map). | +| B21 | Is a generated zone recomputed? | No. A zone pack is generated once, on first entry (`ActionGameManager.cs:727`, `??=`; the entrance in `RunStart.cs:29`), and saved with the galaxy (`Galaxy.cs:70`). Placement computed at generation is saved; it never has to reproduce on another machine. | +| B22 | Can Unity check a shader against C#? | Yes. `ShieldPanelCut3Verify.cs:18, 47-55` dispatches compute kernels and reads them back in batchmode run without `-nographics` (verified 2026-09-18), driven by `tests/mutation_tests_shield_panel_cut3.py`. That is the precedent for the flow parity check. Hands worktrees on Starfire have imported Libraries (`C:\aeth-wt\lock-on\Library` and others). | +| B23 | Overlap with in-flight passes | ew-claims (Weapon.cs, Entity.cs, Sensing.cs, SchematicDisplay.cs, tests), scenarios-lock-on-r3 (Scenarios/LockOn.cs, Scenarios.cs, a test) and sensor-catalog-r2 (Behaviors, Listener.cs, Entity.cs, `GameData/Aetheria.cc`, AetherDb, tests) touch none of the flow cut's files. The flow cut edits `Settings.asset` (LFS); none of the three does. | + +### Decisions made here, not forks + +- **The scroll becomes zone time.** `sim-knows-the-flow` makes the flow a sim fact, and `fauna-pose-pure` needs it to + be a function of zone time. `_FlowScroll` is therefore `GlobalScrollSpeed × Zone.Time`, derived, and the frame-clock + accumulator is deleted. Where no zone exists (menus), the same function runs on the presentation clock; that is a + different input to the one function, not a second law. `_FlowPeriod` and the noise phases on `_Time` stay + presentation: they animate how the nebula shows the flow, not the flow. +- **The flow settings live with the zone's world laws.** `FlowSettings` moves from `ZoneEnvironment` (read by no + zone) to `PlanetSettings.Flow`, which every `Zone` already receives (B19). One zone flow for every zone, as today. + Per-zone environments (Sol's cloudless bubble) are a later cut that adds a zone-pack override; the owner stays + `Zone`. +- **The slope term is ported and guarded.** It is part of the law the ruling names, so the owner carries it; its + term is skipped when its amplitudes are zero (as the shader's keyword does), and a zero gradient gives zero, not + NaN, on both sides. Its parity is pinned as a function of the gradient; making the heightfield's two lowerings + agree is follow-up work (`flow-slope-gradient-parity`). + +### Questions (admitted in the mind) + +`aetheria-fauna:question:fauna-placement`, `:fauna-flow-coupling`, `:flow-moves-what`, `:flow-slope-terms`. The +options and recommendations are in the mind; the research for the first is the placement prior-art file. + +### Cut sequence r2 (superseded by the r3 sequence below) + +1. `fauna-flow-field` (cut spec admitted): the flow's owner moves into `ServerShared` (`FlowField`, `Zone.Flow`), the + shader lowers it from zone time, and a Unity parity check pins HLSL to C#. +2. `fauna-habitat-placement`: the generation pass per `fauna-placement`; its settings record in `ServerShared`; + food at well shoulders and wormhole mouths; Sol excluded; budget measured. Waits on 1 and that ruling. +3. `fauna-krill-swarms`: the krill draft above, re-mapped: krill fields placed by 2, swaying and drifting by + `fauna-flow-coupling`. Waits on 1, 2. It cannot run beside 1: it needs `Zone.Flow`, and both edit `Zone.cs` and + `Settings.cs`. +4. `fauna-krill-catalog`: AetherDb authors the Krill field kind. +5. `fauna-field-presentation`: fauna kinds pick their own look; `SectorRenderer` counts belts only. +6. `fauna-minnow-schools`: minnows, fast milling, grazing the krill filaments. +7. `fauna-anchors`: field frames that move across the flow under class laws (`fauna-motion-model-ruled`). +8. `fauna-sharks-and-whales`: the two classes, generated by 2's map (sharks on steep flanks, whales round gas giants). +9. `fauna-disturbance`: sparse reaction records; schools scatter, sharks veer; reactions are tells. +10. `fauna-attacks-strike`: sharks strike and minnow schools scour, through the ordinary damage path. +11. `fauna-attacks-signal`: whale song as noise in the shared signal space (with aetheria-ew), drifter discharge. +12. `fauna-harvest-goods`: catalog goods per kind (krill paste, photophores, heat-organs, whale bone with strange + matter, spider silk) and yields through the economy's yield table; fields refill by respawn. +13. `fauna-harvest-gear`: resonance fishing, nets and trawls as gear with makers (the lore names Orbital Forge's + retooled resonators); trawls leave straight-edged channels. +14. `fauna-void-spiders`: nets strung across trojan points, snaring and tethering what drifts in; silk. +15. `fauna-gas-giant-drifters`: a cloud-deck class bound to gas giants. +16. `fauna-edge-giants`: larger classes found only far from Sol; the class mix scales with distance from Sol. +17. `fauna-springs`: wormhole mouths feed placement and the refill tide. +18. `fauna-genre-uses`: cultivators' harvesting techniques, necrotech-bound fauna, mecha that ride fauna; each lands + with its owner's campaign, none trimmed for genre consistency. +19. `sol-flatspace-zone`: a per-zone environment override; Sol is cloudless, flowless and fauna-free, with krill + haze outside its Oort edge. +20. `fauna-returns`: what an observer is shown (`fauna-distance-ruled`, `fauna-disguise-path-ruled`). +21. `fauna-in-ew-blend`: fauna background kinds with motion-law envelopes in aetheria-ew's judge. +22. `fauna-krill-obscure`: dense krill thin sight lines through `Zone.Obscuration`. Waits on an operator yes. +23. `flow-moves-matter`: loose matter drifts with the flow, per `flow-moves-what`. +24. `flow-slope-gradient-parity`: the brush-rendered heightfield and `Zone.GetHeight` agree, so the slope term can + be switched on (`flow-slope-terms`). +25. `orbit-sync-helper`: the generic flying aid that holds a ship on the local orbital flow. Waits on an operator yes. + +## r3: placement is a closed form evaluated at run time + +Written by Imagination (agent imagination-aeth-fauna-r3, session self-2026-10-14-ag) against `origin/master` +`b836af48`, with the flow owner read at `eureka/aetheria-fauna-flow-field` `5f5a1e4d`. The operator ruled +`fauna-placement-ruled` against `physarum-at-generation`: placement is "deterministic based on the gravity slope and +flow that makes nice patterns", because "the level is constantly changing". The target is revised to r3 (Placement +law, invariants `fauna-placement-closed-form`, `-story`, `-nested`, `-no-pop`). The B20 probe and the r2 rationale for +a generation pass stand as evidence of what the slime look is; the generation pass itself is dropped. Prior art for +the closed form: `docs/research/2026-10-14-fauna-placement-closed-form.md` (`CF:`). + +### Body facts (r3) + +| # | Question | Result | +|---|---|---| +| B24 | Does the gravity field move? | Yes, in closed form of zone time. Orbit positions are `OrbitData.Evaluate(frac(_time / Period + Phase)) * Distance` plus the parent's position, cached per tick (`Zone.cs:476-497`). `GetHeight` subtracts each gas giant's `RadialWaves(..., _time * speed)` (`Zone.cs:645-655`), and `Sun` derives from `GasGiant` (`Zone.cs:771`), so the sun's well ripples too; `GasGiantData` defaults give wave speed x8 (`ZoneData.cs:199`). The slope at a point is a function of `_time`, and nothing in `GetHeight` can be evaluated at another time without a time parameter. | +| B25 | Which pointwise closed form makes the slime look? (scratch probe, not committed) | A pure-Python transliteration of `FlowField.Global`/`Slope`/`Scroll` at `5f5a1e4d` and `Zone.GetHeight`/`GetNormal`/`PowerPulse`/`RadialWaves` at `b836af48`, on the B20 zone (sun, four planets, a gas giant; radius 2000; live flow scale 512, amplitude 15, scroll speed .025), 256² grid at t = 100 s, float64 (C# is float32). Density images were written per candidate, member-dot images under fixed per-candidate thresholds (jittered 16 u lattice, about 49k candidates), and correlated with the B20 Physarum maps (64x32 blocks). Results follow in the next rows. Scripts, images and how to rerun: `docs/research/2026-10-14-fauna-habitat-probe/` (README there). These rows' member counts normalise density by its zone maximum, which the law may not do (CF:56); B25g gives the counts under the spec's law. The first `members_c6_band_soft_windrows_swirl.png` was a mislabelled render and is not kept. | +| B25a | Slope band alone (`c0`: the operator's `Deposition(slope)`, zero past slope .8) | Rings on every planet's shoulder, a bright bridge where two shoulders meet; correlation with Physarum A .517 (B .483), the highest of all candidates. 1,435 members. Changes 3.3 % of members in 1 s and 20 % in 8 s from the wells' ripples alone (B24). | +| B25b | Band times flow convergence (`c1`, gain 3; `c6`, gain 1.5, slope terms on: swirl 6, slide 1.5) | Langmuir-windrow analogue (CF:17-18). The band keeps its rings, cut by the flow's convergence into a crisp triangular texture: `Tri3D` is piecewise linear (`tri`), so its derivatives are piecewise constant and the convergence field is a tiling of hard-edged triangles and diagonal streaks. `c6` correlation .464 (B .449); `c1` .428. Members gather in clumps on the shoulders with thin lines between wells. Under continuous evaluation 20-22 % of members change in 1 s and 89-94 % in 8 s: the flow scrolls a full first-octave phase in 40 s (1 / .025). Convergence std over the zone is .147 /s live and .151 /s with the slope terms on. | +| B25c | Band times flow-along-contour (`c5`, narrow; `c7`, wide) | Members where the flow runs along the well's contour (neither climbing nor falling). Fine scalloped arcs, more organic than `c6`, but sparse (94 members narrow, 395 wide) and unstable: 42-134 % of members change in 1 s. `c7` correlation .480. | +| B25d | Okubo-Weiss strain (`c2`) and gravity saddles (`c3`, `c4`) | `c2` (band times sigmoid of W, CF:11) correlation .507, texture like `c1`. `c3` (negative Hessian determinant of the height: outer shoulders and saddles between wells) makes clean rings with dark gaps and no links, .377. `c4` (`c3` times convergence) .316. | +| B25e | Does a presence fade on the density stop pops? (`docs/research/2026-10-14-fauna-habitat-probe/pop_probe.py`) | No. `c6` with a fade band of .1 around each threshold, 600 shoulder candidates, 180 steps of 1/60 s from t = 100: the density moves by up to .267 in one step, so presence moves by up to .35 in one step (4 steps over .25; .56 with a band of .05). The same with the slope terms off, so the jumps are the global `Tri3D` term's: its convergence changes almost discontinuously in time at some points. | +| B25f | Does reading the flow term at the member's own cycle start stop them? (`docs/research/2026-10-14-fauna-habitat-probe/pop_cycle.py`) | Yes. Band at now, convergence at the member's cycle start (period 8 s, hashed phase), same fade and candidates: presence moves by at most .0003 per step within a cycle, 0 steps over .25; the flow term changes only at the 221 cycle turns, where `fauna-flow-coupling-ruled` already fades the member. The slope band moves smoothly (B24's ripples are continuous). `FlowField.At` takes a scroll, and `FlowField.Scroll(settings, t)` is pure in t, so the flow at a past zone time needs no new owner. | +| B25g | The options under the spec's law (`habitat_options.py`, `pop_maps.py`) | Absolute density, fixed constants of `cut-fauna-habitat-placement.r1`, candidate thresholds .1 + .9h, fade .1, slope terms on, 49,083 candidates at 16 u. Hosted at t = 100 and changed under continuous evaluation in 1 s / 8 s: band-only 4,388, 2.0 % / 12.2 %; band-times-convergence 2,235, 10.3 % / 47.1 %; band-times-strain 2,721, 7.9 % / 31.3 %; band-times-contour-flow 2,307, 15.8 % / 49.2 %. No-pop, convergence law, 5,607 shoulder candidates, 60 steps of 1/60 s, largest presence step with cycle turns excluded and members moving > .1 in a step: presence-fade .33, 2 members; cycle-sampled-flow .0010, 0; cycle-sampled-all .0000, 0. Images: `option_density_