Added COM controller support. Added bridge between COM and InputSystem. Rewritten some code by _sega

This commit is contained in:
Данил Ярош 2025-11-03 17:08:00 +03:00
parent 152066e9a3
commit 868089344b
26 changed files with 33989 additions and 2345 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -28,7 +28,7 @@
"name": "Attack",
"type": "Button",
"id": "6c2ab1b8-8984-453a-af3d-a3c78ae1679a",
"expectedControlType": "Button",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
@ -37,7 +37,7 @@
"name": "Interact",
"type": "Button",
"id": "852140f2-7766-474d-8707-702459ba45f3",
"expectedControlType": "Button",
"expectedControlType": "",
"processors": "",
"interactions": "Hold",
"initialStateCheck": false
@ -46,7 +46,7 @@
"name": "Crouch",
"type": "Button",
"id": "27c5f898-bc57-4ee1-8800-db469aca5fe3",
"expectedControlType": "Button",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
@ -104,7 +104,7 @@
"path": "<Gamepad>/leftStick",
"interactions": "",
"processors": "",
"groups": ";Gamepad",
"groups": "",
"action": "Move",
"isComposite": false,
"isPartOfComposite": false
@ -208,6 +208,61 @@
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "2D Vector",
"id": "6b74498a-60fd-4f91-9063-28e57c3e0208",
"path": "2DVector",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "up",
"id": "8417a5fe-0cc1-48dc-8da2-6fe681ea5dbd",
"path": "<Gamepad>/dpad/up",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "down",
"id": "f288e567-fa55-4a17-8868-8810b910cbb8",
"path": "",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "left",
"id": "a2fe25c9-761c-4cd7-8eac-7f7bb0e09eb0",
"path": "<Gamepad>/dpad/left",
"interactions": "",
"processors": "",
"groups": ";Gamepad",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "right",
"id": "2b6356de-93f4-4a0f-8656-0830323397d7",
"path": "<Gamepad>/dpad/right",
"interactions": "",
"processors": "",
"groups": ";Gamepad",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "",
"id": "c1f7a91b-d0fd-4a62-997e-7fb9b69bf235",
@ -362,21 +417,10 @@
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "eb40bb66-4559-4dfa-9a2f-820438abb426",
"path": "<Keyboard>/space",
"interactions": "",
"processors": "",
"groups": "Keyboard&Mouse",
"action": "Jump",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "daba33a1-ad0c-4742-a909-43ad1cdfbeb6",
"path": "<Gamepad>/buttonSouth",
"path": "<Gamepad>/dpad/up",
"interactions": "",
"processors": "",
"groups": "Gamepad",
@ -431,7 +475,7 @@
{
"name": "",
"id": "1c04ea5f-b012-41d1-a6f7-02e963b52893",
"path": "<Keyboard>/e",
"path": "<Keyboard>/f",
"interactions": "",
"processors": "",
"groups": "Keyboard&Mouse",
@ -442,7 +486,7 @@
{
"name": "",
"id": "b3f66d0b-7751-423f-908b-a11c5bd95930",
"path": "<Gamepad>/buttonNorth",
"path": "<Gamepad>/buttonEast",
"interactions": "",
"processors": "",
"groups": "Gamepad",
@ -489,6 +533,28 @@
"path": "<Keyboard>/ctrl",
"interactions": "",
"processors": "",
"groups": ";Keyboard&Mouse",
"action": "Fire",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "288bb654-a057-44cd-8f6e-36f833632e66",
"path": "<Gamepad>/buttonSouth",
"interactions": "",
"processors": "",
"groups": ";Gamepad",
"action": "Fire",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "9ba54978-8ff4-49c8-a365-80ff554c2eb5",
"path": "<Keyboard>/space",
"interactions": "",
"processors": "",
"groups": "",
"action": "Fire",
"isComposite": false,
@ -513,7 +579,7 @@
"name": "Submit",
"type": "Button",
"id": "7607c7b6-cd76-4816-beef-bd0341cfe950",
"expectedControlType": "Button",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
@ -865,6 +931,61 @@
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "2D Vector",
"id": "b6b2f3b4-ddaf-4e82-b05e-b88f4a5479ba",
"path": "2DVector",
"interactions": "",
"processors": "",
"groups": "",
"action": "Navigate",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "up",
"id": "1c20943f-4636-44c0-9050-117ce6963f80",
"path": "<Gamepad>/dpad/up",
"interactions": "",
"processors": "",
"groups": ";Gamepad",
"action": "Navigate",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "down",
"id": "3e08e9c4-f46a-4c7a-a28b-2a3df5e8ebd8",
"path": "",
"interactions": "",
"processors": "",
"groups": "",
"action": "Navigate",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "left",
"id": "a01b9794-6401-43d5-be71-186b71aa9498",
"path": "<Gamepad>/dpad/left",
"interactions": "",
"processors": "",
"groups": ";Gamepad",
"action": "Navigate",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "right",
"id": "5e55e405-dc58-40a7-9070-f60be6401971",
"path": "<Gamepad>/dpad/right",
"interactions": "",
"processors": "",
"groups": ";Gamepad",
"action": "Navigate",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "",
"id": "9e92bb26-7e3b-4ec4-b06b-3c8f8e498ddc",

View File

@ -294,11 +294,11 @@ MonoBehaviour:
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_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_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
m_DisabledColor: {r: 0.63529414, g: 0.63529414, b: 0.63529414, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fad7c2f9c5729054584c983f7850543c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,130 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4763496076470024150
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6708844088101150}
- component: {fileID: -6830167632558745604}
- component: {fileID: 4577859410310799261}
- component: {fileID: -6245296037342915518}
- component: {fileID: 6566017136146807207}
- component: {fileID: -3912971501865491093}
m_Layer: 0
m_Name: Globals
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6708844088101150
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4763496076470024150}
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!114 &-6830167632558745604
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4763496076470024150}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e679be5faf94f304d8251931f02c036a, type: 3}
m_Name:
m_EditorClassIdentifier: '::'
--- !u!114 &4577859410310799261
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4763496076470024150}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d793a5f3669a676418d43519feaf3a8d, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::ComWrapper
saveMoneyBetweenSessions: 0
enablePrizeChecking: 0
--- !u!114 &-6245296037342915518
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4763496076470024150}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dec428d33ffedb846aa3568b5dbc6d49, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::In
inputType: 0
--- !u!114 &6566017136146807207
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4763496076470024150}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 04cb8758b49014f4caca890b913d86c0, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::PrizeSystem
prizeErrorSound: {fileID: 0}
--- !u!114 &-3912971501865491093
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4763496076470024150}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 10f5cf4411135b245baf35e2705982c7, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::ComInputToInputSystemAdapter
useAnyPlayer: 1
actionBindings:
- action: 0
target: 0
button: 0
dpadDirection: 0
- action: 1
target: 0
button: 1
dpadDirection: 1
- action: 2
target: 0
button: 2
dpadDirection: 2
- action: 3
target: 0
button: 3
dpadDirection: 3
- action: 4
target: 0
button: 12
dpadDirection: 3
- action: 5
target: 0
button: 13
dpadDirection: 3
pinBindings: []
logCreateDevice: 1

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: bd9fcfd28bd11ab459a9aee1c457a0b8
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -2038,19 +2038,19 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_Mode: 4
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnUp: {fileID: 1294478665}
m_SelectOnDown: {fileID: 1294478665}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.7764706, g: 0.7764706, b: 0.7764706, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
m_DisabledColor: {r: 0.63529414, g: 0.63529414, b: 0.63529414, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
@ -2203,7 +2203,7 @@ MonoBehaviour:
loseText: {fileID: 1131560888}
continueButton: {fileID: 1871409157}
continueButtonText: {fileID: 1670382382}
continueButtonCountdown: 10
continueButtonCountdown: 30
mainMenuButton: {fileID: 593492478}
--- !u!225 &1069927042
CanvasGroup:
@ -2549,11 +2549,11 @@ MonoBehaviour:
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.7764706, g: 0.7764706, b: 0.7764706, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
m_DisabledColor: {r: 0.63529414, g: 0.63529414, b: 0.63529414, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
@ -2724,19 +2724,19 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_Mode: 4
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnUp: {fileID: 1065887711}
m_SelectOnDown: {fileID: 1065887711}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.7764706, g: 0.7764706, b: 0.7764706, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
m_DisabledColor: {r: 0.63529414, g: 0.63529414, b: 0.63529414, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
@ -3601,11 +3601,11 @@ MonoBehaviour:
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.7764706, g: 0.7764706, b: 0.7764706, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
m_DisabledColor: {r: 0.63529414, g: 0.63529414, b: 0.63529414, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:

View File

@ -80690,7 +80690,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 3013926927394175097, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_Name
value: Finish_1
value: Finish
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
@ -123934,7 +123934,6 @@ Transform:
- {fileID: 420109086}
- {fileID: 70046927}
- {fileID: 1975562525}
- {fileID: 1923719231}
- {fileID: 1722488431}
- {fileID: 1219940683}
- {fileID: 1953952572}
@ -188423,7 +188422,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 8891147400174355649, guid: ab23b26a9910d684baf2634211134ca6, type: 3}
propertyPath: m_IsActive
value: 1
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8891147400174355649, guid: ab23b26a9910d684baf2634211134ca6, type: 3}
propertyPath: m_StaticEditorFlags
@ -354338,7 +354337,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 8891147400174355649, guid: ab23b26a9910d684baf2634211134ca6, type: 3}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8891147400174355649, guid: ab23b26a9910d684baf2634211134ca6, type: 3}
propertyPath: m_StaticEditorFlags
@ -358806,72 +358805,6 @@ PrefabInstance:
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
--- !u!1001 &1923719230
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 1053302775}
m_Modifications:
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalPosition.x
value: 115.873245
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalPosition.y
value: 8
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalPosition.z
value: -0.8700783
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3013926927394175097, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_Name
value: Finish
objectReference: {fileID: 0}
- target: {fileID: 3013926927394175097, guid: 70235a41586931d41996f4a80dd71752, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 70235a41586931d41996f4a80dd71752, type: 3}
--- !u!4 &1923719231 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 2891592954758516483, guid: 70235a41586931d41996f4a80dd71752, type: 3}
m_PrefabInstance: {fileID: 1923719230}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &1925685237
PrefabInstance:
m_ObjectHideFlags: 0

