diff --git a/Assets/Hodaart/HodaartLowPolyCharacterCollection3/Packages/Hodaart Low Poly Character Collection 3 - Built-In.unitypackage.meta b/Assets/Hodaart/HodaartLowPolyCharacterCollection3/Packages/Hodaart Low Poly Character Collection 3 - Built-In.unitypackage.meta new file mode 100644 index 0000000..f84d6fe --- /dev/null +++ b/Assets/Hodaart/HodaartLowPolyCharacterCollection3/Packages/Hodaart Low Poly Character Collection 3 - Built-In.unitypackage.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: fe35bb42b8a0bd144a6e5d1d670079ed +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 388758 + packageName: Low Poly Character Collection 3 + packageVersion: 1.1 + assetPath: Assets/Hodaart/HodaartLowPolyCharacterCollection3/Packages/Hodaart Low + Poly Character Collection 3 - Built-In.unitypackage + uploadId: 946460 diff --git a/Assets/Hodaart/HodaartLowPolyCharacterCollection3/Packages/Hodaart Low Poly Character Collection 3 - HDRP.unitypackage.meta b/Assets/Hodaart/HodaartLowPolyCharacterCollection3/Packages/Hodaart Low Poly Character Collection 3 - HDRP.unitypackage.meta new file mode 100644 index 0000000..0c49352 --- /dev/null +++ b/Assets/Hodaart/HodaartLowPolyCharacterCollection3/Packages/Hodaart Low Poly Character Collection 3 - HDRP.unitypackage.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 6236278daa4d5c441a8232dab5ebc22d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 388758 + packageName: Low Poly Character Collection 3 + packageVersion: 1.1 + assetPath: Assets/Hodaart/HodaartLowPolyCharacterCollection3/Packages/Hodaart Low + Poly Character Collection 3 - HDRP.unitypackage + uploadId: 946460 diff --git a/Assets/Physics/Bot_LowFriction.physicsMaterial b/Assets/Physics/Bot_LowFriction.physicsMaterial deleted file mode 100644 index 8f8abf7..0000000 --- a/Assets/Physics/Bot_LowFriction.physicsMaterial +++ /dev/null @@ -1,15 +0,0 @@ -%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: Bot_LowFriction - serializedVersion: 2 - m_DynamicFriction: 0.3 - m_StaticFriction: 0.3 - m_Bounciness: 0 - m_FrictionCombine: 2 - m_BounceCombine: 2 diff --git a/Assets/Physics/Bot_LowFriction.physicsMaterial.meta b/Assets/Physics/Bot_LowFriction.physicsMaterial.meta deleted file mode 100644 index 3fc2129..0000000 --- a/Assets/Physics/Bot_LowFriction.physicsMaterial.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 6c687d24b6f5fbb4783d28d635f71a29 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/M1_Arena.unity b/Assets/Scenes/M1_Arena.unity index b25770a..a9f7918 100644 --- a/Assets/Scenes/M1_Arena.unity +++ b/Assets/Scenes/M1_Arena.unity @@ -469,118 +469,6 @@ Transform: m_CorrespondingSourceObject: {fileID: 400000, guid: 463e9d66ec2b7ad428d27c80a2b2d1db, type: 3} m_PrefabInstance: {fileID: 67875927} m_PrefabAsset: {fileID: 0} ---- !u!1 &101108170 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 101108171} - - component: {fileID: 101108174} - - component: {fileID: 101108173} - - component: {fileID: 101108172} - m_Layer: 0 - m_Name: Stand_Platform - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 2147483647 - m_IsActive: 1 ---- !u!4 &101108171 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 101108170} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1.5, z: 0} - m_LocalScale: {x: 12, y: 3, z: 5} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1532509717} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!23 &101108172 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 101108170} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 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!65 &101108173 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 101108170} - 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_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!33 &101108174 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 101108170} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} --- !u!1001 &130342001 PrefabInstance: m_ObjectHideFlags: 0 @@ -1484,37 +1372,6 @@ BoxCollider: serializedVersion: 3 m_Size: {x: 150.5, y: 4, z: 0.5} m_Center: {x: 0, y: 0, z: 0} ---- !u!1 &506345465 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 506345466} - m_Layer: 0 - m_Name: StandPoint_1 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &506345466 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 506345465} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 1, z: 0, w: -0.00000004371139} - m_LocalPosition: {x: 2.5, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1532509717} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &562137767 GameObject: m_ObjectHideFlags: 0 @@ -1527,7 +1384,6 @@ GameObject: - component: {fileID: 562137769} - component: {fileID: 562137768} - component: {fileID: 562137771} - - component: {fileID: 562137772} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -1627,30 +1483,6 @@ MonoBehaviour: positionSmoothTime: 0.25 lookAtDegreesPerSecond: 180 lookAtHeightOffset: 1 ---- !u!114 &562137772 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 562137767} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: cd21368c9a8b1064d913c375fb607c0b, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::Jankenbots.Prototype.CameraDirector - avatarDistance: 8 - robotDistance: 16 - lookSensitivity: 0.18 - zoomSensitivity: 4 - minDistance: 3 - maxDistance: 80 - minPitch: -8 - maxPitch: 78 - lookHeight: 1.2 - orbitRadius: 20 - orbitHeight: 9 - orbitSpeed: 18 --- !u!1001 &579422633 PrefabInstance: m_ObjectHideFlags: 0 @@ -3447,7 +3279,7 @@ BoxCollider: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 781174154} - m_Material: {fileID: 13400000, guid: 6c687d24b6f5fbb4783d28d635f71a29, type: 2} + m_Material: {fileID: 0} m_IncludeLayers: serializedVersion: 2 m_Bits: 0 @@ -3947,37 +3779,6 @@ Transform: m_CorrespondingSourceObject: {fileID: 400000, guid: 5161c2c79aa7dc44b8a812f624bf37d7, type: 3} m_PrefabInstance: {fileID: 893957807} m_PrefabAsset: {fileID: 0} ---- !u!1 &903945605 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 903945606} - m_Layer: 0 - m_Name: StandPoint_0 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &903945606 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 903945605} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 1, z: 0, w: -0.00000004371139} - m_LocalPosition: {x: -2.5, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1532509717} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1001 &912005198 PrefabInstance: m_ObjectHideFlags: 0 @@ -4398,63 +4199,6 @@ Transform: m_CorrespondingSourceObject: {fileID: 400000, guid: 00ba75879d6ef5745a4888259bde7c0a, type: 3} m_PrefabInstance: {fileID: 954444310} m_PrefabAsset: {fileID: 0} ---- !u!1001 &974200701 -PrefabInstance: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - serializedVersion: 3 - m_TransformParent: {fileID: 0} - m_Modifications: - - target: {fileID: 100000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_Name - value: Bath - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalPosition.x - value: 6.622743 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalPosition.y - value: 0.10000037 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalPosition.z - value: -0.529232 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalRotation.w - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalRotation.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalRotation.y - value: -0 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalRotation.z - value: -0 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 400000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 0 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_RemovedGameObjects: [] - m_AddedGameObjects: [] - m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: ae8352c51c6124747aa9e8a7374b86af, type: 3} --- !u!1001 &974860797 PrefabInstance: m_ObjectHideFlags: 0 @@ -5627,7 +5371,6 @@ MonoBehaviour: chassis: {fileID: 0} cruiseForce: 450 throttleDeadzone: 0.08 - yawAssistTorque: 220 pivotAnchorStrength: 1500 pivotAngularResistance: 400 leanTorque: 500 @@ -5763,7 +5506,6 @@ MonoBehaviour: chassis: {fileID: 0} cruiseForce: 450 throttleDeadzone: 0.08 - yawAssistTorque: 220 pivotAnchorStrength: 1500 pivotAngularResistance: 400 leanTorque: 500 @@ -7172,40 +6914,6 @@ Transform: m_CorrespondingSourceObject: {fileID: 400000, guid: 034ba005b2423b84ebc087e917744363, type: 3} m_PrefabInstance: {fileID: 1531216050} m_PrefabAsset: {fileID: 0} ---- !u!1 &1532509716 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1532509717} - m_Layer: 0 - m_Name: Stand - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1532509717 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1532509716} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 82} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 101108171} - - {fileID: 903945606} - - {fileID: 506345466} - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1001 &1537562849 PrefabInstance: m_ObjectHideFlags: 0 @@ -8752,5 +8460,3 @@ SceneRoots: - {fileID: 1378796740} - {fileID: 850707848} - {fileID: 326006527} - - {fileID: 1532509717} - - {fileID: 974200701} diff --git a/Assets/Scripts/Bot/SeatManager.cs b/Assets/Scripts/Bot/SeatManager.cs index abc1f88..433ad70 100644 --- a/Assets/Scripts/Bot/SeatManager.cs +++ b/Assets/Scripts/Bot/SeatManager.cs @@ -179,20 +179,6 @@ namespace Jankenbots.Prototype { ReleaseSeatRpc(); } - - // Controls hint under the seat box — context-aware (on foot vs driving). - int ty = y + h + 6, th = 54; - GUI.Box(new Rect(x, ty, w, th), "Controls"); - if (mine.HasValue) - { - GUI.Label(new Rect(x + 10, ty + 20, w - 20, 18), "W throttle · LShift pivot · A/D lean"); - GUI.Label(new Rect(x + 10, ty + 34, w - 20, 18), "Q leave · V camera · turn: differ vs teammate"); - } - else - { - GUI.Label(new Rect(x + 10, ty + 20, w - 20, 18), "WASD move · Mouse look · Scroll zoom"); - GUI.Label(new Rect(x + 10, ty + 34, w - 20, 18), "E claim tread · V camera · Esc free cursor"); - } } static string SeatLabel(ulong pilot) => pilot == NoPilot ? "free" : $"#{pilot}"; diff --git a/Assets/Scripts/Bot/TreadPart.cs b/Assets/Scripts/Bot/TreadPart.cs index c852ea9..50c6e0d 100644 --- a/Assets/Scripts/Bot/TreadPart.cs +++ b/Assets/Scripts/Bot/TreadPart.cs @@ -63,9 +63,6 @@ namespace Jankenbots.Prototype [Range(0f, 0.5f)] public float throttleDeadzone = 0.08f; - [Tooltip("Extra yaw torque (N·m) at full throttle, REINFORCING the natural differential turn so steering reads clearly even with ground friction. Left/Right push opposite ways, so equal throttle cancels to zero → straight line preserved. Set 0 to rely on pure emergent differential. Flip sign in code if it ever fights the turn.")] - public float yawAssistTorque = 220f; - // ---- (b) LOCK-PIVOT tuning ----------------------------------------------- [Header("(b) Lock-pivot — plant this tread as an anchor")] [Tooltip("How hard the planted tread resists the chassis sliding at its position.")] @@ -195,13 +192,6 @@ namespace Jankenbots.Prototype { Vector3 drive = transform.forward * (_throttle * cruiseForce); chassis.AddForceAtPosition(drive, treadPos, ForceMode.Force); - - // Yaw assist: reinforce the differential turn (Left throttles → nose right, - // Right throttles → nose left). Cancels to zero when both throttle equally, - // so straight-line driving is untouched; the maxAngularVelocity clamp still - // caps total spin so this can't reintroduce an uncontrolled tip. - float yawSign = side == Side.Left ? 1f : -1f; - chassis.AddTorque(chassis.transform.up * (yawSign * _throttle * yawAssistTorque), ForceMode.Force); } // ---- (c) PASSIVE LEAN — anti-tip ballast --------------------------- diff --git a/Assets/Scripts/Camera/CameraDirector.cs b/Assets/Scripts/Camera/CameraDirector.cs deleted file mode 100644 index 770120d..0000000 --- a/Assets/Scripts/Camera/CameraDirector.cs +++ /dev/null @@ -1,196 +0,0 @@ -using Unity.Cinemachine; -using UnityEngine; -using UnityEngine.InputSystem; - -namespace Jankenbots.Prototype -{ - /// - /// JANKENBOTS — client-local camera director. Owns four Cinemachine cameras, lets - /// the local player cycle between them and orbit/zoom the follow cams; the - /// CinemachineBrain on this Camera blends smoothly on every switch. - /// - /// • AvatarFollow — orbitable 3rd-person cam on YOUR character (on-foot). - /// • RobotFollow — orbitable chase cam on the bot (driving). - /// • StandView — fixed view from your player stand, looking at the bot. - /// • CinematicOrbit— slow auto-orbit of the bot (spectate / flavor). - /// - /// LOOK / ZOOM (Avatar & Robot only): hold RIGHT MOUSE and drag to orbit - /// (yaw/pitch), scroll wheel to zoom in/out (out to so - /// you can pull back and see the arena). RMB-drag keeps the cursor free for the - /// Claim/Leave buttons until the walk-up interaction exists. - /// - /// Default mode auto-follows the control state (on foot → Avatar, seated → Robot), - /// reading the same seat flag as the control handoff (). - /// Press V to cycle manually. Cameras are purely client-local, never networked. - /// - [RequireComponent(typeof(Camera))] - public class CameraDirector : MonoBehaviour - { - public enum Mode { AvatarFollow, RobotFollow, StandView, CinematicOrbit } - - [Header("Follow distances")] - public float avatarDistance = 8f; - public float robotDistance = 16f; - - [Header("Look / zoom (Avatar & Robot)")] - [Tooltip("Degrees of orbit per pixel of mouse drag (while holding RMB).")] - public float lookSensitivity = 0.18f; - [Tooltip("Metres of zoom per scroll notch.")] - public float zoomSensitivity = 4f; - public float minDistance = 3f; - [Tooltip("How far you can pull the camera back. Big so you can survey the arena.")] - public float maxDistance = 80f; - public float minPitch = -8f; - public float maxPitch = 78f; - public float lookHeight = 1.2f; // aim a bit above the target pivot - - [Header("Cinematic orbit")] - public float orbitRadius = 22f; - public float orbitHeight = 10f; - public float orbitSpeed = 16f; // deg/sec - - Transform _bot, _standOverlook; - CinemachineCamera _avatar, _robot, _stand, _orbit; - CinemachineCamera[] _all; - Mode _mode = Mode.AvatarFollow; - bool _userOverride; - bool _lastSeated; - - // Orbit state shared by the two follow cams (player-controlled). - float _yaw; - float _pitch = 18f; - float _dist = 8f; - float _cineAngle; - bool _cursorFree; // Esc toggles the locked cursor free (for GUI / to escape play) - - PlayerAvatar _local; - - void Start() - { - if (GetComponent() == null) gameObject.AddComponent(); - var legacy = GetComponent(); - if (legacy != null) legacy.enabled = false; - - var b = GameObject.Find("Bot"); if (b != null) _bot = b.transform; - var s = GameObject.Find("StandPoint_0"); if (s != null) _standOverlook = s.transform; - - var holder = new GameObject("CameraRigs").transform; - _avatar = Make(holder, "CM_AvatarFollow"); - _robot = Make(holder, "CM_RobotFollow"); - _stand = Make(holder, "CM_StandView"); - _orbit = Make(holder, "CM_CinematicOrbit"); - _all = new[] { _avatar, _robot, _stand, _orbit }; - Apply(_mode); - } - - CinemachineCamera Make(Transform parent, string name) - { - var go = new GameObject(name); - go.transform.SetParent(parent, false); - var vc = go.AddComponent(); - vc.Priority = 0; - return vc; - } - - void Update() - { - if (_local == null) _local = FindLocal(); - - var kb = Keyboard.current; - if (kb != null && kb.vKey.wasPressedThisFrame) - { - _mode = (Mode)(((int)_mode + 1) % _all.Length); - _userOverride = true; - Apply(_mode); - } - - // Seat claim/leave re-asserts the sensible default (clears a manual override). - if (_local != null && _local.IsSeatedLocal != _lastSeated) - { - _lastSeated = _local.IsSeatedLocal; - _userOverride = false; - } - if (!_userOverride && _local != null) - { - Mode want = _local.IsSeatedLocal ? Mode.RobotFollow : Mode.AvatarFollow; - if (want != _mode) { _mode = want; Apply(_mode); } - } - - // Cursor + look. On-foot (AvatarFollow) uses ALWAYS-ON mouse-look with a - // locked cursor (no RMB needed); other modes keep the cursor free (RobotFollow - // orbits while RMB is held). Esc toggles the cursor free to reach GUI / escape. - if (kb != null && kb.escapeKey.wasPressedThisFrame) _cursorFree = !_cursorFree; - bool avatarLook = _mode == Mode.AvatarFollow && !_cursorFree; - Cursor.lockState = avatarLook ? CursorLockMode.Locked : CursorLockMode.None; - Cursor.visible = !avatarLook; - - if (_mode == Mode.AvatarFollow || _mode == Mode.RobotFollow) - { - var m = Mouse.current; - if (m != null) - { - bool look = _mode == Mode.AvatarFollow ? avatarLook : m.rightButton.isPressed; - if (look) - { - Vector2 d = m.delta.ReadValue(); - _yaw += d.x * lookSensitivity; - _pitch = Mathf.Clamp(_pitch - d.y * lookSensitivity, minPitch, maxPitch); - } - float scroll = m.scroll.ReadValue().y; - if (Mathf.Abs(scroll) > 0.01f) - _dist = Mathf.Clamp(_dist - Mathf.Sign(scroll) * zoomSensitivity, minDistance, maxDistance); - } - } - } - - void LateUpdate() - { - if (_local != null) PoseOrbit(_avatar, _local.transform); - - if (_bot != null) - { - PoseOrbit(_robot, _bot); - - _cineAngle += orbitSpeed * Time.deltaTime; - Vector3 focus = _bot.position + Vector3.up * lookHeight; - Vector3 cineOff = Quaternion.Euler(0f, _cineAngle, 0f) * new Vector3(0f, orbitHeight, -orbitRadius); - _orbit.transform.position = focus + cineOff; - _orbit.transform.rotation = Quaternion.LookRotation(focus - _orbit.transform.position); - - if (_standOverlook != null) - { - _stand.transform.position = _standOverlook.position + Vector3.up * 1.5f; - _stand.transform.rotation = Quaternion.LookRotation( - (_bot.position + Vector3.up * lookHeight) - _stand.transform.position); - } - } - } - - // Player-controllable orbit: spherical offset from the target driven by _yaw/_pitch/_dist. - void PoseOrbit(CinemachineCamera vc, Transform target) - { - Vector3 focus = target.position + Vector3.up * lookHeight; - Vector3 dir = Quaternion.Euler(_pitch, _yaw, 0f) * Vector3.back; - Vector3 pos = focus + dir * _dist; - vc.transform.position = pos; - vc.transform.rotation = Quaternion.LookRotation(focus - pos); - } - - PlayerAvatar FindLocal() - { - foreach (var a in FindObjectsByType(FindObjectsSortMode.None)) - if (a.IsOwner) return a; - return null; - } - - void Apply(Mode m) - { - for (int i = 0; i < _all.Length; i++) - _all[i].Priority = ((int)m == i) ? 20 : 0; - - // Reset zoom to the mode's default distance on switch (keep the look angle). - if (m == Mode.AvatarFollow) _dist = avatarDistance; - else if (m == Mode.RobotFollow) _dist = robotDistance; - } - } -} diff --git a/Assets/Scripts/Camera/CameraDirector.cs.meta b/Assets/Scripts/Camera/CameraDirector.cs.meta deleted file mode 100644 index 1e54c67..0000000 --- a/Assets/Scripts/Camera/CameraDirector.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: cd21368c9a8b1064d913c375fb607c0b \ No newline at end of file diff --git a/Assets/Scripts/Player/PlayerAvatar.cs b/Assets/Scripts/Player/PlayerAvatar.cs index 97a22fa..6c9eaaf 100644 --- a/Assets/Scripts/Player/PlayerAvatar.cs +++ b/Assets/Scripts/Player/PlayerAvatar.cs @@ -1,5 +1,4 @@ using Unity.Netcode; -using Unity.Netcode.Components; using UnityEngine; using UnityEngine.InputSystem; @@ -7,24 +6,25 @@ namespace Jankenbots.Prototype { /// /// JANKENBOTS — networked run-around PLAYER avatar (the rigged low-poly - /// character), PLUS the on-foot ↔ driving control handoff. + /// character). This is the foundation for the timed junkyard "gather parts" + /// phase: each player controls one of these, runs around, and (later) hauls + /// scrap back to build the bot. Driving the finished bot happens from player + /// stands, so the avatar and the tread controls are separate systems. /// - /// CONTROL MODEL (the spine): a player is in exactly one mode, derived from a - /// single fact — do I currently hold a bot seat? (). - /// • ON FOOT (no seat) → WASD drives THIS avatar; free-roaming. - /// • DRIVING (holds a seat)→ avatar TELEPORTS to its player stand and FREEZES; - /// it refuses all input, so control transfers and - /// locks to the claimed tread (TreadPart already only - /// listens when you hold its seat). Release the seat → - /// teleport back and resume on-foot control. - /// This is what resolves the WASD overlap: PlayerAvatar and TreadPart become - /// mutually exclusive off one flag — never both live at once. + /// NETCODE: OWNER-authoritative. Only the owning client reads input and moves + /// its CharacterController; an on the + /// same object replicates the resulting motion to everyone. No host round-trip + /// on your own movement → it feels responsive. /// - /// NETCODE: OWNER-authoritative movement (see ). - /// Teleports use NetworkTransform.Teleport so observers don't see a slide. + /// ANIMATION: derived LOCALLY on every client from the avatar's measured + /// horizontal speed (position delta / dt), fed into the Animator's "Speed" + /// float, which drives an Idle→Walk→Run 1-D blend tree. Because observers + /// measure the same replicated motion the owner produces, the animation stays + /// in sync with zero extra network traffic — no NetworkAnimator needed. /// - /// ANIMATION: derived locally on every client from measured horizontal speed → - /// Animator "Speed" → Idle/Walk/Run blend (stays in sync with no extra traffic). + /// NOTE: reads WASD, same keys as the bot's TreadPart — fine while testing the + /// avatar in isolation; the real game separates "running" from "driving" via + /// the (future) player-stand flow, so a player is never doing both at once. /// [RequireComponent(typeof(CharacterController))] public class PlayerAvatar : NetworkBehaviour @@ -45,41 +45,28 @@ namespace Jankenbots.Prototype [Tooltip("Gravity (m/s^2, negative). Keeps the CharacterController grounded.")] public float gravity = -20f; + [Header("Animation")] + [Tooltip("Speed value the Animator treats as full-run, for normalising the blend.")] + public float runAnimSpeed = 5f; + CharacterController _cc; Animator _anim; - NetworkTransform _nt; - SeatManager _seats; - Transform _standLeft, _standRight; // where each pilot teleports (found by name) - float _vy; // vertical velocity (gravity) Vector3 _horizVel; // smoothed horizontal velocity (ramped, not instant) Vector3 _lastPos; float _animSpeed; - - bool _seated; // am I (owner) currently piloting a tread? - Vector3 _returnPos; // where to drop me back when I leave the seat - bool _hasReturn; - static readonly int SpeedHash = Animator.StringToHash("Speed"); - /// True while the LOCAL owner is seated/driving — read by the camera director. - public bool IsSeatedLocal => _seated; - void Awake() { _cc = GetComponent(); _anim = GetComponentInChildren(); - _nt = GetComponent(); _lastPos = transform.position; } public override void OnNetworkSpawn() { _lastPos = transform.position; - _seats = FindFirstObjectByType(); - var sl = GameObject.Find("StandPoint_0"); if (sl != null) _standLeft = sl.transform; - var sr = GameObject.Find("StandPoint_1"); if (sr != null) _standRight = sr.transform; - // Fan owners out a little so multiple players don't stack on the origin. if (IsOwner) { @@ -93,29 +80,7 @@ namespace Jankenbots.Prototype { if (!IsSpawned) return; - if (IsOwner) - { - // Derive mode from seat ownership and handle the transition. - SeatManager.Seat? seat = LocalSeat(); - bool wantSeated = seat.HasValue; - if (wantSeated != _seated) - { - if (wantSeated) EnterSeated(seat.Value); - else ExitSeated(); - } - - // Claim / leave a tread by KEY. On-foot mouse-look locks the cursor, so - // the OnGUI Claim/Leave buttons aren't clickable — E claims, Q leaves. - var kb = Keyboard.current; - if (_seats != null && kb != null) - { - if (!_seated && kb.eKey.wasPressedThisFrame) _seats.ClaimSeatRpc(); - else if (_seated && kb.qKey.wasPressedThisFrame) _seats.ReleaseSeatRpc(); - } - - // On foot → drive the avatar. Seated → do nothing (control is on the tread). - if (!_seated) OwnerMove(); - } + if (IsOwner) OwnerMove(); // Animation on EVERY client, from measured horizontal speed. Vector3 delta = transform.position - _lastPos; @@ -126,46 +91,6 @@ namespace Jankenbots.Prototype if (_anim != null) _anim.SetFloat(SpeedHash, _animSpeed); } - // Which seat (if any) the local player holds — the single source of truth for mode. - SeatManager.Seat? LocalSeat() - { - if (_seats == null || NetworkManager.Singleton == null) return null; - ulong me = NetworkManager.Singleton.LocalClientId; - if (_seats.PilotOf(SeatManager.Seat.Left) == me) return SeatManager.Seat.Left; - if (_seats.PilotOf(SeatManager.Seat.Right) == me) return SeatManager.Seat.Right; - return null; - } - - void EnterSeated(SeatManager.Seat seat) - { - _seated = true; - _returnPos = transform.position; // remember where I left the arena - _hasReturn = true; - _horizVel = Vector3.zero; _vy = 0f; - - Transform sp = seat == SeatManager.Seat.Left ? _standLeft : _standRight; - if (sp != null) TeleportTo(sp.position, sp.rotation); - } - - void ExitSeated() - { - _seated = false; - _horizVel = Vector3.zero; _vy = 0f; - if (_hasReturn) TeleportTo(_returnPos + Vector3.up * 0.2f, transform.rotation); - } - - // Interpolation-free teleport (CharacterController must be off to move it directly; - // NetworkTransform.Teleport keeps observers from seeing a slide across the map). - void TeleportTo(Vector3 pos, Quaternion rot) - { - bool ccWas = _cc.enabled; - _cc.enabled = false; - transform.SetPositionAndRotation(pos, rot); - _cc.enabled = ccWas; - _lastPos = pos; - if (_nt != null) _nt.Teleport(pos, rot, transform.localScale); - } - void OwnerMove() { var kb = Keyboard.current; @@ -178,23 +103,12 @@ namespace Jankenbots.Prototype if (kb.sKey.isPressed || kb.downArrowKey.isPressed) v -= 1f; } - // CAMERA-RELATIVE movement: W goes the way the camera (mouse) is looking, - // not world +Z. Basis is the active game camera flattened onto the ground. - Vector3 camF = Vector3.forward, camR = Vector3.right; - var cam = Camera.main; - if (cam != null) - { - camF = Vector3.ProjectOnPlane(cam.transform.forward, Vector3.up); - if (camF.sqrMagnitude < 1e-4f) camF = Vector3.ProjectOnPlane(cam.transform.up, Vector3.up); // looking straight down - camF.Normalize(); - camR = Vector3.ProjectOnPlane(cam.transform.right, Vector3.up).normalized; - } - - Vector3 input = camR * h + camF * v; + Vector3 input = new Vector3(h, 0f, v); if (input.sqrMagnitude > 1f) input.Normalize(); Vector3 desired = input * moveSpeed; - // Ramp velocity toward the target instead of snapping (smooth start/stop). + // Ramp velocity toward the target instead of snapping — this is what kills + // the "jerky/jarring" feel and lets the anim blend Idle→Walk→Run smoothly. float rate = input.sqrMagnitude > 0.001f ? acceleration : deceleration; _horizVel = Vector3.MoveTowards(_horizVel, desired, rate * Time.deltaTime); @@ -203,6 +117,8 @@ namespace Jankenbots.Prototype _cc.Move((_horizVel + new Vector3(0f, _vy, 0f)) * Time.deltaTime); + // Face the way we're actually moving (uses the smoothed velocity, so turns + // ease too rather than snapping on a key change). if (_horizVel.sqrMagnitude > 0.05f) { Quaternion target = Quaternion.LookRotation(new Vector3(_horizVel.x, 0f, _horizVel.z)); diff --git a/Assets/Settings/UniversalRenderPipelineGlobalSettings.asset b/Assets/Settings/UniversalRenderPipelineGlobalSettings.asset index 2b0e035..f005b0b 100644 --- a/Assets/Settings/UniversalRenderPipelineGlobalSettings.asset +++ b/Assets/Settings/UniversalRenderPipelineGlobalSettings.asset @@ -68,7 +68,22 @@ MonoBehaviour: - rid: 7808513024541851664 - rid: 7808513024541851665 m_RuntimeSettings: - m_List: [] + m_List: + - rid: 6852985685364965378 + - rid: 6852985685364965379 + - rid: 6852985685364965380 + - rid: 6852985685364965381 + - rid: 6852985685364965384 + - rid: 6852985685364965392 + - rid: 6852985685364965394 + - rid: 8712630790384254976 + - rid: 7808513024541851653 + - rid: 7808513024541851655 + - rid: 7808513024541851656 + - rid: 7808513024541851657 + - rid: 7808513024541851658 + - rid: 7808513024541851662 + - rid: 7808513024541851664 m_AssetVersion: 10 m_ObsoleteDefaultVolumeProfile: {fileID: 0} m_RenderingLayerNames: diff --git a/Packages/manifest.json b/Packages/manifest.json index d4e8afd..8eb26be 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -2,7 +2,6 @@ "dependencies": { "com.coplaydev.unity-mcp": "https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main", "com.unity.ai.navigation": "2.0.13", - "com.unity.cinemachine": "3.1.7", "com.unity.collab-proxy": "2.12.4", "com.unity.ide.rider": "3.0.38", "com.unity.ide.visualstudio": "2.0.26", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 67e0777..5639ded 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -36,16 +36,6 @@ }, "url": "https://packages.unity.com" }, - "com.unity.cinemachine": { - "version": "3.1.7", - "depth": 0, - "source": "registry", - "dependencies": { - "com.unity.splines": "2.0.0", - "com.unity.modules.imgui": "1.0.0" - }, - "url": "https://packages.unity.com" - }, "com.unity.collab-proxy": { "version": "2.12.4", "depth": 0, @@ -252,13 +242,6 @@ }, "url": "https://packages.unity.com" }, - "com.unity.settings-manager": { - "version": "2.1.1", - "depth": 2, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" - }, "com.unity.shadergraph": { "version": "17.5.0", "depth": 1, @@ -268,17 +251,6 @@ "com.unity.searcher": "4.9.3" } }, - "com.unity.splines": { - "version": "2.9.0", - "depth": 1, - "source": "registry", - "dependencies": { - "com.unity.mathematics": "1.2.1", - "com.unity.modules.imgui": "1.0.0", - "com.unity.settings-manager": "1.0.3" - }, - "url": "https://packages.unity.com" - }, "com.unity.test-framework": { "version": "1.7.0", "depth": 0, diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index e54c43c..ecbbda3 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -148,7 +148,7 @@ PlayerSettings: loadStoreDebugModeEnabled: 0 visionOSBundleVersion: 1.0 tvOSBundleVersion: 1.0 - bundleVersion: 0.2.0 + bundleVersion: 0.1.0 preloadedAssets: - {fileID: -944628639613478452, guid: 052faaac586de48259a63d0c4782560b, type: 3} metroInputSource: 0 diff --git a/scripts/session-git-check.sh b/scripts/session-git-check.sh deleted file mode 100644 index 61cbab8..0000000 --- a/scripts/session-git-check.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash -# SessionStart digest: fetch remote, report incoming commits + open Forgejo -# issues/PRs. Emits a Claude hook JSON blob on stdout (additionalContext) so -# Claude can surface anything actionable at the top of the session. -# Always exits 0 and always prints valid JSON — must never block a session. - -set -o pipefail -cd "$(dirname "$0")/.." 2>/dev/null || exit 0 - -digest="" -add() { digest+="$1"$'\n'; } - -# --- Remote fetch + incoming/outgoing commit comparison ------------------ -if git rev-parse --git-dir >/dev/null 2>&1; then - git fetch --all --quiet 2>/dev/null - upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null) - if [ -n "$upstream" ]; then - incoming=$(git log --oneline "HEAD..$upstream" 2>/dev/null) - outgoing=$(git log --oneline "$upstream..HEAD" 2>/dev/null) - if [ -n "$incoming" ]; then - add "INCOMING commits on $upstream (you are behind — pull to get them):" - while IFS= read -r l; do add " $l"; done <<< "$incoming" - # Flag incoming edits to Unity scene/prefab/asset files — risky to pull - # while the Editor is open (it may overwrite them or hold a stale copy). - scenefiles=$(git diff --name-only "HEAD..$upstream" 2>/dev/null | grep -Ei '\.(unity|prefab|asset|mat|controller)$') - if [ -n "$scenefiles" ]; then - add " *** WARNING: incoming commits change Unity scene/asset files:" - while IFS= read -r f; do add " $f"; done <<< "$scenefiles" - add " *** CLOSE or save the Unity Editor before pulling to avoid clobbering scene state." - fi - else - add "Up to date with $upstream (no incoming commits)." - fi - [ -n "$outgoing" ] && add "You have $(wc -l <<< "$outgoing") local commit(s) not yet pushed." - fi -fi - -# --- Forgejo open issues + PRs ------------------------------------------- -remote_url=$(git remote get-url origin 2>/dev/null) -if [[ "$remote_url" =~ ^https?://([^/]+)/([^/]+)/([^/.]+) ]]; then - host="${BASH_REMATCH[1]}"; owner="${BASH_REMATCH[2]}"; repo="${BASH_REMATCH[3]}" - cred=$(grep -m1 "$host" "$HOME/.git-credentials" 2>/dev/null) - tok=$(sed -E 's#https?://([^@]+)@.*#\1#' <<< "$cred") - api="https://$host/api/v1/repos/$owner/$repo/issues" - parse='import sys,json -try: d=json.load(sys.stdin) -except: sys.exit(0) -for i in d: print(" #%d %s (by %s)"%(i["number"],i["title"],i["user"]["login"]))' - if [ -n "$tok" ]; then - issues=$(curl -sf --max-time 8 -u "$tok" "$api?state=open&type=issues" 2>/dev/null | python3 -c "$parse" 2>/dev/null) - prs=$(curl -sf --max-time 8 -u "$tok" "$api?state=open&type=pulls" 2>/dev/null | python3 -c "$parse" 2>/dev/null) - if [ -n "$issues" ]; then add "OPEN ISSUES:"; add "$issues"; else add "No open issues."; fi - if [ -n "$prs" ]; then add "OPEN PULL REQUESTS:"; add "$prs"; else add "No open PRs."; fi - fi -fi - -# --- Emit hook JSON ------------------------------------------------------ -ctx="[Session start — repo/remote status] -$digest -If there are INCOMING commits or any open issues/PRs, briefly tell the user at the start of your first reply. If everything is up to date with no open items, do not mention this." - -python3 - "$ctx" <<'PY' -import json,sys -print(json.dumps({"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":sys.argv[1]},"suppressOutput":True})) -PY -exit 0