Add concealment meter and skinned collider baker; reorganize assets
- ConcealmentMeter: standalone component measuring the percentage of the character volume embedded inside environment geometry (bake -> voxelize via column ray-stabbing parity -> classify interior voxels against box/sphere/ capsule/convex colliders and terrain). Always-on, throttled, gizmo debug. - SkinnedColliderBaker: sole per-frame collider bake owner for skinned rigs. MeshPainter now delegates baking and only borrows BakedMesh for the GPU raster and cache refresh, so the collider stays fresh outside paint mode. - Move pose assets to Assets/Poses, retire unused Insect scripts to Assets/Unused, restore Paintman.controller; mode scripts and scene updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
def10541ab
commit
dcfd668422
29 files changed
+2160
-1656
No files matched your search
@@ -616,36 +616,6 @@ MonoBehaviour:
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
m_ClassDefinitionType: 0
|
||||
- m_Index: 21
|
||||
m_Metrics:
|
||||
m_Width: 153.29688
|
||||
m_Height: 219.59375
|
||||
m_HorizontalBearingX: 13.796875
|
||||
m_HorizontalBearingY: 216
|
||||
m_HorizontalAdvance: 178.20312
|
||||
m_GlyphRect:
|
||||
m_X: 1367
|
||||
m_Y: 515
|
||||
m_Width: 155
|
||||
m_Height: 220
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
m_ClassDefinitionType: 0
|
||||
- m_Index: 22
|
||||
m_Metrics:
|
||||
m_Width: 148.79688
|
||||
m_Height: 216.29688
|
||||
m_HorizontalBearingX: 22.203125
|
||||
m_HorizontalBearingY: 212.70312
|
||||
m_HorizontalAdvance: 178.20312
|
||||
m_GlyphRect:
|
||||
m_X: 1551
|
||||
m_Y: 651
|
||||
m_Width: 149
|
||||
m_Height: 217
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
m_ClassDefinitionType: 0
|
||||
- m_Index: 47
|
||||
m_Metrics:
|
||||
m_Width: 163.5
|
||||
@@ -654,8 +624,8 @@ MonoBehaviour:
|
||||
m_HorizontalBearingY: 214.79688
|
||||
m_HorizontalAdvance: 200.09375
|
||||
m_GlyphRect:
|
||||
m_X: 1035
|
||||
m_Y: 643
|
||||
m_X: 1367
|
||||
m_Y: 515
|
||||
m_Width: 165
|
||||
m_Height: 219
|
||||
m_Scale: 1
|
||||
@@ -669,8 +639,8 @@ MonoBehaviour:
|
||||
m_HorizontalBearingY: 218.40625
|
||||
m_HorizontalAdvance: 237.59375
|
||||
m_GlyphRect:
|
||||
m_X: 1229
|
||||
m_Y: 764
|
||||
m_X: 1561
|
||||
m_Y: 651
|
||||
m_Width: 211
|
||||
m_Height: 223
|
||||
m_Scale: 1
|
||||
@@ -684,8 +654,8 @@ MonoBehaviour:
|
||||
m_HorizontalBearingY: 214.79688
|
||||
m_HorizontalAdvance: 200.09375
|
||||
m_GlyphRect:
|
||||
m_X: 837
|
||||
m_Y: 648
|
||||
m_X: 1801
|
||||
m_Y: 711
|
||||
m_Width: 167
|
||||
m_Height: 215
|
||||
m_Scale: 1
|
||||
@@ -699,8 +669,8 @@ MonoBehaviour:
|
||||
m_HorizontalBearingY: 218.40625
|
||||
m_HorizontalAdvance: 237.59375
|
||||
m_GlyphRect:
|
||||
m_X: 513
|
||||
m_Y: 769
|
||||
m_X: 1035
|
||||
m_Y: 643
|
||||
m_Width: 206
|
||||
m_Height: 223
|
||||
m_Scale: 1
|
||||
@@ -714,8 +684,8 @@ MonoBehaviour:
|
||||
m_HorizontalBearingY: 218.40625
|
||||
m_HorizontalAdvance: 187.5
|
||||
m_GlyphRect:
|
||||
m_X: 1033
|
||||
m_Y: 891
|
||||
m_X: 837
|
||||
m_Y: 648
|
||||
m_Width: 160
|
||||
m_Height: 223
|
||||
m_Scale: 1
|
||||
@@ -885,14 +855,6 @@ MonoBehaviour:
|
||||
m_Unicode: 107
|
||||
m_GlyphIndex: 74
|
||||
m_Scale: 1
|
||||
- m_ElementType: 1
|
||||
m_Unicode: 54
|
||||
m_GlyphIndex: 21
|
||||
m_Scale: 1
|
||||
- m_ElementType: 1
|
||||
m_Unicode: 55
|
||||
m_GlyphIndex: 22
|
||||
m_Scale: 1
|
||||
- m_ElementType: 1
|
||||
m_Unicode: 80
|
||||
m_GlyphIndex: 47
|
||||
@@ -1074,30 +1036,22 @@ MonoBehaviour:
|
||||
m_Height: 252
|
||||
- m_X: 1352
|
||||
m_Y: 500
|
||||
m_Width: 184
|
||||
m_Height: 249
|
||||
- m_X: 1536
|
||||
m_Y: 636
|
||||
m_Width: 178
|
||||
m_Height: 246
|
||||
- m_X: 1020
|
||||
m_Y: 628
|
||||
m_Width: 194
|
||||
m_Height: 248
|
||||
- m_X: 1214
|
||||
m_Y: 749
|
||||
- m_X: 1546
|
||||
m_Y: 636
|
||||
m_Width: 240
|
||||
m_Height: 252
|
||||
- m_X: 1786
|
||||
m_Y: 696
|
||||
m_Width: 196
|
||||
m_Height: 244
|
||||
- m_X: 1020
|
||||
m_Y: 628
|
||||
m_Width: 235
|
||||
m_Height: 252
|
||||
- m_X: 822
|
||||
m_Y: 633
|
||||
m_Width: 196
|
||||
m_Height: 244
|
||||
- m_X: 498
|
||||
m_Y: 754
|
||||
m_Width: 235
|
||||
m_Height: 252
|
||||
- m_X: 1018
|
||||
m_Y: 876
|
||||
m_Width: 189
|
||||
m_Height: 252
|
||||
- m_X: 1939
|
||||
@@ -1149,6 +1103,10 @@ MonoBehaviour:
|
||||
m_Y: 1139
|
||||
m_Width: 2047
|
||||
m_Height: 908
|
||||
- m_X: 229
|
||||
m_Y: 944
|
||||
m_Width: 1818
|
||||
m_Height: 1103
|
||||
- m_X: 103
|
||||
m_Y: 864
|
||||
m_Width: 214
|
||||
@@ -1157,6 +1115,14 @@ MonoBehaviour:
|
||||
m_Y: 864
|
||||
m_Width: 88
|
||||
m_Height: 1183
|
||||
- m_X: 531
|
||||
m_Y: 503
|
||||
m_Width: 40
|
||||
m_Height: 1544
|
||||
- m_X: 498
|
||||
m_Y: 695
|
||||
m_Width: 73
|
||||
m_Height: 1352
|
||||
- m_X: 1373
|
||||
m_Y: 192
|
||||
m_Width: 10
|
||||
@@ -1181,18 +1147,26 @@ MonoBehaviour:
|
||||
m_Y: 384
|
||||
m_Width: 21
|
||||
m_Height: 116
|
||||
- m_X: 1536
|
||||
- m_X: 1546
|
||||
m_Y: 500
|
||||
m_Width: 58
|
||||
m_Width: 48
|
||||
m_Height: 136
|
||||
- m_X: 1714
|
||||
- m_X: 498
|
||||
m_Y: 940
|
||||
m_Width: 1549
|
||||
m_Height: 1107
|
||||
- m_X: 498
|
||||
m_Y: 888
|
||||
m_Width: 1288
|
||||
m_Height: 1159
|
||||
- m_X: 1982
|
||||
m_Y: 696
|
||||
m_Width: 333
|
||||
m_Width: 65
|
||||
m_Height: 1351
|
||||
- m_X: 1714
|
||||
- m_X: 1786
|
||||
m_Y: 636
|
||||
m_Width: 139
|
||||
m_Height: 1411
|
||||
m_Width: 67
|
||||
m_Height: 60
|
||||
- m_X: 1020
|
||||
m_Y: 384
|
||||
m_Width: 20
|
||||
@@ -1201,66 +1175,38 @@ MonoBehaviour:
|
||||
m_Y: 558
|
||||
m_Width: 123
|
||||
m_Height: 70
|
||||
- m_X: 1454
|
||||
m_Y: 882
|
||||
m_Width: 593
|
||||
m_Height: 1165
|
||||
- m_X: 1214
|
||||
- m_X: 1255
|
||||
m_Y: 628
|
||||
m_Width: 138
|
||||
m_Height: 121
|
||||
- m_X: 1454
|
||||
m_Y: 749
|
||||
m_Width: 82
|
||||
m_Height: 1298
|
||||
m_Width: 97
|
||||
m_Height: 1419
|
||||
- m_X: 1255
|
||||
m_Y: 748
|
||||
m_Width: 291
|
||||
m_Height: 1299
|
||||
- m_X: 822
|
||||
m_Y: 490
|
||||
m_Width: 17
|
||||
m_Height: 143
|
||||
- m_X: 531
|
||||
m_Y: 503
|
||||
m_Width: 40
|
||||
m_Height: 251
|
||||
- m_X: 498
|
||||
m_Y: 695
|
||||
m_Width: 73
|
||||
m_Height: 59
|
||||
- m_X: 229
|
||||
m_Y: 944
|
||||
m_Width: 269
|
||||
m_Height: 1103
|
||||
- m_X: 641
|
||||
m_Y: 736
|
||||
m_Width: 181
|
||||
m_Height: 18
|
||||
- m_X: 733
|
||||
m_Y: 736
|
||||
m_Width: 89
|
||||
m_Height: 1311
|
||||
- m_X: 1018
|
||||
- m_X: 1011
|
||||
m_Y: 633
|
||||
m_Width: 2
|
||||
m_Height: 243
|
||||
- m_X: 1207
|
||||
m_Y: 876
|
||||
m_Width: 7
|
||||
m_Height: 1171
|
||||
- m_X: 229
|
||||
m_Y: 1128
|
||||
m_Width: 1818
|
||||
m_Height: 919
|
||||
- m_X: 229
|
||||
m_Y: 1006
|
||||
m_Width: 789
|
||||
m_Height: 1041
|
||||
- m_X: 1207
|
||||
m_Y: 1001
|
||||
m_Width: 840
|
||||
m_Height: 1046
|
||||
- m_X: 733
|
||||
m_Y: 877
|
||||
m_Width: 285
|
||||
m_Height: 1170
|
||||
m_Width: 9
|
||||
m_Height: 1414
|
||||
- m_X: 498
|
||||
m_Y: 885
|
||||
m_Width: 1048
|
||||
m_Height: 1162
|
||||
- m_X: 1011
|
||||
m_Y: 880
|
||||
m_Width: 535
|
||||
m_Height: 1167
|
||||
- m_X: 498
|
||||
m_Y: 754
|
||||
m_Width: 324
|
||||
m_Height: 1293
|
||||
- m_X: 1965
|
||||
m_Y: 0
|
||||
m_Width: 82
|
||||
@@ -13906,7 +13852,7 @@ Texture2D:
|
||||
m_ColorSpace: 1
|
||||
m_PlatformBlob:
|
||||
image data: 4194304
|
||||
_typelessdata: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204050506070809090807060505040301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103040505060708090908070605050402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020405050607080909080706050504030100000000000000000000000000000000000000000000000000000000000000000000000000000003050607080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808Line truncated
|
||||
_typelessdata: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204050506070809090807060505040301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103040505060708090908070605050402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020405050607080909080706050504030100000000000000000000000000000000000000000000000000000000000000000000000000000003050607080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808Line truncated
|
||||
m_StreamData:
|
||||
serializedVersion: 2
|
||||
offset: 0
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1101 &-660375709009797784
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: Running
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 75386596242057138}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.25
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.75
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!91 &9100000
|
||||
AnimatorController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Paintman
|
||||
serializedVersion: 5
|
||||
m_AnimatorParameters:
|
||||
- m_Name: Running
|
||||
m_Type: 4
|
||||
m_DefaultFloat: 0
|
||||
m_DefaultInt: 0
|
||||
m_DefaultBool: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
m_AnimatorLayers:
|
||||
- serializedVersion: 5
|
||||
m_Name: Base Layer
|
||||
m_StateMachine: {fileID: 666766380273028185}
|
||||
m_Mask: {fileID: 0}
|
||||
m_Motions: []
|
||||
m_Behaviours: []
|
||||
m_BlendingMode: 0
|
||||
m_SyncedLayerIndex: -1
|
||||
m_DefaultWeight: 0
|
||||
m_IKPass: 0
|
||||
m_SyncedLayerAffectsTiming: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
--- !u!1102 &75386596242057138
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Paintman-Run
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 2420226104770300396}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 7400000, guid: 681e55cb51beb3b44958b7c4aca15a9f, type: 2}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1107 &666766380273028185
|
||||
AnimatorStateMachine:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Base Layer
|
||||
m_ChildStates:
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 1223896944312122709}
|
||||
m_Position: {x: 290, y: 110, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 75386596242057138}
|
||||
m_Position: {x: 540, y: 110, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions: []
|
||||
m_EntryTransitions: []
|
||||
m_StateMachineTransitions: {}
|
||||
m_StateMachineBehaviours: []
|
||||
m_AnyStatePosition: {x: 50, y: 20, z: 0}
|
||||
m_EntryPosition: {x: 50, y: 120, z: 0}
|
||||
m_ExitPosition: {x: 300, y: 40, z: 0}
|
||||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
|
||||
m_DefaultState: {fileID: 1223896944312122709}
|
||||
--- !u!1102 &1223896944312122709
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Paintman-Idle
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: -660375709009797784}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 7400000, guid: 18925b0fe0029224aa6d9f4d9ca9ab72, type: 2}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &2420226104770300396
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 2
|
||||
m_ConditionEvent: Running
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 1223896944312122709}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.25
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.75
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46ea5f6c3d8e3134c854428259abd4c6
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 9100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -13,4 +13,4 @@ MonoBehaviour:
|
||||
m_Name: Pose_Star
|
||||
m_EditorClassIdentifier: Assembly-CSharp::PlayerPose
|
||||
clip: {fileID: 7400000, guid: 933a7fdefa4f6974b9ed61bd940da6ed, type: 2}
|
||||
ceilingYOffset: 0
|
||||
ceilingYOffset: 1
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+37
-1509
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,370 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Standalone volumetric concealment meter for the painted character.
|
||||
///
|
||||
/// Each evaluation bakes the character's current (deformed) skinned mesh, voxelizes its
|
||||
/// SOLID volume, and reports what fraction of that volume sits INSIDE environment colliders
|
||||
/// (= embedded / hidden) versus exposed. <see cref="EmbeddedPercent"/> is the headline value,
|
||||
/// <see cref="VisiblePercent"/> its complement.
|
||||
///
|
||||
/// Pipeline:
|
||||
/// 1. <see cref="SkinnedMeshRenderer.BakeMesh(Mesh)"/> -> mesh in the renderer's LOCAL space
|
||||
/// (same convention MeshPainter uses for its collider; world = transform.localToWorldMatrix).
|
||||
/// 2. Column ray-stabbing in local space: each (x,z) grid column collects the Y where the mesh
|
||||
/// surface crosses it; parity (odd # of crossings below a voxel center) marks interior voxels.
|
||||
/// This is the same XZ triangle rasterization MeshPainter.GetIslandMask uses for UV islands.
|
||||
/// 3. Each interior voxel center -> world; tested against broadphase-filtered environment
|
||||
/// colliders: convex primitives / convex MeshCollider via ClosestPoint, Terrain via
|
||||
/// SampleHeight, optional concave MeshCollider via raycast parity.
|
||||
///
|
||||
/// Surface-watertightness caveat: parity assumes a closed mesh. After the Blender merge-by-distance
|
||||
/// the paintman rig is effectively watertight; small leaks only perturb the percentage slightly.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class ConcealmentMeter : MonoBehaviour
|
||||
{
|
||||
[Header("Targets")]
|
||||
[Tooltip("Skinned character to measure. Auto-resolved from this GameObject / children if empty.")]
|
||||
[SerializeField] private SkinnedMeshRenderer targetRenderer;
|
||||
|
||||
[Tooltip("Root of the character's OWN collider hierarchy, excluded from the environment test. " +
|
||||
"Auto = the renderer transform's root.")]
|
||||
[SerializeField] private Transform characterRoot;
|
||||
|
||||
[Header("Voxelization")]
|
||||
[Min(2)]
|
||||
[Tooltip("Voxels along the longest local bounds axis. Higher = more precise & more cost. ~24 is a good start.")]
|
||||
[SerializeField] private int voxelResolution = 24;
|
||||
|
||||
[Header("Environment")]
|
||||
[Tooltip("Layers that count as environment the body can be embedded in.")]
|
||||
[SerializeField] private LayerMask environmentMask = ~0;
|
||||
|
||||
[Tooltip("Treat concave (non-convex) MeshColliders as solid via raycast parity. Off = ignored " +
|
||||
"(ClosestPoint is unsupported for them, and flat floors are meaningless as 'inside').")]
|
||||
[SerializeField] private bool includeConcaveMeshColliders;
|
||||
|
||||
[Tooltip("Count being below a Terrain surface as embedded.")]
|
||||
[SerializeField] private bool includeTerrain = true;
|
||||
|
||||
[Header("Scheduling")]
|
||||
[Min(0f)]
|
||||
[Tooltip("Seconds between evaluations while playing. 0 = every frame.")]
|
||||
[SerializeField] private float evaluateInterval = 0.1f;
|
||||
|
||||
[SerializeField] private bool evaluateInPlayMode = true;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool drawGizmos;
|
||||
[SerializeField] private Color exposedColor = new Color(0.2f, 1f, 0.3f, 0.25f);
|
||||
[SerializeField] private Color embeddedColor = new Color(1f, 0.25f, 0.2f, 0.5f);
|
||||
|
||||
/// <summary>Percentage [0..100] of the character's solid volume embedded inside environment colliders.</summary>
|
||||
public float EmbeddedPercent { get; private set; }
|
||||
|
||||
public float visiblePercent;
|
||||
|
||||
public int InteriorVoxelCount { get; private set; }
|
||||
public int EmbeddedVoxelCount { get; private set; }
|
||||
public bool HasResult { get; private set; }
|
||||
|
||||
private Mesh _baked;
|
||||
private Vector3[] _verts;
|
||||
private int[] _tris;
|
||||
private float _timer;
|
||||
|
||||
// Per-column Y crossings (index = iz * nx + ix). Reused across evals; sizes grow as needed.
|
||||
private List<float>[] _columns;
|
||||
|
||||
// Broadphase scratch + classified environment candidates (rebuilt each eval).
|
||||
private readonly Collider[] _overlap = new Collider[64];
|
||||
private readonly List<Collider> _convex = new List<Collider>();
|
||||
private readonly List<Terrain> _terrains = new List<Terrain>();
|
||||
private readonly List<MeshCollider> _concave = new List<MeshCollider>();
|
||||
|
||||
// Gizmo cache.
|
||||
private readonly List<Vector3> _gizPos = new List<Vector3>();
|
||||
private readonly List<bool> _gizEmbedded = new List<bool>();
|
||||
private float _gizVoxelWorld;
|
||||
|
||||
// ClosestPoint returns the input point unchanged when it is inside a (convex) collider.
|
||||
private const float InsideEpsSqr = 1e-8f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!targetRenderer) targetRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
if (!characterRoot && targetRenderer) characterRoot = targetRenderer.transform.root;
|
||||
_baked = new Mesh { name = "ConcealmentMeter_Baked" };
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_baked) Destroy(_baked);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!evaluateInPlayMode) return;
|
||||
if (evaluateInterval <= 0f) { Evaluate(); return; }
|
||||
_timer += Time.deltaTime;
|
||||
if (_timer < evaluateInterval) return;
|
||||
_timer = 0f;
|
||||
Evaluate();
|
||||
}
|
||||
|
||||
/// <summary>Bakes the current pose, voxelizes it, and recomputes the embedded percentage.</summary>
|
||||
[ContextMenu("Evaluate Now")]
|
||||
public void Evaluate()
|
||||
{
|
||||
if (!targetRenderer) return;
|
||||
|
||||
targetRenderer.BakeMesh(_baked);
|
||||
_verts = _baked.vertices;
|
||||
_tris = _baked.triangles;
|
||||
if (_verts.Length == 0 || _tris.Length < 3) return;
|
||||
|
||||
Bounds lb = _baked.bounds; // local-space AABB of the baked pose
|
||||
Vector3 size = lb.size;
|
||||
float maxExtent = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
|
||||
if (maxExtent <= 1e-6f) return;
|
||||
|
||||
float voxel = maxExtent / voxelResolution;
|
||||
int nx = Mathf.Max(1, Mathf.CeilToInt(size.x / voxel));
|
||||
int ny = Mathf.Max(1, Mathf.CeilToInt(size.y / voxel));
|
||||
int nz = Mathf.Max(1, Mathf.CeilToInt(size.z / voxel));
|
||||
Vector3 origin = lb.min;
|
||||
|
||||
StabColumns(origin, voxel, nx, nz);
|
||||
|
||||
Matrix4x4 l2w = targetRenderer.transform.localToWorldMatrix;
|
||||
// Derive the broadphase box from the ACTUAL transformed geometry, not SkinnedMeshRenderer.bounds
|
||||
// (the latter is a root-bone approximation that can be badly offset for a deformed/posed rig).
|
||||
Bounds worldBounds = TransformBounds(l2w, lb);
|
||||
BuildEnvironmentCandidates(worldBounds);
|
||||
|
||||
bool anyEnv = _convex.Count > 0 ||
|
||||
(includeTerrain && _terrains.Count > 0) ||
|
||||
(includeConcaveMeshColliders && _concave.Count > 0);
|
||||
|
||||
_gizPos.Clear();
|
||||
_gizEmbedded.Clear();
|
||||
_gizVoxelWorld = voxel * AverageScale(targetRenderer.transform);
|
||||
|
||||
int interior = 0, embedded = 0;
|
||||
|
||||
for (int iz = 0; iz < nz; iz++)
|
||||
{
|
||||
for (int ix = 0; ix < nx; ix++)
|
||||
{
|
||||
List<float> col = _columns[iz * nx + ix];
|
||||
if (col == null || col.Count < 2) continue;
|
||||
col.Sort();
|
||||
|
||||
for (int iy = 0; iy < ny; iy++)
|
||||
{
|
||||
float cy = origin.y + (iy + 0.5f) * voxel;
|
||||
|
||||
int below = 0;
|
||||
for (int k = 0; k < col.Count; k++)
|
||||
{
|
||||
if (col[k] <= cy) below++;
|
||||
else break; // sorted ascending
|
||||
}
|
||||
if ((below & 1) == 0) continue; // even crossings below -> outside the solid
|
||||
|
||||
interior++;
|
||||
Vector3 localC = new Vector3(origin.x + (ix + 0.5f) * voxel, cy, origin.z + (iz + 0.5f) * voxel);
|
||||
Vector3 worldC = l2w.MultiplyPoint3x4(localC);
|
||||
|
||||
bool inside = anyEnv && IsInsideAnyEnvironment(worldC);
|
||||
if (inside) embedded++;
|
||||
|
||||
if (drawGizmos)
|
||||
{
|
||||
_gizPos.Add(worldC);
|
||||
_gizEmbedded.Add(inside);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InteriorVoxelCount = interior;
|
||||
EmbeddedVoxelCount = embedded;
|
||||
EmbeddedPercent = interior > 0 ? 100f * embedded / interior : 0f;
|
||||
visiblePercent = 100 - EmbeddedPercent;
|
||||
HasResult = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rasterizes every triangle into the XZ column grid; each column accumulates the Y values
|
||||
/// where the surface crosses it (one per triangle whose XZ projection covers the column center).
|
||||
/// </summary>
|
||||
private void StabColumns(Vector3 origin, float voxel, int nx, int nz)
|
||||
{
|
||||
int cells = nx * nz;
|
||||
if (_columns == null || _columns.Length < cells) _columns = new List<float>[cells];
|
||||
for (int i = 0; i < cells; i++) _columns[i]?.Clear();
|
||||
|
||||
int triCount = _tris.Length / 3;
|
||||
for (int t = 0; t < triCount; t++)
|
||||
{
|
||||
Vector3 a = _verts[_tris[t * 3]];
|
||||
Vector3 b = _verts[_tris[t * 3 + 1]];
|
||||
Vector3 c = _verts[_tris[t * 3 + 2]];
|
||||
|
||||
float ax = a.x, az = a.z, bx = b.x, bz = b.z, cx = c.x, cz = c.z;
|
||||
float d = (bz - cz) * (ax - cx) + (cx - bx) * (az - cz);
|
||||
if (Mathf.Abs(d) < 1e-12f) continue; // degenerate in XZ (e.g. a vertical wall triangle)
|
||||
float invD = 1f / d;
|
||||
|
||||
float minXf = Mathf.Min(ax, Mathf.Min(bx, cx));
|
||||
float maxXf = Mathf.Max(ax, Mathf.Max(bx, cx));
|
||||
float minZf = Mathf.Min(az, Mathf.Min(bz, cz));
|
||||
float maxZf = Mathf.Max(az, Mathf.Max(bz, cz));
|
||||
|
||||
int ix0 = Mathf.Clamp(Mathf.FloorToInt((minXf - origin.x) / voxel), 0, nx - 1);
|
||||
int ix1 = Mathf.Clamp(Mathf.CeilToInt((maxXf - origin.x) / voxel), 0, nx - 1);
|
||||
int iz0 = Mathf.Clamp(Mathf.FloorToInt((minZf - origin.z) / voxel), 0, nz - 1);
|
||||
int iz1 = Mathf.Clamp(Mathf.CeilToInt((maxZf - origin.z) / voxel), 0, nz - 1);
|
||||
|
||||
for (int iz = iz0; iz <= iz1; iz++)
|
||||
{
|
||||
float pz = origin.z + (iz + 0.5f) * voxel;
|
||||
for (int ix = ix0; ix <= ix1; ix++)
|
||||
{
|
||||
float px = origin.x + (ix + 0.5f) * voxel;
|
||||
|
||||
float wa = ((bz - cz) * (px - cx) + (cx - bx) * (pz - cz)) * invD;
|
||||
if (wa < 0f) continue;
|
||||
float wb = ((cz - az) * (px - cx) + (ax - cx) * (pz - cz)) * invD;
|
||||
if (wb < 0f) continue;
|
||||
float wc = 1f - wa - wb;
|
||||
if (wc < 0f) continue;
|
||||
|
||||
float y = wa * a.y + wb * b.y + wc * c.y;
|
||||
int ci = iz * nx + ix;
|
||||
(_columns[ci] ?? (_columns[ci] = new List<float>(8))).Add(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Broadphase-overlaps the character bounds and classifies the hit colliders by test type, excluding the character itself.</summary>
|
||||
private void BuildEnvironmentCandidates(Bounds wb)
|
||||
{
|
||||
_convex.Clear();
|
||||
_terrains.Clear();
|
||||
_concave.Clear();
|
||||
|
||||
int n = Physics.OverlapBoxNonAlloc(wb.center, wb.extents, _overlap, Quaternion.identity,
|
||||
environmentMask, QueryTriggerInteraction.Ignore);
|
||||
if (n > _overlap.Length) n = _overlap.Length;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
Collider col = _overlap[i];
|
||||
if (!col) continue;
|
||||
if (characterRoot && (col.transform == characterRoot || col.transform.IsChildOf(characterRoot))) continue;
|
||||
|
||||
if (col is TerrainCollider)
|
||||
{
|
||||
Terrain terr = col.GetComponent<Terrain>();
|
||||
if (terr) _terrains.Add(terr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (col is MeshCollider mc && !mc.convex)
|
||||
{
|
||||
if (includeConcaveMeshColliders) _concave.Add(mc);
|
||||
continue; // concave can't use ClosestPoint
|
||||
}
|
||||
|
||||
_convex.Add(col); // Box / Sphere / Capsule / convex MeshCollider
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsInsideAnyEnvironment(Vector3 p)
|
||||
{
|
||||
for (int i = 0; i < _convex.Count; i++)
|
||||
{
|
||||
if ((_convex[i].ClosestPoint(p) - p).sqrMagnitude <= InsideEpsSqr) return true;
|
||||
}
|
||||
|
||||
if (includeTerrain)
|
||||
{
|
||||
for (int i = 0; i < _terrains.Count; i++)
|
||||
{
|
||||
Terrain terr = _terrains[i];
|
||||
Vector3 tp = terr.transform.position;
|
||||
TerrainData td = terr.terrainData;
|
||||
float lx = p.x - tp.x, lz = p.z - tp.z;
|
||||
if (lx < 0f || lz < 0f || lx > td.size.x || lz > td.size.z) continue;
|
||||
if (p.y <= tp.y + terr.SampleHeight(p)) return true; // below the surface
|
||||
}
|
||||
}
|
||||
|
||||
if (includeConcaveMeshColliders)
|
||||
{
|
||||
for (int i = 0; i < _concave.Count; i++)
|
||||
{
|
||||
if (InsideConcave(_concave[i], p)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>Parity test for a closed concave MeshCollider: odd # of surface crossings straight up = inside.</summary>
|
||||
private static bool InsideConcave(MeshCollider mc, Vector3 p)
|
||||
{
|
||||
const float maxDist = 1000f;
|
||||
const float skin = 1e-4f;
|
||||
Vector3 dir = Vector3.up;
|
||||
Ray ray = new Ray(p, dir);
|
||||
int hits = 0;
|
||||
float travelled = 0f;
|
||||
|
||||
while (travelled < maxDist && mc.Raycast(ray, out RaycastHit h, maxDist - travelled))
|
||||
{
|
||||
hits++;
|
||||
travelled += h.distance + skin;
|
||||
ray = new Ray(h.point + dir * skin, dir);
|
||||
}
|
||||
return (hits & 1) == 1;
|
||||
}
|
||||
|
||||
/// <summary>World AABB enclosing a local AABB after an affine transform (encapsulates the 8 transformed corners).</summary>
|
||||
private static Bounds TransformBounds(Matrix4x4 m, Bounds local)
|
||||
{
|
||||
Vector3 mn = local.min, mx = local.max;
|
||||
Vector3 c0 = m.MultiplyPoint3x4(mn);
|
||||
Bounds b = new Bounds(c0, Vector3.zero);
|
||||
b.Encapsulate(m.MultiplyPoint3x4(new Vector3(mx.x, mn.y, mn.z)));
|
||||
b.Encapsulate(m.MultiplyPoint3x4(new Vector3(mn.x, mx.y, mn.z)));
|
||||
b.Encapsulate(m.MultiplyPoint3x4(new Vector3(mn.x, mn.y, mx.z)));
|
||||
b.Encapsulate(m.MultiplyPoint3x4(new Vector3(mx.x, mx.y, mn.z)));
|
||||
b.Encapsulate(m.MultiplyPoint3x4(new Vector3(mx.x, mn.y, mx.z)));
|
||||
b.Encapsulate(m.MultiplyPoint3x4(new Vector3(mn.x, mx.y, mx.z)));
|
||||
b.Encapsulate(m.MultiplyPoint3x4(mx));
|
||||
return b;
|
||||
}
|
||||
|
||||
private static float AverageScale(Transform t)
|
||||
{
|
||||
Vector3 s = t.lossyScale;
|
||||
return (Mathf.Abs(s.x) + Mathf.Abs(s.y) + Mathf.Abs(s.z)) / 3f;
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
if (!drawGizmos || _gizPos.Count == 0) return;
|
||||
Vector3 cube = Vector3.one * (_gizVoxelWorld * 0.9f);
|
||||
for (int i = 0; i < _gizPos.Count; i++)
|
||||
{
|
||||
Gizmos.color = _gizEmbedded[i] ? embeddedColor : exposedColor;
|
||||
Gizmos.DrawCube(_gizPos[i], cube);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8baaa10e1e77f0944b3aa0b4312fc5a1
|
||||
@@ -22,8 +22,8 @@ public class GameModeManager : MonoBehaviour
|
||||
[Tooltip("Mesh painter. Empty = found automatically.")]
|
||||
public MeshPainter painter;
|
||||
|
||||
[Tooltip("Insect / surface-walk controller. Empty = found automatically.")]
|
||||
public InsectController insect;
|
||||
//[Tooltip("Insect / surface-walk controller. Empty = found automatically.")]
|
||||
//public InsectController insect;
|
||||
|
||||
[Header("Switching")]
|
||||
[Tooltip("Key that cycles to the next mode.")]
|
||||
@@ -39,7 +39,7 @@ public class GameModeManager : MonoBehaviour
|
||||
public PlayerCharacterController Player => player;
|
||||
public ThirdPersonOrbitInput CameraInput => cameraInput;
|
||||
public MeshPainter Painter => painter;
|
||||
public InsectController Insect => insect;
|
||||
//public InsectController Insect => insect;
|
||||
|
||||
/// <summary>Raised after a mode switch finishes (the new mode's Enter has already run).
|
||||
/// Argument = the now-active mode. Used by UI (e.g. the paint HUD) to follow the mode.</summary>
|
||||
@@ -57,7 +57,7 @@ public class GameModeManager : MonoBehaviour
|
||||
if (!player) player = FindFirstObjectByType<PlayerCharacterController>();
|
||||
if (!cameraInput) cameraInput = FindFirstObjectByType<ThirdPersonOrbitInput>();
|
||||
if (!painter) painter = FindFirstObjectByType<MeshPainter>();
|
||||
if (!insect) insect = FindFirstObjectByType<InsectController>();
|
||||
//if (!insect) insect = FindFirstObjectByType<InsectController>();
|
||||
|
||||
BuildModes();
|
||||
}
|
||||
@@ -82,8 +82,8 @@ public class GameModeManager : MonoBehaviour
|
||||
|
||||
// Insect mode only joins the Tab cycle when a surface walker is present, so a scene
|
||||
// without one behaves exactly as before (no dead, player-freezing mode in the cycle).
|
||||
if (insect)
|
||||
_modes.Add(new InsectMode());
|
||||
//if (insect)
|
||||
// _modes.Add(new InsectMode());
|
||||
|
||||
foreach (var m in _modes)
|
||||
m.Bind(this);
|
||||
|
||||
@@ -10,13 +10,22 @@ public partial class MeshPainter
|
||||
if (!_collider) _collider = gameObject.AddComponent<MeshCollider>();
|
||||
_collider.convex = false; // non-convex provides triangleIndex / textureCoord
|
||||
|
||||
_bakedMesh = new Mesh { name = "MeshPainter_Baked" };
|
||||
// An always-on SkinnedColliderBaker (skinned rigs only) owns the bake even outside paint
|
||||
// mode; we delegate to it and only borrow its mesh. Without one we keep our own legacy bake.
|
||||
_baker = _skinned ? GetComponent<SkinnedColliderBaker>() : null;
|
||||
if (!_baker) _bakedMesh = new Mesh { name = "MeshPainter_Baked" };
|
||||
BakeColliderMesh();
|
||||
}
|
||||
|
||||
private void BakeColliderMesh()
|
||||
{
|
||||
if (_skinned)
|
||||
if (_baker)
|
||||
{
|
||||
// Baker already baked (negative execution order) and keeps _collider.sharedMesh fresh;
|
||||
// we only track its mesh for the GPU raster path. No bake here - that's the whole point.
|
||||
_bakedMesh = _baker.BakedMesh;
|
||||
}
|
||||
else if (_skinned)
|
||||
{
|
||||
// Static skinned mesh: bake into local coordinates (scale = 1).
|
||||
_skinned.BakeMesh(_bakedMesh);
|
||||
|
||||
@@ -195,6 +195,9 @@ public partial class MeshPainter : MonoBehaviour
|
||||
private SkinnedMeshRenderer _skinned;
|
||||
private MeshCollider _collider;
|
||||
private Mesh _bakedMesh;
|
||||
// When present, this always-on baker owns the collider bake (also outside paint mode); we
|
||||
// stop baking and only borrow its mesh. Null = no baker -> we keep our own legacy bake.
|
||||
private SkinnedColliderBaker _baker;
|
||||
private Material _materialInstance;
|
||||
|
||||
// Mesh caches (in local/collider space).
|
||||
@@ -854,7 +857,7 @@ public partial class MeshPainter : MonoBehaviour
|
||||
// scene unload that does not raise OnApplicationQuit; the once-guard prevents a re-save.
|
||||
SavePaintOnTeardown();
|
||||
|
||||
if (_bakedMesh) Destroy(_bakedMesh);
|
||||
if (_bakedMesh && !_baker) Destroy(_bakedMesh); // _baker owns its mesh; only free our own
|
||||
if (_materialInstance) Destroy(_materialInstance);
|
||||
if (_proceduralMask) Destroy(_proceduralMask);
|
||||
if (_previewMat) Destroy(_previewMat);
|
||||
|
||||
@@ -8,8 +8,8 @@ public class PaintMode : GameMode
|
||||
|
||||
public override void Enter()
|
||||
{
|
||||
if (Manager.Insect)
|
||||
Manager.Insect.enabled = false;
|
||||
//if (Manager.Insect)
|
||||
// Manager.Insect.enabled = false;
|
||||
|
||||
if (Manager.Player)
|
||||
{
|
||||
|
||||
@@ -8,8 +8,8 @@ public class PlayerControlMode : GameMode
|
||||
|
||||
public override void Enter()
|
||||
{
|
||||
if (Manager.Insect)
|
||||
Manager.Insect.enabled = false;
|
||||
//if (Manager.Insect)
|
||||
// Manager.Insect.enabled = false;
|
||||
|
||||
if (Manager.Player)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Sole owner of the animated character's collider bake: keeps a non-convex MeshCollider in sync with
|
||||
/// the SkinnedMeshRenderer's current pose every frame, independent of any paint/game mode. MeshPainter's
|
||||
/// own per-frame bake sits behind its PaintingEnabled gate, so the collider would otherwise freeze in
|
||||
/// player-control / insect mode. When this component is present MeshPainter delegates to it (it stops
|
||||
/// baking and only borrows <see cref="BakedMesh"/> for its GPU raster path), so the deformed-pose
|
||||
/// collider stays fresh for everyone - paint raycasts, physics, future seeker / line-of-sight queries.
|
||||
///
|
||||
/// Bakes in the renderer's LOCAL space (BakeMesh, scale = 1) - the same convention MeshPainter and
|
||||
/// ConcealmentMeter use (world = transform.localToWorldMatrix). Runs at a negative execution order so
|
||||
/// the collider is fresh before MeshPainter (and other consumers) read it in the same frame. Owns the
|
||||
/// baked Mesh (creates + destroys it); MeshPainter never destroys a borrowed mesh.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
[DefaultExecutionOrder(-50)]
|
||||
[RequireComponent(typeof(SkinnedMeshRenderer))]
|
||||
public class SkinnedColliderBaker : MonoBehaviour
|
||||
{
|
||||
[Min(0f)]
|
||||
[Tooltip("Seconds between collider re-bakes. 0 = every frame (matches MeshPainter's per-frame bake). " +
|
||||
"Raise it to trade collider freshness for CPU on a high-poly rig.")]
|
||||
[SerializeField] private float bakeInterval = 0f;
|
||||
|
||||
/// <summary>The mesh baked from the current pose, in local space. Valid after the first bake.</summary>
|
||||
public Mesh BakedMesh => _baked;
|
||||
|
||||
private SkinnedMeshRenderer _skinned;
|
||||
private MeshCollider _collider;
|
||||
private Mesh _baked;
|
||||
private float _timer;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_skinned = GetComponent<SkinnedMeshRenderer>();
|
||||
if (!_skinned)
|
||||
{
|
||||
Debug.LogError("[SkinnedColliderBaker] No SkinnedMeshRenderer on this GameObject.", this);
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_collider = GetComponent<MeshCollider>();
|
||||
if (!_collider) _collider = gameObject.AddComponent<MeshCollider>();
|
||||
_collider.convex = false; // non-convex provides triangleIndex / textureCoord for paint raycasts
|
||||
|
||||
_baked = new Mesh { name = "SkinnedColliderBaker_Baked" };
|
||||
Bake(); // valid collider on frame 0, before any consumer reads it
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (bakeInterval <= 0f) { Bake(); return; }
|
||||
_timer += Time.deltaTime;
|
||||
if (_timer < bakeInterval) return;
|
||||
_timer = 0f;
|
||||
Bake();
|
||||
}
|
||||
|
||||
private void Bake()
|
||||
{
|
||||
if (!_skinned) return;
|
||||
_skinned.BakeMesh(_baked);
|
||||
_collider.sharedMesh = null; // force a physics re-cook of the new geometry
|
||||
_collider.sharedMesh = _baked;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_baked) Destroy(_baked);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 161b7cf82dd54e74d92b5ca72d3be3af
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54e7941c6d0121a43b23c184d6245569
|
||||
guid: 11727b51a902d4f44827a5be2a05018a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
File renamed without changes.
File renamed without changes.
@@ -13,12 +13,12 @@ public class InsectMode : GameMode
|
||||
if (Manager.Player)
|
||||
Manager.Player.enabled = false; // stop the gravity controller (its Update/gravity)
|
||||
|
||||
if (Manager.Insect)
|
||||
{
|
||||
Manager.Insect.enabled = true;
|
||||
Manager.Insect.ControlEnabled = true;
|
||||
Manager.Insect.SnapToSurface();
|
||||
}
|
||||
//if (Manager.Insect)
|
||||
//{
|
||||
// Manager.Insect.enabled = true;
|
||||
// Manager.Insect.ControlEnabled = true;
|
||||
// Manager.Insect.SnapToSurface();
|
||||
//}
|
||||
|
||||
if (Manager.CameraInput)
|
||||
Manager.CameraInput.LookMode = ThirdPersonOrbitInput.OrbitLookMode.AlwaysActive;
|
||||
@@ -29,8 +29,8 @@ public class InsectMode : GameMode
|
||||
|
||||
public override void Exit()
|
||||
{
|
||||
if (Manager.Insect)
|
||||
Manager.Insect.enabled = false;
|
||||
//if (Manager.Insect)
|
||||
// Manager.Insect.enabled = false;
|
||||
|
||||
if (Manager.Player)
|
||||
Manager.Player.enabled = true;
|
||||
File renamed without changes.
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bccbff0e6a6dcb54bbe58022842213f4
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,219 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &2753207977301565134
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7343299364369393213}
|
||||
- component: {fileID: 22507459658410499}
|
||||
m_Layer: 0
|
||||
m_Name: Player (Variant 2, Hand)
|
||||
m_TagString: Player
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &7343299364369393213
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2753207977301565134}
|
||||
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:
|
||||
- {fileID: 4014907164611811682}
|
||||
- {fileID: 1262072125491596160}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &22507459658410499
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2753207977301565134}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: bf4039bad99e6e64aae35786e6a87ba6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::InsectController
|
||||
moveSpeed: 4
|
||||
sprintSpeedMultiplier: 1.8
|
||||
alignSmoothing: 16
|
||||
cameraRelative: 1
|
||||
cameraTransform: {fileID: 0}
|
||||
hoverHeight: 0.1
|
||||
probeRadius: 0.5
|
||||
stepHeight: 0.3
|
||||
groundMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
wallWrapAngle: 70
|
||||
wallProbeDistance: 0.6
|
||||
maxWrapAngle: 150
|
||||
animator: {fileID: 0}
|
||||
runningParameter: Running
|
||||
--- !u!1 &9012401119129405183
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1262072125491596160}
|
||||
m_Layer: 0
|
||||
m_Name: CameraTarget
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1262072125491596160
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 9012401119129405183}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.226, z: -0.155}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7343299364369393213}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1001 &4502887663618702391
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 7343299364369393213}
|
||||
m_Modifications:
|
||||
- target: {fileID: 180557533655662575, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: WhiteHand
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0.1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 180
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 1338243545944059599, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 1165829002027726284}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
--- !u!1 &3237838625342182136 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 1338243545944059599, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
m_PrefabInstance: {fileID: 4502887663618702391}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &1165829002027726284
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3237838625342182136}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5fc799adb27d5ea45990b5522b75ddda, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MeshPainter
|
||||
brushShader: {fileID: 0}
|
||||
dilateShader: {fileID: 0}
|
||||
packMsShader: {fileID: 0}
|
||||
persistPaint: 1
|
||||
saveId:
|
||||
pipette: 0
|
||||
spray: 0
|
||||
sprayDots: 24
|
||||
sprayDotSizeMin: 0.05
|
||||
sprayDotSizeMax: 0.18
|
||||
sprayDotAlphaMin: 0.25
|
||||
sprayDotAlphaMax: 1
|
||||
useGpu: 1
|
||||
paintAlbedo: 1
|
||||
paintMetallicSmoothness: 0
|
||||
paintOcclusion: 0
|
||||
paintEmission: 0
|
||||
brushColor: {r: 0.6, g: 0.6, b: 1, a: 1}
|
||||
metallic: 1
|
||||
smoothness: 1
|
||||
metallicSmoothnessOpacity: 1
|
||||
occlusion: 1
|
||||
occlusionOpacity: 1
|
||||
emissionColor: {r: 1, g: 0.6, b: 0, a: 1}
|
||||
emissionIntensity: 200
|
||||
brushSize: 100
|
||||
brushMasks:
|
||||
- {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10912, guid: 0000000000000000f000000000000000, type: 0}
|
||||
activeBrushIndex: 0
|
||||
brushAlignment: 0
|
||||
brushRotation: 0
|
||||
paintOnMoveOnly: 1
|
||||
paintInterval: 0
|
||||
previewMode: 2
|
||||
previewOpacity: 1
|
||||
textureSize: 1024
|
||||
baseColor: {r: 0.8, g: 0.8, b: 0.8, a: 1}
|
||||
paddingTexels: 2
|
||||
paintCamera: {fileID: 0}
|
||||
updateColliderEveryFrame: 1
|
||||
previewShader: {fileID: 0}
|
||||
--- !u!4 &4014907164611811682 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
m_PrefabInstance: {fileID: 4502887663618702391}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3a1e0eb07937fa418c99504f882bee2
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user