View File

@ -908,7 +908,7 @@ MonoBehaviour:
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 0.83137256, g: 0.83137256, b: 0.83137256, a: 1}
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
@ -1034,7 +1034,7 @@ MonoBehaviour:
m_HandleRect: {fileID: 434895585}
m_Direction: 2
m_Value: 0
m_Size: 1
m_Size: 0.9957961
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
@ -1473,15 +1473,15 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_Mode: 4
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnUp: {fileID: 254276108}
m_SelectOnDown: {fileID: 1707733837}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 0.83137256, g: 0.83137256, b: 0.83137256, a: 1}
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
@ -2478,9 +2478,8 @@ MonoBehaviour:
m_PersistentCalls:
m_Calls: []
m_text: "\u0414\u0432\u0438\u0433\u0430\u0442\u044C\u0441\u044F\nAD \u0438\u043B\u0438
\u2190\u2192\n\u041F\u0440\u044B\u0433\u0430\u0442\u044C\nSpace \u0438\u043B\u0438
\u2191\n\u0421\u0442\u0440\u0435\u043B\u044F\u0442\u044C\nF \u0438\u043B\u0438
LCtrl"
\u2190\u2192\n\u041F\u0440\u044B\u0433\u0430\u0442\u044C\nW \u0438\u043B\u0438
\u2191\n\u0421\u0442\u0440\u0435\u043B\u044F\u0442\u044C\n\u041F\u0440\u043E\u0431\u0435\u043B"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_sharedMaterial: {fileID: 2164040, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
@ -3323,6 +3322,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: a051668844a44474c99441ddb8b727f0, type: 3}
m_Name:
m_EditorClassIdentifier:
globalsPrefabResourcePath: Prefabs/Globals
maxLives: 3
playerPrefab: {fileID: 6550761235523395909, guid: 5e2f7649694807646a991b80b725b2e5, type: 3}
playerPrefabResourcePath: Prefabs/Player
@ -4298,15 +4298,15 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_Mode: 4
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnUp: {fileID: 477076300}
m_SelectOnDown: {fileID: 254276108}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 0.83137256, g: 0.83137256, b: 0.83137256, a: 1}
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
@ -4540,7 +4540,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0.0006207353}
m_AnchoredPosition: {x: 0, y: -0.000009311028}
m_SizeDelta: {x: 0, y: 300}
m_Pivot: {x: 0, y: 1}
--- !u!114 &1792218764
@ -4731,11 +4731,11 @@ MonoBehaviour:
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.7764706, g: 0.7764706, b: 0.7764706, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
m_DisabledColor: {r: 0.63529414, g: 0.63529414, b: 0.63529414, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
@ -4824,7 +4824,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!224 &1851115885
RectTransform:
m_ObjectHideFlags: 0

View File

@ -1,4 +1,5 @@
using UnityEngine;
using System.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
using RR.Common.Interfaces;
@ -110,7 +111,7 @@ namespace RR.Game2D.Behaviour
_jumpPressed |= jumpAction.action.WasPressedThisFrame();
_jumpReleased |= jumpAction.action.WasReleasedThisFrame();
_jumpHold |= jumpAction.action.IsPressed();
if (_inputX != 0f)
transform.localEulerAngles = Mathf.Sign(_inputX) > 0 ? Vector3.zero : new Vector3(0, 180f, 0);

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9903aacc42977d145b0706d2a1eff407
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.LowLevel;
/// <summary>
/// Мост из твоего фасада In (COM/клава и т.д.) в новый Input System.
/// Создаёт виртуальный Gamepad и обновляет его состояние на основе:
/// - действий игроков (PlayerAction), или
/// - физических пинов (int / ButtonPinMapping)
/// Выбирай способ через списки маппинга в инспекторе.
/// </summary>
[DefaultExecutionOrder(-100)] // пораньше, чтобы UI увидел ввод
public class ComInputToInputSystemAdapter : MonoBehaviour
{
[Header("Источник состояния")]
[Tooltip("Если true — брать состояние из In.GetButton* AnyPlayer; если false — из CurrentPlayer.")]
public bool useAnyPlayer = true;
[Header("Маппинг по действиям (PlayerAction -> Gamepad)")]
public List<ActionBinding> actionBindings = new();
[Header("Маппинг по пинам (индекс пина -> Gamepad)")]
public List<PinBinding> pinBindings = new();
[Header("Отладка")]
public bool logCreateDevice = true;
private static Gamepad _virtualPad;
private GamepadState _state;
// Защита от дублей при отключённом Domain Reload
private static bool _deviceCreated;
[Serializable]
public struct ActionBinding
{
public PlayerAction action; // твой enum
public TargetTarget target;
public GamepadButton button; // если target == Button
public DpadDir dpadDirection; // если target == Dpad
}
[Serializable]
public struct PinBinding
{
public int pinIndex; // твой физический индекс пина
public TargetTarget target;
public GamepadButton button; // если target == Button
public DpadDir dpadDirection; // если target == Dpad
}
public enum TargetTarget { Button, Dpad }
public enum DpadDir { Up, Down, Left, Right }
private void Awake()
{
EnsureVirtualGamepad();
TryAddDefaultBindingsIfEmpty();
}
private void OnEnable() => EnsureVirtualGamepad();
private void OnDisable()
{
// Обычно устройство не удаляем, чтобы не ломать PlayerInput при живых сценах.
// Если нужно строго чистить — раскомментируй:
// if (_virtualPad != null) { InputSystem.RemoveDevice(_virtualPad); _virtualPad = null; _deviceCreated = false; }
}
private void Update()
{
if (_virtualPad == null) return;
_state = default;
// 1) По действиям
for (int i = 0; i < actionBindings.Count; i++)
{
var b = actionBindings[i];
bool pressed = useAnyPlayer
? In.GetButtonAnyPlayer(b.action)
: In.GetButtonCurrentPlayer(b.action);
ApplyBinding(ref _state, b.target, b.button, b.dpadDirection, pressed);
}
// 2) По пинам
for (int i = 0; i < pinBindings.Count; i++)
{
var b = pinBindings[i];
bool pressed = In.GetButton(b.pinIndex);
ApplyBinding(ref _state, b.target, b.button, b.dpadDirection, pressed);
}
InputSystem.QueueStateEvent(_virtualPad, _state);
// Обновлять InputSystem вручную не нужно (обновится в цикле Unity)
}
private static void ApplyBinding(ref GamepadState st, TargetTarget target, GamepadButton btn, DpadDir dir, bool pressed)
{
if (!pressed) return;
if (target == TargetTarget.Button)
{
st = st.WithButton(btn, true);
}
else
{
switch (dir)
{
case DpadDir.Up: st = st.WithButton(GamepadButton.DpadUp, true); break;
case DpadDir.Down: st = st.WithButton(GamepadButton.DpadDown, true); break;
case DpadDir.Left: st = st.WithButton(GamepadButton.DpadLeft, true); break;
case DpadDir.Right: st = st.WithButton(GamepadButton.DpadRight, true); break;
}
}
}
private void EnsureVirtualGamepad()
{
if (_deviceCreated && _virtualPad != null) return;
// ищем уже созданный «COM Bridge», чтобы не дублировать
foreach (var dev in InputSystem.devices)
{
if (dev is Gamepad gp && gp.description.product == "COM Bridge Gamepad")
{
_virtualPad = gp;
_deviceCreated = true;
return;
}
}
var desc = new InputDeviceDescription
{
interfaceName = "Virtual",
deviceClass = "Gamepad",
product = "COM Bridge Gamepad",
manufacturer = "YourCompany"
};
_virtualPad = (Gamepad)InputSystem.AddDevice(desc);
_deviceCreated = true;
if (logCreateDevice) Debug.Log("[InputBridge] Виртуальный Gamepad создан: " + _virtualPad);
}
private void TryAddDefaultBindingsIfEmpty()
{
// Если пусто — добавим базовый маппинг стрелок на D-Pad.
if (actionBindings.Count == 0)
{
// Переименуй ниже на свои реальные имена в enum PlayerAction, если отличаются.
TryAddActionBinding(PlayerAction.up, TargetTarget.Dpad, GamepadButton.North, DpadDir.Up);
TryAddActionBinding(PlayerAction.down, TargetTarget.Dpad, GamepadButton.South, DpadDir.Down);
TryAddActionBinding(PlayerAction.left, TargetTarget.Dpad, GamepadButton.West, DpadDir.Left);
TryAddActionBinding(PlayerAction.right, TargetTarget.Dpad, GamepadButton.East, DpadDir.Right);
// Часто удобно:
// Confirm -> South (A), Back/Cancel -> East (B)
SafeTry(() => actionBindings.Add(new ActionBinding { action = PlayerAction.action, target = TargetTarget.Button, button = GamepadButton.South, dpadDirection = DpadDir.Up }));
SafeTry(() => actionBindings.Add(new ActionBinding { action = PlayerAction.extra, target = TargetTarget.Button, button = GamepadButton.East, dpadDirection = DpadDir.Up }));
}
}
private void TryAddActionBinding(PlayerAction action, TargetTarget target, GamepadButton btn, DpadDir dir)
{
SafeTry(() => actionBindings.Add(new ActionBinding { action = action, target = target, button = btn, dpadDirection = dir }));
}
private static void SafeTry(Action a)
{
try { a(); } catch { /* если в твоём enum нет таких значений — просто пропустим */ }
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 10f5cf4411135b245baf35e2705982c7

View File

@ -17,6 +17,11 @@ namespace RR.Game2D.Core.Managers
// AudioManager instance
public AudioManager Audio {get; private set;}
// Globals
[Header("Globals")]
private GameObject globals;
[SerializeField] private string globalsPrefabResourcePath = "Prefabs/Globals";
[Header("Пауза")]
public bool IsPaused { get; private set; }
@ -55,12 +60,22 @@ namespace RR.Game2D.Core.Managers
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Bootstrap()
{
GameObject go;
if (Instance == null)
{
var go = new GameObject(nameof(GameManager));
go = new GameObject(nameof(GameManager));
Instance = go.AddComponent<GameManager>();
DontDestroyOnLoad(go);
}
// else
// {
// go = Instance.gameObject;
// }
//
// go.AddComponent<ComWrapper>();
// go.AddComponent<In>();
// go.AddComponent<PrizeSystem>();
}
private void Awake()
@ -79,7 +94,19 @@ namespace RR.Game2D.Core.Managers
Audio = gameObject.AddComponent<AudioManager>();
Audio.Initialize();
}
gameStartTime = Time.time;
if (globals == null)
{
GameObject prefab = Resources.Load<GameObject>(globalsPrefabResourcePath);
if (prefab != null)
{
globals = Instantiate(prefab);
DontDestroyOnLoad(globals);
}
}
gameStartTime = Time.unscaledTime;
Debug.Log($"{gameObject.name}: Start time = {gameStartTime}");
if (SceneManager.GetActiveScene().name != "MainMenu") _shouldSpawnPlayer = true;
}
@ -159,7 +186,7 @@ namespace RR.Game2D.Core.Managers
// LoadScene("MainMenu", false);
// Lives = maxLives;
// LivesChanged?.Invoke(Lives);
float totalTime = Time.time - gameStartTime;
float totalTime = Time.unscaledTime - gameStartTime;
GameOverEvent?.Invoke(totalTime);
}
// --
@ -169,7 +196,7 @@ namespace RR.Game2D.Core.Managers
// LoadScene("MainMenu", false);
// Lives = maxLives;
// LivesChanged?.Invoke(Lives);
float totalTime = Time.time - gameStartTime;
float totalTime = Time.unscaledTime - gameStartTime;
GameWonEvent?.Invoke(totalTime);
}

