Smooth free-camera flight and look
FreeCamController: ease movement via dt-correct Vector3.SmoothDamp on a world-space velocity (accel/decel ramp) and lag the look with Mathf.SmoothDampAngle. Both are framerate-independent and collapse to instant at smoothTime 0; smoothed state is snapped on activation (SyncToCurrentView) so entering freecam never jumps to catch up. Bundles accumulated deferred work: PlayerScaler uniform-scale helper, scale-aware wall/ceiling climb probes and the double-scale skinned-collider bake fix, plus user content authoring (Sit pose + animation, font SDF, scene/prefab edits). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
f66ebbf10a
commit
8c89e95014
14 files changed
+12083
-360
No files matched your search
@@ -736,6 +736,36 @@ MonoBehaviour:
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
m_ClassDefinitionType: 0
|
||||
- m_Index: 24
|
||||
m_Metrics:
|
||||
m_Width: 153.29688
|
||||
m_Height: 219.59375
|
||||
m_HorizontalBearingX: 9.296875
|
||||
m_HorizontalBearingY: 216
|
||||
m_HorizontalAdvance: 178.20312
|
||||
m_GlyphRect:
|
||||
m_X: 1202
|
||||
m_Y: 891
|
||||
m_Width: 154
|
||||
m_Height: 220
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
m_ClassDefinitionType: 0
|
||||
- m_Index: 17
|
||||
m_Metrics:
|
||||
m_Width: 150.29688
|
||||
m_Height: 216.29688
|
||||
m_HorizontalBearingX: 16.5
|
||||
m_HorizontalBearingY: 216.29688
|
||||
m_HorizontalAdvance: 178.20312
|
||||
m_GlyphRect:
|
||||
m_X: 729
|
||||
m_Y: 839
|
||||
m_Width: 151
|
||||
m_Height: 217
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
m_ClassDefinitionType: 0
|
||||
m_CharacterTable:
|
||||
- m_ElementType: 1
|
||||
m_Unicode: 8230
|
||||
@@ -917,6 +947,14 @@ MonoBehaviour:
|
||||
m_Unicode: 73
|
||||
m_GlyphIndex: 40
|
||||
m_Scale: 1
|
||||
- m_ElementType: 1
|
||||
m_Unicode: 57
|
||||
m_GlyphIndex: 24
|
||||
m_Scale: 1
|
||||
- m_ElementType: 1
|
||||
m_Unicode: 50
|
||||
m_GlyphIndex: 17
|
||||
m_Scale: 1
|
||||
m_AtlasTextures:
|
||||
- {fileID: 2664084111089754775}
|
||||
m_AtlasTextureIndex: 0
|
||||
@@ -1104,6 +1142,14 @@ MonoBehaviour:
|
||||
m_Y: 632
|
||||
m_Width: 74
|
||||
m_Height: 252
|
||||
- m_X: 1187
|
||||
m_Y: 876
|
||||
m_Width: 183
|
||||
m_Height: 249
|
||||
- m_X: 714
|
||||
m_Y: 824
|
||||
m_Width: 180
|
||||
m_Height: 246
|
||||
m_FreeGlyphRects:
|
||||
- m_X: 415
|
||||
m_Y: 45
|
||||
@@ -1221,10 +1267,6 @@ MonoBehaviour:
|
||||
m_Y: 804
|
||||
m_Width: 144
|
||||
m_Height: 11
|
||||
- m_X: 714
|
||||
m_Y: 804
|
||||
m_Width: 44
|
||||
m_Height: 1243
|
||||
- m_X: 1221
|
||||
m_Y: 492
|
||||
m_Width: 28
|
||||
@@ -1233,18 +1275,6 @@ MonoBehaviour:
|
||||
m_Y: 576
|
||||
m_Width: 85
|
||||
m_Height: 165
|
||||
- m_X: 1187
|
||||
m_Y: 741
|
||||
m_Width: 34
|
||||
m_Height: 1306
|
||||
- m_X: 714
|
||||
m_Y: 993
|
||||
m_Width: 1333
|
||||
m_Height: 1054
|
||||
- m_X: 714
|
||||
m_Y: 824
|
||||
m_Width: 238
|
||||
m_Height: 1223
|
||||
- m_X: 343
|
||||
m_Y: 867
|
||||
m_Width: 10
|
||||
@@ -1257,10 +1287,6 @@ MonoBehaviour:
|
||||
m_Y: 1119
|
||||
m_Width: 175
|
||||
m_Height: 928
|
||||
- m_X: 532
|
||||
m_Y: 1064
|
||||
m_Width: 1515
|
||||
m_Height: 983
|
||||
- m_X: 532
|
||||
m_Y: 936
|
||||
m_Width: 2
|
||||
@@ -1274,13 +1300,41 @@ MonoBehaviour:
|
||||
m_Width: 556
|
||||
m_Height: 1292
|
||||
- m_X: 1187
|
||||
m_Y: 741
|
||||
m_Width: 34
|
||||
m_Height: 135
|
||||
- m_X: 532
|
||||
m_Y: 1125
|
||||
m_Width: 1515
|
||||
m_Height: 922
|
||||
- m_X: 1370
|
||||
m_Y: 884
|
||||
m_Width: 860
|
||||
m_Width: 677
|
||||
m_Height: 1163
|
||||
- m_X: 1187
|
||||
- m_X: 1370
|
||||
m_Y: 876
|
||||
m_Width: 230
|
||||
m_Width: 47
|
||||
m_Height: 1171
|
||||
- m_X: 714
|
||||
m_Y: 804
|
||||
m_Width: 44
|
||||
m_Height: 20
|
||||
- m_X: 894
|
||||
m_Y: 824
|
||||
m_Width: 58
|
||||
m_Height: 1223
|
||||
- m_X: 894
|
||||
m_Y: 993
|
||||
m_Width: 293
|
||||
m_Height: 1054
|
||||
- m_X: 532
|
||||
m_Y: 1070
|
||||
m_Width: 655
|
||||
m_Height: 977
|
||||
- m_X: 532
|
||||
m_Y: 1064
|
||||
m_Width: 182
|
||||
m_Height: 983
|
||||
m_FontFeatureTable:
|
||||
m_MultipleSubstitutionRecords: []
|
||||
m_LigatureSubstitutionRecords:
|
||||
@@ -13918,7 +13972,7 @@ Texture2D:
|
||||
m_ColorSpace: 1
|
||||
m_PlatformBlob:
|
||||
image data: 4194304
|
||||
_typelessdata: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204050506070809090807060505040301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103040505060708090908070605050402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020405050607080909080706050504030100000000000000000000000000000000000000000000000000000000000000000000000000000003050607080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808Line truncated
|
||||
_typelessdata: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204050506070809090807060505040301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103040505060708090908070605050402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020405050607080909080706050504030100000000000000000000000000000000000000000000000000000000000000000000000000000003050607080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808Line truncated
|
||||
m_StreamData:
|
||||
serializedVersion: 2
|
||||
offset: 0
|
||||
|
||||
+199
-199
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8080490af5235b043abfca704be7ff8d
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,24 @@
|
||||
%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: e3e6fee2893b9d848b8b1ccca743c14f, type: 3}
|
||||
m_Name: Pose_Sit
|
||||
m_EditorClassIdentifier: Assembly-CSharp::PlayerPose
|
||||
clip: {fileID: 7400000, guid: 8080490af5235b043abfca704be7ff8d, type: 2}
|
||||
clipSpeed: 1
|
||||
walkClip: {fileID: 0}
|
||||
walkClipSpeed: 1
|
||||
runClip: {fileID: 0}
|
||||
runClipSpeed: 1
|
||||
controllerCenterY: 0.45
|
||||
controllerRadius: 0.1
|
||||
controllerHeight: 0.85
|
||||
cameraTargetYOffset: -0.2
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90df501d86681394b834f647f6f4e939
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -13,6 +13,7 @@ GameObject:
|
||||
- component: {fileID: 1035623159758896108}
|
||||
- component: {fileID: 4587432968399885263}
|
||||
- component: {fileID: 3810343734243857883}
|
||||
- component: {fileID: 273411532115212066}
|
||||
m_Layer: 0
|
||||
m_Name: Player
|
||||
m_TagString: Player
|
||||
@@ -159,6 +160,20 @@ MonoBehaviour:
|
||||
exposedColor: {r: 0.2, g: 1, b: 0.3, a: 0.25}
|
||||
embeddedColor: {r: 1, g: 0.25, b: 0.2, a: 0.5}
|
||||
visiblePercent: 0
|
||||
--- !u!114 &273411532115212066
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5384024074013944205}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 26105206120a119419bee8bb5f810902, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::PlayerScaler
|
||||
scale: 1
|
||||
scaleJumpAndGravity: 1
|
||||
--- !u!1 &6840099669803454162
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -579,9 +579,9 @@ MonoBehaviour:
|
||||
invertY: 0
|
||||
rotationSmoothing: 20
|
||||
enableZoom: 1
|
||||
zoomSpeed: 0.5
|
||||
zoomSpeed: 0.25
|
||||
zoomSmoothing: 10
|
||||
minRadius: 1.5
|
||||
minRadius: 0.5
|
||||
maxRadius: 8
|
||||
manageCursor: 1
|
||||
--- !u!114 &172071432
|
||||
@@ -767,7 +767,7 @@ Transform:
|
||||
m_GameObject: {fileID: 172071430}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0.1305262, y: 2.1996925e-11, z: -4.1198815e-12, w: 0.9914449}
|
||||
m_LocalPosition: {x: 0, y: 1.9146858, z: -4.3466663}
|
||||
m_LocalPosition: {x: 0, y: 1.5396858, z: -4.3466663}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
@@ -1480,7 +1480,7 @@ Transform:
|
||||
m_GameObject: {fileID: 330585543}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0.1305262, y: 2.1832952e-11, z: -2.8743629e-12, w: 0.9914449}
|
||||
m_LocalPosition: {x: 0, y: 1.9146858, z: -4.3466663}
|
||||
m_LocalPosition: {x: 0, y: 1.5396858, z: -4.3466663}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
@@ -4917,10 +4917,10 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 5ca7cff7542b53b498f0a9834786b9e0, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::FreeCamController
|
||||
moveSpeed: 6
|
||||
sprintMultiplier: 3
|
||||
moveSpeed: 4
|
||||
sprintMultiplier: 2
|
||||
horizontalSensitivity: 0.1
|
||||
verticalSensitivity: 0.07
|
||||
verticalSensitivity: 0.075
|
||||
invertY: 0
|
||||
maxPitch: 89
|
||||
activePriority: 100
|
||||
@@ -4943,13 +4943,13 @@ CharacterController:
|
||||
m_ProvidesContacts: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Height: 1.3
|
||||
m_Height: 0.21
|
||||
m_Radius: 0.1
|
||||
m_SlopeLimit: 59
|
||||
m_StepOffset: 0.15
|
||||
m_StepOffset: 0.1
|
||||
m_SkinWidth: 0.01
|
||||
m_MinMoveDistance: 0.001
|
||||
m_Center: {x: 0, y: -0.09, z: 0}
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1282734306
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -7684,10 +7684,50 @@ PrefabInstance:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 273411532115212066, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: scale
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1514890176713383521, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: m_Enabled
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: poses.Array.size
|
||||
value: 5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: 'poses.Array.data[2]'
|
||||
value:
|
||||
objectReference: {fileID: 11400000, guid: 90df501d86681394b834f647f6f4e939, type: 2}
|
||||
- target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: 'poses.Array.data[3]'
|
||||
value:
|
||||
objectReference: {fileID: 11400000, guid: c5cf9d420554e5e4e96d3bee1903967a, type: 2}
|
||||
- target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: 'poses.Array.data[4]'
|
||||
value:
|
||||
objectReference: {fileID: 11400000, guid: 1545cfba9b5e06d41ae72c7ec766baaf, type: 2}
|
||||
- target: {fileID: 5280718916654756701, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5384024074013944205, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Player
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: m_LocalScale.x
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: m_LocalScale.y
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: m_LocalScale.z
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
@@ -7741,6 +7781,7 @@ SceneRoots:
|
||||
- {fileID: 2009475134}
|
||||
- {fileID: 330585546}
|
||||
- {fileID: 172071436}
|
||||
- {fileID: 1282734307}
|
||||
- {fileID: 832575519}
|
||||
- {fileID: 410087041}
|
||||
- {fileID: 2025317892}
|
||||
@@ -7748,4 +7789,3 @@ SceneRoots:
|
||||
- {fileID: 686187287}
|
||||
- {fileID: 489277934}
|
||||
- {fileID: 347639557}
|
||||
- {fileID: 1282734307}
|
||||
@@ -39,6 +39,15 @@ public class FreeCamController : MonoBehaviour
|
||||
[Range(1f, 89.9f)]
|
||||
public float maxPitch = 89f;
|
||||
|
||||
[Header("Smoothing")]
|
||||
[Tooltip("Acceleration/deceleration smoothing for flight, in seconds. 0 = instant (snappy starts/stops); higher = floatier ramp-up and coast-down.")]
|
||||
[Range(0f, 1f)]
|
||||
public float moveSmoothTime = 0.12f;
|
||||
|
||||
[Tooltip("Look smoothing, in seconds. 0 = raw mouse (instant); small values take the edge off jitter without feeling laggy.")]
|
||||
[Range(0f, 0.3f)]
|
||||
public float lookSmoothTime = 0.04f;
|
||||
|
||||
[Header("Camera")]
|
||||
[Tooltip("Priority the dedicated CinemachineCamera takes while active (must beat the gameplay camera).")]
|
||||
public int activePriority = 100;
|
||||
@@ -48,8 +57,14 @@ public class FreeCamController : MonoBehaviour
|
||||
|
||||
CharacterController _controller;
|
||||
CinemachineCamera _vcam;
|
||||
float _yaw;
|
||||
float _yaw; // look target (raw input accumulates here)
|
||||
float _pitch;
|
||||
float _displayYaw; // smoothed value actually applied to the transform
|
||||
float _displayPitch;
|
||||
float _yawSmoothRef;
|
||||
float _pitchSmoothRef;
|
||||
Vector3 _moveVelocity; // smoothed world-space flight velocity
|
||||
Vector3 _moveVelocityRef;
|
||||
bool _ignoredPlayer;
|
||||
|
||||
void Awake()
|
||||
@@ -98,8 +113,21 @@ public class FreeCamController : MonoBehaviour
|
||||
_yaw += delta.x * horizontalSensitivity;
|
||||
float vs = verticalSensitivity * (invertY ? 1f : -1f);
|
||||
_pitch = Mathf.Clamp(_pitch + delta.y * vs, -maxPitch, maxPitch);
|
||||
|
||||
if (lookSmoothTime > 0f)
|
||||
{
|
||||
// SmoothDampAngle is frame-rate-independent and wraps yaw correctly.
|
||||
_displayYaw = Mathf.SmoothDampAngle(_displayYaw, _yaw, ref _yawSmoothRef, lookSmoothTime);
|
||||
_displayPitch = Mathf.SmoothDampAngle(_displayPitch, _pitch, ref _pitchSmoothRef, lookSmoothTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_displayYaw = _yaw;
|
||||
_displayPitch = _pitch;
|
||||
}
|
||||
|
||||
// Rotation is unconstrained by the CharacterController; only position is.
|
||||
transform.rotation = Quaternion.Euler(_pitch, _yaw, 0f);
|
||||
transform.rotation = Quaternion.Euler(_displayPitch, _displayYaw, 0f);
|
||||
}
|
||||
|
||||
void MoveTick()
|
||||
@@ -109,7 +137,14 @@ public class FreeCamController : MonoBehaviour
|
||||
dir.Normalize();
|
||||
|
||||
float speed = moveSpeed * (SprintHeld() ? sprintMultiplier : 1f);
|
||||
_controller.Move(dir * (speed * Time.deltaTime));
|
||||
Vector3 targetVelocity = dir * speed;
|
||||
|
||||
// SmoothDamp eases accel/decel and is already dt-correct; 0 collapses to instant.
|
||||
_moveVelocity = moveSmoothTime > 0f
|
||||
? Vector3.SmoothDamp(_moveVelocity, targetVelocity, ref _moveVelocityRef, moveSmoothTime)
|
||||
: targetVelocity;
|
||||
|
||||
_controller.Move(_moveVelocity * Time.deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>Place the rig at the currently rendered view so going live produces no visible jump.</summary>
|
||||
@@ -128,6 +163,14 @@ public class FreeCamController : MonoBehaviour
|
||||
_yaw = e.y;
|
||||
float p = e.x > 180f ? e.x - 360f : e.x;
|
||||
_pitch = Mathf.Clamp(p, -maxPitch, maxPitch);
|
||||
|
||||
// Snap the smoothed state to the fresh pose so entering freecam never lags/jumps to catch up.
|
||||
_displayYaw = _yaw;
|
||||
_displayPitch = _pitch;
|
||||
_yawSmoothRef = 0f;
|
||||
_pitchSmoothRef = 0f;
|
||||
_moveVelocity = Vector3.zero;
|
||||
_moveVelocityRef = Vector3.zero;
|
||||
}
|
||||
|
||||
/// <summary>Stop the freecam capsule from being blocked by the (frozen) player's capsule.</summary>
|
||||
|
||||
@@ -636,7 +636,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
if (!found)
|
||||
{
|
||||
// Wall only: losing the center ray while climbing up the face = top edge → mantle.
|
||||
if (!onCeiling && alongSurface.y > 0f && WallInFront(_controller.height * 0.5f))
|
||||
if (!onCeiling && alongSurface.y > 0f && WallInFront(WorldHalfHeight))
|
||||
{
|
||||
_mantling = true;
|
||||
_mantleClearedFeet = false;
|
||||
@@ -695,8 +695,8 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
// longer moves the capsule (only the visual mesh), so it always rests against the wall.
|
||||
// The controller's depenetration never fights back, so there's no buzz and no quantizing
|
||||
// deadzone is needed. Exponential follow keeps it framerate-stable; clamp guards spikes.
|
||||
const float maxPerpSpeed = 8f;
|
||||
float gapError = _controller.skinWidth - gap;
|
||||
float maxPerpSpeed = 8f * CapsuleScale;
|
||||
float gapError = _controller.skinWidth * CapsuleScale - gap;
|
||||
float follow = 1f - Mathf.Exp(-wallOffsetFollow * dt);
|
||||
velocity += _wallNormal * Mathf.Clamp(gapError * follow / dt, -maxPerpSpeed, maxPerpSpeed);
|
||||
}
|
||||
@@ -877,6 +877,19 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
cameraTarget.localPosition = _cameraTargetBaseLocalPos + Vector3.up * y;
|
||||
}
|
||||
|
||||
// The CharacterController's serialized center/radius/height are authored at the player's base
|
||||
// (scale-1) size; transform.localScale resizes the ACTUAL collision capsule via lossyScale but
|
||||
// leaves those serialized numbers untouched. Every climb probe below raycasts in WORLD space, so
|
||||
// it must use the scaled (world) capsule dimensions and scale its world-distance paddings too --
|
||||
// otherwise the wall grab range, head-to-ceiling gap and mantle distance are all measured at the
|
||||
// authored size on a shrunk/grown player (PlayerScaler scales the tunables but not these probes).
|
||||
// Uniform player scale is enforced by PlayerScaler, so a single lossyScale component suffices.
|
||||
private float CapsuleScale => transform.lossyScale.y;
|
||||
private Vector3 WorldCapsuleCenter => transform.TransformPoint(_controller.center);
|
||||
private float WorldRadius => _controller.radius * CapsuleScale;
|
||||
private float WorldHalfHeight => _controller.height * 0.5f * CapsuleScale;
|
||||
private const float ProbeReachSlack = 0.5f; // extra ray length beyond the capsule surface (scale-1 units)
|
||||
|
||||
/// <summary>
|
||||
/// Raycasts from the character center toward the surface (along -_wallNormal) to find the
|
||||
/// current normal and the gap (surface clearance) to it. The capsule's support distance
|
||||
@@ -888,10 +901,10 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
normal = _wallNormal;
|
||||
gap = 0f;
|
||||
|
||||
Vector3 origin = transform.position + _controller.center;
|
||||
Vector3 origin = WorldCapsuleCenter;
|
||||
Vector3 dir = -_wallNormal;
|
||||
float extent = CapsuleExtent(dir);
|
||||
float maxDist = extent + wallMaxOffset + 0.5f;
|
||||
float maxDist = extent + wallMaxOffset + ProbeReachSlack * CapsuleScale;
|
||||
|
||||
int count = Physics.RaycastNonAlloc(
|
||||
origin, dir, _wallProbe, maxDist, ~0, QueryTriggerInteraction.Ignore);
|
||||
@@ -921,8 +934,8 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
/// </summary>
|
||||
private float CapsuleExtent(Vector3 dir)
|
||||
{
|
||||
float radius = _controller.radius;
|
||||
return radius + Mathf.Abs(dir.y) * (_controller.height * 0.5f - radius);
|
||||
float radius = WorldRadius;
|
||||
return radius + Mathf.Abs(dir.y) * (WorldHalfHeight - radius);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -934,9 +947,9 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
normal = Vector3.down;
|
||||
gap = 0f;
|
||||
|
||||
Vector3 origin = transform.position + _controller.center;
|
||||
float half = _controller.height * 0.5f;
|
||||
float maxDist = half + wallMaxOffset + 0.5f;
|
||||
Vector3 origin = WorldCapsuleCenter;
|
||||
float half = WorldHalfHeight;
|
||||
float maxDist = half + wallMaxOffset + ProbeReachSlack * CapsuleScale;
|
||||
|
||||
int count = Physics.RaycastNonAlloc(
|
||||
origin, Vector3.up, _wallProbe, maxDist, ~0, QueryTriggerInteraction.Ignore);
|
||||
@@ -980,7 +993,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
{
|
||||
// Phase 1: climb straight up until no wall is left in front of the feet.
|
||||
_controller.Move(Vector3.up * (speed * dt));
|
||||
if (!WallInFront(_controller.height * 0.5f))
|
||||
if (!WallInFront(WorldHalfHeight))
|
||||
_mantleClearedFeet = true;
|
||||
}
|
||||
else
|
||||
@@ -988,7 +1001,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
// Phase 2: move forward onto the top surface, then finish.
|
||||
_controller.Move(forward * (speed * dt));
|
||||
_mantleOverDist += speed * dt;
|
||||
if (_mantleOverDist >= _controller.radius * 2f + 0.15f || _controller.isGrounded)
|
||||
if (_mantleOverDist >= WorldRadius * 2f + 0.15f * CapsuleScale || _controller.isGrounded)
|
||||
{
|
||||
_reentryCooldown = TopOutRegrabCooldown;
|
||||
ExitWallClimb();
|
||||
@@ -1010,8 +1023,8 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
/// </summary>
|
||||
private bool WallInFront(float downOffset)
|
||||
{
|
||||
Vector3 origin = transform.position + _controller.center - Vector3.up * downOffset;
|
||||
float maxDist = _controller.radius + wallMaxOffset + 0.5f;
|
||||
Vector3 origin = WorldCapsuleCenter - Vector3.up * downOffset;
|
||||
float maxDist = WorldRadius + wallMaxOffset + ProbeReachSlack * CapsuleScale;
|
||||
|
||||
int count = Physics.RaycastNonAlloc(
|
||||
origin, -_wallNormal, _wallProbe, maxDist, ~0, QueryTriggerInteraction.Ignore);
|
||||
@@ -1032,8 +1045,8 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
/// </summary>
|
||||
private bool WalkableGroundBelow()
|
||||
{
|
||||
Vector3 origin = transform.position + _controller.center;
|
||||
float maxDist = _controller.center.y + _controller.stepOffset;
|
||||
Vector3 origin = WorldCapsuleCenter;
|
||||
float maxDist = (_controller.center.y + _controller.stepOffset) * CapsuleScale;
|
||||
|
||||
int count = Physics.RaycastNonAlloc(
|
||||
origin, Vector3.down, _wallProbe, maxDist, ~0, QueryTriggerInteraction.Ignore);
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// One knob that resizes the whole player. Setting <see cref="Scale"/> drives <c>transform.localScale</c>
|
||||
/// — which Unity already propagates to the visible mesh, the CharacterController capsule, the per-pose
|
||||
/// capsules (written as local values) and the camera target — and additionally rescales the movement,
|
||||
/// jump, slide and wall tunables on <see cref="PlayerCharacterController"/> proportionally, so a smaller
|
||||
/// or larger player still moves at the same body-relative pace instead of zipping or crawling. Without
|
||||
/// this the speeds (units/second, not geometry) stay put and a half-size player feels twice as fast.
|
||||
///
|
||||
/// The authored values on the controller ARE the scale-1 design values: tune them normally there. They are
|
||||
/// captured as the base in Awake and multiplied by Scale at runtime, so the serialized design values are
|
||||
/// never overwritten on disk. In the editor only <c>localScale</c> is previewed live (geometry is the only
|
||||
/// visual part); the speed rescale happens on play. The skinned mesh collider scales correctly because
|
||||
/// <see cref="SkinnedColliderBaker"/> divides the player scale back out of its bake.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(PlayerCharacterController))]
|
||||
public class PlayerScaler : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Uniform size multiplier for the whole player. 1 = authored size. Drives transform.localScale " +
|
||||
"(mesh, CharacterController capsule, per-pose capsules and camera target follow automatically) " +
|
||||
"and rescales the controller's movement/jump/slide/wall speeds proportionally.")]
|
||||
[Min(0.01f)]
|
||||
[SerializeField] private float scale = 1f;
|
||||
|
||||
[Tooltip("Also scale jump height, gravity and the wall top-out hop so the motion is geometrically " +
|
||||
"self-similar: identical trajectory shape and air-time, just smaller/larger. Off keeps the " +
|
||||
"authored gravity, giving a small player a floatier, relatively higher jump.")]
|
||||
[SerializeField] private bool scaleJumpAndGravity = true;
|
||||
|
||||
/// <summary>Current uniform scale. Use <see cref="SetScale"/> to change it at runtime.</summary>
|
||||
public float Scale => scale;
|
||||
|
||||
private PlayerCharacterController _pcc;
|
||||
private bool _captured;
|
||||
|
||||
// Authored (scale-1) base values, snapshotted once from the controller in Awake. All are world-unit
|
||||
// scalars (units, units/s, units/s^2) that do NOT follow transform.localScale; dimensionless ratios
|
||||
// (sprint/climb multipliers), angular rates (rotation/turn speed) and times (exit grace) are left
|
||||
// untouched — they are already scale-invariant.
|
||||
private float _bMove, _bAccel, _bDecel, _bStick, _bSlideAcc, _bMaxSlide;
|
||||
private float _bWallOffset, _bWallInset, _bWallReturn, _bWallSens, _bCeilGrab;
|
||||
private float _bJump, _bGravity, _bTopOut;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_pcc = GetComponent<PlayerCharacterController>();
|
||||
CaptureBase();
|
||||
ApplyScale(scale);
|
||||
}
|
||||
|
||||
/// <summary>Sets the scale at runtime (e.g. a grow/shrink mechanic) and re-applies from the base values.</summary>
|
||||
public void SetScale(float newScale)
|
||||
{
|
||||
scale = Mathf.Max(0.01f, newScale);
|
||||
if (!_pcc) _pcc = GetComponent<PlayerCharacterController>();
|
||||
if (!_captured) CaptureBase();
|
||||
ApplyScale(scale);
|
||||
}
|
||||
|
||||
private void CaptureBase()
|
||||
{
|
||||
if (!_pcc) return;
|
||||
_bMove = _pcc.moveSpeed;
|
||||
_bAccel = _pcc.acceleration;
|
||||
_bDecel = _pcc.deceleration;
|
||||
_bStick = _pcc.groundedStickVelocity;
|
||||
_bSlideAcc = _pcc.slideAcceleration;
|
||||
_bMaxSlide = _pcc.maxSlideSpeed;
|
||||
_bWallOffset = _pcc.wallMaxOffset;
|
||||
_bWallInset = _pcc.wallMaxInset;
|
||||
_bWallReturn = _pcc.wallOffsetReturnSpeed;
|
||||
_bWallSens = _pcc.wallOffsetSensitivity;
|
||||
_bCeilGrab = _pcc.ceilingGrabDistance;
|
||||
_bJump = _pcc.jumpHeight;
|
||||
_bGravity = _pcc.gravity;
|
||||
_bTopOut = _pcc.wallTopOutBoost;
|
||||
_captured = true;
|
||||
}
|
||||
|
||||
private void ApplyScale(float s)
|
||||
{
|
||||
transform.localScale = Vector3.one * s;
|
||||
if (!_pcc) return;
|
||||
|
||||
_pcc.moveSpeed = _bMove * s;
|
||||
_pcc.acceleration = _bAccel * s;
|
||||
_pcc.deceleration = _bDecel * s;
|
||||
_pcc.groundedStickVelocity = _bStick * s;
|
||||
_pcc.slideAcceleration = _bSlideAcc * s;
|
||||
_pcc.maxSlideSpeed = _bMaxSlide * s;
|
||||
_pcc.wallMaxOffset = _bWallOffset * s;
|
||||
_pcc.wallMaxInset = _bWallInset * s;
|
||||
_pcc.wallOffsetReturnSpeed = _bWallReturn * s;
|
||||
_pcc.wallOffsetSensitivity = _bWallSens * s;
|
||||
_pcc.ceilingGrabDistance = _bCeilGrab * s;
|
||||
|
||||
if (scaleJumpAndGravity)
|
||||
{
|
||||
_pcc.jumpHeight = _bJump * s;
|
||||
_pcc.gravity = _bGravity * s;
|
||||
_pcc.wallTopOutBoost = _bTopOut * s;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void OnValidate()
|
||||
{
|
||||
// Live geometry preview in edit mode only; the speed rescale runs at play time from the authored
|
||||
// base so the design values on the controller are never serialized in their scaled form.
|
||||
if (!Application.isPlaying)
|
||||
transform.localScale = Vector3.one * Mathf.Max(0.01f, scale);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26105206120a119419bee8bb5f810902
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
@@ -30,6 +31,7 @@ public class SkinnedColliderBaker : MonoBehaviour
|
||||
private MeshCollider _collider;
|
||||
private Mesh _baked;
|
||||
private float _timer;
|
||||
private readonly List<Vector3> _vbuf = new List<Vector3>(); // reused vertex scratch so the scale fixup allocates nothing per bake
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -62,10 +64,39 @@ public class SkinnedColliderBaker : MonoBehaviour
|
||||
{
|
||||
if (!_skinned) return;
|
||||
_skinned.BakeMesh(_baked);
|
||||
|
||||
// BakeMesh freezes the bone deformation — which already carries this transform's world scale —
|
||||
// into the mesh. The MeshCollider below then applies the same lossyScale a SECOND time, so a
|
||||
// scaled player (see PlayerScaler) would get a collider half/double the size of the visible
|
||||
// mesh. Divide the scale back out so the baked mesh is true scale-1 local geometry (the contract
|
||||
// this class already documents): the MeshCollider re-applies it exactly once (matching the
|
||||
// renderer), and MeshPainter / ConcealmentMeter — which raise the baked mesh to world via
|
||||
// localToWorldMatrix — stay correct at any player scale. No-op (and untouched) at scale 1; the
|
||||
// uniform divide is rotation-independent, which the player's uniform scale guarantees.
|
||||
Vector3 ls = transform.lossyScale;
|
||||
if (ls.x != 1f || ls.y != 1f || ls.z != 1f)
|
||||
RescaleToUnitScale(ls);
|
||||
|
||||
_collider.sharedMesh = null; // force a physics re-cook of the new geometry
|
||||
_collider.sharedMesh = _baked;
|
||||
}
|
||||
|
||||
private void RescaleToUnitScale(Vector3 lossyScale)
|
||||
{
|
||||
float ix = lossyScale.x != 0f ? 1f / lossyScale.x : 0f;
|
||||
float iy = lossyScale.y != 0f ? 1f / lossyScale.y : 0f;
|
||||
float iz = lossyScale.z != 0f ? 1f / lossyScale.z : 0f;
|
||||
_baked.GetVertices(_vbuf);
|
||||
for (int i = 0; i < _vbuf.Count; i++)
|
||||
{
|
||||
Vector3 v = _vbuf[i];
|
||||
v.x *= ix; v.y *= iy; v.z *= iz;
|
||||
_vbuf[i] = v;
|
||||
}
|
||||
_baked.SetVertices(_vbuf);
|
||||
_baked.RecalculateBounds();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_baked) Destroy(_baked);
|
||||
|
||||
Reference in new issue
Block a user