From 64e326ff1720ceb5e4bdcb9a763f62de8ffbee4f Mon Sep 17 00:00:00 2001 From: SmallFox <2806143047@qq.com> Date: Sat, 31 Jan 2026 12:31:28 +0800 Subject: Drag --- .../Animations/Player/PlayerAnimation.controller | 122 ++++++++++++++++++++- Assets/Prefabs/Player.prefab | 31 ++++++ Assets/Scenes/PlayScene.unity | 97 ++++++++++++++++ Assets/Scenes/Test.unity | 52 +++++++-- Assets/Scripts/GrabStateMachine.cs | 47 ++++++++ Assets/Scripts/GrabStateMachine.cs.meta | 2 + Assets/Scripts/PlayerDrag.cs | 70 ++++++++++++ Assets/Scripts/PlayerDrag.cs.meta | 2 + 8 files changed, 410 insertions(+), 13 deletions(-) create mode 100644 Assets/Scripts/GrabStateMachine.cs create mode 100644 Assets/Scripts/GrabStateMachine.cs.meta create mode 100644 Assets/Scripts/PlayerDrag.cs create mode 100644 Assets/Scripts/PlayerDrag.cs.meta (limited to 'Assets') diff --git a/Assets/Animations/Player/PlayerAnimation.controller b/Assets/Animations/Player/PlayerAnimation.controller index f1e922f..161064d 100644 --- a/Assets/Animations/Player/PlayerAnimation.controller +++ b/Assets/Animations/Player/PlayerAnimation.controller @@ -1,5 +1,57 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1102 &-8160761117747578489 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: "\u9AA8\u67B6|Catch" + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: 8871391444622004071} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 966450124619330743, guid: ce903e52583f4664a945b7c2eb161634, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1101 &-6563261956464721863 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: grabbing + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: -8160761117747578489} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.87234044 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!91 &9100000 AnimatorController: m_ObjectHideFlags: 0 @@ -8,7 +60,13 @@ AnimatorController: m_PrefabAsset: {fileID: 0} m_Name: PlayerAnimation serializedVersion: 5 - m_AnimatorParameters: [] + m_AnimatorParameters: + - m_Name: grabbing + m_Type: 4 + m_DefaultFloat: 0 + m_DefaultInt: 0 + m_DefaultBool: 0 + m_Controller: {fileID: 9100000} m_AnimatorLayers: - serializedVersion: 5 m_Name: Base Layer @@ -22,6 +80,58 @@ AnimatorController: m_IKPass: 0 m_SyncedLayerAffectsTiming: 0 m_Controller: {fileID: 9100000} +--- !u!1102 &4865996011263048567 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: "\u9AA8\u67B6|Idle" + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: -6563261956464721863} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: -7662094304892612981, guid: ce903e52583f4664a945b7c2eb161634, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1101 &8871391444622004071 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 2 + m_ConditionEvent: grabbing + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 4865996011263048567} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.87234044 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!1107 &8981667683938968433 AnimatorStateMachine: serializedVersion: 6 @@ -30,7 +140,13 @@ AnimatorStateMachine: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: Base Layer - m_ChildStates: [] + m_ChildStates: + - serializedVersion: 1 + m_State: {fileID: 4865996011263048567} + m_Position: {x: 310, y: 110, z: 0} + - serializedVersion: 1 + m_State: {fileID: -8160761117747578489} + m_Position: {x: 310, y: 270, z: 0} m_ChildStateMachines: [] m_AnyStateTransitions: [] m_EntryTransitions: [] @@ -40,4 +156,4 @@ AnimatorStateMachine: m_EntryPosition: {x: 50, y: 120, z: 0} m_ExitPosition: {x: 800, y: 120, z: 0} m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} - m_DefaultState: {fileID: 0} + m_DefaultState: {fileID: 4865996011263048567} diff --git a/Assets/Prefabs/Player.prefab b/Assets/Prefabs/Player.prefab index 2e8ced1..5e65ebf 100644 --- a/Assets/Prefabs/Player.prefab +++ b/Assets/Prefabs/Player.prefab @@ -119,6 +119,7 @@ GameObject: - component: {fileID: 4976293655274419266} - component: {fileID: 7519057055885485454} - component: {fileID: 8250406697026396419} + - component: {fileID: 2341430063894590208} m_Layer: 0 m_Name: Player m_TagString: Untagged @@ -327,6 +328,18 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Assembly-CSharp::RandomSpawnPosition range: 3 +--- !u!114 &2341430063894590208 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4314353825088690500} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8cbfd87026c9dc54bbd983d8aa98eafd, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::PlayerDrag --- !u!1 &4328717198840516823 GameObject: m_ObjectHideFlags: 0 @@ -405,6 +418,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 7ef2d969201f5284b968982b605fb3ff, type: 3} m_Name: m_EditorClassIdentifier: Assembly-CSharp::PlayerRotationController + lerpSpeed: 0.25 lookAt: {fileID: 4408286991926610371} control: {fileID: 3267697200445213522} --- !u!1183024399 &1683818354991653245 @@ -680,6 +694,9 @@ PrefabInstance: - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: ce903e52583f4664a945b7c2eb161634, type: 3} insertIndex: -1 addedObject: {fileID: 2498788679243921835} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: ce903e52583f4664a945b7c2eb161634, type: 3} + insertIndex: -1 + addedObject: {fileID: 1186084585528594294} m_SourcePrefab: {fileID: 100100000, guid: ce903e52583f4664a945b7c2eb161634, type: 3} --- !u!1 &4619365361263074837 stripped GameObject: @@ -708,6 +725,20 @@ Animator: m_AllowConstantClipSamplingOptimization: 1 m_KeepAnimatorStateOnDisable: 0 m_WriteDefaultValuesOnDisable: 0 +--- !u!114 &1186084585528594294 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4619365361263074837} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 811939d88c0df0c44bf13cae7f13a581, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::GrabStateMachine + anim: {fileID: 0} + grabKey: 103 --- !u!4 &5427005771150001327 stripped Transform: m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: ce903e52583f4664a945b7c2eb161634, type: 3} diff --git a/Assets/Scenes/PlayScene.unity b/Assets/Scenes/PlayScene.unity index 3e54908..c924c3c 100644 --- a/Assets/Scenes/PlayScene.unity +++ b/Assets/Scenes/PlayScene.unity @@ -119,6 +119,30 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &738278464 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 4619365361263074837, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + m_PrefabInstance: {fileID: 1731624642} + m_PrefabAsset: {fileID: 0} +--- !u!114 &738278467 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 738278464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 811939d88c0df0c44bf13cae7f13a581, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::GrabStateMachine + anim: {fileID: 0} + grabKey: 103 +--- !u!4 &826326573 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 3858086185141390273, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + m_PrefabInstance: {fileID: 1731624642} + m_PrefabAsset: {fileID: 0} --- !u!1 &1250508122 GameObject: m_ObjectHideFlags: 0 @@ -198,6 +222,78 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &1731624642 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalPosition.x + value: -2.9113557 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalPosition.y + value: -0.00000019833448 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalPosition.z + value: -1.1362278 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4314353825088690500, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_Name + value: Player + objectReference: {fileID: 0} + - target: {fileID: 6804967426155711280, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_Enabled + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 8017654697833592608, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: targetObject + value: + objectReference: {fileID: 826326573} + - target: {fileID: 8622649025587430758, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + propertyPath: m_Controller + value: + objectReference: {fileID: 9100000, guid: b557819f13ae72f4789f2a749b6d950e, type: 2} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 4619365361263074837, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} + insertIndex: -1 + addedObject: {fileID: 738278467} + m_SourcePrefab: {fileID: 100100000, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} --- !u!1 &1976095976 GameObject: m_ObjectHideFlags: 0 @@ -668,3 +764,4 @@ SceneRoots: - {fileID: 1250508125} - {fileID: 1976095978} - {fileID: 1992053536} + - {fileID: 1731624642} diff --git a/Assets/Scenes/Test.unity b/Assets/Scenes/Test.unity index 46c3663..d091020 100644 --- a/Assets/Scenes/Test.unity +++ b/Assets/Scenes/Test.unity @@ -119,7 +119,7 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} ---- !u!1001 &244695222 +--- !u!1001 &240209370 PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 @@ -129,15 +129,15 @@ PrefabInstance: m_Modifications: - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} propertyPath: m_LocalPosition.x - value: 3.1808016 + value: 2.5715754 objectReference: {fileID: 0} - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} propertyPath: m_LocalPosition.y - value: -0.00000014205148 + value: -0.000000112629465 objectReference: {fileID: 0} - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} propertyPath: m_LocalPosition.z - value: -9.667192 + value: -8.4289465 objectReference: {fileID: 0} - target: {fileID: 2684917141693768409, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} propertyPath: m_LocalRotation.w @@ -171,10 +171,6 @@ PrefabInstance: propertyPath: m_Name value: Player objectReference: {fileID: 0} - - target: {fileID: 6804967426155711280, guid: 5a380f4e0f263cee8b2148dbffce9758, type: 3} - propertyPath: m_Enabled - value: 1 - objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -552,7 +548,7 @@ Transform: serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: -0.13, y: 0, z: -9.71} - m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalScale: {x: 4.8802, y: 4.8802, z: 4.8802} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} @@ -568,6 +564,8 @@ GameObject: - component: {fileID: 808063312} - component: {fileID: 808063311} - component: {fileID: 808063310} + - component: {fileID: 808063313} + - component: {fileID: 808063314} m_Layer: 0 m_Name: Plane_1 m_TagString: Untagged @@ -647,6 +645,40 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &808063313 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 808063308} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c69e2aa4d45550a818a819efbd91c846, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::DragItem + dragger: {fileID: 0} +--- !u!65 &808063314 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 808063308} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 1 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 9.999999, y: 2.2204459e-16, z: 10} + m_Center: {x: 0, y: 0, z: 0} --- !u!1 &832575517 GameObject: m_ObjectHideFlags: 0 @@ -705,4 +737,4 @@ SceneRoots: - {fileID: 832575519} - {fileID: 605998533} - {fileID: 808063312} - - {fileID: 244695222} + - {fileID: 240209370} diff --git a/Assets/Scripts/GrabStateMachine.cs b/Assets/Scripts/GrabStateMachine.cs new file mode 100644 index 0000000..8242097 --- /dev/null +++ b/Assets/Scripts/GrabStateMachine.cs @@ -0,0 +1,47 @@ +using UnityEngine; + +public class GrabStateMachine : MonoBehaviour +{ + private bool grabbing = false; + + // 动画组件引用(需要在Inspector面板赋值,或通过代码自动获取) + [Header("动画组件引用")] + [SerializeField] private Animator anim; + + // 按键设置(可在Inspector面板修改,无需硬编码) + [Header("控制按键")] + [SerializeField] private KeyCode grabKey = KeyCode.G; + + /// + /// 初始化 + /// + private void Start() + { + anim = GetComponent(); + } + + private void Update() + { + DetectGrabKeyInput(); + UpdateAnimatorState(); + } + + private void DetectGrabKeyInput() + { + if (Input.GetKey(grabKey)) + { + grabbing = true; + } + + if (Input.GetKeyUp(grabKey)) + { + grabbing = false; + } + } + + + private void UpdateAnimatorState() + { + anim.SetBool("grabbing", grabbing); + } +} diff --git a/Assets/Scripts/GrabStateMachine.cs.meta b/Assets/Scripts/GrabStateMachine.cs.meta new file mode 100644 index 0000000..70b2bc3 --- /dev/null +++ b/Assets/Scripts/GrabStateMachine.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 811939d88c0df0c44bf13cae7f13a581 \ No newline at end of file diff --git a/Assets/Scripts/PlayerDrag.cs b/Assets/Scripts/PlayerDrag.cs new file mode 100644 index 0000000..10300af --- /dev/null +++ b/Assets/Scripts/PlayerDrag.cs @@ -0,0 +1,70 @@ +using UnityEngine; + +/// +/// 简化版玩家拖拽脚本(Trigger触发判定,仅保留核心拖拽逻辑) +/// +public class PlayerDrag : MonoBehaviour +{ + // 拖拽核心配置 + [SerializeField] private KeyCode grabKey = KeyCode.G; // 抓取按键 + + // 临时缓存:当前触发接触的可拖拽物品 + private DragItem currentDragItem; + // 标记是否处于拖拽状态 + private bool isDragging; + + private void Update() + { + // 仅检测G键输入,控制抓取/松开(核心逻辑不变) + CheckGrabInput(); + } + + + private void CheckGrabInput() + { + // 按下G键:抓取物品(仅当触发接触且未拖拽时生效) + if (Input.GetKeyDown(grabKey) && !isDragging && currentDragItem != null) + { + isDragging = true; + currentDragItem.dragger = this.transform; // 给物品赋值拖拽锚点(玩家) + } + + // 松开G键:放下物品(解除关联) + if (Input.GetKeyUp(grabKey) && isDragging) + { + isDragging = false; + if (currentDragItem != null) + { + currentDragItem.dragger = null; // 清空物品的拖拽锚点 + } + currentDragItem = null; + } + } + + private void OnTriggerStay(Collider other) + { + // 如果已在拖拽状态,直接返回,不处理新物品 + if (isDragging) return; + + // 尝试获取对方的DragItem组件,缓存为当前可抓取物品 + DragItem dragItem = other.GetComponent(); + if (dragItem != null) + { + currentDragItem = dragItem; + } + } + + + private void OnTriggerExit(Collider other) + { + // 如果已在拖拽状态,直接返回(避免拖拽中丢失目标) + if (isDragging) return; + + // 确认离开的是当前缓存的物品,清空缓存 + DragItem dragItem = other.GetComponent(); + if (dragItem != null && dragItem == currentDragItem) + { + currentDragItem = null; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/PlayerDrag.cs.meta b/Assets/Scripts/PlayerDrag.cs.meta new file mode 100644 index 0000000..5512a1e --- /dev/null +++ b/Assets/Scripts/PlayerDrag.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 8cbfd87026c9dc54bbd983d8aa98eafd \ No newline at end of file -- cgit