View File

@ -0,0 +1,28 @@
using System;
using UnityEngine;
using UnityEngine.InputSystem;
namespace RR.Common.Managers
{
public class GlobalsManager : MonoBehaviour
{
private ComWrapper _comWrapper;
private In _in;
private PrizeSystem _prizeSystem;
private void Awake()
{
_comWrapper = GetComponent<ComWrapper>();
_in = GetComponent<In>();
_prizeSystem = GetComponent<PrizeSystem>();
if (_comWrapper == null) gameObject.AddComponent<ComWrapper>();
if (_in == null) gameObject.AddComponent<In>();
if (_prizeSystem == null) gameObject.AddComponent<PrizeSystem>();
_comWrapper.Initialize();
_in.Initialize();
_prizeSystem.Initialize();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e679be5faf94f304d8251931f02c036a

View File

@ -19,7 +19,7 @@ public class COMinput : InputSource
//Свойство для определения текущего игрока
//Должно возвращать 1 или 2
//Используется для получения состояния кнопок с пометкой ...CurrentPlayer
private int currentPlayer = 1;//ПЕРЕОПРЕДЕЛИТЕ ОПРЕДЕЛЕНИЕ ТЕКУЩЕГО ИГРОКА ПОД СВОЮ СИСТЕМУ.
private int currentPlayer => 1;//ПЕРЕОПРЕДЕЛИТЕ ОПРЕДЕЛЕНИЕ ТЕКУЩЕГО ИГРОКА ПОД СВОЮ СИСТЕМУ.
private GameManager gm;//я получаю кто сейчас ходит через этого менеджера. Если у вас другое, допишите.
public override bool Initialize()
@ -29,12 +29,12 @@ public class COMinput : InputSource
gm = GameManager.Instance;
//ОБЯЗАТЕЛЬНЫЙ БЛОК
ComWrapper.onInputRecieved.AddListener(UpdateInputState);
ComWrapper.OnInputReceived.AddListener(UpdateInputState);
}
catch (Exception e)
{
Debug.Log($"Что то в COMInput {e.ToString()}");
Debug.Log($"Что то в COMinput {e.ToString()}");
return false;
}
return true;
@ -227,7 +227,7 @@ public class COMinput : InputSource
}
if (input[^1] == POSITIVE) PlayerPrefs.SetInt("PrizeGivenBuffer", 1); //пишем в буфер чтобы между кадрами и порядком вызова не проебать
Debug.Log("Инпуты: " + string.Join("", buttonState));//можно вырезать
// DebugWindow.Message("Инпуты: " + string.Join("", buttonState));//можно вырезать
}
// Потребление "Нажатия"/"Отжатия". Возвращает что там было и чистит флаг из буфера

