feat: add Unity project (Assets, ProjectSettings)
This commit is contained in:
1
game
1
game
Submodule game deleted from c30fe2cbcf
15
game/Assets/Bouncy.physicMaterial
Normal file
15
game/Assets/Bouncy.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Bouncy
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 0.6
|
||||||
|
m_StaticFriction: 0.6
|
||||||
|
m_Bounciness: 0.74
|
||||||
|
m_FrictionCombine: 0
|
||||||
|
m_BounceCombine: 0
|
||||||
8
game/Assets/Bouncy.physicMaterial.meta
Normal file
8
game/Assets/Bouncy.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 38ed95051af515848a7513429d4f0413
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 13400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/GelBleu.physicMaterial
Normal file
15
game/Assets/GelBleu.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: GelBleu
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 0
|
||||||
|
m_StaticFriction: 0
|
||||||
|
m_Bounciness: 1
|
||||||
|
m_FrictionCombine: 1
|
||||||
|
m_BounceCombine: 3
|
||||||
8
game/Assets/GelBleu.physicMaterial.meta
Normal file
8
game/Assets/GelBleu.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 458e6466a22c1204cb2e77d378867d7b
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 13400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/GelOrange.physicMaterial
Normal file
15
game/Assets/GelOrange.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: GelOrange
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 0.6
|
||||||
|
m_StaticFriction: 0.6
|
||||||
|
m_Bounciness: 0.74
|
||||||
|
m_FrictionCombine: 0
|
||||||
|
m_BounceCombine: 0
|
||||||
8
game/Assets/GelOrange.physicMaterial.meta
Normal file
8
game/Assets/GelOrange.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 61512ca9473715648874e2d1f555c50f
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 13400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/GelViolet.physicMaterial
Normal file
15
game/Assets/GelViolet.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: GelViolet
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 1
|
||||||
|
m_StaticFriction: 1
|
||||||
|
m_Bounciness: 0
|
||||||
|
m_FrictionCombine: 3
|
||||||
|
m_BounceCombine: 0
|
||||||
8
game/Assets/GelViolet.physicMaterial.meta
Normal file
8
game/Assets/GelViolet.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 86c56232f118b4c4caa7fc9d124fc344
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
702
game/Assets/InputSystem_Actions.inputactions
Normal file
702
game/Assets/InputSystem_Actions.inputactions
Normal file
@@ -0,0 +1,702 @@
|
|||||||
|
{
|
||||||
|
"name": "InputSystem_Actions",
|
||||||
|
"maps": [
|
||||||
|
{
|
||||||
|
"name": "Player",
|
||||||
|
"id": "df70fa95-8a34-4494-b137-73ab6b9c7d37",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "forward",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "63f99bf9-5435-425c-b5b8-5b81453bb4b9",
|
||||||
|
"expectedControlType": "",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "Hold",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "backwards",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "f718adfe-dddf-414d-b3c6-b55287209179",
|
||||||
|
"expectedControlType": "",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "46eec8c5-1829-4d01-9711-71a9a3abab38",
|
||||||
|
"expectedControlType": "",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "e2764bdd-11f1-4c3b-a8a0-76b63dae881d",
|
||||||
|
"expectedControlType": "",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "jump",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "8553c4e4-05ac-4af4-a480-0c7bbda03480",
|
||||||
|
"expectedControlType": "",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bindings": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "d97e4d20-426c-48b9-a737-fa161b0582aa",
|
||||||
|
"path": "<Keyboard>/downArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "backwards",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "bb1a993d-9c48-41a8-a20f-0d49a4da1bda",
|
||||||
|
"path": "<Keyboard>/leftArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "left",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "dc468d7c-b51c-4360-b5d2-e3511e49a181",
|
||||||
|
"path": "<Keyboard>/rightArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "right",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "6d27d55a-8853-4557-9a9b-db4e15c19b80",
|
||||||
|
"path": "<Mouse>/leftButton",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "jump",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "a1b2c3d4-5678-9abc-def0-123456789abc",
|
||||||
|
"path": "<Keyboard>/space",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "jump",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "8b7b94be-e23e-4648-827e-f0ec13a5e26c",
|
||||||
|
"path": "<Keyboard>/upArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "forward",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "UI",
|
||||||
|
"id": "272f6d14-89ba-496f-b7ff-215263d3219f",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Navigate",
|
||||||
|
"type": "PassThrough",
|
||||||
|
"id": "c95b2375-e6d9-4b88-9c4c-c5e76515df4b",
|
||||||
|
"expectedControlType": "Vector2",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Submit",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "7607c7b6-cd76-4816-beef-bd0341cfe950",
|
||||||
|
"expectedControlType": "Button",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Cancel",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "15cef263-9014-4fd5-94d9-4e4a6234a6ef",
|
||||||
|
"expectedControlType": "Button",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Point",
|
||||||
|
"type": "PassThrough",
|
||||||
|
"id": "32b35790-4ed0-4e9a-aa41-69ac6d629449",
|
||||||
|
"expectedControlType": "Vector2",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Click",
|
||||||
|
"type": "PassThrough",
|
||||||
|
"id": "3c7022bf-7922-4f7c-a998-c437916075ad",
|
||||||
|
"expectedControlType": "Button",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RightClick",
|
||||||
|
"type": "PassThrough",
|
||||||
|
"id": "44b200b1-1557-4083-816c-b22cbdf77ddf",
|
||||||
|
"expectedControlType": "Button",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "MiddleClick",
|
||||||
|
"type": "PassThrough",
|
||||||
|
"id": "dad70c86-b58c-4b17-88ad-f5e53adf419e",
|
||||||
|
"expectedControlType": "Button",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ScrollWheel",
|
||||||
|
"type": "PassThrough",
|
||||||
|
"id": "0489e84a-4833-4c40-bfae-cea84b696689",
|
||||||
|
"expectedControlType": "Vector2",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TrackedDevicePosition",
|
||||||
|
"type": "PassThrough",
|
||||||
|
"id": "24908448-c609-4bc3-a128-ea258674378a",
|
||||||
|
"expectedControlType": "Vector3",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TrackedDeviceOrientation",
|
||||||
|
"type": "PassThrough",
|
||||||
|
"id": "9caa3d8a-6b2f-4e8e-8bad-6ede561bd9be",
|
||||||
|
"expectedControlType": "Quaternion",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bindings": [
|
||||||
|
{
|
||||||
|
"name": "Gamepad",
|
||||||
|
"id": "809f371f-c5e2-4e7a-83a1-d867598f40dd",
|
||||||
|
"path": "2DVector",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": true,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "up",
|
||||||
|
"id": "14a5d6e8-4aaf-4119-a9ef-34b8c2c548bf",
|
||||||
|
"path": "<Gamepad>/leftStick/up",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "up",
|
||||||
|
"id": "9144cbe6-05e1-4687-a6d7-24f99d23dd81",
|
||||||
|
"path": "<Gamepad>/rightStick/up",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "down",
|
||||||
|
"id": "2db08d65-c5fb-421b-983f-c71163608d67",
|
||||||
|
"path": "<Gamepad>/leftStick/down",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "down",
|
||||||
|
"id": "58748904-2ea9-4a80-8579-b500e6a76df8",
|
||||||
|
"path": "<Gamepad>/rightStick/down",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"id": "8ba04515-75aa-45de-966d-393d9bbd1c14",
|
||||||
|
"path": "<Gamepad>/leftStick/left",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"id": "712e721c-bdfb-4b23-a86c-a0d9fcfea921",
|
||||||
|
"path": "<Gamepad>/rightStick/left",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"id": "fcd248ae-a788-4676-a12e-f4d81205600b",
|
||||||
|
"path": "<Gamepad>/leftStick/right",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"id": "1f04d9bc-c50b-41a1-bfcc-afb75475ec20",
|
||||||
|
"path": "<Gamepad>/rightStick/right",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "fb8277d4-c5cd-4663-9dc7-ee3f0b506d90",
|
||||||
|
"path": "<Gamepad>/dpad",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Joystick",
|
||||||
|
"id": "e25d9774-381c-4a61-b47c-7b6b299ad9f9",
|
||||||
|
"path": "2DVector",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": true,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "up",
|
||||||
|
"id": "3db53b26-6601-41be-9887-63ac74e79d19",
|
||||||
|
"path": "<Joystick>/stick/up",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Joystick",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "down",
|
||||||
|
"id": "0cb3e13e-3d90-4178-8ae6-d9c5501d653f",
|
||||||
|
"path": "<Joystick>/stick/down",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Joystick",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"id": "0392d399-f6dd-4c82-8062-c1e9c0d34835",
|
||||||
|
"path": "<Joystick>/stick/left",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Joystick",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"id": "942a66d9-d42f-43d6-8d70-ecb4ba5363bc",
|
||||||
|
"path": "<Joystick>/stick/right",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Joystick",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Keyboard",
|
||||||
|
"id": "ff527021-f211-4c02-933e-5976594c46ed",
|
||||||
|
"path": "2DVector",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": true,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "up",
|
||||||
|
"id": "563fbfdd-0f09-408d-aa75-8642c4f08ef0",
|
||||||
|
"path": "<Keyboard>/w",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "up",
|
||||||
|
"id": "eb480147-c587-4a33-85ed-eb0ab9942c43",
|
||||||
|
"path": "<Keyboard>/upArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "down",
|
||||||
|
"id": "2bf42165-60bc-42ca-8072-8c13ab40239b",
|
||||||
|
"path": "<Keyboard>/s",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "down",
|
||||||
|
"id": "85d264ad-e0a0-4565-b7ff-1a37edde51ac",
|
||||||
|
"path": "<Keyboard>/downArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"id": "74214943-c580-44e4-98eb-ad7eebe17902",
|
||||||
|
"path": "<Keyboard>/a",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"id": "cea9b045-a000-445b-95b8-0c171af70a3b",
|
||||||
|
"path": "<Keyboard>/leftArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"id": "8607c725-d935-4808-84b1-8354e29bab63",
|
||||||
|
"path": "<Keyboard>/d",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"id": "4cda81dc-9edd-4e03-9d7c-a71a14345d0b",
|
||||||
|
"path": "<Keyboard>/rightArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Navigate",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "9e92bb26-7e3b-4ec4-b06b-3c8f8e498ddc",
|
||||||
|
"path": "*/{Submit}",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse;Gamepad;Touch;Joystick;XR",
|
||||||
|
"action": "Submit",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "82627dcc-3b13-4ba9-841d-e4b746d6553e",
|
||||||
|
"path": "*/{Cancel}",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse;Gamepad;Touch;Joystick;XR",
|
||||||
|
"action": "Cancel",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "c52c8e0b-8179-41d3-b8a1-d149033bbe86",
|
||||||
|
"path": "<Mouse>/position",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Point",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "e1394cbc-336e-44ce-9ea8-6007ed6193f7",
|
||||||
|
"path": "<Pen>/position",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "Point",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "5693e57a-238a-46ed-b5ae-e64e6e574302",
|
||||||
|
"path": "<Touchscreen>/touch*/position",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Touch",
|
||||||
|
"action": "Point",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "4faf7dc9-b979-4210-aa8c-e808e1ef89f5",
|
||||||
|
"path": "<Mouse>/leftButton",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Click",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "8d66d5ba-88d7-48e6-b1cd-198bbfef7ace",
|
||||||
|
"path": "<Pen>/tip",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Click",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "47c2a644-3ebc-4dae-a106-589b7ca75b59",
|
||||||
|
"path": "<Touchscreen>/touch*/press",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Touch",
|
||||||
|
"action": "Click",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "bb9e6b34-44bf-4381-ac63-5aa15d19f677",
|
||||||
|
"path": "<XRController>/trigger",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "XR",
|
||||||
|
"action": "Click",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "38c99815-14ea-4617-8627-164d27641299",
|
||||||
|
"path": "<Mouse>/scroll",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "ScrollWheel",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "4c191405-5738-4d4b-a523-c6a301dbf754",
|
||||||
|
"path": "<Mouse>/rightButton",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "RightClick",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "24066f69-da47-44f3-a07e-0015fb02eb2e",
|
||||||
|
"path": "<Mouse>/middleButton",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Keyboard&Mouse",
|
||||||
|
"action": "MiddleClick",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "7236c0d9-6ca3-47cf-a6ee-a97f5b59ea77",
|
||||||
|
"path": "<XRController>/devicePosition",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "XR",
|
||||||
|
"action": "TrackedDevicePosition",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "23e01e3a-f935-4948-8d8b-9bcac77714fb",
|
||||||
|
"path": "<XRController>/deviceRotation",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "XR",
|
||||||
|
"action": "TrackedDeviceOrientation",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"controlSchemes": [
|
||||||
|
{
|
||||||
|
"name": "Keyboard&Mouse",
|
||||||
|
"bindingGroup": "Keyboard&Mouse",
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"devicePath": "<Keyboard>",
|
||||||
|
"isOptional": false,
|
||||||
|
"isOR": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"devicePath": "<Mouse>",
|
||||||
|
"isOptional": false,
|
||||||
|
"isOR": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gamepad",
|
||||||
|
"bindingGroup": "Gamepad",
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"devicePath": "<Gamepad>",
|
||||||
|
"isOptional": false,
|
||||||
|
"isOR": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Touch",
|
||||||
|
"bindingGroup": "Touch",
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"devicePath": "<Touchscreen>",
|
||||||
|
"isOptional": false,
|
||||||
|
"isOR": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Joystick",
|
||||||
|
"bindingGroup": "Joystick",
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"devicePath": "<Joystick>",
|
||||||
|
"isOptional": false,
|
||||||
|
"isOR": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "XR",
|
||||||
|
"bindingGroup": "XR",
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"devicePath": "<XRController>",
|
||||||
|
"isOptional": false,
|
||||||
|
"isOR": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
14
game/Assets/InputSystem_Actions.inputactions.meta
Normal file
14
game/Assets/InputSystem_Actions.inputactions.meta
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 052faaac586de48259a63d0c4782560b
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
|
||||||
|
generateWrapperCode: 0
|
||||||
|
wrapperCodePath:
|
||||||
|
wrapperClassName:
|
||||||
|
wrapperCodeNamespace:
|
||||||
8
game/Assets/Material.meta
Normal file
8
game/Assets/Material.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e369ee33db3904146a6714496a803ee8
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1125
game/Assets/Material/BallShader.shadergraph
Normal file
1125
game/Assets/Material/BallShader.shadergraph
Normal file
File diff suppressed because it is too large
Load Diff
10
game/Assets/Material/BallShader.shadergraph.meta
Normal file
10
game/Assets/Material/BallShader.shadergraph.meta
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9535ecd79e34e1341bfe13a806935455
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
|
||||||
84
game/Assets/Material/Default.mat
Normal file
84
game/Assets/Material/Default.mat
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
%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: Default
|
||||||
|
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Parent: {fileID: 0}
|
||||||
|
m_ModifiedSerializedProperties: 0
|
||||||
|
m_ValidKeywords: []
|
||||||
|
m_InvalidKeywords: []
|
||||||
|
m_LightmapFlags: 4
|
||||||
|
m_EnableInstancingVariants: 0
|
||||||
|
m_DoubleSidedGI: 0
|
||||||
|
m_CustomRenderQueue: -1
|
||||||
|
stringTagMap: {}
|
||||||
|
disabledShaderPasses: []
|
||||||
|
m_LockedProperties:
|
||||||
|
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.5
|
||||||
|
- _DetailNormalMapScale: 1
|
||||||
|
- _DstBlend: 0
|
||||||
|
- _GlossMapScale: 1
|
||||||
|
- _Glossiness: 0.5
|
||||||
|
- _GlossyReflections: 1
|
||||||
|
- _Metallic: 0
|
||||||
|
- _Mode: 0
|
||||||
|
- _OcclusionStrength: 1
|
||||||
|
- _Parallax: 0.02
|
||||||
|
- _SmoothnessTextureChannel: 0
|
||||||
|
- _SpecularHighlights: 1
|
||||||
|
- _SrcBlend: 1
|
||||||
|
- _UVSec: 0
|
||||||
|
- _ZWrite: 1
|
||||||
|
m_Colors:
|
||||||
|
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
m_BuildTextureStacks: []
|
||||||
|
m_AllowLocking: 1
|
||||||
8
game/Assets/Material/Default.mat.meta
Normal file
8
game/Assets/Material/Default.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b2319e64b0c552c4b8fe93deb9f368a6
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 2100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
84
game/Assets/Material/DefaultObjects.mat
Normal file
84
game/Assets/Material/DefaultObjects.mat
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
%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: DefaultObjects
|
||||||
|
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Parent: {fileID: 0}
|
||||||
|
m_ModifiedSerializedProperties: 0
|
||||||
|
m_ValidKeywords: []
|
||||||
|
m_InvalidKeywords: []
|
||||||
|
m_LightmapFlags: 4
|
||||||
|
m_EnableInstancingVariants: 0
|
||||||
|
m_DoubleSidedGI: 0
|
||||||
|
m_CustomRenderQueue: -1
|
||||||
|
stringTagMap: {}
|
||||||
|
disabledShaderPasses: []
|
||||||
|
m_LockedProperties:
|
||||||
|
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.5
|
||||||
|
- _DetailNormalMapScale: 1
|
||||||
|
- _DstBlend: 0
|
||||||
|
- _GlossMapScale: 1
|
||||||
|
- _Glossiness: 0.5
|
||||||
|
- _GlossyReflections: 1
|
||||||
|
- _Metallic: 0
|
||||||
|
- _Mode: 0
|
||||||
|
- _OcclusionStrength: 1
|
||||||
|
- _Parallax: 0.02
|
||||||
|
- _SmoothnessTextureChannel: 0
|
||||||
|
- _SpecularHighlights: 1
|
||||||
|
- _SrcBlend: 1
|
||||||
|
- _UVSec: 0
|
||||||
|
- _ZWrite: 1
|
||||||
|
m_Colors:
|
||||||
|
- _Color: {r: 0.5188679, g: 0.4478907, b: 0.4478907, a: 1}
|
||||||
|
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
m_BuildTextureStacks: []
|
||||||
|
m_AllowLocking: 1
|
||||||
8
game/Assets/Material/DefaultObjects.mat.meta
Normal file
8
game/Assets/Material/DefaultObjects.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6d096827457e4971faa7080575edf3f0
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 2100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1125
game/Assets/Material/GelBleu.shadergraph
Normal file
1125
game/Assets/Material/GelBleu.shadergraph
Normal file
File diff suppressed because it is too large
Load Diff
10
game/Assets/Material/GelBleu.shadergraph.meta
Normal file
10
game/Assets/Material/GelBleu.shadergraph.meta
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0a329f303532f9a43b372c933defe584
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
|
||||||
1125
game/Assets/Material/GelOrange.shadergraph
Normal file
1125
game/Assets/Material/GelOrange.shadergraph
Normal file
File diff suppressed because it is too large
Load Diff
10
game/Assets/Material/GelOrange.shadergraph.meta
Normal file
10
game/Assets/Material/GelOrange.shadergraph.meta
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c52a5eb90c085474582a223ce9475866
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
|
||||||
1520
game/Assets/Material/GelViolet.shadergraph
Normal file
1520
game/Assets/Material/GelViolet.shadergraph
Normal file
File diff suppressed because it is too large
Load Diff
18
game/Assets/Material/GelViolet.shadergraph.meta
Normal file
18
game/Assets/Material/GelViolet.shadergraph.meta
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 06f69bd25ed3dc04e985414e09c3ab04
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
|
||||||
|
useAsTemplate: 0
|
||||||
|
exposeTemplateAsShader: 0
|
||||||
|
template:
|
||||||
|
name:
|
||||||
|
category:
|
||||||
|
description:
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
thumbnail: {instanceID: 0}
|
||||||
84
game/Assets/Material/NPCBallMaterial.mat
Normal file
84
game/Assets/Material/NPCBallMaterial.mat
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
%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: NPCBallMaterial
|
||||||
|
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Parent: {fileID: 0}
|
||||||
|
m_ModifiedSerializedProperties: 0
|
||||||
|
m_ValidKeywords: []
|
||||||
|
m_InvalidKeywords: []
|
||||||
|
m_LightmapFlags: 4
|
||||||
|
m_EnableInstancingVariants: 0
|
||||||
|
m_DoubleSidedGI: 0
|
||||||
|
m_CustomRenderQueue: -1
|
||||||
|
stringTagMap: {}
|
||||||
|
disabledShaderPasses: []
|
||||||
|
m_LockedProperties:
|
||||||
|
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.5
|
||||||
|
- _DetailNormalMapScale: 1
|
||||||
|
- _DstBlend: 0
|
||||||
|
- _GlossMapScale: 1
|
||||||
|
- _Glossiness: 0.5
|
||||||
|
- _GlossyReflections: 1
|
||||||
|
- _Metallic: 0
|
||||||
|
- _Mode: 0
|
||||||
|
- _OcclusionStrength: 1
|
||||||
|
- _Parallax: 0.02
|
||||||
|
- _SmoothnessTextureChannel: 0
|
||||||
|
- _SpecularHighlights: 1
|
||||||
|
- _SrcBlend: 1
|
||||||
|
- _UVSec: 0
|
||||||
|
- _ZWrite: 1
|
||||||
|
m_Colors:
|
||||||
|
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
m_BuildTextureStacks: []
|
||||||
|
m_AllowLocking: 1
|
||||||
8
game/Assets/Material/NPCBallMaterial.mat.meta
Normal file
8
game/Assets/Material/NPCBallMaterial.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c93d9d21a1c0ad441bb61c171c1a68f0
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 2100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
game/Assets/New Terrain.asset
Normal file
BIN
game/Assets/New Terrain.asset
Normal file
Binary file not shown.
8
game/Assets/New Terrain.asset.meta
Normal file
8
game/Assets/New Terrain.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4279fd2269068774e8504ae1bbb18572
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 15600000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
23
game/Assets/NewLayer.terrainlayer
Normal file
23
game/Assets/NewLayer.terrainlayer
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1953259897 &8574412962073106934
|
||||||
|
TerrainLayer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: NewLayer
|
||||||
|
m_DiffuseTexture: {fileID: 10309, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_NormalMapTexture: {fileID: 0}
|
||||||
|
m_MaskMapTexture: {fileID: 0}
|
||||||
|
m_TileSize: {x: 2, y: 2}
|
||||||
|
m_TileOffset: {x: 0, y: 0}
|
||||||
|
m_Specular: {r: 0, g: 0, b: 0, a: 0}
|
||||||
|
m_Metallic: 0
|
||||||
|
m_Smoothness: 0
|
||||||
|
m_NormalScale: 1
|
||||||
|
m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
m_SmoothnessSource: 1
|
||||||
8
game/Assets/NewLayer.terrainlayer.meta
Normal file
8
game/Assets/NewLayer.terrainlayer.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d45e8a9a8d70a6eefa7856e3c62c03cf
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 8574412962073106934
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/Normal.physicMaterial
Normal file
15
game/Assets/Normal.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Normal
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 0.6
|
||||||
|
m_StaticFriction: 0.6
|
||||||
|
m_Bounciness: 0
|
||||||
|
m_FrictionCombine: 0
|
||||||
|
m_BounceCombine: 0
|
||||||
8
game/Assets/Normal.physicMaterial.meta
Normal file
8
game/Assets/Normal.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 36e82e5cf5450404999af634c1d3cbbd
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 13400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
751
game/Assets/PlayerController.cs
Normal file
751
game/Assets/PlayerController.cs
Normal file
@@ -0,0 +1,751 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
using UnityEngine.InputSystem.Controls;
|
||||||
|
|
||||||
|
public class PlayerController : MonoBehaviour
|
||||||
|
{
|
||||||
|
// Reference to the Player Input component
|
||||||
|
private bool isJumpPressed = false;
|
||||||
|
private float jumpPressTime = 0f;
|
||||||
|
private bool _isLocalPlayer = false;
|
||||||
|
public float maxJumpHoldTime = 0.5f; // Ex. limite la puissance du saut
|
||||||
|
|
||||||
|
public float JumpForce = 5f; // Force applied when jumping
|
||||||
|
|
||||||
|
public float MovementSpeed = 5f; // Speed of player movement
|
||||||
|
public float BoostSpeed = 2f; // Multiplicateur de vitesse sur GelOrange
|
||||||
|
|
||||||
|
[Header("Bump Collision")]
|
||||||
|
public float bumpForce = 4f; // Impulse force when bumping a remote player
|
||||||
|
public float bumpCooldown = 0.25f; // Minimum time between bumps from the same player
|
||||||
|
private Dictionary<int, float> _lastBumpTime = new Dictionary<int, float>();
|
||||||
|
|
||||||
|
// Ajout des états pour chaque direction
|
||||||
|
private bool isForwardHeld = false;
|
||||||
|
private bool isBackwardsHeld = false;
|
||||||
|
private bool isLeftHeld = false;
|
||||||
|
private bool isRightHeld = false;
|
||||||
|
private bool isOnGelOrange = false; // Indique si la boule est sur GelOrange
|
||||||
|
private bool isOnGelViolet = false; // Indique si la boule est sur GelViolet (sticky)
|
||||||
|
private Vector3 stickyNormal = Vector3.up; // Normale de la surface sticky en contact
|
||||||
|
public float StickyForce = 20f; // Force qui plaque la balle contre la surface GelViolet
|
||||||
|
private float originalDrag = 0f; // Sauvegarde du drag original du Rigidbody
|
||||||
|
|
||||||
|
[Header("Limits")]
|
||||||
|
public float maxVelocity = 120f; // Velocity cap to prevent infinite acceleration
|
||||||
|
public float respawnY = -10f; // Y threshold for respawn
|
||||||
|
private Vector3 _spawnPos = new Vector3(0f, 3f, -30f);
|
||||||
|
|
||||||
|
// Squash & stretch
|
||||||
|
private bool _isSquashing = false;
|
||||||
|
private Transform _meshTransform; // Reference to visual mesh for squash effect
|
||||||
|
|
||||||
|
// Fall warning
|
||||||
|
private static Texture2D _fallWarningTex;
|
||||||
|
private float _fallWarningAlpha = 0f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public GameObject CameraReference; // Référence à la caméra (drag & drop dans l'inspecteur)
|
||||||
|
|
||||||
|
// --- Local player floating name label ---
|
||||||
|
private GameObject _nameLabelObj;
|
||||||
|
private TextMesh _nameLabel;
|
||||||
|
|
||||||
|
// --- Jump power (exposed for HUD) ---
|
||||||
|
public bool IsJumpCharging => isJumpPressed && IsGrounded();
|
||||||
|
public float JumpChargeNormalized => Mathf.Clamp01(jumpPressTime / maxJumpHoldTime);
|
||||||
|
|
||||||
|
// --- Shared font for TextMesh labels (WebGL-safe) ---
|
||||||
|
private static Font _labelFont;
|
||||||
|
public static Font LabelFont
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_labelFont == null)
|
||||||
|
_labelFont = Resources.Load<Font>("LiberationSans");
|
||||||
|
return _labelFont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
Debug.Log("PlayerController script initialized.");
|
||||||
|
// Cursor lock is handled by LobbyUI on connect/disconnect
|
||||||
|
_meshTransform = transform; // Will be the sphere itself for squash
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called by LobbyUI after connecting. Sets up the local player
|
||||||
|
/// with a floating name label and a 50% color tint.
|
||||||
|
/// </summary>
|
||||||
|
public void SetupLocalPlayer(string playerName, Color playerColor)
|
||||||
|
{
|
||||||
|
_isLocalPlayer = true;
|
||||||
|
// --- Color tint (multiply blend to keep original pattern visible) ---
|
||||||
|
var ballRenderer = GetComponent<Renderer>();
|
||||||
|
if (ballRenderer != null)
|
||||||
|
{
|
||||||
|
var mat = new Material(ballRenderer.sharedMaterial);
|
||||||
|
Color original = Color.white;
|
||||||
|
if (mat.HasProperty("_BaseColor")) original = mat.GetColor("_BaseColor");
|
||||||
|
else if (mat.HasProperty("_Color")) original = mat.GetColor("_Color");
|
||||||
|
|
||||||
|
// Multiply tint: keeps the original pattern while colorizing
|
||||||
|
// Strength 0.7 = strong color, 0.3 original preserved
|
||||||
|
float strength = 0.7f;
|
||||||
|
Color tint = new Color(
|
||||||
|
Mathf.Lerp(original.r, original.r * playerColor.r * 2f, strength),
|
||||||
|
Mathf.Lerp(original.g, original.g * playerColor.g * 2f, strength),
|
||||||
|
Mathf.Lerp(original.b, original.b * playerColor.b * 2f, strength),
|
||||||
|
original.a
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", tint);
|
||||||
|
if (mat.HasProperty("_Color")) mat.color = tint;
|
||||||
|
ballRenderer.material = mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Floating name label (parented to Player root, NOT the sphere) ---
|
||||||
|
if (_nameLabelObj != null) Destroy(_nameLabelObj);
|
||||||
|
|
||||||
|
_nameLabelObj = new GameObject("LocalNameLabel");
|
||||||
|
// Parent to the Player root (one level up) so ball rotation doesn't affect it
|
||||||
|
_nameLabelObj.transform.SetParent(transform.parent, false);
|
||||||
|
_nameLabelObj.transform.localScale = Vector3.one * 0.1f;
|
||||||
|
|
||||||
|
_nameLabel = _nameLabelObj.AddComponent<TextMesh>();
|
||||||
|
_nameLabel.text = playerName;
|
||||||
|
_nameLabel.fontSize = 144;
|
||||||
|
_nameLabel.characterSize = 0.15f;
|
||||||
|
_nameLabel.anchor = TextAnchor.MiddleCenter;
|
||||||
|
_nameLabel.alignment = TextAlignment.Center;
|
||||||
|
_nameLabel.color = playerColor;
|
||||||
|
if (LabelFont != null) _nameLabel.font = LabelFont;
|
||||||
|
|
||||||
|
var renderer = _nameLabel.GetComponent<MeshRenderer>();
|
||||||
|
if (LabelFont != null && LabelFont.material != null)
|
||||||
|
renderer.material = LabelFont.material;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var textShader = Shader.Find("GUI/Text Shader") ?? Shader.Find("Unlit/Texture");
|
||||||
|
if (textShader != null) renderer.material = new Material(textShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Speed trail renderer ---
|
||||||
|
var trail = gameObject.GetComponent<TrailRenderer>();
|
||||||
|
if (trail == null) trail = gameObject.AddComponent<TrailRenderer>();
|
||||||
|
trail.time = 0.4f;
|
||||||
|
trail.startWidth = 0.3f;
|
||||||
|
trail.endWidth = 0.02f;
|
||||||
|
trail.material = new Material(Shader.Find("Sprites/Default"));
|
||||||
|
trail.startColor = new Color(1f, 0.7f, 0.2f, 0.7f);
|
||||||
|
trail.endColor = new Color(1f, 0.4f, 0.1f, 0f);
|
||||||
|
trail.minVertexDistance = 0.1f;
|
||||||
|
trail.autodestruct = false;
|
||||||
|
trail.emitting = true;
|
||||||
|
|
||||||
|
Debug.Log($"[Player] Local setup: {playerName}, tint={playerColor}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LateUpdate()
|
||||||
|
{
|
||||||
|
// Keep local name label floating above the ball and facing the camera
|
||||||
|
if (_nameLabelObj != null)
|
||||||
|
{
|
||||||
|
_nameLabelObj.transform.position = transform.position + Vector3.up * 1.5f;
|
||||||
|
var cam = Camera.main;
|
||||||
|
if (cam != null)
|
||||||
|
{
|
||||||
|
// Billboard locked to Y axis — only rotate around vertical
|
||||||
|
Vector3 lookDir = _nameLabelObj.transform.position - cam.transform.position;
|
||||||
|
lookDir.y = 0f;
|
||||||
|
if (lookDir.sqrMagnitude > 0.001f)
|
||||||
|
_nameLabelObj.transform.rotation = Quaternion.LookRotation(lookDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is called once per frame
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
// Toggle cursor lock/unlock avec clic droit (disabled when keybind menu is open)
|
||||||
|
if (!KeyBindingUI.IsVisible && Mouse.current != null && Mouse.current.rightButton.wasPressedThisFrame)
|
||||||
|
{
|
||||||
|
if (Cursor.lockState == CursorLockMode.Locked)
|
||||||
|
{
|
||||||
|
Cursor.lockState = CursorLockMode.None;
|
||||||
|
Cursor.visible = true;
|
||||||
|
Debug.Log("Cursor UNLOCKED");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cursor.lockState = CursorLockMode.Locked;
|
||||||
|
Cursor.visible = false;
|
||||||
|
Debug.Log("Cursor LOCKED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Player update logic can be added here
|
||||||
|
if (isJumpPressed)
|
||||||
|
{
|
||||||
|
jumpPressTime += Time.deltaTime;
|
||||||
|
if (jumpPressTime > maxJumpHoldTime)
|
||||||
|
{
|
||||||
|
jumpPressTime = maxJumpHoldTime; // Clamp to max hold time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Respawn if fallen off the map ---
|
||||||
|
if (transform.position.y < respawnY)
|
||||||
|
{
|
||||||
|
Rigidbody rbRespawn = GetComponent<Rigidbody>();
|
||||||
|
if (rbRespawn != null)
|
||||||
|
{
|
||||||
|
rbRespawn.linearVelocity = Vector3.zero;
|
||||||
|
rbRespawn.angularVelocity = Vector3.zero;
|
||||||
|
}
|
||||||
|
transform.position = _spawnPos;
|
||||||
|
isOnGelViolet = false;
|
||||||
|
isOnGelOrange = false;
|
||||||
|
if (rbRespawn != null) rbRespawn.useGravity = true;
|
||||||
|
Debug.Log("[Player] Respawned after falling.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Fall warning (tint screen red when low) ---
|
||||||
|
float fallTarget = (transform.position.y < -3f) ? Mathf.Clamp01((-3f - transform.position.y) / 7f) : 0f;
|
||||||
|
_fallWarningAlpha = Mathf.Lerp(_fallWarningAlpha, fallTarget, Time.deltaTime * 5f);
|
||||||
|
|
||||||
|
// Mouvement continu selon les directions maintenues
|
||||||
|
Rigidbody rb = GetComponent<Rigidbody>();
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
float currentSpeed = MovementSpeed;
|
||||||
|
if (isOnGelOrange)
|
||||||
|
{
|
||||||
|
currentSpeed *= BoostSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Détermination des directions selon la caméra
|
||||||
|
Vector3 forward = Vector3.forward;
|
||||||
|
Vector3 right = Vector3.right;
|
||||||
|
if (CameraReference != null)
|
||||||
|
{
|
||||||
|
Vector3 camForward = CameraReference.transform.forward;
|
||||||
|
Vector3 camRight = CameraReference.transform.right;
|
||||||
|
|
||||||
|
if (isOnGelViolet)
|
||||||
|
{
|
||||||
|
// PROJECT onto sticky surface plane for surface-relative movement
|
||||||
|
forward = Vector3.ProjectOnPlane(camForward, stickyNormal).normalized;
|
||||||
|
right = Vector3.ProjectOnPlane(camRight, stickyNormal).normalized;
|
||||||
|
// Fallback if projection is degenerate
|
||||||
|
if (forward.sqrMagnitude < 0.01f)
|
||||||
|
forward = Vector3.ProjectOnPlane(Vector3.forward, stickyNormal).normalized;
|
||||||
|
if (right.sqrMagnitude < 0.01f)
|
||||||
|
right = Vector3.ProjectOnPlane(Vector3.right, stickyNormal).normalized;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Normal mode: project onto horizontal plane
|
||||||
|
camForward.y = 0;
|
||||||
|
camForward.Normalize();
|
||||||
|
forward = camForward;
|
||||||
|
camRight.y = 0;
|
||||||
|
camRight.Normalize();
|
||||||
|
right = camRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isForwardHeld)
|
||||||
|
{
|
||||||
|
rb.AddForce(forward * currentSpeed * Time.deltaTime, ForceMode.VelocityChange);
|
||||||
|
}
|
||||||
|
if (isBackwardsHeld)
|
||||||
|
{
|
||||||
|
rb.AddForce(-forward * currentSpeed * Time.deltaTime, ForceMode.VelocityChange);
|
||||||
|
}
|
||||||
|
if (isLeftHeld)
|
||||||
|
{
|
||||||
|
rb.AddForce(-right * currentSpeed * Time.deltaTime, ForceMode.VelocityChange);
|
||||||
|
}
|
||||||
|
if (isRightHeld)
|
||||||
|
{
|
||||||
|
rb.AddForce(right * currentSpeed * Time.deltaTime, ForceMode.VelocityChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GelViolet : colle la balle à la surface (sticky)
|
||||||
|
if (isOnGelViolet)
|
||||||
|
{
|
||||||
|
// Désactive la gravité Unity sur le Rigidbody
|
||||||
|
rb.useGravity = false;
|
||||||
|
|
||||||
|
// Applique une gravité inversée vers la surface
|
||||||
|
rb.AddForce(-stickyNormal * Physics.gravity.magnitude, ForceMode.Acceleration);
|
||||||
|
|
||||||
|
// Force de placage supplémentaire
|
||||||
|
rb.AddForce(-stickyNormal * StickyForce, ForceMode.Acceleration);
|
||||||
|
|
||||||
|
// Annule la vélocité qui s'éloigne de la surface (empêche le rebond)
|
||||||
|
float velocityAwayFromSurface = Vector3.Dot(rb.linearVelocity, stickyNormal);
|
||||||
|
if (velocityAwayFromSurface > 0)
|
||||||
|
{
|
||||||
|
rb.linearVelocity -= stickyNormal * velocityAwayFromSurface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb.useGravity = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Velocity cap ---
|
||||||
|
if (rb.linearVelocity.magnitude > maxVelocity)
|
||||||
|
{
|
||||||
|
rb.linearVelocity = rb.linearVelocity.normalized * maxVelocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCollisionStay(Collision collision)
|
||||||
|
{
|
||||||
|
Collider col = collision.collider;
|
||||||
|
if (col != null && col.sharedMaterial != null)
|
||||||
|
{
|
||||||
|
if (col.sharedMaterial.name.Contains("GelOrange"))
|
||||||
|
{
|
||||||
|
isOnGelOrange = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isOnGelOrange = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col.sharedMaterial.name.Contains("GelViolet"))
|
||||||
|
{
|
||||||
|
if (!isOnGelViolet)
|
||||||
|
{
|
||||||
|
// Premier contact : sauvegarder le drag et augmenter le frein
|
||||||
|
Rigidbody rb = GetComponent<Rigidbody>();
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
originalDrag = rb.linearDamping;
|
||||||
|
rb.linearDamping = 1f; // Fort frein pour éviter le catapultage aux bords
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isOnGelViolet = true;
|
||||||
|
// Normale instantanée de la surface de contact
|
||||||
|
Vector3 avgNormal = Vector3.zero;
|
||||||
|
foreach (ContactPoint contact in collision.contacts)
|
||||||
|
{
|
||||||
|
avgNormal += contact.normal;
|
||||||
|
}
|
||||||
|
stickyNormal = avgNormal.normalized;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isOnGelViolet = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCollisionExit(Collision collision)
|
||||||
|
{
|
||||||
|
Collider col = collision.collider;
|
||||||
|
if (col != null && col.sharedMaterial != null)
|
||||||
|
{
|
||||||
|
if (col.sharedMaterial.name.Contains("GelOrange"))
|
||||||
|
{
|
||||||
|
isOnGelOrange = false;
|
||||||
|
}
|
||||||
|
if (col.sharedMaterial.name.Contains("GelViolet"))
|
||||||
|
{
|
||||||
|
isOnGelViolet = false;
|
||||||
|
// Restaure le drag original et réactive la gravité
|
||||||
|
Rigidbody rb = GetComponent<Rigidbody>();
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
rb.useGravity = true;
|
||||||
|
rb.linearDamping = originalDrag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnJump(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
if (context.started)
|
||||||
|
{
|
||||||
|
// Touche appuyée
|
||||||
|
isJumpPressed = true;
|
||||||
|
jumpPressTime = 0f;
|
||||||
|
Debug.Log("Jump Started");
|
||||||
|
}
|
||||||
|
else if (context.performed)
|
||||||
|
{
|
||||||
|
// Action validée (utile pour saut immédiat aussi)
|
||||||
|
Debug.Log("Jump Performed");
|
||||||
|
}
|
||||||
|
else if (context.canceled)
|
||||||
|
{
|
||||||
|
// Touche relâchée
|
||||||
|
float jumpForceFactor = Mathf.Clamp01(jumpPressTime / maxJumpHoldTime);
|
||||||
|
if (IsGrounded())
|
||||||
|
{
|
||||||
|
PerformJump(jumpForceFactor * JumpForce);
|
||||||
|
Debug.Log($"Jump Released after {jumpPressTime}s -> Force factor: {jumpForceFactor}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log("Jump Released but not grounded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset jump state so gauge goes back to 0
|
||||||
|
isJumpPressed = false;
|
||||||
|
jumpPressTime = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PerformJump(float force)
|
||||||
|
{
|
||||||
|
Rigidbody rb = GetComponent<Rigidbody>();
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
// Jump direction: surface normal when on sticky, otherwise up
|
||||||
|
Vector3 jumpDir = isOnGelViolet ? stickyNormal : Vector3.up;
|
||||||
|
rb.AddForce(jumpDir * force, ForceMode.Impulse);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Rigidbody component not found on PlayerController.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsGrounded()
|
||||||
|
{
|
||||||
|
// On sticky surface: raycast toward the surface (opposite of normal)
|
||||||
|
if (isOnGelViolet)
|
||||||
|
return Physics.Raycast(transform.position, -stickyNormal, 1.1f);
|
||||||
|
// Normal: raycast downward
|
||||||
|
return Physics.Raycast(transform.position, Vector3.down, 1.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnForward(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
if (context.started)
|
||||||
|
{
|
||||||
|
isForwardHeld = true;
|
||||||
|
Debug.Log("Forward Action Started");
|
||||||
|
}
|
||||||
|
else if (context.performed)
|
||||||
|
{
|
||||||
|
// Forward action performed
|
||||||
|
Debug.Log("Forward Action Performed");
|
||||||
|
}
|
||||||
|
else if (context.canceled)
|
||||||
|
{
|
||||||
|
isForwardHeld = false;
|
||||||
|
Debug.Log("Forward Action Canceled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBackwards(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
if (context.started)
|
||||||
|
{
|
||||||
|
isBackwardsHeld = true;
|
||||||
|
Debug.Log("Backwards Action Started");
|
||||||
|
}
|
||||||
|
else if (context.performed)
|
||||||
|
{
|
||||||
|
Debug.Log("Backwards Action Performed");
|
||||||
|
}
|
||||||
|
else if (context.canceled)
|
||||||
|
{
|
||||||
|
isBackwardsHeld = false;
|
||||||
|
Debug.Log("Backwards Action Canceled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnLeft(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
if (context.started)
|
||||||
|
{
|
||||||
|
isLeftHeld = true;
|
||||||
|
Debug.Log("Left Action Started");
|
||||||
|
}
|
||||||
|
else if (context.performed)
|
||||||
|
{
|
||||||
|
Debug.Log("Left Action Performed");
|
||||||
|
}
|
||||||
|
else if (context.canceled)
|
||||||
|
{
|
||||||
|
isLeftHeld = false;
|
||||||
|
Debug.Log("Left Action Canceled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnRight(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
if (context.started)
|
||||||
|
{
|
||||||
|
isRightHeld = true;
|
||||||
|
Debug.Log("Right Action Started");
|
||||||
|
}
|
||||||
|
else if (context.performed)
|
||||||
|
{
|
||||||
|
Debug.Log("Right Action Performed");
|
||||||
|
}
|
||||||
|
else if (context.canceled)
|
||||||
|
{
|
||||||
|
isRightHeld = false;
|
||||||
|
Debug.Log("Right Action Canceled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Bump collision with remote players ---
|
||||||
|
void OnTriggerEnter(Collider other)
|
||||||
|
{
|
||||||
|
HandleBump(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTriggerStay(Collider other)
|
||||||
|
{
|
||||||
|
HandleBump(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleBump(Collider other)
|
||||||
|
{
|
||||||
|
var remote = other.GetComponent<RemotePlayerController>();
|
||||||
|
if (remote == null) return;
|
||||||
|
|
||||||
|
int id = other.gameObject.GetInstanceID();
|
||||||
|
if (_lastBumpTime.TryGetValue(id, out float lastTime) && Time.time - lastTime < bumpCooldown)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lastBumpTime[id] = Time.time;
|
||||||
|
|
||||||
|
// Repulsion direction: from remote toward local player
|
||||||
|
Vector3 dir = (transform.position - other.transform.position).normalized;
|
||||||
|
// Add slight upward component so the ball lifts off the ground
|
||||||
|
dir = (dir + Vector3.up * 0.3f).normalized;
|
||||||
|
|
||||||
|
var rb = GetComponent<Rigidbody>();
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
rb.AddForce(dir * bumpForce, ForceMode.Impulse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCollisionEnter(Collision collision)
|
||||||
|
{
|
||||||
|
if (!_isLocalPlayer) return;
|
||||||
|
// Squash & stretch on landing/impact
|
||||||
|
if (collision.relativeVelocity.magnitude > 2f && !_isSquashing)
|
||||||
|
{
|
||||||
|
StartCoroutine(SquashStretch());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator SquashStretch()
|
||||||
|
{
|
||||||
|
_isSquashing = true;
|
||||||
|
Vector3 original = Vector3.one;
|
||||||
|
Vector3 squash = new Vector3(1.2f, 0.7f, 1.2f);
|
||||||
|
float t = 0f;
|
||||||
|
float dur = 0.08f;
|
||||||
|
// Squash
|
||||||
|
while (t < dur)
|
||||||
|
{
|
||||||
|
t += Time.deltaTime;
|
||||||
|
transform.localScale = Vector3.Lerp(original, squash, t / dur);
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
// Stretch back
|
||||||
|
t = 0f;
|
||||||
|
dur = 0.12f;
|
||||||
|
while (t < dur)
|
||||||
|
{
|
||||||
|
t += Time.deltaTime;
|
||||||
|
transform.localScale = Vector3.Lerp(squash, original, t / dur);
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
transform.localScale = original;
|
||||||
|
_isSquashing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
// Clean up name label (it's not parented to the ball)
|
||||||
|
if (_nameLabelObj != null) Destroy(_nameLabelObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================
|
||||||
|
// JUMP POWER GAUGE (HUD)
|
||||||
|
// ========================
|
||||||
|
private static Texture2D _gaugeBarTex;
|
||||||
|
private static Texture2D _gaugeBgTex;
|
||||||
|
private static Texture2D _gaugeGlowTex;
|
||||||
|
private float _gaugeDisplayAlpha = 0f; // smooth fade-in/out
|
||||||
|
private float _lastChargeValue = 0f; // for smooth lerp
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
if (!_isLocalPlayer) return;
|
||||||
|
|
||||||
|
// Target alpha: 1 when charging, 0 otherwise (keep visible briefly after release)
|
||||||
|
float targetAlpha = IsJumpCharging ? 1f : 0f;
|
||||||
|
_gaugeDisplayAlpha = Mathf.MoveTowards(_gaugeDisplayAlpha, targetAlpha, Time.deltaTime * 6f);
|
||||||
|
|
||||||
|
// Smooth the charge value for a fluid bar animation
|
||||||
|
float chargeTarget = IsJumpCharging ? JumpChargeNormalized : 0f;
|
||||||
|
_lastChargeValue = Mathf.Lerp(_lastChargeValue, chargeTarget, Time.deltaTime * 12f);
|
||||||
|
|
||||||
|
if (_gaugeDisplayAlpha < 0.01f) return;
|
||||||
|
|
||||||
|
// Gauge dimensions
|
||||||
|
float barWidth = 400f;
|
||||||
|
float barHeight = 22f;
|
||||||
|
float x = (Screen.width - barWidth) / 2f;
|
||||||
|
float y = Screen.height - 80f;
|
||||||
|
|
||||||
|
// Label
|
||||||
|
var labelStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
alignment = TextAnchor.MiddleCenter,
|
||||||
|
fontSize = 12,
|
||||||
|
fontStyle = FontStyle.Bold
|
||||||
|
};
|
||||||
|
labelStyle.normal.textColor = new Color(1f, 1f, 1f, _gaugeDisplayAlpha * 0.9f);
|
||||||
|
GUI.Label(new Rect(x, y - 26f, barWidth, 24f), "JUMP POWER", labelStyle);
|
||||||
|
|
||||||
|
// Ensure textures
|
||||||
|
if (_gaugeBgTex == null)
|
||||||
|
{
|
||||||
|
_gaugeBgTex = new Texture2D(1, 1);
|
||||||
|
_gaugeBgTex.SetPixel(0, 0, new Color(0.08f, 0.08f, 0.12f, 1f));
|
||||||
|
_gaugeBgTex.Apply();
|
||||||
|
}
|
||||||
|
if (_gaugeBarTex == null)
|
||||||
|
{
|
||||||
|
_gaugeBarTex = new Texture2D(1, 1);
|
||||||
|
_gaugeBarTex.SetPixel(0, 0, Color.white);
|
||||||
|
_gaugeBarTex.Apply();
|
||||||
|
}
|
||||||
|
if (_gaugeGlowTex == null)
|
||||||
|
{
|
||||||
|
_gaugeGlowTex = new Texture2D(1, 1);
|
||||||
|
_gaugeGlowTex.SetPixel(0, 0, Color.white);
|
||||||
|
_gaugeGlowTex.Apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
Color prevBg = GUI.backgroundColor;
|
||||||
|
Color prevColor = GUI.color;
|
||||||
|
|
||||||
|
// Background (dark panel)
|
||||||
|
float pad = 4f;
|
||||||
|
Rect bgRect = new Rect(x - pad, y - pad, barWidth + pad * 2f, barHeight + pad * 2f);
|
||||||
|
GUI.color = new Color(1f, 1f, 1f, _gaugeDisplayAlpha * 0.85f);
|
||||||
|
GUI.DrawTexture(bgRect, _gaugeBgTex);
|
||||||
|
|
||||||
|
// Border
|
||||||
|
float b = 1f;
|
||||||
|
Color borderColor = new Color(0.35f, 0.35f, 0.45f, _gaugeDisplayAlpha * 0.7f);
|
||||||
|
GUI.color = borderColor;
|
||||||
|
GUI.DrawTexture(new Rect(bgRect.x, bgRect.y, bgRect.width, b), _gaugeBarTex); // top
|
||||||
|
GUI.DrawTexture(new Rect(bgRect.x, bgRect.yMax - b, bgRect.width, b), _gaugeBarTex); // bottom
|
||||||
|
GUI.DrawTexture(new Rect(bgRect.x, bgRect.y, b, bgRect.height), _gaugeBarTex); // left
|
||||||
|
GUI.DrawTexture(new Rect(bgRect.xMax - b, bgRect.y, b, bgRect.height), _gaugeBarTex); // right
|
||||||
|
|
||||||
|
// Filled bar with gradient color (blue -> cyan -> yellow -> red)
|
||||||
|
float fill = _lastChargeValue;
|
||||||
|
Color barColor;
|
||||||
|
if (fill < 0.5f)
|
||||||
|
barColor = Color.Lerp(new Color(0.2f, 0.6f, 1f), new Color(0.1f, 0.95f, 0.85f), fill * 2f);
|
||||||
|
else
|
||||||
|
barColor = Color.Lerp(new Color(0.1f, 0.95f, 0.85f), new Color(1f, 0.3f, 0.2f), (fill - 0.5f) * 2f);
|
||||||
|
|
||||||
|
Rect barRect = new Rect(x, y, barWidth * fill, barHeight);
|
||||||
|
GUI.color = new Color(barColor.r, barColor.g, barColor.b, _gaugeDisplayAlpha);
|
||||||
|
GUI.DrawTexture(barRect, _gaugeBarTex);
|
||||||
|
|
||||||
|
// Glow overlay on the filled portion (bright center highlight)
|
||||||
|
Color glowColor = new Color(1f, 1f, 1f, _gaugeDisplayAlpha * 0.2f * fill);
|
||||||
|
GUI.color = glowColor;
|
||||||
|
float glowH = barHeight * 0.4f;
|
||||||
|
GUI.DrawTexture(new Rect(x, y + (barHeight - glowH) * 0.3f, barWidth * fill, glowH), _gaugeGlowTex);
|
||||||
|
|
||||||
|
// Pulsing edge glow when near max
|
||||||
|
if (fill > 0.85f)
|
||||||
|
{
|
||||||
|
float pulse = 0.4f + 0.6f * Mathf.Abs(Mathf.Sin(Time.time * 6f));
|
||||||
|
GUI.color = new Color(1f, 0.3f, 0.15f, _gaugeDisplayAlpha * 0.35f * pulse);
|
||||||
|
GUI.DrawTexture(bgRect, _gaugeBarTex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Percentage text
|
||||||
|
var pctStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
alignment = TextAnchor.MiddleCenter,
|
||||||
|
fontSize = 11,
|
||||||
|
fontStyle = FontStyle.Bold
|
||||||
|
};
|
||||||
|
pctStyle.normal.textColor = new Color(1f, 1f, 1f, _gaugeDisplayAlpha * 0.95f);
|
||||||
|
GUI.Label(new Rect(x, y, barWidth, barHeight), Mathf.RoundToInt(fill * 100f) + "%", pctStyle);
|
||||||
|
|
||||||
|
GUI.color = prevColor;
|
||||||
|
GUI.backgroundColor = prevBg;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ========================
|
||||||
|
// FALL WARNING (red tint)
|
||||||
|
// ========================
|
||||||
|
if (_fallWarningAlpha > 0.01f)
|
||||||
|
{
|
||||||
|
if (_fallWarningTex == null)
|
||||||
|
{
|
||||||
|
_fallWarningTex = new Texture2D(1, 1);
|
||||||
|
_fallWarningTex.SetPixel(0, 0, Color.white);
|
||||||
|
_fallWarningTex.Apply();
|
||||||
|
}
|
||||||
|
GUI.color = new Color(0.9f, 0.1f, 0.05f, _fallWarningAlpha * 0.35f);
|
||||||
|
GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), _fallWarningTex);
|
||||||
|
|
||||||
|
// Warning text
|
||||||
|
var warnStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
alignment = TextAnchor.MiddleCenter,
|
||||||
|
fontSize = 24,
|
||||||
|
fontStyle = FontStyle.Bold
|
||||||
|
};
|
||||||
|
warnStyle.normal.textColor = new Color(1f, 0.3f, 0.2f, _fallWarningAlpha);
|
||||||
|
GUI.Label(new Rect(0, Screen.height * 0.35f, Screen.width, 40f), "\u26A0 DANGER - CHUTE !", warnStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================
|
||||||
|
// SPEED INDICATOR
|
||||||
|
// ========================
|
||||||
|
Rigidbody rbHud = GetComponent<Rigidbody>();
|
||||||
|
if (rbHud != null)
|
||||||
|
{
|
||||||
|
float speed = rbHud.linearVelocity.magnitude;
|
||||||
|
var speedStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
alignment = TextAnchor.MiddleRight,
|
||||||
|
fontSize = 12,
|
||||||
|
fontStyle = FontStyle.Bold
|
||||||
|
};
|
||||||
|
float speedAlpha = Mathf.Clamp01(speed / 5f) * 0.8f;
|
||||||
|
Color speedCol = Color.Lerp(new Color(0.8f, 0.8f, 0.8f), new Color(1f, 0.5f, 0.1f), Mathf.Clamp01(speed / 30f));
|
||||||
|
speedStyle.normal.textColor = new Color(speedCol.r, speedCol.g, speedCol.b, Mathf.Max(0.3f, speedAlpha));
|
||||||
|
GUI.Label(new Rect(Screen.width - 160f, Screen.height - 50f, 140f, 24f),
|
||||||
|
$"{speed:F1} m/s", speedStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI.color = Color.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
game/Assets/PlayerController.cs.meta
Normal file
2
game/Assets/PlayerController.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6796198cbd5a2204ea7698616ca96372
|
||||||
8
game/Assets/Plugins.meta
Normal file
8
game/Assets/Plugins.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b669f3c1d7a4e274aaac1bc4e6bca307
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
game/Assets/Plugins/Roslyn.meta
Normal file
8
game/Assets/Plugins/Roslyn.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9d70d730866df364abd37c4fa03391ed
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
game/Assets/Plugins/Roslyn/Microsoft.CodeAnalysis.CSharp.dll
LFS
Normal file
BIN
game/Assets/Plugins/Roslyn/Microsoft.CodeAnalysis.CSharp.dll
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: da60e3d4d34f7504eb8294b64639aa6e
|
||||||
BIN
game/Assets/Plugins/Roslyn/Microsoft.CodeAnalysis.dll
LFS
Normal file
BIN
game/Assets/Plugins/Roslyn/Microsoft.CodeAnalysis.dll
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 029a94254cd6cf7498d5a3327c2de37a
|
||||||
BIN
game/Assets/Plugins/Roslyn/System.Collections.Immutable.dll
LFS
Normal file
BIN
game/Assets/Plugins/Roslyn/System.Collections.Immutable.dll
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8df225368be7a6e41befb607a2710cfd
|
||||||
BIN
game/Assets/Plugins/Roslyn/System.Reflection.Metadata.dll
LFS
Normal file
BIN
game/Assets/Plugins/Roslyn/System.Reflection.Metadata.dll
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e195a025404a590429a3905439960615
|
||||||
38
game/Assets/PostProcessing Profile.asset
Normal file
38
game/Assets/PostProcessing Profile.asset
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &-670956545734759409
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 3
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b94fcd11afffcb142908bfcb1e261fba, type: 3}
|
||||||
|
m_Name: MotionBlur
|
||||||
|
m_EditorClassIdentifier: Unity.Postprocessing.Runtime::UnityEngine.Rendering.PostProcessing.MotionBlur
|
||||||
|
active: 1
|
||||||
|
enabled:
|
||||||
|
overrideState: 1
|
||||||
|
value: 1
|
||||||
|
shutterAngle:
|
||||||
|
overrideState: 0
|
||||||
|
value: 270
|
||||||
|
sampleCount:
|
||||||
|
overrideState: 0
|
||||||
|
value: 10
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 8e6292b2c06870d4495f009f912b9600, type: 3}
|
||||||
|
m_Name: PostProcessing Profile
|
||||||
|
m_EditorClassIdentifier: Unity.Postprocessing.Runtime::UnityEngine.Rendering.PostProcessing.PostProcessProfile
|
||||||
|
settings:
|
||||||
|
- {fileID: -670956545734759409}
|
||||||
8
game/Assets/PostProcessing Profile.asset.meta
Normal file
8
game/Assets/PostProcessing Profile.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fc446179a9ae97a4a8ad5c8aa1c2dd47
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
game/Assets/Prefabs.meta
Normal file
8
game/Assets/Prefabs.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7510f86f3630df54180192234fc5f254
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
142
game/Assets/Prefabs/NPCBall.prefab
Normal file
142
game/Assets/Prefabs/NPCBall.prefab
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &1924030532290729092
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1899090404946461022}
|
||||||
|
- component: {fileID: 5883490258770931827}
|
||||||
|
- component: {fileID: 3238571154939426495}
|
||||||
|
- component: {fileID: 7413271144341016275}
|
||||||
|
- component: {fileID: 4571999804817866886}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: NPCBall
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &1899090404946461022
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1924030532290729092}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 2.6, 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 &5883490258770931827
|
||||||
|
MeshFilter:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1924030532290729092}
|
||||||
|
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
--- !u!135 &3238571154939426495
|
||||||
|
SphereCollider:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1924030532290729092}
|
||||||
|
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
|
||||||
|
m_Radius: 0.5
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!23 &7413271144341016275
|
||||||
|
MeshRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1924030532290729092}
|
||||||
|
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: 10303, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_StaticBatchInfo:
|
||||||
|
firstSubMesh: 0
|
||||||
|
subMeshCount: 0
|
||||||
|
m_StaticBatchRoot: {fileID: 0}
|
||||||
|
m_ProbeAnchor: {fileID: 0}
|
||||||
|
m_LightProbeVolumeOverride: {fileID: 0}
|
||||||
|
m_ScaleInLightmap: 1
|
||||||
|
m_ReceiveGI: 1
|
||||||
|
m_PreserveUVs: 1
|
||||||
|
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!54 &4571999804817866886
|
||||||
|
Rigidbody:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1924030532290729092}
|
||||||
|
serializedVersion: 5
|
||||||
|
m_Mass: 1
|
||||||
|
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: 1
|
||||||
|
m_IsKinematic: 0
|
||||||
|
m_Interpolate: 0
|
||||||
|
m_Constraints: 0
|
||||||
|
m_CollisionDetection: 0
|
||||||
7
game/Assets/Prefabs/NPCBall.prefab.meta
Normal file
7
game/Assets/Prefabs/NPCBall.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 649e6be5129a3b04f9833f793a86eef3
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
725
game/Assets/Prefabs/Player.prefab
Normal file
725
game/Assets/Prefabs/Player.prefab
Normal file
@@ -0,0 +1,725 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &479061706002273379
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 557582741204835402}
|
||||||
|
- component: {fileID: 3398873857287864649}
|
||||||
|
- component: {fileID: 299801412010955336}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: CinemachineBrain
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &557582741204835402
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 479061706002273379}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0.15212338, y: -0, z: -0, w: 0.98836154}
|
||||||
|
m_LocalPosition: {x: 58.85725, y: 3.0773075, z: -107.02734}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 8078295614007575380}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &3398873857287864649
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 479061706002273379}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 72ece51f2901e7445ab60da3685d6b5f, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
ShowDebugText: 0
|
||||||
|
ShowCameraFrustum: 0
|
||||||
|
IgnoreTimeScale: 0
|
||||||
|
WorldUpOverride: {fileID: 0}
|
||||||
|
ChannelMask: -1
|
||||||
|
UpdateMethod: 2
|
||||||
|
BlendUpdateMethod: 1
|
||||||
|
LensModeOverride:
|
||||||
|
Enabled: 0
|
||||||
|
DefaultMode: 2
|
||||||
|
DefaultBlend:
|
||||||
|
Style: 1
|
||||||
|
Time: 2
|
||||||
|
CustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve: []
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
CustomBlends: {fileID: 0}
|
||||||
|
--- !u!20 &299801412010955336
|
||||||
|
Camera:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 479061706002273379}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 2
|
||||||
|
m_ClearFlags: 1
|
||||||
|
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||||
|
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_NormalizedViewPortRect:
|
||||||
|
serializedVersion: 2
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
near clip plane: 0.1
|
||||||
|
far clip plane: 5000
|
||||||
|
field of view: 60
|
||||||
|
orthographic: 0
|
||||||
|
orthographic size: 10
|
||||||
|
m_Depth: 0
|
||||||
|
m_CullingMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 4294967295
|
||||||
|
m_RenderingPath: -1
|
||||||
|
m_TargetTexture: {fileID: 0}
|
||||||
|
m_TargetDisplay: 0
|
||||||
|
m_TargetEye: 3
|
||||||
|
m_HDR: 1
|
||||||
|
m_AllowMSAA: 1
|
||||||
|
m_AllowDynamicResolution: 0
|
||||||
|
m_ForceIntoRT: 0
|
||||||
|
m_OcclusionCulling: 1
|
||||||
|
m_StereoConvergence: 10
|
||||||
|
m_StereoSeparation: 0.022
|
||||||
|
--- !u!1 &1072275384359532290
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4965340560060435204}
|
||||||
|
- component: {fileID: 774506301913899538}
|
||||||
|
- component: {fileID: 5690785067609964014}
|
||||||
|
- component: {fileID: 6449108384251546983}
|
||||||
|
- component: {fileID: 1937370112805218085}
|
||||||
|
- component: {fileID: 8917665877240411764}
|
||||||
|
- component: {fileID: 1997613910040928409}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: PlayerSphere
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4965340560060435204
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1072275384359532290}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
|
m_LocalPosition: {x: 58.85725, y: 1.61287, z: -102.38274}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 8078295614007575380}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!33 &774506301913899538
|
||||||
|
MeshFilter:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1072275384359532290}
|
||||||
|
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
--- !u!23 &5690785067609964014
|
||||||
|
MeshRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1072275384359532290}
|
||||||
|
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: -876546973899608171, guid: 9535ecd79e34e1341bfe13a806935455, type: 3}
|
||||||
|
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!135 &6449108384251546983
|
||||||
|
SphereCollider:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1072275384359532290}
|
||||||
|
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
|
||||||
|
m_Radius: 0.5
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!54 &1937370112805218085
|
||||||
|
Rigidbody:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1072275384359532290}
|
||||||
|
serializedVersion: 5
|
||||||
|
m_Mass: 1
|
||||||
|
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: 1
|
||||||
|
m_IsKinematic: 0
|
||||||
|
m_Interpolate: 1
|
||||||
|
m_Constraints: 0
|
||||||
|
m_CollisionDetection: 0
|
||||||
|
--- !u!114 &8917665877240411764
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1072275384359532290}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 6796198cbd5a2204ea7698616ca96372, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
maxJumpHoldTime: 0.5
|
||||||
|
JumpForce: 10
|
||||||
|
MovementSpeed: 5
|
||||||
|
BoostSpeed: 3.83
|
||||||
|
bumpForce: 4
|
||||||
|
bumpCooldown: 0.25
|
||||||
|
StickyForce: 20
|
||||||
|
CameraReference: {fileID: 5476660720536128040}
|
||||||
|
--- !u!114 &1997613910040928409
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1072275384359532290}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 62899f850307741f2a39c98a8b639597, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Actions: {fileID: -944628639613478452, guid: 052faaac586de48259a63d0c4782560b, type: 3}
|
||||||
|
m_NotificationBehavior: 2
|
||||||
|
m_UIInputModule: {fileID: 0}
|
||||||
|
m_DeviceLostEvent:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_DeviceRegainedEvent:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ControlsChangedEvent:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionEvents:
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls:
|
||||||
|
- m_Target: {fileID: 8917665877240411764}
|
||||||
|
m_TargetAssemblyTypeName: PlayerController, Assembly-CSharp
|
||||||
|
m_MethodName: OnForward
|
||||||
|
m_Mode: 0
|
||||||
|
m_Arguments:
|
||||||
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
|
m_IntArgument: 0
|
||||||
|
m_FloatArgument: 0
|
||||||
|
m_StringArgument:
|
||||||
|
m_BoolArgument: 0
|
||||||
|
m_CallState: 2
|
||||||
|
m_ActionId: 63f99bf9-5435-425c-b5b8-5b81453bb4b9
|
||||||
|
m_ActionName: 'Player/forward[/Keyboard/upArrow]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls:
|
||||||
|
- m_Target: {fileID: 8917665877240411764}
|
||||||
|
m_TargetAssemblyTypeName: PlayerController, Assembly-CSharp
|
||||||
|
m_MethodName: OnBackwards
|
||||||
|
m_Mode: 0
|
||||||
|
m_Arguments:
|
||||||
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
|
m_IntArgument: 0
|
||||||
|
m_FloatArgument: 0
|
||||||
|
m_StringArgument:
|
||||||
|
m_BoolArgument: 0
|
||||||
|
m_CallState: 2
|
||||||
|
m_ActionId: f718adfe-dddf-414d-b3c6-b55287209179
|
||||||
|
m_ActionName: 'Player/backwards[/Keyboard/downArrow]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls:
|
||||||
|
- m_Target: {fileID: 8917665877240411764}
|
||||||
|
m_TargetAssemblyTypeName: PlayerController, Assembly-CSharp
|
||||||
|
m_MethodName: OnLeft
|
||||||
|
m_Mode: 0
|
||||||
|
m_Arguments:
|
||||||
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
|
m_IntArgument: 0
|
||||||
|
m_FloatArgument: 0
|
||||||
|
m_StringArgument:
|
||||||
|
m_BoolArgument: 0
|
||||||
|
m_CallState: 2
|
||||||
|
m_ActionId: 46eec8c5-1829-4d01-9711-71a9a3abab38
|
||||||
|
m_ActionName: 'Player/left[/Keyboard/leftArrow]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls:
|
||||||
|
- m_Target: {fileID: 8917665877240411764}
|
||||||
|
m_TargetAssemblyTypeName: PlayerController, Assembly-CSharp
|
||||||
|
m_MethodName: OnRight
|
||||||
|
m_Mode: 0
|
||||||
|
m_Arguments:
|
||||||
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
|
m_IntArgument: 0
|
||||||
|
m_FloatArgument: 0
|
||||||
|
m_StringArgument:
|
||||||
|
m_BoolArgument: 0
|
||||||
|
m_CallState: 2
|
||||||
|
m_ActionId: e2764bdd-11f1-4c3b-a8a0-76b63dae881d
|
||||||
|
m_ActionName: 'Player/right[/Keyboard/rightArrow]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls:
|
||||||
|
- m_Target: {fileID: 8917665877240411764}
|
||||||
|
m_TargetAssemblyTypeName: PlayerController, Assembly-CSharp
|
||||||
|
m_MethodName: OnJump
|
||||||
|
m_Mode: 0
|
||||||
|
m_Arguments:
|
||||||
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
|
m_IntArgument: 0
|
||||||
|
m_FloatArgument: 0
|
||||||
|
m_StringArgument: PlayerController.OnJump
|
||||||
|
m_BoolArgument: 0
|
||||||
|
m_CallState: 2
|
||||||
|
m_ActionId: 8553c4e4-05ac-4af4-a480-0c7bbda03480
|
||||||
|
m_ActionName: 'Player/jump[/Keyboard/space]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: c95b2375-e6d9-4b88-9c4c-c5e76515df4b
|
||||||
|
m_ActionName: 'UI/Navigate[/Keyboard/w,/Keyboard/upArrow,/Keyboard/s,/Keyboard/downArrow,/Keyboard/a,/Keyboard/leftArrow,/Keyboard/d,/Keyboard/rightArrow]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: 7607c7b6-cd76-4816-beef-bd0341cfe950
|
||||||
|
m_ActionName: 'UI/Submit[/Keyboard/enter]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: 15cef263-9014-4fd5-94d9-4e4a6234a6ef
|
||||||
|
m_ActionName: 'UI/Cancel[/Keyboard/escape]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: 32b35790-4ed0-4e9a-aa41-69ac6d629449
|
||||||
|
m_ActionName: 'UI/Point[/Mouse/position,/Touchscreen/touch0/position,/Touchscreen/touch1/position,/Touchscreen/touch2/position,/Touchscreen/touch3/position,/Touchscreen/touch4/position,/Touchscreen/touch5/position,/Touchscreen/touch6/position,/Touchscreen/touch7/position,/Touchscreen/touch8/position,/Touchscreen/touch9/position]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: 3c7022bf-7922-4f7c-a998-c437916075ad
|
||||||
|
m_ActionName: 'UI/Click[/Mouse/leftButton,/Touchscreen/touch0/press,/Touchscreen/touch1/press,/Touchscreen/touch2/press,/Touchscreen/touch3/press,/Touchscreen/touch4/press,/Touchscreen/touch5/press,/Touchscreen/touch6/press,/Touchscreen/touch7/press,/Touchscreen/touch8/press,/Touchscreen/touch9/press]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: 44b200b1-1557-4083-816c-b22cbdf77ddf
|
||||||
|
m_ActionName: 'UI/RightClick[/Mouse/rightButton]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: dad70c86-b58c-4b17-88ad-f5e53adf419e
|
||||||
|
m_ActionName: 'UI/MiddleClick[/Mouse/middleButton]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: 0489e84a-4833-4c40-bfae-cea84b696689
|
||||||
|
m_ActionName: 'UI/ScrollWheel[/Mouse/scroll]'
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: 24908448-c609-4bc3-a128-ea258674378a
|
||||||
|
m_ActionName: UI/TrackedDevicePosition
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionId: 9caa3d8a-6b2f-4e8e-8bad-6ede561bd9be
|
||||||
|
m_ActionName: UI/TrackedDeviceOrientation
|
||||||
|
m_NeverAutoSwitchControlSchemes: 0
|
||||||
|
m_DefaultControlScheme:
|
||||||
|
m_DefaultActionMap: Player
|
||||||
|
m_SplitScreenIndex: -1
|
||||||
|
m_Camera: {fileID: 0}
|
||||||
|
--- !u!1 &5148984459453260515
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 8078295614007575380}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Player
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &8078295614007575380
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5148984459453260515}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 7.53275, y: 0.00713, z: 49.41274}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 4965340560060435204}
|
||||||
|
- {fileID: 557582741204835402}
|
||||||
|
- {fileID: 7953263469538813421}
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1 &5476660720536128040
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 7953263469538813421}
|
||||||
|
- component: {fileID: 484684628478533039}
|
||||||
|
- component: {fileID: 1699369473331842138}
|
||||||
|
- component: {fileID: 105357817482922116}
|
||||||
|
- component: {fileID: 5239147339255103855}
|
||||||
|
- component: {fileID: 111899527427379675}
|
||||||
|
- component: {fileID: 7256497806279944528}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: CinemachineCamera
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &7953263469538813421
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5476660720536128040}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0.15212338, y: -0, z: -0, w: 0.98836154}
|
||||||
|
m_LocalPosition: {x: 58.85725, y: 3.0773075, z: -107.02734}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 8078295614007575380}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &484684628478533039
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5476660720536128040}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: f9dfa5b682dcd46bda6128250e975f58, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
Priority:
|
||||||
|
Enabled: 0
|
||||||
|
m_Value: 0
|
||||||
|
OutputChannel: 1
|
||||||
|
StandbyUpdate: 2
|
||||||
|
m_StreamingVersion: 20241001
|
||||||
|
m_LegacyPriority: 0
|
||||||
|
Target:
|
||||||
|
TrackingTarget: {fileID: 4965340560060435204}
|
||||||
|
LookAtTarget: {fileID: 0}
|
||||||
|
CustomLookAtTarget: 0
|
||||||
|
Lens:
|
||||||
|
FieldOfView: 60
|
||||||
|
OrthographicSize: 10
|
||||||
|
NearClipPlane: 0.1
|
||||||
|
FarClipPlane: 5000
|
||||||
|
Dutch: 0
|
||||||
|
ModeOverride: 0
|
||||||
|
PhysicalProperties:
|
||||||
|
GateFit: 2
|
||||||
|
SensorSize: {x: 21.946, y: 16.002}
|
||||||
|
LensShift: {x: 0, y: 0}
|
||||||
|
FocusDistance: 10
|
||||||
|
Iso: 200
|
||||||
|
ShutterSpeed: 0.005
|
||||||
|
Aperture: 16
|
||||||
|
BladeCount: 5
|
||||||
|
Curvature: {x: 2, y: 11}
|
||||||
|
BarrelClipping: 0.25
|
||||||
|
Anamorphism: 0
|
||||||
|
BlendHint: 0
|
||||||
|
--- !u!114 &1699369473331842138
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5476660720536128040}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 3b5d7c088409d9a40b7b09aa707777f8, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
TargetOffset: {x: 0, y: 0, z: 0}
|
||||||
|
TrackerSettings:
|
||||||
|
BindingMode: 4
|
||||||
|
PositionDamping: {x: 1, y: 1, z: 1}
|
||||||
|
AngularDampingMode: 0
|
||||||
|
RotationDamping: {x: 1, y: 1, z: 1}
|
||||||
|
QuaternionDamping: 1
|
||||||
|
OrbitStyle: 0
|
||||||
|
Radius: 4.87
|
||||||
|
Orbits:
|
||||||
|
Top:
|
||||||
|
Radius: 2
|
||||||
|
Height: 5
|
||||||
|
Center:
|
||||||
|
Radius: 4
|
||||||
|
Height: 2.25
|
||||||
|
Bottom:
|
||||||
|
Radius: 2.5
|
||||||
|
Height: 0.1
|
||||||
|
SplineCurvature: 0.5
|
||||||
|
RecenteringTarget: 2
|
||||||
|
HorizontalAxis:
|
||||||
|
Value: 0
|
||||||
|
Center: 0
|
||||||
|
Range: {x: -180, y: 180}
|
||||||
|
Wrap: 1
|
||||||
|
Recentering:
|
||||||
|
Enabled: 0
|
||||||
|
Wait: 1
|
||||||
|
Time: 2
|
||||||
|
Restrictions: 0
|
||||||
|
VerticalAxis:
|
||||||
|
Value: 17.5
|
||||||
|
Center: 17.5
|
||||||
|
Range: {x: -10, y: 45}
|
||||||
|
Wrap: 0
|
||||||
|
Recentering:
|
||||||
|
Enabled: 0
|
||||||
|
Wait: 1
|
||||||
|
Time: 2
|
||||||
|
Restrictions: 0
|
||||||
|
RadialAxis:
|
||||||
|
Value: 1
|
||||||
|
Center: 1
|
||||||
|
Range: {x: 1, y: 1}
|
||||||
|
Wrap: 0
|
||||||
|
Recentering:
|
||||||
|
Enabled: 0
|
||||||
|
Wait: 1
|
||||||
|
Time: 2
|
||||||
|
Restrictions: 0
|
||||||
|
--- !u!114 &105357817482922116
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5476660720536128040}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1e8b78ac948f05a46a6d8339a503172b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
LookAtOffset: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &5239147339255103855
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5476660720536128040}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: dbe43d662878a7c43bcd44d43c9e2094, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
CollideAgainst:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 1
|
||||||
|
IgnoreTag:
|
||||||
|
TransparentLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
MinimumDistanceFromTarget: 1.1
|
||||||
|
AvoidObstacles:
|
||||||
|
Enabled: 1
|
||||||
|
DistanceLimit: 0
|
||||||
|
MinimumOcclusionTime: 0
|
||||||
|
CameraRadius: 0.3
|
||||||
|
UseFollowTarget:
|
||||||
|
Enabled: 0
|
||||||
|
YOffset: 0
|
||||||
|
Strategy: 0
|
||||||
|
MaximumEffort: 4
|
||||||
|
SmoothingTime: 0
|
||||||
|
Damping: 0.4
|
||||||
|
DampingWhenOccluded: 0.2
|
||||||
|
ShotQualityEvaluation:
|
||||||
|
Enabled: 0
|
||||||
|
OptimalDistance: 10
|
||||||
|
NearLimit: 5
|
||||||
|
FarLimit: 30
|
||||||
|
MaxQualityBoost: 0.2
|
||||||
|
--- !u!114 &111899527427379675
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5476660720536128040}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 89875cdc57c54474a8a74efd9b2a3b5d, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
ScanRecursively: 1
|
||||||
|
SuppressInputWhileBlending: 1
|
||||||
|
IgnoreTimeScale: 0
|
||||||
|
m_ControllerManager:
|
||||||
|
Controllers:
|
||||||
|
- Name: Look Orbit X
|
||||||
|
Owner: {fileID: 1699369473331842138}
|
||||||
|
Enabled: 1
|
||||||
|
Input:
|
||||||
|
InputAction: {fileID: -5630151704836100654, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
|
||||||
|
Gain: 1
|
||||||
|
CancelDeltaTime: 0
|
||||||
|
InputValue: 0
|
||||||
|
Driver:
|
||||||
|
AccelTime: 0.2
|
||||||
|
DecelTime: 0.2
|
||||||
|
- Name: Look Orbit Y
|
||||||
|
Owner: {fileID: 1699369473331842138}
|
||||||
|
Enabled: 1
|
||||||
|
Input:
|
||||||
|
InputAction: {fileID: -5630151704836100654, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
|
||||||
|
Gain: -1
|
||||||
|
CancelDeltaTime: 0
|
||||||
|
InputValue: 0
|
||||||
|
Driver:
|
||||||
|
AccelTime: 0.2
|
||||||
|
DecelTime: 0.2
|
||||||
|
- Name: Orbit Scale
|
||||||
|
Owner: {fileID: 1699369473331842138}
|
||||||
|
Enabled: 1
|
||||||
|
Input:
|
||||||
|
InputAction: {fileID: 5082991133974614888, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
|
||||||
|
Gain: -1
|
||||||
|
CancelDeltaTime: 0
|
||||||
|
InputValue: 0
|
||||||
|
Driver:
|
||||||
|
AccelTime: 0
|
||||||
|
DecelTime: 0
|
||||||
|
PlayerIndex: -1
|
||||||
|
AutoEnableInputs: 1
|
||||||
|
--- !u!114 &7256497806279944528
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5476660720536128040}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 9948893cc71ec924bb9e06e3afd66bd2, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: Assembly-CSharp::CameraOrbitKeyboard
|
||||||
|
horizontalSpeed: 150
|
||||||
|
verticalSpeed: 80
|
||||||
7
game/Assets/Prefabs/Player.prefab.meta
Normal file
7
game/Assets/Prefabs/Player.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4ee2843accacdf44f8c5588357bf772f
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
0
game/Assets/ROLLD.txt
Normal file
0
game/Assets/ROLLD.txt
Normal file
7
game/Assets/ROLLD.txt.meta
Normal file
7
game/Assets/ROLLD.txt.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 86e399105fbd4ee4e8decbb67adab122
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
34
game/Assets/Readme.asset
Normal file
34
game/Assets/Readme.asset
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fcf7219bab7fe46a1ad266029b2fee19, type: 3}
|
||||||
|
m_Name: Readme
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
icon: {fileID: 2800000, guid: 727a75301c3d24613a3ebcec4a24c2c8, type: 3}
|
||||||
|
title: URP Empty Template
|
||||||
|
sections:
|
||||||
|
- heading: Welcome to the Universal Render Pipeline
|
||||||
|
text: This template includes the settings and assets you need to start creating with the Universal Render Pipeline.
|
||||||
|
linkText:
|
||||||
|
url:
|
||||||
|
- heading: URP Documentation
|
||||||
|
text:
|
||||||
|
linkText: Read more about URP
|
||||||
|
url: https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@latest
|
||||||
|
- heading: Forums
|
||||||
|
text:
|
||||||
|
linkText: Get answers and support
|
||||||
|
url: https://forum.unity.com/forums/universal-render-pipeline.383/
|
||||||
|
- heading: Report bugs
|
||||||
|
text:
|
||||||
|
linkText: Submit a report
|
||||||
|
url: https://unity3d.com/unity/qa/bug-reporting
|
||||||
|
loadedLayout: 1
|
||||||
8
game/Assets/Readme.asset.meta
Normal file
8
game/Assets/Readme.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8105016687592461f977c054a80ce2f2
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
game/Assets/Resources.meta
Normal file
8
game/Assets/Resources.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f3b13edb1b795144c80bf482fb46bf4a
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/Resources/Bouncy.physicMaterial
Normal file
15
game/Assets/Resources/Bouncy.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Bouncy
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 0.6
|
||||||
|
m_StaticFriction: 0.6
|
||||||
|
m_Bounciness: 0.74
|
||||||
|
m_FrictionCombine: 0
|
||||||
|
m_BounceCombine: 0
|
||||||
8
game/Assets/Resources/Bouncy.physicMaterial.meta
Normal file
8
game/Assets/Resources/Bouncy.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b09539f4b3dec4f418a63b923933793a
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 13400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/Resources/GelBleu.physicMaterial
Normal file
15
game/Assets/Resources/GelBleu.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: GelBleu
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 0.6
|
||||||
|
m_StaticFriction: 0.6
|
||||||
|
m_Bounciness: 1
|
||||||
|
m_FrictionCombine: 0
|
||||||
|
m_BounceCombine: 3
|
||||||
8
game/Assets/Resources/GelBleu.physicMaterial.meta
Normal file
8
game/Assets/Resources/GelBleu.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 99855f2babc61df49b70ff57e4dc5e5d
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 13400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/Resources/GelOrange.physicMaterial
Normal file
15
game/Assets/Resources/GelOrange.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: GelOrange
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 0.6
|
||||||
|
m_StaticFriction: 0.6
|
||||||
|
m_Bounciness: 0.74
|
||||||
|
m_FrictionCombine: 0
|
||||||
|
m_BounceCombine: 0
|
||||||
8
game/Assets/Resources/GelOrange.physicMaterial.meta
Normal file
8
game/Assets/Resources/GelOrange.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c4b91015238db1a4ba16aa5e5c4efa20
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 13400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/Resources/GelViolet.physicMaterial
Normal file
15
game/Assets/Resources/GelViolet.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: GelViolet
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 1
|
||||||
|
m_StaticFriction: 1
|
||||||
|
m_Bounciness: 0
|
||||||
|
m_FrictionCombine: 3
|
||||||
|
m_BounceCombine: 0
|
||||||
8
game/Assets/Resources/GelViolet.physicMaterial.meta
Normal file
8
game/Assets/Resources/GelViolet.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: efa30f5e48c586d40a08f8dba94f93c4
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
game/Assets/Resources/LiberationSans.ttf
LFS
Normal file
BIN
game/Assets/Resources/LiberationSans.ttf
LFS
Normal file
Binary file not shown.
21
game/Assets/Resources/LiberationSans.ttf.meta
Normal file
21
game/Assets/Resources/LiberationSans.ttf.meta
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 63a89ed196414594bb8d6656bf5eb69e
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- Liberation Sans
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
game/Assets/Resources/Normal.physicMaterial
Normal file
15
game/Assets/Resources/Normal.physicMaterial
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!134 &13400000
|
||||||
|
PhysicsMaterial:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Normal
|
||||||
|
serializedVersion: 2
|
||||||
|
m_DynamicFriction: 0.6
|
||||||
|
m_StaticFriction: 0.6
|
||||||
|
m_Bounciness: 0
|
||||||
|
m_FrictionCombine: 0
|
||||||
|
m_BounceCombine: 0
|
||||||
8
game/Assets/Resources/Normal.physicMaterial.meta
Normal file
8
game/Assets/Resources/Normal.physicMaterial.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 401c7ab0e39322c46ad49105130affee
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 13400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
game/Assets/Scenes.meta
Normal file
8
game/Assets/Scenes.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9c53962885c2c4f449125a979d6ad240
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1455
game/Assets/Scenes/BallSample.unity
Normal file
1455
game/Assets/Scenes/BallSample.unity
Normal file
File diff suppressed because it is too large
Load Diff
7
game/Assets/Scenes/BallSample.unity.meta
Normal file
7
game/Assets/Scenes/BallSample.unity.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bf771c2b873497f4aaaeeed4b6979e5e
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
432
game/Assets/Scenes/SampleScene.unity
Normal file
432
game/Assets/Scenes/SampleScene.unity
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!29 &1
|
||||||
|
OcclusionCullingSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_OcclusionBakeSettings:
|
||||||
|
smallestOccluder: 5
|
||||||
|
smallestHole: 0.25
|
||||||
|
backfaceThreshold: 100
|
||||||
|
m_SceneGUID: 00000000000000000000000000000000
|
||||||
|
m_OcclusionCullingData: {fileID: 0}
|
||||||
|
--- !u!104 &2
|
||||||
|
RenderSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 10
|
||||||
|
m_Fog: 0
|
||||||
|
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||||
|
m_FogMode: 3
|
||||||
|
m_FogDensity: 0.01
|
||||||
|
m_LinearFogStart: 0
|
||||||
|
m_LinearFogEnd: 300
|
||||||
|
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
||||||
|
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
||||||
|
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
||||||
|
m_AmbientIntensity: 1
|
||||||
|
m_AmbientMode: 0
|
||||||
|
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||||
|
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_HaloStrength: 0.5
|
||||||
|
m_FlareStrength: 1
|
||||||
|
m_FlareFadeSpeed: 3
|
||||||
|
m_HaloTexture: {fileID: 0}
|
||||||
|
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
m_DefaultReflectionMode: 0
|
||||||
|
m_DefaultReflectionResolution: 128
|
||||||
|
m_ReflectionBounces: 1
|
||||||
|
m_ReflectionIntensity: 1
|
||||||
|
m_CustomReflection: {fileID: 0}
|
||||||
|
m_Sun: {fileID: 0}
|
||||||
|
m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
|
||||||
|
m_UseRadianceAmbientProbe: 0
|
||||||
|
--- !u!157 &3
|
||||||
|
LightmapSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 12
|
||||||
|
m_GISettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_BounceScale: 1
|
||||||
|
m_IndirectOutputScale: 1
|
||||||
|
m_AlbedoBoost: 1
|
||||||
|
m_EnvironmentLightingMode: 0
|
||||||
|
m_EnableBakedLightmaps: 1
|
||||||
|
m_EnableRealtimeLightmaps: 0
|
||||||
|
m_LightmapEditorSettings:
|
||||||
|
serializedVersion: 12
|
||||||
|
m_Resolution: 2
|
||||||
|
m_BakeResolution: 40
|
||||||
|
m_AtlasSize: 1024
|
||||||
|
m_AO: 0
|
||||||
|
m_AOMaxDistance: 1
|
||||||
|
m_CompAOExponent: 1
|
||||||
|
m_CompAOExponentDirect: 0
|
||||||
|
m_ExtractAmbientOcclusion: 0
|
||||||
|
m_Padding: 2
|
||||||
|
m_LightmapParameters: {fileID: 0}
|
||||||
|
m_LightmapsBakeMode: 1
|
||||||
|
m_TextureCompression: 1
|
||||||
|
m_ReflectionCompression: 2
|
||||||
|
m_MixedBakeMode: 2
|
||||||
|
m_BakeBackend: 1
|
||||||
|
m_PVRSampling: 1
|
||||||
|
m_PVRDirectSampleCount: 32
|
||||||
|
m_PVRSampleCount: 512
|
||||||
|
m_PVRBounces: 2
|
||||||
|
m_PVREnvironmentSampleCount: 256
|
||||||
|
m_PVREnvironmentReferencePointCount: 2048
|
||||||
|
m_PVRFilteringMode: 1
|
||||||
|
m_PVRDenoiserTypeDirect: 1
|
||||||
|
m_PVRDenoiserTypeIndirect: 1
|
||||||
|
m_PVRDenoiserTypeAO: 1
|
||||||
|
m_PVRFilterTypeDirect: 0
|
||||||
|
m_PVRFilterTypeIndirect: 0
|
||||||
|
m_PVRFilterTypeAO: 0
|
||||||
|
m_PVREnvironmentMIS: 1
|
||||||
|
m_PVRCulling: 1
|
||||||
|
m_PVRFilteringGaussRadiusDirect: 1
|
||||||
|
m_PVRFilteringGaussRadiusIndirect: 5
|
||||||
|
m_PVRFilteringGaussRadiusAO: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||||
|
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||||
|
m_ExportTrainingData: 0
|
||||||
|
m_TrainingDataDestination: TrainingData
|
||||||
|
m_LightProbeSampleCountMultiplier: 4
|
||||||
|
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_LightingSettings: {fileID: 0}
|
||||||
|
--- !u!196 &4
|
||||||
|
NavMeshSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_BuildSettings:
|
||||||
|
serializedVersion: 3
|
||||||
|
agentTypeID: 0
|
||||||
|
agentRadius: 0.5
|
||||||
|
agentHeight: 2
|
||||||
|
agentSlope: 45
|
||||||
|
agentClimb: 0.4
|
||||||
|
ledgeDropHeight: 0
|
||||||
|
maxJumpAcrossDistance: 0
|
||||||
|
minRegionArea: 2
|
||||||
|
manualCellSize: 0
|
||||||
|
cellSize: 0.16666667
|
||||||
|
manualTileSize: 0
|
||||||
|
tileSize: 256
|
||||||
|
buildHeightMesh: 0
|
||||||
|
maxJobWorkers: 0
|
||||||
|
preserveTilesOutsideBounds: 0
|
||||||
|
debug:
|
||||||
|
m_Flags: 0
|
||||||
|
m_NavMeshData: {fileID: 0}
|
||||||
|
--- !u!1 &330585543
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 330585546}
|
||||||
|
- component: {fileID: 330585545}
|
||||||
|
- component: {fileID: 330585544}
|
||||||
|
- component: {fileID: 330585547}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Main Camera
|
||||||
|
m_TagString: MainCamera
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!81 &330585544
|
||||||
|
AudioListener:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 330585543}
|
||||||
|
m_Enabled: 1
|
||||||
|
--- !u!20 &330585545
|
||||||
|
Camera:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 330585543}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 2
|
||||||
|
m_ClearFlags: 1
|
||||||
|
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||||
|
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_NormalizedViewPortRect:
|
||||||
|
serializedVersion: 2
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
near clip plane: 0.3
|
||||||
|
far clip plane: 1000
|
||||||
|
field of view: 60
|
||||||
|
orthographic: 0
|
||||||
|
orthographic size: 5
|
||||||
|
m_Depth: -1
|
||||||
|
m_CullingMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 4294967295
|
||||||
|
m_RenderingPath: -1
|
||||||
|
m_TargetTexture: {fileID: 0}
|
||||||
|
m_TargetDisplay: 0
|
||||||
|
m_TargetEye: 3
|
||||||
|
m_HDR: 1
|
||||||
|
m_AllowMSAA: 1
|
||||||
|
m_AllowDynamicResolution: 0
|
||||||
|
m_ForceIntoRT: 0
|
||||||
|
m_OcclusionCulling: 1
|
||||||
|
m_StereoConvergence: 10
|
||||||
|
m_StereoSeparation: 0.022
|
||||||
|
--- !u!4 &330585546
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 330585543}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 1, z: -10}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &330585547
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 330585543}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_RenderShadows: 1
|
||||||
|
m_RequiresDepthTextureOption: 2
|
||||||
|
m_RequiresOpaqueTextureOption: 2
|
||||||
|
m_CameraType: 0
|
||||||
|
m_Cameras: []
|
||||||
|
m_RendererIndex: -1
|
||||||
|
m_VolumeLayerMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 1
|
||||||
|
m_VolumeTrigger: {fileID: 0}
|
||||||
|
m_VolumeFrameworkUpdateModeOption: 2
|
||||||
|
m_RenderPostProcessing: 1
|
||||||
|
m_Antialiasing: 0
|
||||||
|
m_AntialiasingQuality: 2
|
||||||
|
m_StopNaN: 0
|
||||||
|
m_Dithering: 0
|
||||||
|
m_ClearDepth: 1
|
||||||
|
m_AllowXRRendering: 1
|
||||||
|
m_AllowHDROutput: 1
|
||||||
|
m_UseScreenCoordOverride: 0
|
||||||
|
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_RequiresDepthTexture: 0
|
||||||
|
m_RequiresColorTexture: 0
|
||||||
|
m_Version: 2
|
||||||
|
m_TaaSettings:
|
||||||
|
quality: 3
|
||||||
|
frameInfluence: 0.1
|
||||||
|
jitterScale: 1
|
||||||
|
mipBias: 0
|
||||||
|
varianceClampScale: 0.9
|
||||||
|
contrastAdaptiveSharpening: 0
|
||||||
|
--- !u!1 &410087039
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 410087041}
|
||||||
|
- component: {fileID: 410087040}
|
||||||
|
- component: {fileID: 410087042}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Directional Light
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!108 &410087040
|
||||||
|
Light:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 410087039}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 11
|
||||||
|
m_Type: 1
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_Intensity: 2
|
||||||
|
m_Range: 10
|
||||||
|
m_SpotAngle: 30
|
||||||
|
m_InnerSpotAngle: 21.80208
|
||||||
|
m_CookieSize: 10
|
||||||
|
m_Shadows:
|
||||||
|
m_Type: 2
|
||||||
|
m_Resolution: -1
|
||||||
|
m_CustomResolution: -1
|
||||||
|
m_Strength: 1
|
||||||
|
m_Bias: 0.05
|
||||||
|
m_NormalBias: 0.4
|
||||||
|
m_NearPlane: 0.2
|
||||||
|
m_CullingMatrixOverride:
|
||||||
|
e00: 1
|
||||||
|
e01: 0
|
||||||
|
e02: 0
|
||||||
|
e03: 0
|
||||||
|
e10: 0
|
||||||
|
e11: 1
|
||||||
|
e12: 0
|
||||||
|
e13: 0
|
||||||
|
e20: 0
|
||||||
|
e21: 0
|
||||||
|
e22: 1
|
||||||
|
e23: 0
|
||||||
|
e30: 0
|
||||||
|
e31: 0
|
||||||
|
e32: 0
|
||||||
|
e33: 1
|
||||||
|
m_UseCullingMatrixOverride: 0
|
||||||
|
m_Cookie: {fileID: 0}
|
||||||
|
m_DrawHalo: 0
|
||||||
|
m_Flare: {fileID: 0}
|
||||||
|
m_RenderMode: 0
|
||||||
|
m_CullingMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 4294967295
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_Lightmapping: 4
|
||||||
|
m_LightShadowCasterMode: 0
|
||||||
|
m_AreaSize: {x: 1, y: 1}
|
||||||
|
m_BounceIntensity: 1
|
||||||
|
m_ColorTemperature: 5000
|
||||||
|
m_UseColorTemperature: 1
|
||||||
|
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_UseBoundingSphereOverride: 0
|
||||||
|
m_UseViewFrustumForShadowCasterCull: 1
|
||||||
|
m_ForceVisible: 0
|
||||||
|
m_ShadowRadius: 0
|
||||||
|
m_ShadowAngle: 0
|
||||||
|
--- !u!4 &410087041
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 410087039}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
||||||
|
m_LocalPosition: {x: 0, y: 3, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||||
|
--- !u!114 &410087042
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 410087039}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Version: 3
|
||||||
|
m_UsePipelineSettings: 1
|
||||||
|
m_AdditionalLightsShadowResolutionTier: 2
|
||||||
|
m_LightLayerMask: 1
|
||||||
|
m_RenderingLayers: 1
|
||||||
|
m_CustomShadowLayers: 0
|
||||||
|
m_ShadowLayerMask: 1
|
||||||
|
m_ShadowRenderingLayers: 1
|
||||||
|
m_LightCookieSize: {x: 1, y: 1}
|
||||||
|
m_LightCookieOffset: {x: 0, y: 0}
|
||||||
|
m_SoftShadowQuality: 1
|
||||||
|
--- !u!1 &832575517
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 832575519}
|
||||||
|
- component: {fileID: 832575518}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Global Volume
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &832575518
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 832575517}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 172515602e62fb746b5d573b38a5fe58, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_IsGlobal: 1
|
||||||
|
priority: 0
|
||||||
|
blendDistance: 0
|
||||||
|
weight: 1
|
||||||
|
sharedProfile: {fileID: 11400000, guid: 10fc4df2da32a41aaa32d77bc913491c, type: 2}
|
||||||
|
--- !u!4 &832575519
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 832575517}
|
||||||
|
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!1660057539 &9223372036854775807
|
||||||
|
SceneRoots:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_Roots:
|
||||||
|
- {fileID: 330585546}
|
||||||
|
- {fileID: 410087041}
|
||||||
|
- {fileID: 832575519}
|
||||||
7
game/Assets/Scenes/SampleScene.unity.meta
Normal file
7
game/Assets/Scenes/SampleScene.unity.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 99c9720ab356a0642a771bea13969a05
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
5218
game/Assets/Scenes/Tutorial.unity
Normal file
5218
game/Assets/Scenes/Tutorial.unity
Normal file
File diff suppressed because it is too large
Load Diff
7
game/Assets/Scenes/Tutorial.unity.meta
Normal file
7
game/Assets/Scenes/Tutorial.unity.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b4fc289f5833f754392af65bd8b5bac0
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
game/Assets/Scripts.meta
Normal file
8
game/Assets/Scripts.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2b823c5a766b721479afefc032a262b2
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
573
game/Assets/Scripts/ArenaZoneBuilder.cs
Normal file
573
game/Assets/Scripts/ArenaZoneBuilder.cs
Normal file
@@ -0,0 +1,573 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds a compact 80×80 tutorial arena at runtime with connected zones:
|
||||||
|
///
|
||||||
|
/// Zone A (South) — Movement basics + jump gaps
|
||||||
|
/// Zone B (Center-S) — Bounce (GelBleu) training
|
||||||
|
/// Zone C (West) — Speed (GelOrange) training
|
||||||
|
/// Zone D (NW) — Moving platforms
|
||||||
|
/// Zone E (NE) — Sticky walls (GelViolet) training
|
||||||
|
/// Zone F (North) — Combo challenge (all gels + platforms)
|
||||||
|
/// Zone G (Center) — Central tower (final challenge)
|
||||||
|
///
|
||||||
|
/// Spawn: (0, 2, -30) — south edge
|
||||||
|
///
|
||||||
|
/// Ball capabilities reference (from PlayerController):
|
||||||
|
/// Max jump height ≈ 5.1 units (JumpForce=10, gravity=9.81)
|
||||||
|
/// Horizontal jump range ≈ 6-8 units at cruising speed
|
||||||
|
/// GelBleu bounce = perfect elasticity (bounciness 1.0, combine=Max)
|
||||||
|
/// GelOrange speed = ×3.83 multiplier (~19 u/s)
|
||||||
|
/// GelViolet sticky = surface-relative movement, jump = surface normal
|
||||||
|
/// Ball radius = 0.5, min platform 2×2 for playability
|
||||||
|
///
|
||||||
|
/// Loads PhysicMaterials from Resources/ folder.
|
||||||
|
/// Attach to a persistent GameObject (e.g. NetworkManager).
|
||||||
|
/// </summary>
|
||||||
|
public class ArenaZoneBuilder : MonoBehaviour
|
||||||
|
{
|
||||||
|
private PhysicsMaterial _matGelBleu;
|
||||||
|
private PhysicsMaterial _matGelOrange;
|
||||||
|
private PhysicsMaterial _matGelViolet;
|
||||||
|
private PhysicsMaterial _matBouncy;
|
||||||
|
private PhysicsMaterial _matNormal;
|
||||||
|
private Material _baseMat;
|
||||||
|
|
||||||
|
private readonly List<MovingPlatform> _movingPlatforms = new List<MovingPlatform>();
|
||||||
|
|
||||||
|
// ── Color palette ──
|
||||||
|
private static readonly Color ColFloor = new Color(0.28f, 0.29f, 0.34f, 1f);
|
||||||
|
private static readonly Color ColBleu = new Color(0.2f, 0.5f, 1f, 0.85f);
|
||||||
|
private static readonly Color ColBleuLt = new Color(0.3f, 0.65f, 1f, 0.9f);
|
||||||
|
private static readonly Color ColOrange = new Color(1f, 0.55f, 0.1f, 0.85f);
|
||||||
|
private static readonly Color ColOrangeLt = new Color(1f, 0.65f, 0.2f, 0.9f);
|
||||||
|
private static readonly Color ColViolet = new Color(0.6f, 0.2f, 0.8f, 0.8f);
|
||||||
|
private static readonly Color ColVioletLt = new Color(0.7f, 0.35f, 0.9f, 0.85f);
|
||||||
|
private static readonly Color ColNormal = new Color(0.42f, 0.43f, 0.50f, 0.9f);
|
||||||
|
private static readonly Color ColNormalLt = new Color(0.52f, 0.53f, 0.60f, 0.95f);
|
||||||
|
private static readonly Color ColDark = new Color(0.22f, 0.22f, 0.28f, 0.95f);
|
||||||
|
private static readonly Color ColGold = new Color(1f, 0.84f, 0f, 0.95f);
|
||||||
|
private static readonly Color ColWall = new Color(0.35f, 0.35f, 0.42f, 0.95f);
|
||||||
|
private static readonly Color ColPath = new Color(0.38f, 0.40f, 0.48f, 0.9f);
|
||||||
|
private static readonly Color ColSignBleu = new Color(0.15f, 0.4f, 0.9f, 0.95f);
|
||||||
|
private static readonly Color ColSignOrange= new Color(0.9f, 0.45f, 0.05f, 0.95f);
|
||||||
|
private static readonly Color ColSignViolet= new Color(0.5f, 0.15f, 0.7f, 0.95f);
|
||||||
|
private static readonly Color ColSignGrey = new Color(0.5f, 0.5f, 0.55f, 0.95f);
|
||||||
|
private static readonly Color ColSignGold = new Color(0.9f, 0.75f, 0f, 0.95f);
|
||||||
|
private static readonly Color ColGuide = new Color(0.5f, 0.5f, 0.6f, 0.5f);
|
||||||
|
|
||||||
|
// ── Constants ──
|
||||||
|
private const float HALF = 40f; // Arena half-size
|
||||||
|
private const float WALL_H = 12f; // Perimeter wall height
|
||||||
|
private const float WALL_T = 1f; // Perimeter wall thickness
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
LoadMaterials();
|
||||||
|
if (_baseMat == null) FindBaseMaterial();
|
||||||
|
|
||||||
|
BuildFloorAndWalls();
|
||||||
|
BuildPaths();
|
||||||
|
BuildZoneA_Movement();
|
||||||
|
BuildZoneB_Bounce();
|
||||||
|
BuildZoneC_Speed();
|
||||||
|
BuildZoneD_MovingPlatforms();
|
||||||
|
BuildZoneE_StickyWalls();
|
||||||
|
BuildZoneF_Combo();
|
||||||
|
BuildZoneG_CentralTower();
|
||||||
|
|
||||||
|
Debug.Log("[ArenaZoneBuilder] 80x80 tutorial arena built successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _movingPlatforms.Count; i++)
|
||||||
|
{
|
||||||
|
var mp = _movingPlatforms[i];
|
||||||
|
if (mp.go == null) continue;
|
||||||
|
mp.t += Time.deltaTime * mp.speed;
|
||||||
|
float ping = Mathf.PingPong(mp.t, 1f);
|
||||||
|
mp.go.transform.position = Vector3.Lerp(mp.posA, mp.posB, ping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
_movingPlatforms.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// FLOOR, WALLS & PATHS
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void BuildFloorAndWalls()
|
||||||
|
{
|
||||||
|
// Main floor
|
||||||
|
CreateZone("Arena_Floor", new Vector3(0, -0.25f, 0),
|
||||||
|
new Vector3(HALF * 2f, 0.5f, HALF * 2f), _matNormal, ColFloor);
|
||||||
|
|
||||||
|
// Perimeter walls (high to prevent escape)
|
||||||
|
float h2 = WALL_H / 2f;
|
||||||
|
float full = HALF * 2f + 2f;
|
||||||
|
CreateZone("Wall_N", new Vector3(0, h2, HALF), new Vector3(full, WALL_H, WALL_T), _matNormal, ColWall);
|
||||||
|
CreateZone("Wall_S", new Vector3(0, h2, -HALF), new Vector3(full, WALL_H, WALL_T), _matNormal, ColWall);
|
||||||
|
CreateZone("Wall_E", new Vector3(HALF, h2, 0), new Vector3(WALL_T, WALL_H, full), _matNormal, ColWall);
|
||||||
|
CreateZone("Wall_W", new Vector3(-HALF, h2, 0), new Vector3(WALL_T, WALL_H, full), _matNormal, ColWall);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ground-level paths connecting all zones, with directional color markers.</summary>
|
||||||
|
private void BuildPaths()
|
||||||
|
{
|
||||||
|
float pathH = 0.06f;
|
||||||
|
float pathY = 0.03f;
|
||||||
|
|
||||||
|
// Spawn -> Zone A (already at spawn)
|
||||||
|
// Zone A -> Zone B (south to center-south)
|
||||||
|
CreateZone("Path_A_B", new Vector3(0, pathY, -22f), new Vector3(3f, pathH, 10f), _matNormal, ColPath);
|
||||||
|
// Zone B -> Zone G center
|
||||||
|
CreateZone("Path_B_G", new Vector3(0, pathY, -8f), new Vector3(3f, pathH, 10f), _matNormal, ColPath);
|
||||||
|
// Zone G -> Zone C (center to west)
|
||||||
|
CreateZone("Path_G_C", new Vector3(-10f, pathY, 0f), new Vector3(12f, pathH, 3f), _matNormal, ColPath);
|
||||||
|
// Zone C -> Zone D (west to northwest)
|
||||||
|
CreateZone("Path_C_D", new Vector3(-28f, pathY, 12f), new Vector3(3f, pathH, 16f), _matNormal, ColPath);
|
||||||
|
// Zone G -> Zone E (center to northeast)
|
||||||
|
CreateZone("Path_G_E", new Vector3(12f, pathY, 10f), new Vector3(16f, pathH, 3f), _matNormal, ColPath);
|
||||||
|
// Zone D/E -> Zone F (north)
|
||||||
|
CreateZone("Path_D_F", new Vector3(-12f, pathY, 28f), new Vector3(16f, pathH, 3f), _matNormal, ColPath);
|
||||||
|
CreateZone("Path_E_F", new Vector3(12f, pathY, 28f), new Vector3(16f, pathH, 3f), _matNormal, ColPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// ZONE A — MOVEMENT BASICS + JUMP GAPS (South)
|
||||||
|
// Origin: (0, 0, -32)
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void BuildZoneA_Movement()
|
||||||
|
{
|
||||||
|
// Sign
|
||||||
|
CreateSign("Sign_A", new Vector3(-4f, 1.5f, -35f), ColSignGrey);
|
||||||
|
|
||||||
|
// Spawn platform (raised)
|
||||||
|
CreateZone("A_Spawn", new Vector3(0, 0.4f, -32f), new Vector3(8f, 0.8f, 6f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Straight corridor with slight turns to learn rolling
|
||||||
|
CreateZone("A_Corr1", new Vector3(0, 0.15f, -27f), new Vector3(4f, 0.3f, 5f), _matNormal, ColNormal);
|
||||||
|
CreateZone("A_Corr2", new Vector3(3f, 0.15f, -23f), new Vector3(4f, 0.3f, 4f), _matNormal, ColNormal);
|
||||||
|
CreateZone("A_Corr3", new Vector3(0f, 0.15f, -19.5f), new Vector3(4f, 0.3f, 4f), _matNormal, ColNormal);
|
||||||
|
|
||||||
|
// Low guide walls for the corridor
|
||||||
|
CreateZone("A_GuideL1", new Vector3(-2.5f, 0.6f, -27f), new Vector3(0.3f, 0.9f, 5f), _matNormal, ColGuide);
|
||||||
|
CreateZone("A_GuideR1", new Vector3(2.5f, 0.6f, -27f), new Vector3(0.3f, 0.9f, 5f), _matNormal, ColGuide);
|
||||||
|
|
||||||
|
// Jump gaps: 3 gaps of increasing difficulty
|
||||||
|
// Gap 1: 2 units gap
|
||||||
|
CreateZone("A_Plat1", new Vector3(-3f, 0.15f, -16f), new Vector3(4f, 0.3f, 4f), _matNormal, ColNormalLt);
|
||||||
|
// (gap of 2 units)
|
||||||
|
CreateZone("A_Plat2", new Vector3(-3f, 0.15f, -10f), new Vector3(4f, 0.3f, 4f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Gap 2: 3 units gap
|
||||||
|
// (gap of 3 units)
|
||||||
|
CreateZone("A_Plat3", new Vector3(-3f, 0.15f, -3f), new Vector3(4f, 0.3f, 4f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Gap 3: 4.5 units gap (needs charged jump)
|
||||||
|
// (gap of 4.5 units)
|
||||||
|
CreateZone("A_Plat4", new Vector3(-3f, 0.15f, 5f), new Vector3(4f, 0.3f, 4f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Return ramp to ground
|
||||||
|
CreateRamp("A_Ramp", new Vector3(-3f, 1.0f, 9f), new Vector3(4f, 0.3f, 5f),
|
||||||
|
-12f, Vector3.right, _matNormal, ColNormal);
|
||||||
|
|
||||||
|
Debug.Log("[ArenaZoneBuilder] Zone A (Movement) built.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// ZONE B — BOUNCE TRAINING (Center-South)
|
||||||
|
// Origin: (10, 0, -15)
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void BuildZoneB_Bounce()
|
||||||
|
{
|
||||||
|
Vector3 o = new Vector3(10f, 0f, -15f);
|
||||||
|
|
||||||
|
// Sign
|
||||||
|
CreateSign("Sign_B", o + new Vector3(-3f, 1.5f, -3f), ColSignBleu);
|
||||||
|
|
||||||
|
// Entry pad
|
||||||
|
CreateZone("B_Entry", o + new Vector3(0, 0.15f, 0), new Vector3(5f, 0.3f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Bounce pads with targets at increasing heights
|
||||||
|
// Pad 1 (small) -> target at 3m
|
||||||
|
CreateZone("B_Pad1", o + new Vector3(0, 0.2f, 5f), new Vector3(3f, 0.25f, 3f), _matGelBleu, ColBleu);
|
||||||
|
CreateZone("B_Tgt1", o + new Vector3(0, 3f, 9f), new Vector3(4f, 0.4f, 4f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Pad 2 (medium) -> target at 4.5m
|
||||||
|
CreateZone("B_Pad2", o + new Vector3(0, 3.2f, 9f), new Vector3(3.5f, 0.25f, 3.5f), _matGelBleu, ColBleuLt);
|
||||||
|
CreateZone("B_Tgt2", o + new Vector3(4f, 5.5f, 12f), new Vector3(4f, 0.4f, 4f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Pad 3 on target 2 -> top at 8m
|
||||||
|
CreateZone("B_Pad3", o + new Vector3(4f, 5.7f, 12f), new Vector3(3f, 0.2f, 3f), _matGelBleu, ColBleu);
|
||||||
|
CreateZone("B_Tgt3", o + new Vector3(0, 8f, 15f), new Vector3(5f, 0.4f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Bounce staircase: fall from 8m -> bounce up further
|
||||||
|
CreateZone("B_Stair_Bnc", o + new Vector3(-5f, 0.2f, 15f), new Vector3(4f, 0.25f, 4f), _matGelBleu, ColBleu);
|
||||||
|
CreateZone("B_Stair_Mid", o + new Vector3(-5f, 5f, 19f), new Vector3(4f, 0.4f, 4f), _matNormal, ColNormalLt);
|
||||||
|
CreateZone("B_Stair_Top", o + new Vector3(-5f, 8.5f, 23f), new Vector3(5f, 0.4f, 4f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Return to ground via gentle ramp
|
||||||
|
CreateRamp("B_Return", o + new Vector3(-5f, 4f, 27f), new Vector3(4f, 0.3f, 8f),
|
||||||
|
-20f, Vector3.right, _matNormal, ColNormal);
|
||||||
|
|
||||||
|
Debug.Log("[ArenaZoneBuilder] Zone B (Bounce) built.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// ZONE C — SPEED TRAINING (West)
|
||||||
|
// Origin: (-25, 0, -5)
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void BuildZoneC_Speed()
|
||||||
|
{
|
||||||
|
Vector3 o = new Vector3(-25f, 0f, -5f);
|
||||||
|
|
||||||
|
// Sign
|
||||||
|
CreateSign("Sign_C", o + new Vector3(8f, 1.5f, -2f), ColSignOrange);
|
||||||
|
|
||||||
|
// Entry
|
||||||
|
CreateZone("C_Entry", o + new Vector3(0, 0.15f, 0), new Vector3(5f, 0.3f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Speed strip 1 -> short, straight, with ramp launch
|
||||||
|
CreateZone("C_Strip1", o + new Vector3(0, 0.12f, 5f), new Vector3(4f, 0.15f, 8f), _matGelOrange, ColOrange);
|
||||||
|
// Guide walls
|
||||||
|
CreateZone("C_GuideL1", new Vector3(o.x - 2.5f, 0.5f, o.z + 5f), new Vector3(0.3f, 1f, 8f), _matNormal, ColGuide);
|
||||||
|
CreateZone("C_GuideR1", new Vector3(o.x + 2.5f, 0.5f, o.z + 5f), new Vector3(0.3f, 1f, 8f), _matNormal, ColGuide);
|
||||||
|
|
||||||
|
// Ramp at end of strip 1
|
||||||
|
CreateRamp("C_Ramp1", o + new Vector3(0, 0.8f, 10.5f), new Vector3(4f, 0.25f, 4f),
|
||||||
|
20f, Vector3.right, _matGelOrange, ColOrangeLt);
|
||||||
|
|
||||||
|
// Landing platform (12m ahead, 2m up)
|
||||||
|
CreateZone("C_Land1", o + new Vector3(0, 2f, 18f), new Vector3(5f, 0.4f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Speed strip 2 -> longer with a curve
|
||||||
|
CreateZone("C_Strip2a", o + new Vector3(0, 2.1f, 22f), new Vector3(4f, 0.15f, 5f), _matGelOrange, ColOrange);
|
||||||
|
CreateZone("C_Strip2b", o + new Vector3(4f, 2.1f, 26f), new Vector3(5f, 0.15f, 4f), _matGelOrange, ColOrangeLt);
|
||||||
|
CreateZone("C_Strip2c", o + new Vector3(8f, 2.1f, 30f), new Vector3(4f, 0.15f, 5f), _matGelOrange, ColOrange);
|
||||||
|
// Guide walls for curve
|
||||||
|
CreateZone("C_GuideO", o + new Vector3(-2.5f, 2.6f, 22f), new Vector3(0.3f, 1f, 5f), _matNormal, ColGuide);
|
||||||
|
CreateZone("C_GuideI", o + new Vector3(10.5f, 2.6f, 30f), new Vector3(0.3f, 1f, 5f), _matNormal, ColGuide);
|
||||||
|
|
||||||
|
// Final landing with another ramp
|
||||||
|
CreateRamp("C_Ramp2", o + new Vector3(8f, 3f, 34f), new Vector3(4f, 0.25f, 4f),
|
||||||
|
25f, Vector3.right, _matGelOrange, ColOrangeLt);
|
||||||
|
CreateZone("C_Land2", o + new Vector3(8f, 4.5f, 38f), new Vector3(6f, 0.4f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
Debug.Log("[ArenaZoneBuilder] Zone C (Speed) built.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// ZONE D — MOVING PLATFORMS (Northwest)
|
||||||
|
// Origin: (-28, 0, 18)
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void BuildZoneD_MovingPlatforms()
|
||||||
|
{
|
||||||
|
Vector3 o = new Vector3(-28f, 0f, 18f);
|
||||||
|
|
||||||
|
// Sign
|
||||||
|
CreateSign("Sign_D", o + new Vector3(4f, 1.5f, -2f), ColSignGrey);
|
||||||
|
|
||||||
|
// Entry platform
|
||||||
|
CreateZone("D_Entry", o + new Vector3(0, 0.2f, 0), new Vector3(6f, 0.4f, 6f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// 3 horizontal sliders (oscillate along X, spaced along Z, rising)
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
Vector3 a = o + new Vector3(-2f, 1.5f + i * 2f, 5f + i * 6f);
|
||||||
|
Vector3 b = a + new Vector3(8f, 0f, 0f);
|
||||||
|
var go = CreateZone("D_Slide" + i, a, new Vector3(4f, 0.5f, 4f), _matNormal, ColDark);
|
||||||
|
AddMovingPlatform(go, a, b, 0.3f + i * 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mid-platform
|
||||||
|
CreateZone("D_Mid", o + new Vector3(2f, 7f, 20f), new Vector3(5f, 0.4f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// 2 vertical lifts
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
Vector3 a = o + new Vector3(-4f + i * 8f, 7.5f, 24f + i * 5f);
|
||||||
|
Vector3 b = a + new Vector3(0f, 5f, 0f);
|
||||||
|
var go = CreateZone("D_Lift" + i, a, new Vector3(4f, 0.5f, 4f), _matNormal, ColDark);
|
||||||
|
AddMovingPlatform(go, a, b, 0.22f + i * 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// End platform (high, with view)
|
||||||
|
CreateZone("D_End", o + new Vector3(2f, 12f, 32f), new Vector3(6f, 0.4f, 6f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Bouncy descent pad at ground level
|
||||||
|
CreateZone("D_Desc", o + new Vector3(2f, 0.2f, 32f), new Vector3(4f, 0.25f, 4f), _matGelBleu, ColBleu);
|
||||||
|
|
||||||
|
Debug.Log("[ArenaZoneBuilder] Zone D (Moving Platforms) built.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// ZONE E — STICKY WALLS (Northeast)
|
||||||
|
// Origin: (24, 0, 15)
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void BuildZoneE_StickyWalls()
|
||||||
|
{
|
||||||
|
Vector3 o = new Vector3(24f, 0f, 15f);
|
||||||
|
|
||||||
|
// Sign
|
||||||
|
CreateSign("Sign_E", o + new Vector3(-5f, 1.5f, -2f), ColSignViolet);
|
||||||
|
|
||||||
|
// Entry pad
|
||||||
|
CreateZone("E_Entry", o + new Vector3(0, 0.15f, 0), new Vector3(5f, 0.3f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// === Intro wall: simple vertical climb (4m high) ===
|
||||||
|
// Wall face pointing -X (ball approaches from the left)
|
||||||
|
CreateZone("E_Wall1", o + new Vector3(3f, 3f, 3f), new Vector3(0.5f, 6f, 5f), _matGelViolet, ColViolet);
|
||||||
|
// Platform at top of wall
|
||||||
|
CreateZone("E_Top1", o + new Vector3(3f, 6.2f, 3f), new Vector3(4f, 0.4f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// === L-shaped sticky: wall -> turn -> wall ===
|
||||||
|
// Vertical wall going up (face -Z)
|
||||||
|
CreateZone("E_Wall2a", o + new Vector3(0, 3.5f, 8f), new Vector3(4f, 7f, 0.5f), _matGelViolet, ColViolet);
|
||||||
|
// Ceiling connecting to second wall (face down, -Y)
|
||||||
|
CreateZone("E_Ceil", o + new Vector3(0, 7.1f, 10f), new Vector3(4f, 0.5f, 4f), _matGelViolet, ColVioletLt);
|
||||||
|
// Second wall going down (face +Z)
|
||||||
|
CreateZone("E_Wall2b", o + new Vector3(0, 3.5f, 12f), new Vector3(4f, 7f, 0.5f), _matGelViolet, ColViolet);
|
||||||
|
// Landing after L traverse
|
||||||
|
CreateZone("E_Land2", o + new Vector3(0, 0.2f, 14f), new Vector3(5f, 0.4f, 4f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// === Vertical tunnel: two sticky walls face-to-face, zigzag up ===
|
||||||
|
// Left wall
|
||||||
|
CreateZone("E_Tun_L", o + new Vector3(-3.5f, 6f, 18f), new Vector3(0.5f, 12f, 4f), _matGelViolet, ColViolet);
|
||||||
|
// Right wall
|
||||||
|
CreateZone("E_Tun_R", o + new Vector3(3.5f, 6f, 18f), new Vector3(0.5f, 12f, 4f), _matGelViolet, ColVioletLt);
|
||||||
|
// Small ledges alternating sides to help zigzag
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
float side = (i % 2 == 0) ? -2.5f : 2.5f;
|
||||||
|
float h = 2f + i * 2.8f;
|
||||||
|
CreateZone("E_Tun_Ledge" + i, o + new Vector3(side, h, 18f),
|
||||||
|
new Vector3(2f, 0.3f, 3f), _matNormal, ColNormalLt);
|
||||||
|
}
|
||||||
|
// Top of tunnel
|
||||||
|
CreateZone("E_TunTop", o + new Vector3(0, 12.2f, 18f), new Vector3(5f, 0.4f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
Debug.Log("[ArenaZoneBuilder] Zone E (Sticky Walls) built.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// ZONE F — COMBO CHALLENGE (North)
|
||||||
|
// Origin: (0, 0, 30)
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void BuildZoneF_Combo()
|
||||||
|
{
|
||||||
|
Vector3 o = new Vector3(0f, 0f, 30f);
|
||||||
|
|
||||||
|
// Sign
|
||||||
|
CreateSign("Sign_F", o + new Vector3(-5f, 1.5f, -4f), ColSignGold);
|
||||||
|
|
||||||
|
// Entry
|
||||||
|
CreateZone("F_Entry", o + new Vector3(0, 0.15f, 0), new Vector3(5f, 0.3f, 5f), _matNormal, ColNormalLt);
|
||||||
|
|
||||||
|
// Step 1: Speed strip launch
|
||||||
|
CreateZone("F_Speed", o + new Vector3(0, 0.12f, 4f), new Vector3(3f, 0.15f, 6f), _matGelOrange, ColOrange);
|
||||||
|
CreateZone("F_GuidL", o + new Vector3(-2f, 0.5f, 4f), new Vector3(0.3f, 0.7f, 6f), _matNormal, ColGuide);
|
||||||
|
CreateZone("F_GuidR", o + new Vector3(2f, 0.5f, 4f), new Vector3(0.3f, 0.7f, 6f), _matNormal, ColGuide);
|
||||||
|
|
||||||
|
// Step 2: Ramp -> bounce pad
|
||||||
|
CreateRamp("F_Ramp", o + new Vector3(0, 0.6f, 8.5f), new Vector3(3f, 0.25f, 3f),
|
||||||
|
22f, Vector3.right, _matGelOrange, ColOrangeLt);
|
||||||
|
CreateZone("F_BncPad", o + new Vector3(0, 0.2f, 13f), new Vector3(4f, 0.25f, 4f), _matGelBleu, ColBleu);
|
||||||
|
|
||||||
|
// Step 3: High platform with sticky wall leading higher
|
||||||
|
CreateZone("F_MidPlat", o + new Vector3(0, 4.5f, 17f), new Vector3(5f, 0.4f, 4f), _matNormal, ColNormalLt);
|
||||||
|
CreateZone("F_StickyWall", o + new Vector3(-3f, 7f, 17f), new Vector3(0.5f, 5f, 4f), _matGelViolet, ColViolet);
|
||||||
|
|
||||||
|
// Step 4: Moving platform to final
|
||||||
|
Vector3 mpA = o + new Vector3(0, 9.5f, 17f);
|
||||||
|
Vector3 mpB = o + new Vector3(0, 9.5f, 23f);
|
||||||
|
var mp = CreateZone("F_MovPlat", mpA, new Vector3(4f, 0.5f, 4f), _matNormal, ColDark);
|
||||||
|
AddMovingPlatform(mp, mpA, mpB, 0.25f);
|
||||||
|
|
||||||
|
// Step 5: Gold finish platform
|
||||||
|
CreateZone("F_Finish", o + new Vector3(0, 10f, 27f), new Vector3(6f, 0.5f, 5f), _matNormal, ColGold);
|
||||||
|
CreateZone("F_FinBnc", o + new Vector3(0, 10.3f, 27f), new Vector3(3f, 0.2f, 3f), _matGelBleu, ColBleuLt);
|
||||||
|
|
||||||
|
Debug.Log("[ArenaZoneBuilder] Zone F (Combo) built.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// ZONE G — CENTRAL TOWER (Center)
|
||||||
|
// Origin: (0, 0, 5)
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void BuildZoneG_CentralTower()
|
||||||
|
{
|
||||||
|
Vector3 o = new Vector3(0f, 0f, 5f);
|
||||||
|
|
||||||
|
// Base (accessible from ground)
|
||||||
|
CreateZone("G_Base", o + new Vector3(0, 0.25f, 0), new Vector3(10f, 0.5f, 10f), _matNormal, ColNormal);
|
||||||
|
|
||||||
|
// Access ramp from south
|
||||||
|
CreateRamp("G_Ramp", o + new Vector3(0, 0.8f, -6f), new Vector3(4f, 0.3f, 5f),
|
||||||
|
-10f, Vector3.right, _matNormal, ColNormal);
|
||||||
|
|
||||||
|
// Level 1: Bounce pad -> L2
|
||||||
|
CreateZone("G_L1_Bnc", o + new Vector3(0, 0.5f, 0), new Vector3(3.5f, 0.25f, 3.5f), _matGelBleu, ColBleu);
|
||||||
|
|
||||||
|
// Level 2 (3.5m): platform + speed strip
|
||||||
|
CreateZone("G_L2", o + new Vector3(0, 3.5f, 0), new Vector3(8f, 0.4f, 8f), _matNormal, ColNormalLt);
|
||||||
|
CreateZone("G_L2_Spd", o + new Vector3(0, 3.7f, 0), new Vector3(6f, 0.15f, 2f), _matGelOrange, ColOrange);
|
||||||
|
CreateRamp("G_L2_Ramp", o + new Vector3(3f, 4.5f, 3f), new Vector3(3f, 0.25f, 3f),
|
||||||
|
25f, Vector3.right, _matGelOrange, ColOrangeLt);
|
||||||
|
|
||||||
|
// Level 3 (7m): platform + moving platform to L4
|
||||||
|
CreateZone("G_L3", o + new Vector3(0, 7f, 0), new Vector3(7f, 0.4f, 7f), _matNormal, ColNormalLt);
|
||||||
|
CreateZone("G_L3_Bnc", o + new Vector3(2f, 7.25f, 2f), new Vector3(3f, 0.2f, 3f), _matGelBleu, ColBleuLt);
|
||||||
|
|
||||||
|
// Moving platform L3->L4
|
||||||
|
Vector3 mp3a = o + new Vector3(5f, 8f, 0);
|
||||||
|
Vector3 mp3b = o + new Vector3(0, 8f, 5f);
|
||||||
|
var m3 = CreateZone("G_MP3", mp3a, new Vector3(3.5f, 0.5f, 3.5f), _matNormal, ColDark);
|
||||||
|
AddMovingPlatform(m3, mp3a, mp3b, 0.2f);
|
||||||
|
|
||||||
|
// Level 4 (10.5m): platform + sticky wall to L5
|
||||||
|
CreateZone("G_L4", o + new Vector3(0, 10.5f, 0), new Vector3(7f, 0.4f, 7f), _matNormal, ColNormalLt);
|
||||||
|
CreateZone("G_L4_Sticky", o + new Vector3(-3.8f, 13f, 0), new Vector3(0.5f, 5f, 5f), _matGelViolet, ColViolet);
|
||||||
|
|
||||||
|
// Level 5 — SUMMIT (15.5m): gold platform
|
||||||
|
CreateZone("G_L5", o + new Vector3(0, 15.5f, 0), new Vector3(8f, 0.5f, 8f), _matNormal, ColGold);
|
||||||
|
CreateZone("G_L5_Bnc", o + new Vector3(0, 15.85f, 0), new Vector3(4f, 0.25f, 4f), _matGelBleu, ColBleuLt);
|
||||||
|
|
||||||
|
// Orbital moving platform for alternative L3->L4 access
|
||||||
|
Vector3 orb_a = o + new Vector3(-6f, 9f, 0);
|
||||||
|
Vector3 orb_b = o + new Vector3(0, 9f, -6f);
|
||||||
|
var orb = CreateZone("G_Orb", orb_a, new Vector3(3.5f, 0.5f, 3.5f), _matNormal, ColDark);
|
||||||
|
AddMovingPlatform(orb, orb_a, orb_b, 0.18f);
|
||||||
|
|
||||||
|
Debug.Log("[ArenaZoneBuilder] Zone G (Central Tower) built.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// SIGN HELPER (zone entrance markers)
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void CreateSign(string name, Vector3 position, Color color)
|
||||||
|
{
|
||||||
|
// Tall thin panel as zone marker
|
||||||
|
CreateZone(name, position, new Vector3(0.3f, 2.5f, 0.3f), _matNormal, color);
|
||||||
|
// Colored cap on top
|
||||||
|
CreateZone(name + "_Cap", position + new Vector3(0, 1.45f, 0), new Vector3(0.8f, 0.4f, 0.8f), _matNormal, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// MATERIAL LOADING
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private void LoadMaterials()
|
||||||
|
{
|
||||||
|
_matGelBleu = Resources.Load<PhysicsMaterial>("GelBleu");
|
||||||
|
_matGelOrange = Resources.Load<PhysicsMaterial>("GelOrange");
|
||||||
|
_matGelViolet = Resources.Load<PhysicsMaterial>("GelViolet");
|
||||||
|
_matBouncy = Resources.Load<PhysicsMaterial>("Bouncy");
|
||||||
|
_matNormal = Resources.Load<PhysicsMaterial>("Normal");
|
||||||
|
|
||||||
|
if (_matGelBleu == null) Debug.LogWarning("[ArenaZoneBuilder] GelBleu not found in Resources!");
|
||||||
|
if (_matGelOrange == null) Debug.LogWarning("[ArenaZoneBuilder] GelOrange not found in Resources!");
|
||||||
|
if (_matGelViolet == null) Debug.LogWarning("[ArenaZoneBuilder] GelViolet not found in Resources!");
|
||||||
|
if (_matBouncy == null) Debug.LogWarning("[ArenaZoneBuilder] Bouncy not found in Resources!");
|
||||||
|
if (_matNormal == null) Debug.LogWarning("[ArenaZoneBuilder] Normal not found in Resources!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FindBaseMaterial()
|
||||||
|
{
|
||||||
|
var shader = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard");
|
||||||
|
_baseMat = new Material(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// ZONE HELPERS
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private GameObject CreateZone(string name, Vector3 position, Vector3 size,
|
||||||
|
PhysicsMaterial physMat, Color color)
|
||||||
|
{
|
||||||
|
var go = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||||
|
go.name = name;
|
||||||
|
go.transform.position = position;
|
||||||
|
go.transform.localScale = size;
|
||||||
|
go.isStatic = true;
|
||||||
|
|
||||||
|
var col = go.GetComponent<Collider>();
|
||||||
|
if (col != null && physMat != null) col.material = physMat;
|
||||||
|
|
||||||
|
var rend = go.GetComponent<Renderer>();
|
||||||
|
if (rend != null)
|
||||||
|
{
|
||||||
|
var mat = new Material(_baseMat);
|
||||||
|
SetMatColor(mat, color);
|
||||||
|
if (color.a < 1f) SetMatTransparent(mat, color);
|
||||||
|
rend.material = mat;
|
||||||
|
}
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameObject CreateRamp(string name, Vector3 position, Vector3 size,
|
||||||
|
float angle, Vector3 axis, PhysicsMaterial physMat, Color color)
|
||||||
|
{
|
||||||
|
var go = CreateZone(name, position, size, physMat, color);
|
||||||
|
go.transform.rotation = Quaternion.AngleAxis(angle, axis);
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddMovingPlatform(GameObject go, Vector3 posA, Vector3 posB, float speed)
|
||||||
|
{
|
||||||
|
go.isStatic = false;
|
||||||
|
_movingPlatforms.Add(new MovingPlatform { go = go, posA = posA, posB = posB, speed = speed });
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// MATERIAL HELPERS
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private static void SetMatColor(Material mat, Color color)
|
||||||
|
{
|
||||||
|
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", color);
|
||||||
|
if (mat.HasProperty("_Color")) mat.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetMatTransparent(Material mat, Color color)
|
||||||
|
{
|
||||||
|
if (mat.HasProperty("_Surface"))
|
||||||
|
{
|
||||||
|
mat.SetFloat("_Surface", 1);
|
||||||
|
mat.SetFloat("_Blend", 0);
|
||||||
|
}
|
||||||
|
mat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
|
||||||
|
mat.DisableKeyword("_SURFACE_TYPE_OPAQUE");
|
||||||
|
mat.EnableKeyword("_ALPHAPREMULTIPLY_ON");
|
||||||
|
mat.renderQueue = 3000;
|
||||||
|
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", color);
|
||||||
|
if (mat.HasProperty("_Color")) mat.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
// MOVING PLATFORM DATA
|
||||||
|
// ═══════════════════════════════════════════
|
||||||
|
|
||||||
|
private class MovingPlatform
|
||||||
|
{
|
||||||
|
public GameObject go;
|
||||||
|
public Vector3 posA;
|
||||||
|
public Vector3 posB;
|
||||||
|
public float speed;
|
||||||
|
public float t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
2
game/Assets/Scripts/ArenaZoneBuilder.cs.meta
Normal file
2
game/Assets/Scripts/ArenaZoneBuilder.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 31c6f8ef706b51448b461b2b027e2ea8
|
||||||
66
game/Assets/Scripts/CameraOrbitKeyboard.cs
Normal file
66
game/Assets/Scripts/CameraOrbitKeyboard.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
using Unity.Cinemachine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds ZQSD (AZERTY) / WASD (QWERTY) keyboard orbit for the Cinemachine camera.
|
||||||
|
/// Works in parallel with mouse orbit via CinemachineInputAxisController.
|
||||||
|
/// Attach to the CinemachineCamera GameObject alongside CinemachineOrbitalFollow.
|
||||||
|
/// </summary>
|
||||||
|
public class CameraOrbitKeyboard : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Orbit Speed (degrees/sec)")]
|
||||||
|
public float horizontalSpeed = 150f;
|
||||||
|
public float verticalSpeed = 80f;
|
||||||
|
|
||||||
|
private CinemachineOrbitalFollow _orbital;
|
||||||
|
private CinemachineInputAxisController _axisController;
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
_orbital = GetComponent<CinemachineOrbitalFollow>();
|
||||||
|
_axisController = GetComponent<CinemachineInputAxisController>();
|
||||||
|
if (_orbital == null)
|
||||||
|
Debug.LogWarning("[CameraOrbitKeyboard] CinemachineOrbitalFollow not found on this GameObject.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (_orbital == null) return;
|
||||||
|
// Freeze camera orbit (keyboard + mouse) when keybind menu is open
|
||||||
|
if (KeyBindingUI.IsVisible)
|
||||||
|
{
|
||||||
|
if (_axisController != null && _axisController.enabled)
|
||||||
|
_axisController.enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (_axisController != null && !_axisController.enabled)
|
||||||
|
{
|
||||||
|
_axisController.enabled = true;
|
||||||
|
}
|
||||||
|
var kb = Keyboard.current;
|
||||||
|
if (kb == null) return;
|
||||||
|
|
||||||
|
// Physical-key mapping: W/A/S/D positions = Z/Q/S/D on AZERTY
|
||||||
|
Key kUp = KeyBindingUI.GetKey("CamUp", Key.W);
|
||||||
|
Key kDown = KeyBindingUI.GetKey("CamDown", Key.S);
|
||||||
|
Key kLeft = KeyBindingUI.GetKey("CamLeft", Key.A);
|
||||||
|
Key kRight = KeyBindingUI.GetKey("CamRight", Key.D);
|
||||||
|
|
||||||
|
float h = 0f, v = 0f;
|
||||||
|
if (kb[kRight].isPressed) h += 1f;
|
||||||
|
if (kb[kLeft].isPressed) h -= 1f;
|
||||||
|
if (kb[kUp].isPressed) v += 1f;
|
||||||
|
if (kb[kDown].isPressed) v -= 1f;
|
||||||
|
|
||||||
|
if (Mathf.Abs(h) > 0.001f || Mathf.Abs(v) > 0.001f)
|
||||||
|
{
|
||||||
|
_orbital.HorizontalAxis.Value += h * horizontalSpeed * Time.deltaTime;
|
||||||
|
_orbital.VerticalAxis.Value = Mathf.Clamp(
|
||||||
|
_orbital.VerticalAxis.Value + v * verticalSpeed * Time.deltaTime,
|
||||||
|
_orbital.VerticalAxis.Range.x,
|
||||||
|
_orbital.VerticalAxis.Range.y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
game/Assets/Scripts/CameraOrbitKeyboard.cs.meta
Normal file
2
game/Assets/Scripts/CameraOrbitKeyboard.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9948893cc71ec924bb9e06e3afd66bd2
|
||||||
217
game/Assets/Scripts/GameManager.cs
Normal file
217
game/Assets/Scripts/GameManager.cs
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Singleton game state machine. Drives all game UI and player state transitions
|
||||||
|
/// based on server events received from NetworkManager.
|
||||||
|
/// States: Lobby → Countdown → Playing → Eliminated/Qualified → RoundEnd → GameEnd
|
||||||
|
/// </summary>
|
||||||
|
public class GameManager : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static GameManager Instance { get; private set; }
|
||||||
|
|
||||||
|
[Header("Scene References")]
|
||||||
|
public GameObject playerRoot;
|
||||||
|
public SpectatorCamera spectatorCamera;
|
||||||
|
public GameHUD gameHUD;
|
||||||
|
public EliminationOverlay eliminationOverlay;
|
||||||
|
|
||||||
|
public GamePhase CurrentPhase { get; private set; } = GamePhase.Lobby;
|
||||||
|
public bool IsLocalEliminated { get; private set; } = false;
|
||||||
|
public string CurrentMode { get; private set; } = "race";
|
||||||
|
public int CurrentRound { get; private set; } = 1;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
|
||||||
|
Instance = this;
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnEnable()
|
||||||
|
{
|
||||||
|
var nm = NetworkManager.Instance;
|
||||||
|
if (nm == null) return;
|
||||||
|
nm.OnPhaseChanged += HandlePhaseChanged;
|
||||||
|
nm.OnCountdownChanged += HandleCountdownChanged;
|
||||||
|
nm.OnEliminated += HandleEliminated;
|
||||||
|
nm.OnQualified += HandleQualified;
|
||||||
|
nm.OnRoundStart += HandleRoundStart;
|
||||||
|
nm.OnRoundEnd += HandleRoundEnd;
|
||||||
|
nm.OnGameEnd += HandleGameEnd;
|
||||||
|
nm.OnDisconnected += HandleDisconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDisable()
|
||||||
|
{
|
||||||
|
var nm = NetworkManager.Instance;
|
||||||
|
if (nm == null) return;
|
||||||
|
nm.OnPhaseChanged -= HandlePhaseChanged;
|
||||||
|
nm.OnCountdownChanged -= HandleCountdownChanged;
|
||||||
|
nm.OnEliminated -= HandleEliminated;
|
||||||
|
nm.OnQualified -= HandleQualified;
|
||||||
|
nm.OnRoundStart -= HandleRoundStart;
|
||||||
|
nm.OnRoundEnd -= HandleRoundEnd;
|
||||||
|
nm.OnGameEnd -= HandleGameEnd;
|
||||||
|
nm.OnDisconnected -= HandleDisconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Event Handlers ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
void HandlePhaseChanged(string phase)
|
||||||
|
{
|
||||||
|
switch (phase)
|
||||||
|
{
|
||||||
|
case "countdown":
|
||||||
|
TransitionTo(GamePhase.Countdown);
|
||||||
|
break;
|
||||||
|
case "playing":
|
||||||
|
if (!IsLocalEliminated)
|
||||||
|
TransitionTo(GamePhase.Playing);
|
||||||
|
break;
|
||||||
|
case "roundEnd":
|
||||||
|
TransitionTo(GamePhase.RoundEnd);
|
||||||
|
break;
|
||||||
|
case "gameEnd":
|
||||||
|
TransitionTo(GamePhase.GameEnd);
|
||||||
|
break;
|
||||||
|
case "lobby":
|
||||||
|
// New round lobby — reset eliminated state
|
||||||
|
IsLocalEliminated = false;
|
||||||
|
TransitionTo(GamePhase.Lobby);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleCountdownChanged(float value)
|
||||||
|
{
|
||||||
|
gameHUD?.SetCountdown(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleEliminated(string sessionId, string reason)
|
||||||
|
{
|
||||||
|
if (sessionId == NetworkManager.Instance?.LocalSessionId)
|
||||||
|
{
|
||||||
|
IsLocalEliminated = true;
|
||||||
|
TransitionTo(GamePhase.Eliminated);
|
||||||
|
eliminationOverlay?.ShowEliminated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleQualified(string sessionId)
|
||||||
|
{
|
||||||
|
if (sessionId == NetworkManager.Instance?.LocalSessionId)
|
||||||
|
{
|
||||||
|
TransitionTo(GamePhase.Qualified);
|
||||||
|
eliminationOverlay?.ShowQualified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleRoundStart(int round, string mode)
|
||||||
|
{
|
||||||
|
CurrentRound = round;
|
||||||
|
CurrentMode = mode;
|
||||||
|
gameHUD?.SetRoundInfo(round, mode);
|
||||||
|
IsLocalEliminated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleRoundEnd(int round)
|
||||||
|
{
|
||||||
|
// Overlay already shown by elimination/qualification handlers
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleGameEnd(string winner)
|
||||||
|
{
|
||||||
|
eliminationOverlay?.ShowGameEnd(winner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleDisconnected()
|
||||||
|
{
|
||||||
|
IsLocalEliminated = false;
|
||||||
|
TransitionTo(GamePhase.Lobby);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── State Transitions ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
void TransitionTo(GamePhase phase)
|
||||||
|
{
|
||||||
|
CurrentPhase = phase;
|
||||||
|
Debug.Log($"[GameManager] → {phase}");
|
||||||
|
|
||||||
|
switch (phase)
|
||||||
|
{
|
||||||
|
case GamePhase.Lobby:
|
||||||
|
SetPlayerActive(false);
|
||||||
|
SetSpectatorActive(false);
|
||||||
|
gameHUD?.SetPhase("lobby");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GamePhase.Countdown:
|
||||||
|
gameHUD?.SetPhase("countdown");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GamePhase.Playing:
|
||||||
|
SetPlayerActive(true);
|
||||||
|
SetSpectatorActive(false);
|
||||||
|
gameHUD?.SetPhase("playing");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GamePhase.Eliminated:
|
||||||
|
SetPlayerActive(false);
|
||||||
|
SetSpectatorActive(true);
|
||||||
|
gameHUD?.SetPhase("eliminated");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GamePhase.Qualified:
|
||||||
|
// Keep player active but freeze input briefly
|
||||||
|
gameHUD?.SetPhase("qualified");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GamePhase.RoundEnd:
|
||||||
|
gameHUD?.SetPhase("roundEnd");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GamePhase.GameEnd:
|
||||||
|
SetPlayerActive(false);
|
||||||
|
SetSpectatorActive(true);
|
||||||
|
gameHUD?.SetPhase("gameEnd");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPlayerActive(bool active)
|
||||||
|
{
|
||||||
|
if (playerRoot == null) return;
|
||||||
|
playerRoot.SetActive(active);
|
||||||
|
var pc = playerRoot.GetComponentInChildren<PlayerController>(true);
|
||||||
|
if (pc != null) pc.enabled = active;
|
||||||
|
|
||||||
|
if (active)
|
||||||
|
{
|
||||||
|
Cursor.lockState = CursorLockMode.Locked;
|
||||||
|
Cursor.visible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cursor.lockState = CursorLockMode.None;
|
||||||
|
Cursor.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSpectatorActive(bool active)
|
||||||
|
{
|
||||||
|
if (spectatorCamera == null) return;
|
||||||
|
if (active) spectatorCamera.Activate();
|
||||||
|
else spectatorCamera.Deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GamePhase
|
||||||
|
{
|
||||||
|
Lobby,
|
||||||
|
Countdown,
|
||||||
|
Playing,
|
||||||
|
Eliminated,
|
||||||
|
Qualified,
|
||||||
|
RoundEnd,
|
||||||
|
GameEnd,
|
||||||
|
}
|
||||||
2
game/Assets/Scripts/GameManager.cs.meta
Normal file
2
game/Assets/Scripts/GameManager.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3b251a545afa938409a896585ea92a96
|
||||||
154
game/Assets/Scripts/GameSetup.cs
Normal file
154
game/Assets/Scripts/GameSetup.cs
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Global game setup applied at startup:
|
||||||
|
/// - Application.runInBackground (physics continues on ALT-TAB)
|
||||||
|
/// - Tall invisible arena barriers (prevent ball escape)
|
||||||
|
/// - Visual enhancements: obstacle colors, floor tint, lighting contrast
|
||||||
|
/// Attach to a persistent GameObject (e.g. NetworkManager).
|
||||||
|
/// </summary>
|
||||||
|
public class GameSetup : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Arena Boundaries")]
|
||||||
|
public float arenaHalfSize = 45f;
|
||||||
|
public float barrierHeight = 50f;
|
||||||
|
public float barrierThickness = 1f;
|
||||||
|
|
||||||
|
[Header("Visuals")]
|
||||||
|
public bool enhanceVisuals = true;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
// --- Keep physics and network running on focus loss ---
|
||||||
|
Application.runInBackground = true;
|
||||||
|
Application.targetFrameRate = 60;
|
||||||
|
|
||||||
|
// Barriers removed — respawn system handles falls (Y < -10)
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
if (enhanceVisuals)
|
||||||
|
EnhanceVisuals();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Barrier creation ---
|
||||||
|
|
||||||
|
private void CreateBarrier(string name, Vector3 position, Vector3 size)
|
||||||
|
{
|
||||||
|
var go = new GameObject(name);
|
||||||
|
go.transform.position = position;
|
||||||
|
var col = go.AddComponent<BoxCollider>();
|
||||||
|
col.size = size;
|
||||||
|
// No Renderer = invisible. Static collider = immovable wall.
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Visual enhancements ---
|
||||||
|
|
||||||
|
private void EnhanceVisuals()
|
||||||
|
{
|
||||||
|
TintFloor();
|
||||||
|
ColorObstacles();
|
||||||
|
ColorWallsAndGrids();
|
||||||
|
EnhanceLighting();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TintFloor()
|
||||||
|
{
|
||||||
|
var plane = GameObject.Find("Plane");
|
||||||
|
if (plane == null) return;
|
||||||
|
var rend = plane.GetComponent<Renderer>();
|
||||||
|
if (rend == null) return;
|
||||||
|
|
||||||
|
var mat = new Material(rend.sharedMaterial);
|
||||||
|
// Soft blue-gray instead of flat white
|
||||||
|
Color floorColor = new Color(0.70f, 0.74f, 0.82f, 1f);
|
||||||
|
SetMatColor(mat, floorColor);
|
||||||
|
rend.material = mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ColorObstacles()
|
||||||
|
{
|
||||||
|
Color[] palette =
|
||||||
|
{
|
||||||
|
new Color(0.42f, 0.55f, 0.75f), // Steel blue
|
||||||
|
new Color(0.60f, 0.45f, 0.68f), // Muted purple
|
||||||
|
new Color(0.48f, 0.68f, 0.55f), // Sage green
|
||||||
|
new Color(0.74f, 0.52f, 0.42f), // Warm terracotta
|
||||||
|
new Color(0.68f, 0.65f, 0.44f), // Sandy gold
|
||||||
|
new Color(0.44f, 0.62f, 0.72f), // Slate teal
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 1; i <= 18; i++)
|
||||||
|
{
|
||||||
|
var obs = GameObject.Find($"Obs_{i}");
|
||||||
|
if (obs == null) continue;
|
||||||
|
var rend = obs.GetComponent<Renderer>();
|
||||||
|
if (rend == null) continue;
|
||||||
|
|
||||||
|
var mat = new Material(rend.sharedMaterial);
|
||||||
|
SetMatColor(mat, palette[i % palette.Length]);
|
||||||
|
rend.material = mat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ColorWallsAndGrids()
|
||||||
|
{
|
||||||
|
Color wallColor = new Color(0.50f, 0.54f, 0.62f);
|
||||||
|
foreach (string name in new[] { "Wall_North", "Wall_South", "Wall_East", "Wall_West" })
|
||||||
|
{
|
||||||
|
var wall = GameObject.Find(name);
|
||||||
|
if (wall == null) continue;
|
||||||
|
var rend = wall.GetComponent<Renderer>();
|
||||||
|
if (rend == null) continue;
|
||||||
|
var mat = new Material(rend.sharedMaterial);
|
||||||
|
SetMatColor(mat, wallColor);
|
||||||
|
rend.material = mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color gridColor = new Color(0.58f, 0.61f, 0.68f);
|
||||||
|
for (int i = 1; i <= 4; i++)
|
||||||
|
{
|
||||||
|
foreach (string dir in new[] { "NS", "EW" })
|
||||||
|
{
|
||||||
|
var grid = GameObject.Find($"Grid_{dir}_{i}");
|
||||||
|
if (grid == null) continue;
|
||||||
|
var rend = grid.GetComponent<Renderer>();
|
||||||
|
if (rend == null) continue;
|
||||||
|
var mat = new Material(rend.sharedMaterial);
|
||||||
|
SetMatColor(mat, gridColor);
|
||||||
|
rend.material = mat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnhanceLighting()
|
||||||
|
{
|
||||||
|
// Directional light: warm white, stronger, soft shadows
|
||||||
|
var lights = FindObjectsByType<Light>(FindObjectsSortMode.None);
|
||||||
|
foreach (var light in lights)
|
||||||
|
{
|
||||||
|
if (light.type == LightType.Directional)
|
||||||
|
{
|
||||||
|
light.color = new Color(1f, 0.96f, 0.90f); // Warm white
|
||||||
|
light.intensity = 1.6f;
|
||||||
|
light.shadows = LightShadows.Soft;
|
||||||
|
light.shadowStrength = 0.75f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambient: cool tint for contrast with warm direct light
|
||||||
|
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Flat;
|
||||||
|
RenderSettings.ambientLight = new Color(0.32f, 0.36f, 0.48f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Utility ---
|
||||||
|
|
||||||
|
private static void SetMatColor(Material mat, Color color)
|
||||||
|
{
|
||||||
|
if (mat.HasProperty("_BaseColor"))
|
||||||
|
mat.SetColor("_BaseColor", color);
|
||||||
|
if (mat.HasProperty("_Color"))
|
||||||
|
mat.color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
game/Assets/Scripts/GameSetup.cs.meta
Normal file
2
game/Assets/Scripts/GameSetup.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: eb7b4298ea08e184781c08e50c18a677
|
||||||
317
game/Assets/Scripts/KeyBindingUI.cs
Normal file
317
game/Assets/Scripts/KeyBindingUI.cs
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runtime key rebinding UI. Toggle with F2.
|
||||||
|
/// Manages rebinding for InputSystem actions (movement, jump)
|
||||||
|
/// and custom camera orbit keys (ZQSD).
|
||||||
|
/// All overrides persist in PlayerPrefs.
|
||||||
|
/// </summary>
|
||||||
|
public class KeyBindingUI : MonoBehaviour
|
||||||
|
{
|
||||||
|
private bool _visible = false;
|
||||||
|
private string _rebindingAction = null;
|
||||||
|
|
||||||
|
/// <summary>True when the keybind config menu is open. Used to freeze camera + unlock cursor.</summary>
|
||||||
|
public static bool IsVisible { get; private set; }
|
||||||
|
private InputActionRebindingExtensions.RebindingOperation _rebindOp;
|
||||||
|
|
||||||
|
// Default camera keys (physical WASD positions = ZQSD on AZERTY)
|
||||||
|
private static readonly Dictionary<string, Key> _defaultCameraKeys = new()
|
||||||
|
{
|
||||||
|
{ "CamUp", Key.W },
|
||||||
|
{ "CamDown", Key.S },
|
||||||
|
{ "CamLeft", Key.A },
|
||||||
|
{ "CamRight", Key.D },
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] _cameraKeyNames = { "CamUp", "CamDown", "CamLeft", "CamRight" };
|
||||||
|
private static readonly string[] _cameraKeyLabels = { "Caméra haut", "Caméra bas", "Caméra gauche", "Caméra droite" };
|
||||||
|
|
||||||
|
private static Dictionary<string, Key> _currentCameraKeys;
|
||||||
|
|
||||||
|
private PlayerInput _playerInput;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
LoadCameraKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
_playerInput = FindFirstObjectByType<PlayerInput>();
|
||||||
|
LoadBindingOverrides();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (Keyboard.current != null && Keyboard.current[Key.F2].wasPressedThisFrame)
|
||||||
|
{
|
||||||
|
_visible = !_visible;
|
||||||
|
IsVisible = _visible;
|
||||||
|
if (_visible)
|
||||||
|
{
|
||||||
|
Cursor.lockState = CursorLockMode.None;
|
||||||
|
Cursor.visible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CancelRebind();
|
||||||
|
Cursor.lockState = CursorLockMode.Locked;
|
||||||
|
Cursor.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LateUpdate()
|
||||||
|
{
|
||||||
|
// Process camera key rebinding
|
||||||
|
if (_rebindingAction == null) return;
|
||||||
|
if (!_defaultCameraKeys.ContainsKey(_rebindingAction)) return;
|
||||||
|
|
||||||
|
var kb = Keyboard.current;
|
||||||
|
if (kb == null) return;
|
||||||
|
|
||||||
|
foreach (Key k in Enum.GetValues(typeof(Key)))
|
||||||
|
{
|
||||||
|
if (k == Key.None) continue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (kb[k].wasPressedThisFrame)
|
||||||
|
{
|
||||||
|
if (k == Key.Escape)
|
||||||
|
{
|
||||||
|
_rebindingAction = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_currentCameraKeys[_rebindingAction] = k;
|
||||||
|
SaveCameraKeys();
|
||||||
|
_rebindingAction = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
if (!_visible) return;
|
||||||
|
|
||||||
|
ImGuiSkin.EnsureReady();
|
||||||
|
|
||||||
|
// Overlay
|
||||||
|
ImGuiSkin.DrawOverlay();
|
||||||
|
|
||||||
|
float w = 480, h = 540;
|
||||||
|
|
||||||
|
ImGuiSkin.BeginWindow(w, h, "Configuration des touches");
|
||||||
|
|
||||||
|
// --- Movement ---
|
||||||
|
ImGuiSkin.DrawSectionHeader("DÉPLACEMENT");
|
||||||
|
GUILayout.Space(4);
|
||||||
|
DrawActionBinding("forward", "Avancer");
|
||||||
|
DrawActionBinding("backwards", "Reculer");
|
||||||
|
DrawActionBinding("left", "Gauche");
|
||||||
|
DrawActionBinding("right", "Droite");
|
||||||
|
DrawActionBinding("jump", "Sauter");
|
||||||
|
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
// --- Camera ---
|
||||||
|
ImGuiSkin.DrawSectionHeader("CAMÉRA (+ SOURIS)");
|
||||||
|
GUILayout.Space(4);
|
||||||
|
for (int i = 0; i < _cameraKeyNames.Length; i++)
|
||||||
|
DrawCameraKeyBinding(_cameraKeyNames[i], _cameraKeyLabels[i]);
|
||||||
|
|
||||||
|
GUILayout.Space(16);
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
if (GUILayout.Button("Réinitialiser tout", ImGuiSkin.Button, GUILayout.Height(32)))
|
||||||
|
ResetAllBindings();
|
||||||
|
if (GUILayout.Button("Fermer (F2)", ImGuiSkin.Button, GUILayout.Height(32)))
|
||||||
|
{
|
||||||
|
_visible = false;
|
||||||
|
CancelRebind();
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.Space(6);
|
||||||
|
|
||||||
|
if (_rebindingAction != null)
|
||||||
|
{
|
||||||
|
GUILayout.Label("Appuyez sur une touche pour assigner...", ImGuiSkin.Hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// F2 hint
|
||||||
|
GUILayout.Label("F2 — Ouvrir / Fermer ce menu", ImGuiSkin.Footer);
|
||||||
|
|
||||||
|
ImGuiSkin.EndWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Drawing helpers ---
|
||||||
|
|
||||||
|
private void DrawActionBinding(string actionName, string label)
|
||||||
|
{
|
||||||
|
if (_playerInput == null) return;
|
||||||
|
var action = _playerInput.actions.FindAction(actionName);
|
||||||
|
if (action == null) return;
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label(label, ImGuiSkin.Label, GUILayout.Width(150));
|
||||||
|
|
||||||
|
string currentBinding = "---";
|
||||||
|
if (action.bindings.Count > 0)
|
||||||
|
currentBinding = InputControlPath.ToHumanReadableString(
|
||||||
|
action.bindings[0].effectivePath,
|
||||||
|
InputControlPath.HumanReadableStringOptions.OmitDevice);
|
||||||
|
|
||||||
|
bool isRebinding = _rebindingAction == actionName;
|
||||||
|
string btnText = isRebinding ? "[ ... ]" : currentBinding;
|
||||||
|
|
||||||
|
GUIStyle btnStyle = isRebinding ? ImGuiSkin.ButtonAccent : ImGuiSkin.ButtonSmall;
|
||||||
|
if (GUILayout.Button(btnText, btnStyle, GUILayout.Width(170), GUILayout.Height(26)))
|
||||||
|
{
|
||||||
|
if (!isRebinding) StartActionRebind(actionName);
|
||||||
|
else CancelRebind();
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawCameraKeyBinding(string keyName, string label)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label(label, ImGuiSkin.Label, GUILayout.Width(150));
|
||||||
|
|
||||||
|
Key current = GetKey(keyName, _defaultCameraKeys[keyName]);
|
||||||
|
bool isRebinding = _rebindingAction == keyName;
|
||||||
|
string btnText = isRebinding ? "[ ... ]" : current.ToString();
|
||||||
|
|
||||||
|
GUIStyle btnStyle = isRebinding ? ImGuiSkin.ButtonAccent : ImGuiSkin.ButtonSmall;
|
||||||
|
if (GUILayout.Button(btnText, btnStyle, GUILayout.Width(170), GUILayout.Height(26)))
|
||||||
|
{
|
||||||
|
if (!isRebinding) StartCameraKeyRebind(keyName);
|
||||||
|
else CancelRebind();
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Rebinding logic ---
|
||||||
|
|
||||||
|
private void StartActionRebind(string actionName)
|
||||||
|
{
|
||||||
|
CancelRebind();
|
||||||
|
var action = _playerInput?.actions.FindAction(actionName);
|
||||||
|
if (action == null) return;
|
||||||
|
|
||||||
|
_rebindingAction = actionName;
|
||||||
|
action.Disable();
|
||||||
|
|
||||||
|
_rebindOp = action.PerformInteractiveRebinding(0)
|
||||||
|
.WithControlsExcluding("Mouse")
|
||||||
|
.OnMatchWaitForAnother(0.1f)
|
||||||
|
.OnComplete(op =>
|
||||||
|
{
|
||||||
|
action.Enable();
|
||||||
|
SaveBindingOverrides();
|
||||||
|
_rebindingAction = null;
|
||||||
|
op.Dispose();
|
||||||
|
_rebindOp = null;
|
||||||
|
})
|
||||||
|
.OnCancel(op =>
|
||||||
|
{
|
||||||
|
action.Enable();
|
||||||
|
_rebindingAction = null;
|
||||||
|
op.Dispose();
|
||||||
|
_rebindOp = null;
|
||||||
|
})
|
||||||
|
.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartCameraKeyRebind(string keyName)
|
||||||
|
{
|
||||||
|
CancelRebind();
|
||||||
|
_rebindingAction = keyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelRebind()
|
||||||
|
{
|
||||||
|
if (_rebindOp != null)
|
||||||
|
{
|
||||||
|
_rebindOp.Cancel();
|
||||||
|
_rebindOp.Dispose();
|
||||||
|
_rebindOp = null;
|
||||||
|
}
|
||||||
|
_rebindingAction = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Persistence ---
|
||||||
|
|
||||||
|
private void SaveBindingOverrides()
|
||||||
|
{
|
||||||
|
if (_playerInput == null) return;
|
||||||
|
string json = _playerInput.actions.SaveBindingOverridesAsJson();
|
||||||
|
PlayerPrefs.SetString("InputOverrides", json);
|
||||||
|
PlayerPrefs.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadBindingOverrides()
|
||||||
|
{
|
||||||
|
if (_playerInput == null) return;
|
||||||
|
string json = PlayerPrefs.GetString("InputOverrides", "");
|
||||||
|
if (!string.IsNullOrEmpty(json))
|
||||||
|
_playerInput.actions.LoadBindingOverridesFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LoadCameraKeys()
|
||||||
|
{
|
||||||
|
_currentCameraKeys = new Dictionary<string, Key>();
|
||||||
|
foreach (var kv in _defaultCameraKeys)
|
||||||
|
{
|
||||||
|
string saved = PlayerPrefs.GetString($"CamKey_{kv.Key}", "");
|
||||||
|
if (!string.IsNullOrEmpty(saved) && Enum.TryParse<Key>(saved, out Key parsed))
|
||||||
|
_currentCameraKeys[kv.Key] = parsed;
|
||||||
|
else
|
||||||
|
_currentCameraKeys[kv.Key] = kv.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SaveCameraKeys()
|
||||||
|
{
|
||||||
|
if (_currentCameraKeys == null) return;
|
||||||
|
foreach (var kv in _currentCameraKeys)
|
||||||
|
PlayerPrefs.SetString($"CamKey_{kv.Key}", kv.Value.ToString());
|
||||||
|
PlayerPrefs.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a camera key binding. Usable globally (static).
|
||||||
|
/// </summary>
|
||||||
|
public static Key GetKey(string name, Key fallback)
|
||||||
|
{
|
||||||
|
if (_currentCameraKeys == null) LoadCameraKeys();
|
||||||
|
return _currentCameraKeys != null && _currentCameraKeys.TryGetValue(name, out Key k) ? k : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetAllBindings()
|
||||||
|
{
|
||||||
|
// Reset InputSystem actions
|
||||||
|
if (_playerInput != null)
|
||||||
|
{
|
||||||
|
foreach (var action in _playerInput.actions)
|
||||||
|
action.RemoveAllBindingOverrides();
|
||||||
|
PlayerPrefs.DeleteKey("InputOverrides");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset camera keys
|
||||||
|
_currentCameraKeys = new Dictionary<string, Key>(_defaultCameraKeys);
|
||||||
|
foreach (var kv in _defaultCameraKeys)
|
||||||
|
PlayerPrefs.DeleteKey($"CamKey_{kv.Key}");
|
||||||
|
|
||||||
|
PlayerPrefs.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
2
game/Assets/Scripts/KeyBindingUI.cs.meta
Normal file
2
game/Assets/Scripts/KeyBindingUI.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 91245bd4a2621ba49ab2e6d622041061
|
||||||
8
game/Assets/Scripts/Network.meta
Normal file
8
game/Assets/Scripts/Network.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7d06329eb03f74741b61872baf05e25c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
171
game/Assets/Scripts/Network/DebugNetworkUI.cs
Normal file
171
game/Assets/Scripts/Network/DebugNetworkUI.cs
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Debug overlay:
|
||||||
|
/// – Always-visible HUD strip at the top (player name, status, room, FPS)
|
||||||
|
/// – Detailed panel toggled with F1 (full network + physics info)
|
||||||
|
/// Uses Dear ImGui–style skin via ImGuiSkin.
|
||||||
|
/// </summary>
|
||||||
|
public class DebugNetworkUI : MonoBehaviour
|
||||||
|
{
|
||||||
|
private bool _detailsVisible = false;
|
||||||
|
private Vector2 _scrollPos;
|
||||||
|
|
||||||
|
// FPS tracking
|
||||||
|
private float _fpsTimer;
|
||||||
|
private int _fpsCount;
|
||||||
|
private float _currentFps;
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
// FPS counter
|
||||||
|
_fpsTimer += Time.unscaledDeltaTime;
|
||||||
|
_fpsCount++;
|
||||||
|
if (_fpsTimer >= 0.5f)
|
||||||
|
{
|
||||||
|
_currentFps = _fpsCount / _fpsTimer;
|
||||||
|
_fpsTimer = 0f;
|
||||||
|
_fpsCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle detailed panel with F1
|
||||||
|
if (Keyboard.current != null && Keyboard.current[Key.F1].wasPressedThisFrame)
|
||||||
|
_detailsVisible = !_detailsVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
ImGuiSkin.EnsureReady();
|
||||||
|
|
||||||
|
var nm = NetworkManager.Instance;
|
||||||
|
if (nm == null) return;
|
||||||
|
|
||||||
|
DrawHUDStrip(nm);
|
||||||
|
|
||||||
|
if (_detailsVisible)
|
||||||
|
DrawDetailPanel(nm);
|
||||||
|
|
||||||
|
// Hint
|
||||||
|
GUI.Label(new Rect(10, Screen.height - 25, 300, 20), "F1 — Debug details", ImGuiSkin.Footer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ───────── HUD Strip (always visible) ─────────
|
||||||
|
|
||||||
|
private void DrawHUDStrip(NetworkManager nm)
|
||||||
|
{
|
||||||
|
float h = 28;
|
||||||
|
ImGuiSkin.DrawHudStripBg(h);
|
||||||
|
|
||||||
|
string dot = nm.IsConnected
|
||||||
|
? "<color=#44FF44>\u25CF</color>"
|
||||||
|
: "<color=#FF4444>\u25CF</color>";
|
||||||
|
|
||||||
|
string info;
|
||||||
|
if (nm.IsConnected)
|
||||||
|
{
|
||||||
|
string name = !string.IsNullOrEmpty(nm.LocalPlayerName) ? nm.LocalPlayerName : "\u2014";
|
||||||
|
string room = !string.IsNullOrEmpty(nm.RoomId) ? nm.RoomId[..Mathf.Min(8, nm.RoomId.Length)] : "\u2014";
|
||||||
|
string sess = !string.IsNullOrEmpty(nm.LocalSessionId) ? nm.LocalSessionId[..Mathf.Min(6, nm.LocalSessionId.Length)] : "\u2014";
|
||||||
|
info = $" {dot} <b>{name}</b> | Room {room} | Sess {sess} | {nm.PlayerCount}P | {nm.serverURL} | {_currentFps:F0} FPS";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info = $" {dot} {nm.ConnectionStatus} | {nm.serverURL} | {_currentFps:F0} FPS";
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI.Label(new Rect(0, 0, Screen.width, h), info, ImGuiSkin.HudLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ───────── Detail Panel (F1) ─────────
|
||||||
|
|
||||||
|
private void DrawDetailPanel(NetworkManager nm)
|
||||||
|
{
|
||||||
|
float w = 360, h = 480;
|
||||||
|
float x = Screen.width - w - 12;
|
||||||
|
float y = 38;
|
||||||
|
|
||||||
|
ImGuiSkin.BeginWindowAt(x, y, w, h, "Network Debug");
|
||||||
|
|
||||||
|
// ── Connection ──
|
||||||
|
ImGuiSkin.DrawSectionHeader("CONNECTION");
|
||||||
|
GUILayout.Space(2);
|
||||||
|
GUIStyle statusStyle = nm.IsConnected ? ImGuiSkin.StatusGreen : ImGuiSkin.StatusRed;
|
||||||
|
GUILayout.Label($"\u25CF {nm.ConnectionStatus}", statusStyle);
|
||||||
|
|
||||||
|
ImGuiSkin.DrawField("Server", nm.serverURL);
|
||||||
|
ImGuiSkin.DrawField("Room ID", string.IsNullOrEmpty(nm.RoomId) ? "\u2014" : nm.RoomId);
|
||||||
|
ImGuiSkin.DrawField("Session", string.IsNullOrEmpty(nm.LocalSessionId) ? "\u2014" : nm.LocalSessionId);
|
||||||
|
ImGuiSkin.DrawField("Players", nm.PlayerCount.ToString());
|
||||||
|
ImGuiSkin.DrawField("FPS", $"{_currentFps:F0}");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(nm.LastError))
|
||||||
|
{
|
||||||
|
GUILayout.Space(2);
|
||||||
|
GUILayout.Label($"\u26A0 {nm.LastError}", ImGuiSkin.StatusRed);
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.Space(6);
|
||||||
|
|
||||||
|
// ── Local Player ──
|
||||||
|
ImGuiSkin.DrawSectionHeader("LOCAL PLAYER");
|
||||||
|
GUILayout.Space(2);
|
||||||
|
ImGuiSkin.DrawField("Name", string.IsNullOrEmpty(nm.LocalPlayerName) ? "\u2014" : nm.LocalPlayerName);
|
||||||
|
|
||||||
|
var state = nm.GetLocalPlayerState();
|
||||||
|
if (state != null)
|
||||||
|
ImGuiSkin.DrawField("Server Pos", $"({state.x:F1}, {state.y:F1}, {state.z:F1})");
|
||||||
|
|
||||||
|
var pc = FindFirstObjectByType<PlayerController>();
|
||||||
|
if (pc != null && pc.isActiveAndEnabled)
|
||||||
|
{
|
||||||
|
var pos = pc.transform.position;
|
||||||
|
ImGuiSkin.DrawField("Live Pos", $"({pos.x:F1}, {pos.y:F1}, {pos.z:F1})");
|
||||||
|
var rb = pc.GetComponent<Rigidbody>();
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
var v = rb.linearVelocity;
|
||||||
|
ImGuiSkin.DrawField("Velocity", $"({v.x:F1}, {v.y:F1}, {v.z:F1}) [{v.magnitude:F1} m/s]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.Space(6);
|
||||||
|
|
||||||
|
// ── Remote Players ──
|
||||||
|
ImGuiSkin.DrawSectionHeader("REMOTE PLAYERS");
|
||||||
|
GUILayout.Space(2);
|
||||||
|
_scrollPos = GUILayout.BeginScrollView(_scrollPos, ImGuiSkin.ScrollView, GUILayout.Height(100));
|
||||||
|
|
||||||
|
if (nm.RemotePlayers != null && nm.RemotePlayers.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var kvp in nm.RemotePlayers)
|
||||||
|
{
|
||||||
|
if (kvp.Value == null) continue;
|
||||||
|
var rp = kvp.Value;
|
||||||
|
string dist = "";
|
||||||
|
if (pc != null && pc.isActiveAndEnabled)
|
||||||
|
{
|
||||||
|
float d = Vector3.Distance(pc.transform.position, rp.transform.position);
|
||||||
|
dist = $" [{d:F1}m]";
|
||||||
|
}
|
||||||
|
GUILayout.Label($" {rp.PlayerName} ({kvp.Key[..Mathf.Min(6, kvp.Key.Length)]}){dist}", ImGuiSkin.Label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUILayout.Label(" (aucun joueur distant)", ImGuiSkin.LabelDim);
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.EndScrollView();
|
||||||
|
GUILayout.FlexibleSpace();
|
||||||
|
|
||||||
|
if (nm.IsConnected)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("Déconnecter", ImGuiSkin.Button, GUILayout.Height(28)))
|
||||||
|
nm.LeaveRoom();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiSkin.EndWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
2
game/Assets/Scripts/Network/DebugNetworkUI.cs.meta
Normal file
2
game/Assets/Scripts/Network/DebugNetworkUI.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0b20e36c3b15f32449bf872f27bee467
|
||||||
337
game/Assets/Scripts/Network/LobbyUI.cs
Normal file
337
game/Assets/Scripts/Network/LobbyUI.cs
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lobby UI displayed at scene start. Player enters a name, picks a color,
|
||||||
|
/// and clicks "Rejoindre" to connect to the arena.
|
||||||
|
/// Manages the full pre-game → in-game transition:
|
||||||
|
/// - Hides the Player hierarchy until connected
|
||||||
|
/// - Activates a spectator camera while in lobby
|
||||||
|
/// - Teleports the player ball to the server spawn position on join
|
||||||
|
/// Uses Dear ImGui–style skin via ImGuiSkin.
|
||||||
|
/// </summary>
|
||||||
|
public class LobbyUI : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Scene References")]
|
||||||
|
[Tooltip("The root 'Player' GameObject (contains PlayerSphere + cameras). Will be deactivated until connected.")]
|
||||||
|
public GameObject playerRoot;
|
||||||
|
|
||||||
|
[Tooltip("The spectator camera GameObject (SpectatorCamera component).")]
|
||||||
|
public SpectatorCamera spectatorCamera;
|
||||||
|
|
||||||
|
// Preset colors for selection
|
||||||
|
private static readonly Color[] PresetColors = new Color[]
|
||||||
|
{
|
||||||
|
new Color(1f, 0.35f, 0.2f), // Orange-red
|
||||||
|
new Color(0.2f, 0.6f, 1f), // Blue
|
||||||
|
new Color(0.3f, 1f, 0.4f), // Green
|
||||||
|
new Color(1f, 0.85f, 0.1f), // Yellow
|
||||||
|
new Color(0.8f, 0.3f, 1f), // Purple
|
||||||
|
new Color(1f, 0.5f, 0.7f), // Pink
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] ColorNames = new string[]
|
||||||
|
{
|
||||||
|
"Rouge", "Bleu", "Vert", "Jaune", "Violet", "Rose"
|
||||||
|
};
|
||||||
|
|
||||||
|
// UI state
|
||||||
|
private bool _lobbyActive = true;
|
||||||
|
private string _playerName = "";
|
||||||
|
private int _selectedColorIndex = 0;
|
||||||
|
private string _statusMessage = "";
|
||||||
|
private bool _isConnecting = false;
|
||||||
|
private bool _isReady = false;
|
||||||
|
|
||||||
|
// Cached color preview texture (avoid per-frame leak)
|
||||||
|
private Texture2D _colorPreviewTex;
|
||||||
|
private int _lastPreviewColorIndex = -1;
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
// Generate a default name
|
||||||
|
_playerName = "Joueur" + Random.Range(100, 999);
|
||||||
|
|
||||||
|
// --- Hide the player hierarchy until connected ---
|
||||||
|
if (playerRoot != null)
|
||||||
|
playerRoot.SetActive(false);
|
||||||
|
|
||||||
|
// --- Activate spectator camera ---
|
||||||
|
if (spectatorCamera != null)
|
||||||
|
{
|
||||||
|
// Wire the gameplay camera reference so spectator knows what to re-enable
|
||||||
|
var gameplayCam = playerRoot?.GetComponentInChildren<Camera>(true);
|
||||||
|
if (gameplayCam != null)
|
||||||
|
spectatorCamera.gameplayCamera = gameplayCam;
|
||||||
|
|
||||||
|
spectatorCamera.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe to network events
|
||||||
|
if (NetworkManager.Instance != null)
|
||||||
|
{
|
||||||
|
NetworkManager.Instance.OnConnected += OnConnected;
|
||||||
|
NetworkManager.Instance.OnDisconnected += OnDisconnected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Instance != null)
|
||||||
|
{
|
||||||
|
NetworkManager.Instance.OnConnected -= OnConnected;
|
||||||
|
NetworkManager.Instance.OnDisconnected -= OnDisconnected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnConnected()
|
||||||
|
{
|
||||||
|
_lobbyActive = false;
|
||||||
|
_isConnecting = false;
|
||||||
|
_statusMessage = "";
|
||||||
|
|
||||||
|
// --- Activate the player hierarchy ---
|
||||||
|
if (playerRoot != null)
|
||||||
|
playerRoot.SetActive(true);
|
||||||
|
|
||||||
|
// Teleport player ball to the server-assigned spawn position
|
||||||
|
var nm = NetworkManager.Instance;
|
||||||
|
if (nm != null && playerRoot != null)
|
||||||
|
{
|
||||||
|
var pc = playerRoot.GetComponentInChildren<PlayerController>(true);
|
||||||
|
if (pc != null)
|
||||||
|
{
|
||||||
|
// Get spawn pos from the local player's state in the room
|
||||||
|
var localState = nm.GetLocalPlayerState();
|
||||||
|
if (localState != null)
|
||||||
|
{
|
||||||
|
Vector3 spawnPos = new Vector3(localState.x, localState.y, localState.z);
|
||||||
|
var rb = pc.GetComponent<Rigidbody>();
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
rb.linearVelocity = Vector3.zero;
|
||||||
|
rb.angularVelocity = Vector3.zero;
|
||||||
|
rb.position = spawnPos;
|
||||||
|
}
|
||||||
|
pc.transform.position = spawnPos;
|
||||||
|
Debug.Log($"[Lobby] Player teleported to spawn: {spawnPos}");
|
||||||
|
}
|
||||||
|
pc.enabled = true;
|
||||||
|
|
||||||
|
// Setup local player visuals: 50% color tint + floating name label
|
||||||
|
pc.SetupLocalPlayer(nm.LocalPlayerName, nm.LocalPlayerColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Switch from spectator to gameplay camera ---
|
||||||
|
if (spectatorCamera != null)
|
||||||
|
spectatorCamera.Deactivate();
|
||||||
|
|
||||||
|
// Unlock cursor for gameplay
|
||||||
|
Cursor.lockState = CursorLockMode.Locked;
|
||||||
|
Cursor.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisconnected()
|
||||||
|
{
|
||||||
|
_lobbyActive = true;
|
||||||
|
_isConnecting = false;
|
||||||
|
_isReady = false;
|
||||||
|
_statusMessage = "Déconnecté du serveur";
|
||||||
|
|
||||||
|
// Show cursor for lobby
|
||||||
|
Cursor.lockState = CursorLockMode.None;
|
||||||
|
Cursor.visible = true;
|
||||||
|
|
||||||
|
// --- Deactivate the player hierarchy ---
|
||||||
|
if (playerRoot != null)
|
||||||
|
{
|
||||||
|
var pc = playerRoot.GetComponentInChildren<PlayerController>(true);
|
||||||
|
if (pc != null) pc.enabled = false;
|
||||||
|
playerRoot.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Re-enable spectator camera ---
|
||||||
|
if (spectatorCamera != null)
|
||||||
|
spectatorCamera.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
if (!_lobbyActive) return;
|
||||||
|
|
||||||
|
ImGuiSkin.EnsureReady();
|
||||||
|
|
||||||
|
if (Cursor.lockState != CursorLockMode.None)
|
||||||
|
{
|
||||||
|
Cursor.lockState = CursorLockMode.None;
|
||||||
|
Cursor.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiSkin.DrawOverlay();
|
||||||
|
|
||||||
|
bool isConnected = NetworkManager.Instance != null && NetworkManager.Instance.IsConnected;
|
||||||
|
|
||||||
|
if (!isConnected)
|
||||||
|
{
|
||||||
|
// ── Pre-connect panel ────────────────────────────────────────
|
||||||
|
float panelWidth = 420;
|
||||||
|
float panelHeight = 440;
|
||||||
|
ImGuiSkin.BeginWindow(panelWidth, panelHeight, "ROLL'D");
|
||||||
|
|
||||||
|
GUILayout.Label("Rejoindre l'arène multijoueur", ImGuiSkin.WindowSubtitle);
|
||||||
|
GUILayout.Space(16);
|
||||||
|
|
||||||
|
ImGuiSkin.DrawSectionHeader("PSEUDO");
|
||||||
|
GUILayout.Space(4);
|
||||||
|
_playerName = GUILayout.TextField(_playerName, 16, ImGuiSkin.TextField, GUILayout.Height(30));
|
||||||
|
GUILayout.Space(12);
|
||||||
|
|
||||||
|
ImGuiSkin.DrawSectionHeader("COULEUR");
|
||||||
|
GUILayout.Space(6);
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
for (int i = 0; i < PresetColors.Length; i++)
|
||||||
|
{
|
||||||
|
Color c = PresetColors[i];
|
||||||
|
bool selected = _selectedColorIndex == i;
|
||||||
|
Color prevBg = GUI.backgroundColor;
|
||||||
|
GUI.backgroundColor = selected ? c : c * 0.7f;
|
||||||
|
GUIStyle btnStyle = new GUIStyle(ImGuiSkin.ButtonSmall)
|
||||||
|
{
|
||||||
|
fontStyle = selected ? FontStyle.Bold : FontStyle.Normal,
|
||||||
|
};
|
||||||
|
if (selected) btnStyle.normal.textColor = Color.white;
|
||||||
|
string label = selected ? $"▸ {ColorNames[i]}" : ColorNames[i];
|
||||||
|
if (GUILayout.Button(label, btnStyle, GUILayout.Height(32), GUILayout.Width(60)))
|
||||||
|
_selectedColorIndex = i;
|
||||||
|
GUI.backgroundColor = prevBg;
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(4);
|
||||||
|
|
||||||
|
if (_colorPreviewTex == null || _lastPreviewColorIndex != _selectedColorIndex)
|
||||||
|
{
|
||||||
|
if (_colorPreviewTex == null)
|
||||||
|
{
|
||||||
|
_colorPreviewTex = new Texture2D(1, 1, TextureFormat.RGBA32, false);
|
||||||
|
_colorPreviewTex.hideFlags = HideFlags.HideAndDontSave;
|
||||||
|
}
|
||||||
|
_colorPreviewTex.SetPixel(0, 0, PresetColors[_selectedColorIndex]);
|
||||||
|
_colorPreviewTex.Apply();
|
||||||
|
_lastPreviewColorIndex = _selectedColorIndex;
|
||||||
|
}
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.FlexibleSpace();
|
||||||
|
GUILayout.Box(_colorPreviewTex, GUIStyle.none, GUILayout.Width(80), GUILayout.Height(16));
|
||||||
|
GUILayout.FlexibleSpace();
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(16);
|
||||||
|
|
||||||
|
GUI.enabled = !_isConnecting && !string.IsNullOrWhiteSpace(_playerName);
|
||||||
|
string buttonText = _isConnecting ? "Connexion..." : "▶ Rejoindre l'arène";
|
||||||
|
if (GUILayout.Button(buttonText, ImGuiSkin.ButtonAccent, GUILayout.Height(44)))
|
||||||
|
JoinArena();
|
||||||
|
GUI.enabled = true;
|
||||||
|
GUILayout.Space(8);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(_statusMessage))
|
||||||
|
{
|
||||||
|
bool isError = _statusMessage.Contains("Erreur") || _statusMessage.Contains("Déconnecté");
|
||||||
|
GUIStyle statusStyle = isError ? ImGuiSkin.StatusRed : new GUIStyle(ImGuiSkin.Hint);
|
||||||
|
if (!isError) statusStyle.normal.textColor = ImGuiSkin.ColYellow;
|
||||||
|
GUILayout.Label(_statusMessage, statusStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiSkin.EndWindow();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ── Waiting room panel (connected, waiting for game to start) ──
|
||||||
|
float panelWidth = 380;
|
||||||
|
float panelHeight = 320;
|
||||||
|
ImGuiSkin.BeginWindow(panelWidth, panelHeight, "SALLE D'ATTENTE");
|
||||||
|
|
||||||
|
GUILayout.Label("En attente des joueurs...", ImGuiSkin.WindowSubtitle);
|
||||||
|
GUILayout.Space(12);
|
||||||
|
|
||||||
|
// Player list
|
||||||
|
ImGuiSkin.DrawSectionHeader("JOUEURS CONNECTÉS");
|
||||||
|
GUILayout.Space(4);
|
||||||
|
var nm = NetworkManager.Instance;
|
||||||
|
if (nm != null && nm.IsConnected)
|
||||||
|
{
|
||||||
|
// We can't directly iterate NetworkState.players from here easily,
|
||||||
|
// so show basic count
|
||||||
|
var style = new GUIStyle(GUI.skin.label) { fontSize = 13 };
|
||||||
|
style.normal.textColor = new Color(0.75f, 0.75f, 0.85f);
|
||||||
|
GUILayout.Label($" {nm.PlayerCount} joueur(s) dans la salle", style);
|
||||||
|
}
|
||||||
|
GUILayout.Space(16);
|
||||||
|
|
||||||
|
// Ready button
|
||||||
|
if (!_isReady)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("✔ Je suis prêt !", ImGuiSkin.ButtonAccent, GUILayout.Height(44)))
|
||||||
|
{
|
||||||
|
_isReady = true;
|
||||||
|
NetworkManager.Instance?.SendReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var readyStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
alignment = TextAnchor.MiddleCenter,
|
||||||
|
fontSize = 16,
|
||||||
|
fontStyle = FontStyle.Bold,
|
||||||
|
};
|
||||||
|
readyStyle.normal.textColor = new Color(0.3f, 1f, 0.5f);
|
||||||
|
GUILayout.Label("✔ Prêt ! En attente des autres...", readyStyle, GUILayout.Height(44));
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.Space(8);
|
||||||
|
var hintStyle = new GUIStyle(ImGuiSkin.Hint);
|
||||||
|
hintStyle.normal.textColor = new Color(0.5f, 0.5f, 0.6f);
|
||||||
|
GUILayout.Label("La partie démarre quand tout le monde est prêt\nou automatiquement après 30 secondes.", hintStyle);
|
||||||
|
|
||||||
|
ImGuiSkin.EndWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void JoinArena()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Instance == null)
|
||||||
|
{
|
||||||
|
_statusMessage = "Erreur : NetworkManager introuvable";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(_playerName))
|
||||||
|
{
|
||||||
|
_statusMessage = "Entrez un pseudo";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isConnecting = true;
|
||||||
|
_statusMessage = "Connexion au serveur...";
|
||||||
|
|
||||||
|
Color selectedColor = PresetColors[_selectedColorIndex];
|
||||||
|
NetworkManager.Instance.JoinArena(_playerName.Trim(), selectedColor);
|
||||||
|
|
||||||
|
// Monitor for errors after a delay
|
||||||
|
Invoke(nameof(CheckConnectionTimeout), 10f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckConnectionTimeout()
|
||||||
|
{
|
||||||
|
if (_isConnecting && !NetworkManager.Instance.IsConnected)
|
||||||
|
{
|
||||||
|
_isConnecting = false;
|
||||||
|
_statusMessage = "Erreur : Timeout de connexion. Vérifiez que le serveur est lancé.";
|
||||||
|
if (!string.IsNullOrEmpty(NetworkManager.Instance.LastError))
|
||||||
|
{
|
||||||
|
_statusMessage += $"\n{NetworkManager.Instance.LastError}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
game/Assets/Scripts/Network/LobbyUI.cs.meta
Normal file
2
game/Assets/Scripts/Network/LobbyUI.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ad2d984dd466289479165976d300cc09
|
||||||
394
game/Assets/Scripts/Network/NetworkManager.cs
Normal file
394
game/Assets/Scripts/Network/NetworkManager.cs
Normal file
@@ -0,0 +1,394 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using Colyseus;
|
||||||
|
using Colyseus.Schema;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Singleton managing the Colyseus connection, room lifecycle, remote player spawning,
|
||||||
|
/// and game-phase events (eliminated, qualified, roundStart, roundEnd, gameEnd).
|
||||||
|
/// </summary>
|
||||||
|
public class NetworkManager : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static NetworkManager Instance { get; private set; }
|
||||||
|
|
||||||
|
[Header("Connection")]
|
||||||
|
[Tooltip("Colyseus server endpoint (overridden by frontend via SetServerURL)")]
|
||||||
|
public string serverURL = "ws://localhost:2567";
|
||||||
|
|
||||||
|
[Header("Prefab")]
|
||||||
|
[Tooltip("Prefab for remote players (must have RemotePlayerController)")]
|
||||||
|
public GameObject remotePlayerPrefab;
|
||||||
|
|
||||||
|
// --- Public state for UI ---
|
||||||
|
public bool IsConnected { get; private set; }
|
||||||
|
public string RoomId { get; private set; } = "";
|
||||||
|
public string LocalSessionId { get; private set; } = "";
|
||||||
|
public int PlayerCount { get; private set; }
|
||||||
|
public string ConnectionStatus { get; private set; } = "Déconnecté";
|
||||||
|
public string LastError { get; private set; } = "";
|
||||||
|
|
||||||
|
// Expose remote players for debug UI
|
||||||
|
public Dictionary<string, RemotePlayerController> RemotePlayers => _remotePlayers;
|
||||||
|
|
||||||
|
// Local player info (set during join)
|
||||||
|
public string LocalPlayerName { get; private set; } = "";
|
||||||
|
public Color LocalPlayerColor { get; private set; } = Color.white;
|
||||||
|
|
||||||
|
// --- Events ---
|
||||||
|
public event Action OnConnected;
|
||||||
|
public event Action OnDisconnected;
|
||||||
|
public event Action<string> OnPlayerJoined;
|
||||||
|
public event Action<string> OnPlayerLeft;
|
||||||
|
|
||||||
|
// Game flow events
|
||||||
|
public event Action<string> OnPhaseChanged; // phase name
|
||||||
|
public event Action<float> OnCountdownChanged; // seconds remaining
|
||||||
|
public event Action<string, string> OnEliminated; // sessionId, reason
|
||||||
|
public event Action<string> OnQualified; // sessionId
|
||||||
|
public event Action<int, string> OnRoundStart; // roundNumber, mode
|
||||||
|
public event Action<int> OnRoundEnd; // roundNumber
|
||||||
|
public event Action<string> OnGameEnd; // winnerName
|
||||||
|
public event Action<float> OnDeathZoneYChanged; // for survival mode
|
||||||
|
|
||||||
|
// --- Internals ---
|
||||||
|
private Client _client;
|
||||||
|
private Room<NetworkState> _room;
|
||||||
|
private StateCallbackStrategy<NetworkState> _callbacks;
|
||||||
|
private readonly Dictionary<string, RemotePlayerController> _remotePlayers = new();
|
||||||
|
private float _broadcastTimer;
|
||||||
|
private const float BROADCAST_INTERVAL = 0.01667f; // ~60/sec
|
||||||
|
private bool _isJoining;
|
||||||
|
|
||||||
|
private Transform _localPlayer;
|
||||||
|
private Rigidbody _localPlayerRb;
|
||||||
|
|
||||||
|
private Vector3 _lastSentPos;
|
||||||
|
private Vector3 _lastSentVel;
|
||||||
|
private Vector3 _lastSentAngVel;
|
||||||
|
private const float POS_THRESHOLD = 0.005f;
|
||||||
|
private const float VEL_THRESHOLD = 0.05f;
|
||||||
|
|
||||||
|
private string _lastPhase = "";
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
if (Instance != null && Instance != this)
|
||||||
|
{
|
||||||
|
Destroy(gameObject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Instance = this;
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (!IsConnected || _room == null) return;
|
||||||
|
|
||||||
|
_broadcastTimer += Time.deltaTime;
|
||||||
|
if (_broadcastTimer >= BROADCAST_INTERVAL)
|
||||||
|
{
|
||||||
|
_broadcastTimer = 0f;
|
||||||
|
BroadcastPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Called from frontend JS via SendMessage to override the server URL.</summary>
|
||||||
|
public void SetServerURL(string url)
|
||||||
|
{
|
||||||
|
serverURL = url;
|
||||||
|
Debug.Log($"[Network] Server URL set to: {url}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkPlayer GetLocalPlayerState()
|
||||||
|
{
|
||||||
|
if (_room == null || _room.State.players == null || string.IsNullOrEmpty(LocalSessionId)) return null;
|
||||||
|
_room.State.players.TryGetValue(LocalSessionId, out var player);
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Join / Leave ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
public async void JoinArena(string playerName, Color color)
|
||||||
|
{
|
||||||
|
if (_isJoining || IsConnected)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[Network] Already connecting or connected.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isJoining = true;
|
||||||
|
ConnectionStatus = "Connexion en cours...";
|
||||||
|
LastError = "";
|
||||||
|
LocalPlayerName = playerName;
|
||||||
|
LocalPlayerColor = color;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Connecting to {serverURL}...");
|
||||||
|
_client = new Client(serverURL);
|
||||||
|
|
||||||
|
var options = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "name", playerName },
|
||||||
|
{ "colorR", color.r },
|
||||||
|
{ "colorG", color.g },
|
||||||
|
{ "colorB", color.b }
|
||||||
|
};
|
||||||
|
|
||||||
|
_room = await _client.JoinOrCreate<NetworkState>("arena", options);
|
||||||
|
LocalSessionId = _room.SessionId;
|
||||||
|
RoomId = _room.RoomId;
|
||||||
|
IsConnected = true;
|
||||||
|
ConnectionStatus = "Connecté";
|
||||||
|
|
||||||
|
Debug.Log($"[Network] Joined room {RoomId} as {LocalSessionId}");
|
||||||
|
|
||||||
|
_callbacks = Callbacks.Get(_room);
|
||||||
|
|
||||||
|
// Players
|
||||||
|
_callbacks.OnAdd(state => state.players, (key, player) => OnPlayerAdd(key, player));
|
||||||
|
_callbacks.OnRemove(state => state.players, (key, player) => OnPlayerRemove(key, player));
|
||||||
|
|
||||||
|
// Game state changes
|
||||||
|
_callbacks.Listen(state => state.phase, (newValue, prevValue) => _OnPhaseChanged(newValue));
|
||||||
|
_callbacks.Listen(state => state.countdown, (newValue, prevValue) => OnCountdownChanged?.Invoke(newValue));
|
||||||
|
_callbacks.Listen(state => state.deathZoneY, (newValue, prevValue) => OnDeathZoneYChanged?.Invoke(newValue));
|
||||||
|
|
||||||
|
// Server messages
|
||||||
|
_room.OnMessage<EliminatedMsg>("eliminated", msg =>
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Eliminated: {msg.sessionId} ({msg.reason})");
|
||||||
|
OnEliminated?.Invoke(msg.sessionId, msg.reason);
|
||||||
|
});
|
||||||
|
_room.OnMessage<QualifiedMsg>("qualified", msg =>
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Qualified: {msg.sessionId}");
|
||||||
|
OnQualified?.Invoke(msg.sessionId);
|
||||||
|
});
|
||||||
|
_room.OnMessage<RoundStartMsg>("roundStart", msg =>
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Round {msg.round} started ({msg.mode})");
|
||||||
|
OnRoundStart?.Invoke(msg.round, msg.mode);
|
||||||
|
});
|
||||||
|
_room.OnMessage<RoundEndMsg>("roundEnd", msg =>
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Round {msg.round} ended");
|
||||||
|
OnRoundEnd?.Invoke(msg.round);
|
||||||
|
});
|
||||||
|
_room.OnMessage<GameEndMsg>("gameEnd", msg =>
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Game over — Winner: {msg.winner}");
|
||||||
|
OnGameEnd?.Invoke(msg.winner);
|
||||||
|
});
|
||||||
|
|
||||||
|
_room.OnLeave += OnRoomLeave;
|
||||||
|
OnConnected?.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError($"[Network] Failed to join: {e.Message}");
|
||||||
|
ConnectionStatus = "Erreur de connexion";
|
||||||
|
LastError = e.Message;
|
||||||
|
IsConnected = false;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isJoining = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void LeaveRoom()
|
||||||
|
{
|
||||||
|
if (_room != null) await _room.Leave();
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void SendReady()
|
||||||
|
{
|
||||||
|
if (_room != null && IsConnected)
|
||||||
|
await _room.Send("ready", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void SendCheckpoint(int index)
|
||||||
|
{
|
||||||
|
if (_room != null && IsConnected)
|
||||||
|
await _room.Send("checkpointReached", new { index });
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void SendDeathZoneHit()
|
||||||
|
{
|
||||||
|
if (_room != null && IsConnected)
|
||||||
|
await _room.Send("deathZoneHit", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void SendInZone(bool inZone)
|
||||||
|
{
|
||||||
|
if (_room != null && IsConnected)
|
||||||
|
await _room.Send("inZone", new { inZone });
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── State Callbacks ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private void _OnPhaseChanged(string phase)
|
||||||
|
{
|
||||||
|
if (phase == _lastPhase) return;
|
||||||
|
_lastPhase = phase;
|
||||||
|
Debug.Log($"[Network] Phase → {phase}");
|
||||||
|
OnPhaseChanged?.Invoke(phase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayerAdd(string sessionId, NetworkPlayer player)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Player joined: {sessionId} ({player.name})");
|
||||||
|
PlayerCount = _room.State.players?.Count ?? 0;
|
||||||
|
|
||||||
|
if (sessionId == LocalSessionId) return;
|
||||||
|
|
||||||
|
if (remotePlayerPrefab != null)
|
||||||
|
{
|
||||||
|
Vector3 spawnPos = new Vector3(player.x, player.y, player.z);
|
||||||
|
GameObject remoteBall = Instantiate(remotePlayerPrefab, spawnPos, Quaternion.identity);
|
||||||
|
remoteBall.name = $"RemotePlayer_{player.name}_{sessionId[..6]}";
|
||||||
|
|
||||||
|
var controller = remoteBall.GetComponent<RemotePlayerController>()
|
||||||
|
?? remoteBall.AddComponent<RemotePlayerController>();
|
||||||
|
|
||||||
|
controller.Initialize(sessionId, player.name,
|
||||||
|
new Color(player.colorR, player.colorG, player.colorB));
|
||||||
|
|
||||||
|
_remotePlayers[sessionId] = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
_callbacks.OnChange(player, () => OnPlayerChange(sessionId, player));
|
||||||
|
OnPlayerJoined?.Invoke(sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayerRemove(string sessionId, NetworkPlayer player)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Player left: {sessionId}");
|
||||||
|
PlayerCount = _room.State.players?.Count ?? 0;
|
||||||
|
|
||||||
|
if (_remotePlayers.TryGetValue(sessionId, out var controller))
|
||||||
|
{
|
||||||
|
if (controller != null && controller.gameObject != null)
|
||||||
|
Destroy(controller.gameObject);
|
||||||
|
_remotePlayers.Remove(sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPlayerLeft?.Invoke(sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayerChange(string sessionId, NetworkPlayer player)
|
||||||
|
{
|
||||||
|
if (sessionId == LocalSessionId) return;
|
||||||
|
|
||||||
|
if (_remotePlayers.TryGetValue(sessionId, out var controller))
|
||||||
|
{
|
||||||
|
controller.SetTargetState(
|
||||||
|
new Vector3(player.x, player.y, player.z),
|
||||||
|
new Vector3(player.vx, player.vy, player.vz),
|
||||||
|
new Quaternion(player.rx, player.ry, player.rz, player.rw),
|
||||||
|
player.t,
|
||||||
|
new Vector3(player.avx, player.avy, player.avz)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Sync team color changes (for teams mode)
|
||||||
|
controller.UpdateTeamColor(player.team,
|
||||||
|
new Color(player.colorR, player.colorG, player.colorB));
|
||||||
|
|
||||||
|
// Hide/show eliminated remote players
|
||||||
|
controller.SetVisible(!player.isEliminated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Position Broadcasting ────────────────────────────────────────────
|
||||||
|
|
||||||
|
private void BroadcastPosition()
|
||||||
|
{
|
||||||
|
if (_room == null || !IsConnected) return;
|
||||||
|
|
||||||
|
if (_localPlayer == null)
|
||||||
|
{
|
||||||
|
var pc = FindFirstObjectByType<PlayerController>();
|
||||||
|
if (pc != null)
|
||||||
|
{
|
||||||
|
_localPlayer = pc.transform;
|
||||||
|
_localPlayerRb = pc.GetComponent<Rigidbody>();
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 pos = _localPlayer.position;
|
||||||
|
Vector3 vel = _localPlayerRb != null ? _localPlayerRb.linearVelocity : Vector3.zero;
|
||||||
|
Vector3 angVel = _localPlayerRb != null ? _localPlayerRb.angularVelocity : Vector3.zero;
|
||||||
|
|
||||||
|
if (Vector3.Distance(pos, _lastSentPos) < POS_THRESHOLD &&
|
||||||
|
Vector3.Distance(vel, _lastSentVel) < VEL_THRESHOLD &&
|
||||||
|
Vector3.Distance(angVel, _lastSentAngVel) < VEL_THRESHOLD)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lastSentPos = pos;
|
||||||
|
_lastSentVel = vel;
|
||||||
|
_lastSentAngVel = angVel;
|
||||||
|
|
||||||
|
Quaternion rot = _localPlayer.rotation;
|
||||||
|
|
||||||
|
var data = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "x", pos.x }, { "y", pos.y }, { "z", pos.z },
|
||||||
|
{ "vx", vel.x }, { "vy", vel.y }, { "vz", vel.z },
|
||||||
|
{ "rx", rot.x }, { "ry", rot.y }, { "rz", rot.z }, { "rw", rot.w },
|
||||||
|
{ "avx", angVel.x }, { "avy", angVel.y }, { "avz", angVel.z }
|
||||||
|
};
|
||||||
|
|
||||||
|
_ = _room.Send("position", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Room Lifecycle ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private void OnRoomLeave(int code)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Network] Left room (code: {code})");
|
||||||
|
Cleanup();
|
||||||
|
OnDisconnected?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cleanup()
|
||||||
|
{
|
||||||
|
IsConnected = false;
|
||||||
|
ConnectionStatus = "Déconnecté";
|
||||||
|
RoomId = "";
|
||||||
|
PlayerCount = 0;
|
||||||
|
LocalPlayerName = "";
|
||||||
|
LocalPlayerColor = Color.white;
|
||||||
|
_lastPhase = "";
|
||||||
|
|
||||||
|
foreach (var kvp in _remotePlayers)
|
||||||
|
{
|
||||||
|
if (kvp.Value != null && kvp.Value.gameObject != null)
|
||||||
|
Destroy(kvp.Value.gameObject);
|
||||||
|
}
|
||||||
|
_remotePlayers.Clear();
|
||||||
|
|
||||||
|
_room = null;
|
||||||
|
_client = null;
|
||||||
|
_callbacks = null;
|
||||||
|
_localPlayer = null;
|
||||||
|
_localPlayerRb = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
if (_room != null) _ = _room.Leave(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Message DTOs ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[Serializable] public class EliminatedMsg { public string sessionId; public string name; public string reason; }
|
||||||
|
[Serializable] public class QualifiedMsg { public string sessionId; public string name; }
|
||||||
|
[Serializable] public class RoundStartMsg { public int round; public string mode; public int totalRounds; }
|
||||||
|
[Serializable] public class RoundEndMsg { public int round; }
|
||||||
|
[Serializable] public class GameEndMsg { public string winner; }
|
||||||
2
game/Assets/Scripts/Network/NetworkManager.cs.meta
Normal file
2
game/Assets/Scripts/Network/NetworkManager.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6a218ec39b39bcc459a0c0d0ca10207b
|
||||||
48
game/Assets/Scripts/Network/NetworkSchema.cs
Normal file
48
game/Assets/Scripts/Network/NetworkSchema.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using Colyseus.Schema;
|
||||||
|
|
||||||
|
// Must match server-side defineTypes field order exactly
|
||||||
|
public partial class NetworkPlayer : Schema
|
||||||
|
{
|
||||||
|
[Type(0, "int32")] public int userId = 0;
|
||||||
|
[Type(1, "float32")] public float x = 0;
|
||||||
|
[Type(2, "float32")] public float y = 5;
|
||||||
|
[Type(3, "float32")] public float z = 0;
|
||||||
|
[Type(4, "float32")] public float vx = 0;
|
||||||
|
[Type(5, "float32")] public float vy = 0;
|
||||||
|
[Type(6, "float32")] public float vz = 0;
|
||||||
|
[Type(7, "float32")] public float rx = 0;
|
||||||
|
[Type(8, "float32")] public float ry = 0;
|
||||||
|
[Type(9, "float32")] public float rz = 0;
|
||||||
|
[Type(10, "float32")] public float rw = 1;
|
||||||
|
[Type(11, "float64")] public double t = 0;
|
||||||
|
[Type(12, "string")] public string name = "";
|
||||||
|
[Type(13, "float32")] public float colorR = 1;
|
||||||
|
[Type(14, "float32")] public float colorG = 1;
|
||||||
|
[Type(15, "float32")] public float colorB = 1;
|
||||||
|
[Type(16, "float32")] public float avx = 0;
|
||||||
|
[Type(17, "float32")] public float avy = 0;
|
||||||
|
[Type(18, "float32")] public float avz = 0;
|
||||||
|
// Game state
|
||||||
|
[Type(19, "boolean")] public bool isEliminated = false;
|
||||||
|
[Type(20, "boolean")] public bool isQualified = false;
|
||||||
|
[Type(21, "int8")] public int team = 0;
|
||||||
|
[Type(22, "int8")] public int checkpointIndex = 0;
|
||||||
|
[Type(23, "boolean")] public bool isReady = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class NetworkState : Schema
|
||||||
|
{
|
||||||
|
[Type(0, "map", typeof(MapSchema<NetworkPlayer>))]
|
||||||
|
public MapSchema<NetworkPlayer> players;
|
||||||
|
|
||||||
|
[Type(1, "string")] public string phase = "lobby";
|
||||||
|
[Type(2, "float32")] public float countdown = 0;
|
||||||
|
[Type(3, "int8")] public int roundNumber = 1;
|
||||||
|
[Type(4, "int8")] public int totalRounds = 4;
|
||||||
|
[Type(5, "int8")] public int playersAlive = 0;
|
||||||
|
[Type(6, "string")] public string gameMode = "race";
|
||||||
|
[Type(7, "float32")] public float deathZoneY = -100;
|
||||||
|
[Type(8, "int16")] public int teamScoreRed = 0;
|
||||||
|
[Type(9, "int16")] public int teamScoreBlue = 0;
|
||||||
|
[Type(10, "string")] public string winnerName = "";
|
||||||
|
}
|
||||||
2
game/Assets/Scripts/Network/NetworkSchema.cs.meta
Normal file
2
game/Assets/Scripts/Network/NetworkSchema.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0ce16348bc0580b49860d9bd80e7bec0
|
||||||
333
game/Assets/Scripts/Network/RemotePlayerController.cs
Normal file
333
game/Assets/Scripts/Network/RemotePlayerController.cs
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controls a remote player's ball using snapshot interpolation.
|
||||||
|
/// Maintains a ring buffer of recent network snapshots and interpolates
|
||||||
|
/// between them with a fixed delay, producing smooth motion even with jitter.
|
||||||
|
/// Uses Rigidbody.MovePosition for proper physics collision detection.
|
||||||
|
/// </summary>
|
||||||
|
public class RemotePlayerController : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Interpolation")]
|
||||||
|
[Tooltip("Interpolation delay in seconds (higher = smoother, more latency)")]
|
||||||
|
public float interpolationDelay = 0.083f; // ~83ms = 5 frames at 60Hz
|
||||||
|
|
||||||
|
[Tooltip("Max extrapolation time when no new data arrives")]
|
||||||
|
public float maxExtrapolation = 0.08f; // 80ms — short to avoid overshoot
|
||||||
|
|
||||||
|
[Tooltip("If distance exceeds this, snap instead of interpolate")]
|
||||||
|
public float snapDistance = 8f;
|
||||||
|
|
||||||
|
[Tooltip("Final smoothing factor (higher = tighter follow, lower = smoother)")]
|
||||||
|
public float smoothingSpeed = 24f;
|
||||||
|
|
||||||
|
[Tooltip("Rotation slerp speed")]
|
||||||
|
public float rotationSpeed = 24f;
|
||||||
|
|
||||||
|
// Public info
|
||||||
|
public string SessionId { get; private set; }
|
||||||
|
public string PlayerName { get; private set; }
|
||||||
|
public Color PlayerColor { get; private set; }
|
||||||
|
|
||||||
|
// --- Snapshot buffer ---
|
||||||
|
private struct Snapshot
|
||||||
|
{
|
||||||
|
public double serverTime; // server timestamp (ms)
|
||||||
|
public float localTime; // Time.time when received
|
||||||
|
public Vector3 position;
|
||||||
|
public Vector3 velocity;
|
||||||
|
public Quaternion rotation;
|
||||||
|
public Vector3 angularVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private const int BUFFER_SIZE = 16;
|
||||||
|
private readonly Snapshot[] _buffer = new Snapshot[BUFFER_SIZE];
|
||||||
|
private int _bufferCount;
|
||||||
|
private int _newestIndex;
|
||||||
|
private float _firstLocalTime; // local time of first snapshot received
|
||||||
|
private double _firstServerTime; // server time of first snapshot received
|
||||||
|
private bool _initialized;
|
||||||
|
private Quaternion _currentRotation = Quaternion.identity;
|
||||||
|
private Rigidbody _rb; // Cached for MovePosition
|
||||||
|
|
||||||
|
// Optional: floating name label
|
||||||
|
private TextMesh _nameLabel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called by NetworkManager when spawning this remote player.
|
||||||
|
/// </summary>
|
||||||
|
public void Initialize(string sessionId, string playerName, Color color)
|
||||||
|
{
|
||||||
|
SessionId = sessionId;
|
||||||
|
PlayerName = playerName;
|
||||||
|
PlayerColor = color;
|
||||||
|
_currentRotation = transform.rotation;
|
||||||
|
_bufferCount = 0;
|
||||||
|
_initialized = true;
|
||||||
|
|
||||||
|
// Apply color tint (multiply blend to keep pattern visible)
|
||||||
|
var renderer = GetComponent<Renderer>();
|
||||||
|
if (renderer != null)
|
||||||
|
{
|
||||||
|
var mat = new Material(renderer.sharedMaterial);
|
||||||
|
Color original = Color.white;
|
||||||
|
if (mat.HasProperty("_BaseColor")) original = mat.GetColor("_BaseColor");
|
||||||
|
else if (mat.HasProperty("_Color")) original = mat.GetColor("_Color");
|
||||||
|
|
||||||
|
float strength = 0.7f;
|
||||||
|
Color tint = new Color(
|
||||||
|
Mathf.Lerp(original.r, original.r * color.r * 2f, strength),
|
||||||
|
Mathf.Lerp(original.g, original.g * color.g * 2f, strength),
|
||||||
|
Mathf.Lerp(original.b, original.b * color.b * 2f, strength),
|
||||||
|
original.a
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", tint);
|
||||||
|
if (mat.HasProperty("_Color")) mat.color = tint;
|
||||||
|
renderer.material = mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kinematic rigidbody with MovePosition for proper collision detection
|
||||||
|
_rb = GetComponent<Rigidbody>();
|
||||||
|
if (_rb != null)
|
||||||
|
{
|
||||||
|
_rb.isKinematic = true;
|
||||||
|
_rb.useGravity = false;
|
||||||
|
_rb.interpolation = RigidbodyInterpolation.Interpolate;
|
||||||
|
_rb.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a trigger collider slightly larger than the physics collider
|
||||||
|
// so the local player can detect bumps
|
||||||
|
var existingCollider = GetComponent<SphereCollider>();
|
||||||
|
float baseRadius = existingCollider != null ? existingCollider.radius : 0.5f;
|
||||||
|
var trigger = gameObject.AddComponent<SphereCollider>();
|
||||||
|
trigger.isTrigger = true;
|
||||||
|
trigger.radius = baseRadius * 1.15f; // 15% larger
|
||||||
|
|
||||||
|
// Disable any player input on remote balls
|
||||||
|
var playerInput = GetComponent<UnityEngine.InputSystem.PlayerInput>();
|
||||||
|
if (playerInput != null)
|
||||||
|
playerInput.enabled = false;
|
||||||
|
|
||||||
|
var playerController = GetComponent<PlayerController>();
|
||||||
|
if (playerController != null)
|
||||||
|
playerController.enabled = false;
|
||||||
|
|
||||||
|
// Create floating name label
|
||||||
|
CreateNameLabel();
|
||||||
|
|
||||||
|
Debug.Log($"[RemotePlayer] Initialized: {playerName} ({sessionId[..6]}) color={color}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called by NetworkManager when a state update arrives from the server.
|
||||||
|
/// Pushes a new snapshot into the interpolation buffer.
|
||||||
|
/// </summary>
|
||||||
|
public void SetTargetState(Vector3 position, Vector3 velocity, Quaternion rotation, double serverTime, Vector3 angularVelocity = default)
|
||||||
|
{
|
||||||
|
// Bootstrap time mapping on first snapshot
|
||||||
|
if (_bufferCount == 0)
|
||||||
|
{
|
||||||
|
_firstLocalTime = Time.time;
|
||||||
|
_firstServerTime = serverTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance ring buffer
|
||||||
|
_newestIndex = (_newestIndex + 1) % BUFFER_SIZE;
|
||||||
|
_buffer[_newestIndex] = new Snapshot
|
||||||
|
{
|
||||||
|
serverTime = serverTime,
|
||||||
|
localTime = Time.time,
|
||||||
|
position = position,
|
||||||
|
velocity = velocity,
|
||||||
|
rotation = rotation,
|
||||||
|
angularVelocity = angularVelocity
|
||||||
|
};
|
||||||
|
if (_bufferCount < BUFFER_SIZE) _bufferCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (!_initialized || _bufferCount == 0) return;
|
||||||
|
|
||||||
|
// Render time = current time minus interpolation delay
|
||||||
|
float renderTime = Time.time - interpolationDelay;
|
||||||
|
|
||||||
|
// Build a sorted view of the buffer (oldest → newest by localTime)
|
||||||
|
// to safely find the two bracketing snapshots
|
||||||
|
int oldestIdx = (_newestIndex - _bufferCount + 1 + BUFFER_SIZE) % BUFFER_SIZE;
|
||||||
|
|
||||||
|
Snapshot older = default;
|
||||||
|
Snapshot newer = default;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < _bufferCount - 1; i++)
|
||||||
|
{
|
||||||
|
int idxA = (oldestIdx + i) % BUFFER_SIZE;
|
||||||
|
int idxB = (oldestIdx + i + 1) % BUFFER_SIZE;
|
||||||
|
if (_buffer[idxA].localTime <= renderTime && _buffer[idxB].localTime >= renderTime)
|
||||||
|
{
|
||||||
|
older = _buffer[idxA];
|
||||||
|
newer = _buffer[idxB];
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 targetPos;
|
||||||
|
Quaternion targetRot;
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
// Interpolate between the two bounding snapshots
|
||||||
|
float span = newer.localTime - older.localTime;
|
||||||
|
float t = span > 0.001f ? (renderTime - older.localTime) / span : 1f;
|
||||||
|
t = Mathf.Clamp01(t);
|
||||||
|
|
||||||
|
targetPos = Vector3.Lerp(older.position, newer.position, t);
|
||||||
|
targetRot = Quaternion.Slerp(older.rotation, newer.rotation, t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No bracketing pair found
|
||||||
|
var newest = _buffer[_newestIndex];
|
||||||
|
float elapsed = renderTime - newest.localTime;
|
||||||
|
|
||||||
|
if (elapsed < 0)
|
||||||
|
{
|
||||||
|
// Render time is earlier than all snapshots — use oldest, don't extrapolate backwards
|
||||||
|
targetPos = _buffer[oldestIdx].position;
|
||||||
|
targetRot = _buffer[oldestIdx].rotation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Extrapolate forward from newest, but with velocity damping
|
||||||
|
float extTime = Mathf.Min(elapsed, maxExtrapolation);
|
||||||
|
float dampFactor = 1f - Mathf.Clamp01(elapsed / (maxExtrapolation * 2f)); // fade to 0
|
||||||
|
targetPos = newest.position + newest.velocity * extTime * dampFactor;
|
||||||
|
targetRot = newest.rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final smoothing layer: lerp from current position toward computed target
|
||||||
|
float dist = Vector3.Distance(transform.position, targetPos);
|
||||||
|
Vector3 newPos;
|
||||||
|
if (dist > snapDistance)
|
||||||
|
{
|
||||||
|
// Teleport for large distances (spawn, reconnect)
|
||||||
|
newPos = targetPos;
|
||||||
|
_currentRotation = targetRot;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float lerpT = 1f - Mathf.Exp(-smoothingSpeed * Time.deltaTime);
|
||||||
|
newPos = Vector3.Lerp(transform.position, targetPos, lerpT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smooth rotation
|
||||||
|
float rotLerpT = 1f - Mathf.Exp(-rotationSpeed * Time.deltaTime);
|
||||||
|
_currentRotation = Quaternion.Slerp(_currentRotation, targetRot, rotLerpT);
|
||||||
|
|
||||||
|
// Use MovePosition/MoveRotation for proper collision detection
|
||||||
|
if (_rb != null)
|
||||||
|
{
|
||||||
|
_rb.MovePosition(newPos);
|
||||||
|
_rb.MoveRotation(_currentRotation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transform.position = newPos;
|
||||||
|
transform.rotation = _currentRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep name label floating ABOVE the ball (world position, not local)
|
||||||
|
// Billboard: always face camera, locked to vertical axis
|
||||||
|
if (_nameLabelObj != null)
|
||||||
|
{
|
||||||
|
_nameLabelObj.transform.position = transform.position + Vector3.up * 1.5f;
|
||||||
|
var cam = Camera.main;
|
||||||
|
if (cam != null)
|
||||||
|
{
|
||||||
|
// Billboard locked to Y axis — only rotate around vertical
|
||||||
|
Vector3 lookDir = _nameLabelObj.transform.position - cam.transform.position;
|
||||||
|
lookDir.y = 0f; // Lock to horizontal plane
|
||||||
|
if (lookDir.sqrMagnitude > 0.001f)
|
||||||
|
_nameLabelObj.transform.rotation = Quaternion.LookRotation(lookDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameObject _nameLabelObj; // Keep reference for billboard update
|
||||||
|
|
||||||
|
private void CreateNameLabel()
|
||||||
|
{
|
||||||
|
GameObject labelObj = new GameObject("NameLabel");
|
||||||
|
// Do NOT parent to transform — ball rotation would spin the label
|
||||||
|
labelObj.transform.position = transform.position + Vector3.up * 1.5f;
|
||||||
|
labelObj.transform.localScale = Vector3.one * 0.1f;
|
||||||
|
_nameLabelObj = labelObj;
|
||||||
|
|
||||||
|
_nameLabel = labelObj.AddComponent<TextMesh>();
|
||||||
|
_nameLabel.text = PlayerName;
|
||||||
|
_nameLabel.fontSize = 144;
|
||||||
|
_nameLabel.characterSize = 0.15f;
|
||||||
|
_nameLabel.anchor = TextAnchor.MiddleCenter;
|
||||||
|
_nameLabel.alignment = TextAlignment.Center;
|
||||||
|
_nameLabel.color = Color.white;
|
||||||
|
var font = PlayerController.LabelFont;
|
||||||
|
if (font != null) _nameLabel.font = font;
|
||||||
|
|
||||||
|
var meshRenderer = _nameLabel.GetComponent<MeshRenderer>();
|
||||||
|
if (font != null && font.material != null)
|
||||||
|
meshRenderer.material = font.material;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var textShader = Shader.Find("GUI/Text Shader") ?? Shader.Find("Unlit/Texture");
|
||||||
|
if (textShader != null) meshRenderer.material = new Material(textShader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Called by NetworkManager when the player's team or color changes (e.g. teams mode).</summary>
|
||||||
|
public void UpdateTeamColor(int team, Color serverColor)
|
||||||
|
{
|
||||||
|
// Only re-tint if the color actually changed significantly
|
||||||
|
if (PlayerColor == serverColor) return;
|
||||||
|
PlayerColor = serverColor;
|
||||||
|
|
||||||
|
var renderer = GetComponent<Renderer>();
|
||||||
|
if (renderer == null) return;
|
||||||
|
|
||||||
|
var mat = renderer.material;
|
||||||
|
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", serverColor);
|
||||||
|
else mat.color = serverColor;
|
||||||
|
|
||||||
|
// Update name label color to match team
|
||||||
|
if (_nameLabel != null)
|
||||||
|
{
|
||||||
|
_nameLabel.color = team == 1
|
||||||
|
? new Color(1f, 0.5f, 0.5f)
|
||||||
|
: team == 2
|
||||||
|
? new Color(0.5f, 0.7f, 1f)
|
||||||
|
: Color.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Show or hide this remote player (used when eliminated).</summary>
|
||||||
|
public void SetVisible(bool visible)
|
||||||
|
{
|
||||||
|
var renderer = GetComponent<Renderer>();
|
||||||
|
if (renderer != null) renderer.enabled = visible;
|
||||||
|
if (_nameLabelObj != null) _nameLabelObj.SetActive(visible);
|
||||||
|
|
||||||
|
// Disable physics interactions when hidden
|
||||||
|
var col = GetComponent<Collider>();
|
||||||
|
if (col != null) col.enabled = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
if (_nameLabelObj != null) Destroy(_nameLabelObj);
|
||||||
|
Debug.Log($"[RemotePlayer] Destroyed: {PlayerName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d5f5ad6331ffe0d4491eab78cc3b0993
|
||||||
82
game/Assets/Scripts/Network/SpectatorCamera.cs
Normal file
82
game/Assets/Scripts/Network/SpectatorCamera.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spectator camera that slowly orbits around the arena center while the player
|
||||||
|
/// is in the lobby (not yet connected). Automatically disables itself and yields
|
||||||
|
/// to the gameplay Cinemachine camera once the player joins.
|
||||||
|
/// Attach to a dedicated GameObject with a Camera component.
|
||||||
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(Camera))]
|
||||||
|
public class SpectatorCamera : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Orbit Settings")]
|
||||||
|
[Tooltip("World-space point the camera orbits around")]
|
||||||
|
public Vector3 orbitCenter = Vector3.zero;
|
||||||
|
|
||||||
|
[Tooltip("Radius of the orbit circle")]
|
||||||
|
public float orbitRadius = 30f;
|
||||||
|
|
||||||
|
[Tooltip("Height above the orbit center")]
|
||||||
|
public float orbitHeight = 18f;
|
||||||
|
|
||||||
|
[Tooltip("Degrees per second")]
|
||||||
|
public float orbitSpeed = 12f;
|
||||||
|
|
||||||
|
[Tooltip("Downward pitch angle in degrees")]
|
||||||
|
public float pitchAngle = 30f;
|
||||||
|
|
||||||
|
// Internal
|
||||||
|
private float _angle;
|
||||||
|
private Camera _cam;
|
||||||
|
|
||||||
|
// Reference to the gameplay camera (CinemachineBrain) — set by LobbyUI
|
||||||
|
[HideInInspector] public Camera gameplayCamera;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
_cam = GetComponent<Camera>();
|
||||||
|
_angle = Random.Range(0f, 360f); // start at random angle for variety
|
||||||
|
}
|
||||||
|
|
||||||
|
void LateUpdate()
|
||||||
|
{
|
||||||
|
_angle += orbitSpeed * Time.deltaTime;
|
||||||
|
if (_angle >= 360f) _angle -= 360f;
|
||||||
|
|
||||||
|
float rad = _angle * Mathf.Deg2Rad;
|
||||||
|
Vector3 pos = orbitCenter + new Vector3(
|
||||||
|
Mathf.Cos(rad) * orbitRadius,
|
||||||
|
orbitHeight,
|
||||||
|
Mathf.Sin(rad) * orbitRadius
|
||||||
|
);
|
||||||
|
|
||||||
|
transform.position = pos;
|
||||||
|
transform.LookAt(orbitCenter + Vector3.up * 2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Switch to spectator view — enable this camera, disable gameplay camera.
|
||||||
|
/// </summary>
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
_cam.enabled = true;
|
||||||
|
gameObject.SetActive(true);
|
||||||
|
|
||||||
|
// Disable the gameplay camera so we're the active one
|
||||||
|
if (gameplayCamera != null)
|
||||||
|
gameplayCamera.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Switch back to gameplay view — disable this camera, enable gameplay camera.
|
||||||
|
/// </summary>
|
||||||
|
public void Deactivate()
|
||||||
|
{
|
||||||
|
_cam.enabled = false;
|
||||||
|
gameObject.SetActive(false);
|
||||||
|
|
||||||
|
// Re-enable the gameplay camera
|
||||||
|
if (gameplayCamera != null)
|
||||||
|
gameplayCamera.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
game/Assets/Scripts/Network/SpectatorCamera.cs.meta
Normal file
2
game/Assets/Scripts/Network/SpectatorCamera.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 00ccf355f5f18234f9056c4ef6b82395
|
||||||
8
game/Assets/Scripts/Race.meta
Normal file
8
game/Assets/Scripts/Race.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a40d9df5e429e614ca4f4ea42e4fa404
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user