View File

@ -13,17 +13,17 @@ public class ComWrapper : MonoBehaviour
[SerializeField] bool enablePrizeChecking = false; // Если хопер с проверкой наличия приза ставим true
public static UnityEvent<int> onCoinAdded;
public static UnityEvent<int> onCoinRemoved;
public static UnityEvent<string> onInputRecieved;
public static UnityEvent<int> OnCoinAdded;
public static UnityEvent<int> OnCoinRemoved;
public static UnityEvent<string> OnInputReceived;
#region Приватные поля
private const string REQUEST_INPUT = "91";
private const string DEFAULT_INPUT = "INPUT1111111111111111";
private const string LIGHTSIGNAL_PREFIX = "80";
private static int h;//идентификатор хэндла
private static byte[] buf = new byte[1024]; //Байт-буфер куда будут приходить данные с порта
private static int h; // идентификатор хэндла
private static byte[] buf = new byte[1024]; // Байт-буфер куда будут приходить данные с порта
private static int CreditsCount;
private string inputString = DEFAULT_INPUT;
@ -45,8 +45,9 @@ public class ComWrapper : MonoBehaviour
public void Initialize()
{
//Создаем ивенты
onCoinAdded = new UnityEvent<int>();
onCoinRemoved = new UnityEvent<int>();
OnCoinAdded = new UnityEvent<int>();
OnCoinRemoved = new UnityEvent<int>();
OnInputReceived = new();
//Начальная настройка
if (!saveMoneyBetweenSessions) PlayerPrefs.SetInt("CoinsCount", 0);
@ -54,7 +55,7 @@ public class ComWrapper : MonoBehaviour
initPort(); //вот это важный метод который собственно порт открывает.
//Каждые 5 сек запрашиваем инпуты у платы. Надо потому что при заходе в игру с пинов еще не пришла инфа
if (enablePrizeChecking) InvokeRepeating("requestInputs", 0, 5);
if (enablePrizeChecking) InvokeRepeating(nameof(requestInputs), 0, 5);
}
/// <summary>
@ -69,7 +70,7 @@ public class ComWrapper : MonoBehaviour
{
CreditsCount++;
PlayerPrefs.SetInt("CoinsCount", CreditsCount);
onCoinAdded?.Invoke(CreditsCount);
OnCoinAdded?.Invoke(CreditsCount);
}
/// <summary>
@ -85,11 +86,15 @@ public class ComWrapper : MonoBehaviour
{
try
{
int w = ComNativeWrapper.Serial_WriteStringUTF8(h, message, 1); //w-количество записаных символов в порт. можно обработать
int w = ComNativeWrapper.Serial_WriteStringUTF8(h, message,
1); //w-количество записаных символов в порт. можно обработать
//Debug.Log("Wrote: " + w);
}
catch { Debug.Log("Ошибка отправки строкового сигнала."); }
catch
{
// DebugWindow.Message("Ошибка отправки строкового сигнала.");
}
}
/// <summary>
@ -108,21 +113,24 @@ public class ComWrapper : MonoBehaviour
Send(signal);
//ВОТЭТОТ МЕТОД ПОД СВОИ ПОДСВЕТКИ НАДО ПОДГОНЯТЬ
string getLightString(LightMode lightMode) =>
string getLightString(LightMode mode) =>
lightMode switch
mode switch
{
LightMode.Idle => "106",
LightMode.Orange => "107",
LightMode.Blue => "108",
LightMode.Win => "109",
LightMode.Lose => "110",
LightMode.Prize => "111",
_ => "106"
LightMode.Idle => "106",
LightMode.Orange => "107",
LightMode.Blue => "108",
LightMode.Win => "109",
LightMode.Lose => "110",
LightMode.Prize => "111",
_ => "106"
};
}
catch
{
// DebugWindow.Message("Ошибка отправки светового сигнала.");
}
catch { Debug.Log("Ошибка отправки светового сигнала."); }
}
/// <summary>
@ -142,7 +150,8 @@ public class ComWrapper : MonoBehaviour
/// </remarks>
public static bool Pay()
{
//блок проверки оплаты
// блок проверки оплаты
// TODO: Сделать свою систему для проверки оплаты и бесплатной игры
// if (SettingsManager.instance.GetSettingValue("Бесплатная игра") == "Вкл")
// {
// //Счетчики пробега
@ -161,7 +170,7 @@ public class ComWrapper : MonoBehaviour
PlayerPrefs.SetInt(PrizeSystem.key_starts, PlayerPrefs.GetInt(PrizeSystem.key_starts) + 1);
PlayerPrefs.SetInt(PrizeSystem.key_startsNul, PlayerPrefs.GetInt(PrizeSystem.key_startsNul) + 1);
onCoinRemoved?.Invoke(CreditsCount);
OnCoinRemoved?.Invoke(CreditsCount);
return true;
}
@ -243,10 +252,10 @@ public class ComWrapper : MonoBehaviour
string comInput = ReadBufferLine();
if (comInput != "")
{
Debug.Log("COM: " + comInput);
// DebugWindow.Message("COM: " + comInput);
if (comInput == "COIN") AddCredit();
if (comInput.StartsWith("INPUT")) onInputRecieved?.Invoke(comInput.Substring(5)); //инвокаю сразу без префикса "INPUT"
if (comInput.StartsWith("INPUT")) OnInputReceived?.Invoke(comInput.Substring(5)); //инвокаю сразу без префикса "INPUT"
}
}
#endregion

View File

@ -56,12 +56,11 @@ public class PrizeSystem : MonoBehaviour
public static void GivePrize()
{
// bool settingEnabled = SettingsManager.instance.GetSettingValue("Выдача призов при игре с ботом") == "Выдавать";
bool settingEnabled = true;
if (!settingEnabled) { Debug.Log("Выдача приза отключена в настройках"); return; }
if (prizing) { Debug.Log("Уже идет выдача приза. Не спамь кнопку."); return; }
Debug.Log("Выдаю приз");
//
// if (!settingEnabled) { DebugWindow.Message("Выдача приза отключена в настройках"); return; }
// if (prizing) { DebugWindow.Message("Уже идет выдача приза. Не спамь кнопку."); return; }
//
// DebugWindow.Message("Выдаю приз");
if (prizeCoroutine != null) instance.StopCoroutine(prizeCoroutine);
prizeCoroutine = instance.StartCoroutine(instance.Prize());
}
@ -71,7 +70,7 @@ public class PrizeSystem : MonoBehaviour
private IEnumerator Prize()
{
prizing = true;
Debug.Log("Начинаю выдачу");
// DebugWindow.Message("Начинаю выдачу");
float timeout = 10; //сек
ComWrapper.Send("301");//включаем мотор
@ -94,7 +93,7 @@ public class PrizeSystem : MonoBehaviour
//Выключаем мотор
ComWrapper.Send("300");
Debug.Log("Закончил. Успех: " + success);
// DebugWindow.Message("Закончил. Успех: " + success);
prizing = false;
if (!success) AudioManager.Instance.PlaySfx(prizeErrorSound);

View File

@ -1,5 +1,13 @@
using RR.Game2D.Core.Managers;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using RR.Game2D.Core.Managers;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
/// <summary>
/// Реализация системы ввода с клавиатуры для тестирования и разработки.
@ -16,8 +24,264 @@ public class KeyboardInput : InputSource
{
private int currentPlayer = 1;//ПЕРЕОПРЕДЕЛИТЕ ОПРЕДЕЛЕНИЕ ТЕКУЩЕГО ИГРОКА ПОД СВОЮ СИСТЕМУ.
private GameManager gm;//я получаю кто сейчас ходит через этого менеджера. Если у вас другое, допишите.
// Кэш Key -> KeyControl + ссылка на то, для какой клавиатуры он построен
private static readonly Dictionary<Key, KeyControl> _keyCache = new();
private static Keyboard _cachedKeyboard;
private static void EnsureKeyboardCache()
{
var kb = Keyboard.current;
if (kb == null)
{
_keyCache.Clear();
_cachedKeyboard = null;
return;
}
// Если клавиатура сменилась (или кэш пуст) — перестроить
if (_cachedKeyboard == kb && _keyCache.Count != 0) return;
_cachedKeyboard = kb;
_keyCache.Clear();
var keys = kb.allKeys;
if (keys.Count <= 0) return;
foreach (var kc in keys.Where(kc => kc != null))
{
_keyCache[kc.keyCode] = kc;
}
}
private static KeyControl GetKeyControl(Key key)
{
if (key == Key.None) return null;
// Можем спокойно вызываться даже в самом раннем кадре
EnsureKeyboardCache();
return _cachedKeyboard == null ? null : _keyCache.GetValueOrDefault(key);
}
// --- адаптер: из твоего старого KeyCode -> в новый Key ---
private static Key ToNewKey(UnityEngine.KeyCode old)
{
// Пытаемся по имени (у многих совпадают)
if (Enum.TryParse<Key>(old.ToString(), true, out var k)) return k;
// Несовпадающие названия — руками:
return old switch
{
KeyCode.Return => Key.Enter,
KeyCode.KeypadEnter => Key.NumpadEnter,
KeyCode.LeftControl => Key.LeftCtrl,
KeyCode.RightControl => Key.RightCtrl,
KeyCode.LeftShift => Key.LeftShift,
KeyCode.RightShift => Key.RightShift,
KeyCode.LeftAlt => Key.LeftAlt,
KeyCode.RightAlt => Key.RightAlt,
KeyCode.LeftCommand => Key.LeftMeta,
KeyCode.RightCommand => Key.RightMeta,
KeyCode.None => Key.None,
_ => Key.None // если нужен редкий кей — добавь сюда
};
}
// Удобные обёртки
private static bool IsPressed(Key k)
{
if (k == Key.None) return false;
var c = GetKeyControl(k);
return c is { isPressed: true };
}
private static bool WasPressedThisFrame(Key k)
{
if (k == Key.None) return false;
var c = GetKeyControl(k);
return c is { wasPressedThisFrame: true };
}
private static bool WasReleasedThisFrame(Key k)
{
if (k == Key.None) return false;
var c = GetKeyControl(k);
return c is { wasReleasedThisFrame: true };
}
/// Проверяет состояние кнопки по её физическому пину через клавиатуру (Input System)
public override bool GetButton(ButtonPinMapping button) => IsPressed(ToNewKey(getKeyCode(button)));
/// Проверяет нажатие кнопки по пину в текущем кадре (Input System)
public override bool GetButtonDown(ButtonPinMapping button) => WasPressedThisFrame(ToNewKey(getKeyCode(button)));
/// Проверяет отпускание кнопки по пину в текущем кадре (Input System)
public override bool GetButtonUp(ButtonPinMapping button) => WasReleasedThisFrame(ToNewKey(getKeyCode(button)));
//----------------------------------------------------------------------------------
/// По числовому индексу пина
public override bool GetButton(int pinIndex) => IsPressed(ToNewKey(getKeyCode(pinIndex)));
public override bool GetButtonDown(int pinIndex) => WasPressedThisFrame(ToNewKey(getKeyCode(pinIndex)));
public override bool GetButtonUp(int pinIndex) => WasReleasedThisFrame(ToNewKey(getKeyCode(pinIndex)));
//----------------------------------------------------------------------------------
/// Действия текущего игрока (для клавиатуры — это по сути игрок 1)
public override bool GetButtonCurrentPlayer(PlayerAction button) => GetButton(GetButtonForCurrentPlayer(button));
public override bool GetButtonDownCurrentPlayer(PlayerAction button) => GetButtonDown(GetButtonForCurrentPlayer(button));
public override bool GetButtonUpCurrentPlayer(PlayerAction button) => GetButtonUp(GetButtonForCurrentPlayer(button));
//----------------------------------------------------------------------------------
/// Любой игрок (для клавиатуры — эквивалент текущего)
public override bool GetButtonAnyPlayer(PlayerAction button) => GetButtonCurrentPlayer(button);
public override bool GetButtonDownAnyPlayer(PlayerAction button) => GetButtonDownCurrentPlayer(button);
public override bool GetButtonUpAnyPlayer(PlayerAction button) => GetButtonUpCurrentPlayer(button);
//----------------------------------------------------------------------------------
/// <summary>
/// Инициализирует клавиатурный ввод. Всегда возвращает true так как клавиатура всегда доступна.
/// </summary>
/// <returns>Всегда true</returns>
public override bool Initialize()
{
gm = GameManager.Instance;
return true;
}
// ================================================================================
// ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ
// ================================================================================
/// <summary>
/// Определяет кнопку текущего игрока для указанного действия.
/// Для клавиатуры всегда возвращает кнопку первого игрока.
/// </summary>
private ButtonPinMapping GetButtonForCurrentPlayer(PlayerAction button)
{
var buttons = _buttonByAction(button);
return currentPlayer == 1 ? buttons.player1button : buttons.player2button;
}
/// <summary>
/// Проверяет действие для обоих игроков используя указанную функцию проверки.
/// </summary>
private bool CheckBothPlayers(PlayerAction action, System.Func<ButtonPinMapping, bool> buttonFunc)
{
var buttons = _buttonByAction(action);
return buttonFunc(buttons.player1button) || buttonFunc(buttons.player2button);
}
/// <summary>
/// Возвращает соответствие между игровыми действиями и физическими кнопками игроков.
/// </summary>
private (ButtonPinMapping player1button, ButtonPinMapping player2button) _buttonByAction(PlayerAction playerAction) =>
playerAction switch
{
PlayerAction.up => (ButtonPinMapping.up1, ButtonPinMapping.up2),
PlayerAction.down => (ButtonPinMapping.down1, ButtonPinMapping.down2),
PlayerAction.left => (ButtonPinMapping.left1, ButtonPinMapping.left2),
PlayerAction.right => (ButtonPinMapping.right1, ButtonPinMapping.right2),
PlayerAction.action => (ButtonPinMapping.action1, ButtonPinMapping.action2),
PlayerAction.extra => (ButtonPinMapping.extra, ButtonPinMapping.extra),
_ => throw new System.ArgumentException($"Unknown player action: {playerAction}")
};
/// <summary>
/// Преобразует физический пин в соответствующую клавишу клавиатуры.
/// </summary>
private KeyCode getKeyCode(ButtonPinMapping button)
{
return button switch
{
ButtonPinMapping.up1 => KeyCode.W,
ButtonPinMapping.right1 => KeyCode.D,
ButtonPinMapping.down1 => KeyCode.S,
ButtonPinMapping.left1 => KeyCode.A,
ButtonPinMapping.action1 => KeyCode.Space,
ButtonPinMapping.up2 => KeyCode.UpArrow,
ButtonPinMapping.right2 => KeyCode.RightArrow,
ButtonPinMapping.down2 => KeyCode.DownArrow,
ButtonPinMapping.left2 => KeyCode.LeftArrow,
ButtonPinMapping.action2 => KeyCode.RightControl,
ButtonPinMapping.startOnePlayer => KeyCode.Alpha1,
ButtonPinMapping.startTwoPlayers => KeyCode.Alpha2,
ButtonPinMapping.secret => KeyCode.F5,
ButtonPinMapping.extra => KeyCode.Alpha3,
ButtonPinMapping.hasPrize => KeyCode.O,
ButtonPinMapping.prizeGiven => KeyCode.P,
_ => KeyCode.None,
};
}
/// <summary>
/// Преобразует числовой индекс пина в соответствующую клавишу клавиатуры.
/// Используется для методов с прямым доступом по индексу.
/// </summary>
private KeyCode getKeyCode(int pinIndex)
{
return pinIndex switch
{
0 => KeyCode.W, // up1
1 => KeyCode.D, // right1
2 => KeyCode.S, // down1
3 => KeyCode.A, // left1
4 => KeyCode.Space, // action1
5 => KeyCode.UpArrow, // up2
6 => KeyCode.RightArrow, // right2
7 => KeyCode.DownArrow, // down2
8 => KeyCode.LeftArrow, // left2
9 => KeyCode.RightControl, // action2
10 => KeyCode.Alpha1, // startOnePlayer
11 => KeyCode.Alpha2, // startTwoPlayers
12 => KeyCode.F5, // secret
13 => KeyCode.Alpha3, // extra
14 => KeyCode.O, // hasPrize
15 => KeyCode.P, // prizeGiven
_ => KeyCode.None, // невалидный индекс
};
}
}
#else
/// <summary>
/// Реализация системы ввода с клавиатуры для тестирования и разработки.
/// Эмулирует работу периферийной платы через стандартные клавиши клавиатуры.
/// </summary>
/// <remarks>
/// Соответствие клавиш и пинов:
/// - Игрок 1: WASD + Space
/// - Игрок 2: Стрелки + RightControl
/// - Служебные: 1, 2, 3, F5
/// - Датчики хопера: O, P
/// </remarks>
public class KeyboardInput : InputSource
{
private int currentPlayer = 1;//ПЕРЕОПРЕДЕЛИТЕ ОПРЕДЕЛЕНИЕ ТЕКУЩЕГО ИГРОКА ПОД СВОЮ СИСТЕМУ.
private GameManager gm;//я получаю кто сейчас ходит через этого менеджера. Если у вас другое, допишите.
/// <summary>Проверяет состояние кнопки по её физическому пину через клавиатуру</summary>
public override bool GetButton(ButtonPinMapping button) => Input.GetKey(getKeyCode(button));
@ -173,4 +437,7 @@ public class KeyboardInput : InputSource
_ => KeyCode.None, // невалидный индекс
};
}
}
}
#endif

View File

@ -49,6 +49,7 @@ namespace RR.Common.UI
// Изначально скрыто
SetVisible(winPanel, false, true);
SetVisible(losePanel, false, true);
GetComponent<Image>().color = new Color(0, 0,0, 0);
}
private void OnMainMenuClicked()
@ -64,6 +65,7 @@ namespace RR.Common.UI
{
if(winPanel.interactable) SetVisible(winPanel, false);
if(losePanel.interactable) SetVisible(losePanel, false);
GetComponent<Image>().color = new Color(0, 0,0, 0);
BannerDismissed?.Invoke();
}
@ -72,6 +74,7 @@ namespace RR.Common.UI
WinBannerShown?.Invoke(gameTime);
GameManager.Instance.SetPause(true);
winText.text = $"Время игры: {GameEndUIController.FormatTime(gameTime)}";
GetComponent<Image>().color = new Color(0, 0,0, 100f/255f);
SetVisible(winPanel, true);
}
@ -79,6 +82,7 @@ namespace RR.Common.UI
{
LoseBannerShown?.Invoke(gameTime);
GameManager.Instance.SetPause(true);
GetComponent<Image>().color = new Color(0, 0,0, 100f/255f);
SetVisible(losePanel, true);
}
@ -121,9 +125,9 @@ namespace RR.Common.UI
public static string FormatTime(float gameTime)
{
TimeSpan interval = TimeSpan.FromMilliseconds(gameTime);
TimeSpan interval = TimeSpan.FromSeconds(gameTime);
return interval.ToString(@"mm\:ss\.fff");
return interval.ToString(@"mm\:ss");
}
}
}

View File

@ -209,6 +209,9 @@
},
{
"m_Id": "42bc724a5c47474aa5f3307d6a20f621"
},
{
"m_Id": "ad8b71a2bbaa4decb561f019a08e8626"
}
],
"m_GroupDatas": [
@ -300,35 +303,7 @@
},
"m_InputSlot": {
"m_Node": {
"m_Id": "7532ac6874ca4862bc00d22c83764a03"
},
"m_SlotId": 2
}
},
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "2557d04087964c2984053e91fb28be73"
},
"m_SlotId": 2
},
"m_InputSlot": {
"m_Node": {
"m_Id": "a82fe793d3ea49e79295b0692ecefdb2"
},
"m_SlotId": 2
}
},
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "2557d04087964c2984053e91fb28be73"
},
"m_SlotId": 2
},
"m_InputSlot": {
"m_Node": {
"m_Id": "b2cc0d067ee24641a376219e21246f2c"
"m_Id": "ad8b71a2bbaa4decb561f019a08e8626"
},
"m_SlotId": 0
}
@ -739,6 +714,48 @@
"m_SlotId": 1
}
},
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "ad8b71a2bbaa4decb561f019a08e8626"
},
"m_SlotId": 1
},
"m_InputSlot": {
"m_Node": {
"m_Id": "7532ac6874ca4862bc00d22c83764a03"
},
"m_SlotId": 2
}
},
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "ad8b71a2bbaa4decb561f019a08e8626"
},
"m_SlotId": 1
},
"m_InputSlot": {
"m_Node": {
"m_Id": "a82fe793d3ea49e79295b0692ecefdb2"
},
"m_SlotId": 2
}
},
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "ad8b71a2bbaa4decb561f019a08e8626"
},
"m_SlotId": 1
},
"m_InputSlot": {
"m_Node": {
"m_Id": "b2cc0d067ee24641a376219e21246f2c"
},
"m_SlotId": 0
}
},
{
"m_OutputSlot": {
"m_Node": {
@ -1824,10 +1841,10 @@
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": -794.9998779296875,
"y": 337.0,
"width": 207.99993896484376,
"height": 301.99993896484377
"x": -1032.0001220703125,
"y": 336.0000305175781,
"width": 208.00006103515626,
"height": 302.0000305175781
}
},
"m_Slots": [
@ -2055,8 +2072,8 @@
"m_ObjectId": "32c7ee6507bc42d19d23630a9cb644c5",
"m_Title": "Outline",
"m_Position": {
"x": -1029.0,
"y": 278.0
"x": -1057.0,
"y": 277.0
}
}
@ -4669,6 +4686,44 @@
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.AbsoluteNode",
"m_ObjectId": "ad8b71a2bbaa4decb561f019a08e8626",
"m_Group": {
"m_Id": "32c7ee6507bc42d19d23630a9cb644c5"
},
"m_Name": "Absolute",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": -795.0000610351563,
"y": 336.0000305175781,
"width": 208.0,
"height": 278.0000305175781
}
},
"m_Slots": [
{
"m_Id": "b628e1bd46ce4903a81b5b544e61e207"
},
{
"m_Id": "f2e8f9dba0f14495a144597ffa367e09"
}
],
"synonyms": [
"positive"
],
"m_Precision": 0,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot",
@ -4824,6 +4879,30 @@
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot",
"m_ObjectId": "b628e1bd46ce4903a81b5b544e61e207",
"m_Id": 0,
"m_DisplayName": "In",
"m_SlotType": 0,
"m_Hidden": false,
"m_ShaderOutputName": "In",
"m_StageCapability": 3,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot",
@ -6580,6 +6659,30 @@
"m_Labels": []
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot",
"m_ObjectId": "f2e8f9dba0f14495a144597ffa367e09",
"m_Id": 1,
"m_DisplayName": "Out",
"m_SlotType": 1,
"m_Hidden": false,
"m_ShaderOutputName": "Out",
"m_StageCapability": 3,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
{
"m_SGVersion": 1,
"m_Type": "UnityEditor.ShaderGraph.VoronoiNode",

31545
Assets/_Recovery/0 (3).unity Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e4d1644189612aa4990d5054a32ac6f9
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -598,7 +598,7 @@ PlayerSettings:
platformArchitecture: {}
scriptingBackend:
Android: 1
Standalone: 0
Standalone: 1
il2cppCompilerConfiguration: {}
il2cppCodeGeneration: {}
il2cppStacktraceInformation: {}