init
100
.editorconfig
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
# Remove the line below if you want to inherit .editorconfig settings from higher directories
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# C# files
|
||||||
|
[*.{cs,razor}]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
tab_size = 4
|
||||||
|
|
||||||
|
# New line preferences
|
||||||
|
end_of_line = crlf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
|
||||||
|
#### C# Coding Conventions ####
|
||||||
|
|
||||||
|
# Expression-bodied members
|
||||||
|
csharp_style_expression_bodied_accessors = true:silent
|
||||||
|
csharp_style_expression_bodied_constructors = false:silent
|
||||||
|
csharp_style_expression_bodied_indexers = true:silent
|
||||||
|
csharp_style_expression_bodied_lambdas = true:silent
|
||||||
|
csharp_style_expression_bodied_local_functions = false:silent
|
||||||
|
csharp_style_expression_bodied_methods = false:silent
|
||||||
|
csharp_style_expression_bodied_operators = false:silent
|
||||||
|
csharp_style_expression_bodied_properties = true:silent
|
||||||
|
|
||||||
|
# Pattern matching preferences
|
||||||
|
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||||
|
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||||
|
csharp_style_prefer_not_pattern = true:suggestion
|
||||||
|
csharp_style_prefer_pattern_matching = true:silent
|
||||||
|
csharp_style_prefer_switch_expression = true:suggestion
|
||||||
|
|
||||||
|
# Null-checking preferences
|
||||||
|
csharp_style_conditional_delegate_call = true:suggestion
|
||||||
|
|
||||||
|
# Code-block preferences
|
||||||
|
csharp_prefer_braces = true:silent
|
||||||
|
|
||||||
|
# Expression-level preferences
|
||||||
|
csharp_prefer_simple_default_expression = true:suggestion
|
||||||
|
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||||
|
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
|
||||||
|
csharp_style_inlined_variable_declaration = true:suggestion
|
||||||
|
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||||
|
csharp_style_prefer_index_operator = true:suggestion
|
||||||
|
csharp_style_prefer_range_operator = true:suggestion
|
||||||
|
csharp_style_throw_expression = true:suggestion
|
||||||
|
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||||
|
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||||
|
|
||||||
|
# 'using' directive preferences
|
||||||
|
csharp_using_directive_placement = outside_namespace:silent
|
||||||
|
|
||||||
|
#### C# Formatting Rules ####
|
||||||
|
|
||||||
|
# New line preferences
|
||||||
|
csharp_new_line_before_catch = true
|
||||||
|
csharp_new_line_before_else = true
|
||||||
|
csharp_new_line_before_finally = true
|
||||||
|
csharp_new_line_before_members_in_anonymous_types = true
|
||||||
|
csharp_new_line_before_members_in_object_initializers = true
|
||||||
|
csharp_new_line_before_open_brace = all
|
||||||
|
csharp_new_line_between_query_expression_clauses = true
|
||||||
|
|
||||||
|
# Indentation preferences
|
||||||
|
csharp_indent_block_contents = true
|
||||||
|
csharp_indent_braces = false
|
||||||
|
csharp_indent_case_contents = true
|
||||||
|
csharp_indent_case_contents_when_block = true
|
||||||
|
csharp_indent_labels = no_change
|
||||||
|
csharp_indent_switch_labels = true
|
||||||
|
|
||||||
|
# Space preferences
|
||||||
|
csharp_space_after_cast = false
|
||||||
|
csharp_space_after_colon_in_inheritance_clause = true
|
||||||
|
csharp_space_after_comma = true
|
||||||
|
csharp_space_after_dot = false
|
||||||
|
csharp_space_after_keywords_in_control_flow_statements = true
|
||||||
|
csharp_space_after_semicolon_in_for_statement = true
|
||||||
|
csharp_space_around_binary_operators = before_and_after
|
||||||
|
csharp_space_around_declaration_statements = false
|
||||||
|
csharp_space_before_colon_in_inheritance_clause = true
|
||||||
|
csharp_space_before_comma = false
|
||||||
|
csharp_space_before_dot = false
|
||||||
|
csharp_space_before_open_square_brackets = false
|
||||||
|
csharp_space_before_semicolon_in_for_statement = false
|
||||||
|
csharp_space_between_empty_square_brackets = false
|
||||||
|
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||||
|
csharp_space_between_method_call_parameter_list_parentheses = true
|
||||||
|
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||||
|
csharp_space_between_method_declaration_parameter_list_parentheses = true
|
||||||
|
csharp_space_between_parentheses = control_flow_statements
|
||||||
|
csharp_space_between_square_brackets = false
|
||||||
|
|
||||||
|
# Wrapping preferences
|
||||||
|
csharp_preserve_single_line_blocks = true
|
||||||
|
csharp_preserve_single_line_statements = true
|
28
.gitignore
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
# This file describes files and paths that should not be tracked by Git version control
|
||||||
|
# https://git-scm.com/docs/gitignore
|
||||||
|
|
||||||
|
# Auto-generated code editor files
|
||||||
|
.vs/*
|
||||||
|
.vscode/*
|
||||||
|
*.csproj
|
||||||
|
obj
|
||||||
|
bin
|
||||||
|
Properties/*
|
||||||
|
code/obj/*
|
||||||
|
code/Properties/*
|
||||||
|
|
||||||
|
# Auto-generated asset related files
|
||||||
|
.sbox/*
|
||||||
|
*.generated.*
|
||||||
|
*.*_c
|
||||||
|
!*.shader_c
|
||||||
|
*.los
|
||||||
|
*.vpk
|
||||||
|
*launchSettings.json
|
||||||
|
*.sln
|
||||||
|
|
||||||
|
*idea
|
||||||
|
|
||||||
|
# Exported / standalone games
|
||||||
|
Exports/
|
BIN
Assets/maps/nunu.vmap
Normal file
20
Assets/maps/nunu.vmap.meta
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"publish": {
|
||||||
|
"Enabled": false,
|
||||||
|
"ProjectConfig": {
|
||||||
|
"Title": "nunu",
|
||||||
|
"Type": "map",
|
||||||
|
"Org": "local",
|
||||||
|
"Ident": "nunu",
|
||||||
|
"Schema": 0,
|
||||||
|
"IncludeSourceFiles": false,
|
||||||
|
"Resources": null,
|
||||||
|
"PackageReferences": [],
|
||||||
|
"EditorReferences": [],
|
||||||
|
"IsWhitelistDisabled": false,
|
||||||
|
"Metadata": {
|
||||||
|
"SingleAssetSource": "maps/nunu.vmap"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
Assets/maps/test.vmap
Normal file
BIN
Assets/photo_2024-10-16_19-53-34.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
977
Assets/prefabs/player.prefab
Normal file
@ -0,0 +1,977 @@
|
|||||||
|
{
|
||||||
|
"RootObject": {
|
||||||
|
"__guid": "9ab6bf36-8cdf-4834-bd2a-238fc0cbf804",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "player",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "ShrimpleCharacterController.ShrimpleCharacterController",
|
||||||
|
"__guid": "aae5fa89-8749-4ca6-9196-fb35c13baa5c",
|
||||||
|
"AirAcceleration": 300,
|
||||||
|
"AirDeceleration": 0,
|
||||||
|
"Gravity": -850,
|
||||||
|
"GravityEnabled": true,
|
||||||
|
"GripFactorReduction": 1,
|
||||||
|
"GroundAcceleration": 1000,
|
||||||
|
"GroundDeceleration": 1500,
|
||||||
|
"GroundStickDistance": 12,
|
||||||
|
"GroundStickEnabled": true,
|
||||||
|
"IgnoreGroundSurface": false,
|
||||||
|
"IgnoreTags": "",
|
||||||
|
"IgnoreZ": true,
|
||||||
|
"IgnoreZWhenZero": true,
|
||||||
|
"ManuallyUpdate": true,
|
||||||
|
"MaxBounces": 5,
|
||||||
|
"MaxGroundAngle": 60,
|
||||||
|
"MaxUnstuckTries": 20,
|
||||||
|
"PseudoStepsEnabled": true,
|
||||||
|
"PushEnabled": false,
|
||||||
|
"PushTagsWeight": {
|
||||||
|
"player": 1
|
||||||
|
},
|
||||||
|
"ScaleAgainstWalls": true,
|
||||||
|
"StepDepth": 2,
|
||||||
|
"StepHeight": 12,
|
||||||
|
"StepsEnabled": true,
|
||||||
|
"StepTolerance": 1,
|
||||||
|
"TraceHeight": 72,
|
||||||
|
"TraceWidth": 16,
|
||||||
|
"UnstuckEnabled": true,
|
||||||
|
"UseSceneGravity": true,
|
||||||
|
"WallTolerance": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Kal",
|
||||||
|
"__guid": "8467b849-9449-492b-b862-76c3c37aee1e",
|
||||||
|
"CamOffsetX": 200,
|
||||||
|
"CamOffsetZ": 61,
|
||||||
|
"DuckSpeed": 50,
|
||||||
|
"JumpStrength": 350,
|
||||||
|
"RunSpeed": 300,
|
||||||
|
"WalkSpeed": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Citizen.CitizenAnimationHelper",
|
||||||
|
"__guid": "640af9e4-02ed-4391-95ea-e45fba51fa42",
|
||||||
|
"BodyWeight": 1,
|
||||||
|
"EyesWeight": 1,
|
||||||
|
"HeadWeight": 1,
|
||||||
|
"LookAtEnabled": false,
|
||||||
|
"Target": {
|
||||||
|
"_type": "component",
|
||||||
|
"component_id": "4fd8c36d-180b-41af-8439-6b975ca1c7b3",
|
||||||
|
"go": "b99ceffc-a173-4a6e-a239-6d3c1612c09f",
|
||||||
|
"component_type": "SkinnedModelRenderer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "b99ceffc-a173-4a6e-a239-6d3c1612c09f",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Body",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.SkinnedModelRenderer",
|
||||||
|
"__guid": "4fd8c36d-180b-41af-8439-6b975ca1c7b3",
|
||||||
|
"BodyGroups": 341,
|
||||||
|
"CreateBoneObjects": false,
|
||||||
|
"Model": "models/citizen/citizen.vmdl",
|
||||||
|
"Morphs": {},
|
||||||
|
"Parameters": {
|
||||||
|
"bools": {},
|
||||||
|
"ints": {},
|
||||||
|
"floats": {},
|
||||||
|
"vectors": {},
|
||||||
|
"rotations": {}
|
||||||
|
},
|
||||||
|
"RenderOptions": {
|
||||||
|
"GameLayer": true,
|
||||||
|
"OverlayLayer": false,
|
||||||
|
"BloomLayer": false,
|
||||||
|
"AfterUILayer": false
|
||||||
|
},
|
||||||
|
"RenderType": "On",
|
||||||
|
"Tint": "1,1,1,1",
|
||||||
|
"UseAnimGraph": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "55f02b37-0d7a-485b-9ff9-577329327b72",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "pelvis",
|
||||||
|
"Position": "1.09978,0.02634115,30.81247",
|
||||||
|
"Rotation": "-0.4635624,-0.5211884,-0.5340351,0.4777857",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "e6791e79-6d2f-4889-938a-469e36e7a394",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "spine_0",
|
||||||
|
"Position": "3.921841,-0.002455711,-0.000120163",
|
||||||
|
"Rotation": "-0.0005211234,0.004492462,-0.02736789,-0.9996151",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "62632f4c-5251-47ee-99e9-5eca787ebd13",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "spine_1",
|
||||||
|
"Position": "5.610458,0.000005722046,0.00003051758",
|
||||||
|
"Rotation": "-0.0001792312,0.007572293,-0.04617235,-0.9989036",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "9efd1d11-91e3-43b0-8203-122dddd4da0c",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "spine_2",
|
||||||
|
"Position": "5.610497,0.00001525879,-0.000007629395",
|
||||||
|
"Rotation": "-0.0003193617,0.001911119,-0.0103026,-0.9999417",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "7b3a4b1c-3851-444c-9b10-c59019d02a34",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "neck_0",
|
||||||
|
"Position": "5.820332,-0.09347343,-0.003276825",
|
||||||
|
"Rotation": "0.00003476441,-0.0002155006,0.009900302,-0.9999442",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "a660f880-88bb-4972-bb01-5a6a2e2d2a84",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "head",
|
||||||
|
"Position": "4.511508,-0.0006238669,-0.0008400269",
|
||||||
|
"Rotation": "-0.000007912517,-0.0000001043081,0.01384526,-0.9998921",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "ae84828d-d4dc-461b-bbf5-55906713444d",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "ear_R",
|
||||||
|
"Position": "5.622315,-0.4147104,-5.930751",
|
||||||
|
"Rotation": "0.04622595,-0.6934852,0.1379034,-0.7056088",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "9f92ced9-922e-41be-ad20-28a016d36589",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "ear_L",
|
||||||
|
"Position": "5.62321,-0.4153741,5.927209",
|
||||||
|
"Rotation": "0.705609,-0.1379605,0.6934716,-0.04625562",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "46ddc438-4d04-414e-8c83-da033150c6c5",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "face_lid_lower_R",
|
||||||
|
"Position": "6.909532,5.141103,-3.235655",
|
||||||
|
"Rotation": "-0.1292284,0.9817931,-0.1379476,-0.01812655",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "34031d1b-74e3-4053-b701-3e66ec71138b",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "face_lid_lower_L",
|
||||||
|
"Position": "6.90997,5.140628,3.233467",
|
||||||
|
"Rotation": "-0.1292284,0.9817871,0.1379907,0.01812656",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "58f01ec1-49fe-4a7b-82ba-5eed960160b6",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "face_lid_upper_L",
|
||||||
|
"Position": "6.909989,5.140629,3.233452",
|
||||||
|
"Rotation": "0.9817871,0.1292284,0.01812819,-0.1379904",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "0bf32bb9-e057-419e-a942-c23ea0582433",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "face_lid_upper_R",
|
||||||
|
"Position": "6.909554,5.141101,-3.235678",
|
||||||
|
"Rotation": "0.9817932,0.1292284,-0.01812825,0.1379473",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "18358843-3c89-48fd-8be0-5fa0b7955c1f",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "eye_L",
|
||||||
|
"Position": "6.911271,5.140766,3.23198",
|
||||||
|
"Rotation": "0.7092671,0.7048279,0.004742622,-0.004704632",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "0ca9dfc6-8ca1-41f9-9d24-f753227f780d",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "eye_R",
|
||||||
|
"Position": "6.910652,5.141091,-3.237001",
|
||||||
|
"Rotation": "0.7092671,0.7048283,0.004742473,-0.004704908",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "dd94729b-774e-416d-b6c9-d70e663a7549",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "clavicle_L",
|
||||||
|
"Position": "4.038403,0.2752094,1.103661",
|
||||||
|
"Rotation": "-0.08429766,0.6549308,0.08405611,-0.7462444",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "d26a150a-98eb-418d-966c-53a3e640bfa9",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_upper_L",
|
||||||
|
"Position": "6.218311,0.00006532669,-0.001342773",
|
||||||
|
"Rotation": "-0.06809062,0.6623875,-0.01330963,-0.7459265",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "7e697fb9-910c-4642-ac8d-4607ac28caed",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_upper_L_twist1",
|
||||||
|
"Position": "5.020269,-0.0002432466,-0.002967119",
|
||||||
|
"Rotation": "0.009102732,-0.00000002980232,0.00000004470348,-0.9999471",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "6efdeca4-2f83-42fe-8f96-b2712ec06baf",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_lower_L",
|
||||||
|
"Position": "10.04386,0.0002688169,-0.001078844",
|
||||||
|
"Rotation": "0.0000002831221,-0.0000001192093,-0.1624508,-0.9866987",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "ba1a0dca-a8c0-4181-ab02-44b9e7fb259b",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_lower_L_twist0",
|
||||||
|
"Position": "-0.001255035,-0.0001220703,-0.00227356",
|
||||||
|
"Rotation": "-0.0000001341105,-0.0000003427267,0.00000001490116,-0.9999745",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "79070cab-d818-4c61-ad7d-daf4e8177a65",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "hand_L",
|
||||||
|
"Position": "7.705186,0.0006004572,-0.001422405",
|
||||||
|
"Rotation": "0.02671701,-0.04907528,0.04178061,-0.9975375",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "a1b8756b-e6e3-4cac-a998-748f1c9ff1f5",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "hold_L",
|
||||||
|
"Position": "5.358815,0.6225458,3.392119",
|
||||||
|
"Rotation": "-0.695914,-0.1704008,-0.3928553,0.5764221",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "7fd1f7c4-d1c3-436e-b8d5-a8fe9c55de6d",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "hand_R_to_L_ikrule",
|
||||||
|
"Position": "-7.81682,-3.155989,21.13516",
|
||||||
|
"Rotation": "-0.140897,0.3437678,-0.003125086,-0.928382",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "95097fea-f7a1-40cb-acc9-7f56044b1243",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_thumb_0_L",
|
||||||
|
"Position": "1.126226,1.648307,0.8637016",
|
||||||
|
"Rotation": "-0.5683933,-0.1216716,-0.4116745,-0.7018403",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "cc2772c4-9801-4b63-b85b-1549777e767a",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_thumb_1_L",
|
||||||
|
"Position": "1.904869,-0.001191139,-0.004262924",
|
||||||
|
"Rotation": "-0.00000001024455,0.1627173,-0.00000002793968,-0.9866276",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "ef0b2fb4-a3c3-4ad2-9f39-a7b6983eba24",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_thumb_2_L",
|
||||||
|
"Position": "2.133833,-0.001554489,-0.004840851",
|
||||||
|
"Rotation": "-0.00000001490116,0.08416325,-0.00000004842877,-0.9963972",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "07b60cdd-5110-4cee-96dd-5106b51c1fd9",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_index_meta_L",
|
||||||
|
"Position": "2.073688,1.204044,0.3748571",
|
||||||
|
"Rotation": "-0.06033978,-0.04579458,-0.1048825,-0.9915605",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "836eff99-8079-4fc6-a0fa-276e306ae544",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_index_0_L",
|
||||||
|
"Position": "3.066636,0.0002753139,-0.003266573",
|
||||||
|
"Rotation": "0.003366634,0.2652252,0.06858285,-0.9616922",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "c0b06cd5-7ca6-4d93-831a-4a6841bca328",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_index_1_L",
|
||||||
|
"Position": "2.280267,0.0002042651,-0.002904043",
|
||||||
|
"Rotation": "0,0.2334992,-0.00000008940697,-0.972301",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "250e6957-c1d3-4c72-aee1-c337f79511b0",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_index_2_L",
|
||||||
|
"Position": "1.590233,0.0002466887,-0.002176881",
|
||||||
|
"Rotation": "-0.00000005960464,0.0137254,-0.0000003874302,-0.9998416",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "9186496c-cad2-4b94-b5d0-47f2ee6a92d8",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_middle_meta_L",
|
||||||
|
"Position": "2.099168,-0.1590744,0.2834409",
|
||||||
|
"Rotation": "-0.008934826,-0.03483182,0.01933663,-0.9991316",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "50923b14-9231-4087-8d73-a340a8a61028",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_middle_0_L",
|
||||||
|
"Position": "2.997435,-0.00002804399,-0.003062844",
|
||||||
|
"Rotation": "-0.0008631647,0.2334588,-0.001294941,-0.9723202",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "731dc303-c26e-4eb5-a263-13238cfd353d",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_middle_1_L",
|
||||||
|
"Position": "2.557826,0.0001758784,-0.002626687",
|
||||||
|
"Rotation": "-0.00000008940697,0.2322481,-0.0000002086163,-0.9726022",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "c5954938-4384-4036-8b7e-f9e163f89603",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_middle_2_L",
|
||||||
|
"Position": "1.67947,0.0001565814,-0.001923561",
|
||||||
|
"Rotation": "-0.0000001341105,0.04821065,-0.0000002682209,-0.9987773",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "7ae4b8db-9914-4634-9b2d-96c8ee88536e",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_ring_meta_L",
|
||||||
|
"Position": "2.10349,-1.444458,0.2211144",
|
||||||
|
"Rotation": "0.06374946,0.02917722,0.13065,-0.9889115",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "6837225a-451f-40f8-8594-b5c63104c45a",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_ring_0_L",
|
||||||
|
"Position": "2.822251,-0.0002965927,-0.002760768",
|
||||||
|
"Rotation": "-0.004488692,0.1855496,-0.05619583,-0.9809707",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "15bb7037-51de-48d4-b0e9-711193db9d36",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_ring_1_L",
|
||||||
|
"Position": "2.194641,-0.00004752725,-0.002517208",
|
||||||
|
"Rotation": "0.00004316866,0.2565899,0.00004312396,-0.9664629",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "45867c49-3f20-4c44-87b8-7616f0e28ae8",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_ring_2_L",
|
||||||
|
"Position": "1.532103,-0.00003477372,-0.001665652",
|
||||||
|
"Rotation": "0.0000001788139,-0.05036834,0.0000002384186,0.9986643",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "ce073101-82d3-4a55-858f-df5608f6f8a1",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_lower_L_twist1",
|
||||||
|
"Position": "3.850731,0.0001845956,-0.003923535",
|
||||||
|
"Rotation": "0.01740356,-0.00000001490116,0.00000004470348,-0.9998308",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "855af04e-f003-477d-abd8-8e4b9c7b7222",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_elbow_helper_L",
|
||||||
|
"Position": "-0.001174927,-0.003246307,-0.002754211",
|
||||||
|
"Rotation": "0.002399921,0.00216841,0.7619089,-0.6476718",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "254f75ef-591b-48ab-977b-8f05045341c5",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_upper_L_twist0",
|
||||||
|
"Position": "-0.002178192,-0.0006027222,-0.003330231",
|
||||||
|
"Rotation": "0.05913498,0.00000001490116,0,-0.9982385",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "c3c4078b-1077-4888-bc65-2aeda8abd4a1",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "clavicle_R",
|
||||||
|
"Position": "4.037277,0.2748718,-1.108452",
|
||||||
|
"Rotation": "0.08442839,-0.655288,0.08409488,-0.7459114",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "15c9abaf-ac95-4941-81a9-cd94d872e53e",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_upper_R",
|
||||||
|
"Position": "6.218316,0.0003953613,-0.00002598763",
|
||||||
|
"Rotation": "0.06907114,-0.6644883,-0.008399844,-0.744036",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "9c96d6fd-271a-4a7b-a036-6db96dd70497",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_lower_R",
|
||||||
|
"Position": "10.04377,0.0008434057,-0.0004107952",
|
||||||
|
"Rotation": "0.0000002086163,-0.00000002980232,-0.1624506,-0.9866967",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "b6383140-1e6d-4b46-a1b1-5ed35a1fadd5",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_lower_R_twist0",
|
||||||
|
"Position": "-0.001403809,0.0006489754,-0.0008583069",
|
||||||
|
"Rotation": "0,0.0000001490116,-0.00000005960464,-0.9999706",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "cfb6423d-393d-449a-bd98-470519e4bd81",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_elbow_helper_R",
|
||||||
|
"Position": "-0.001998901,-0.002149105,-0.0009536743",
|
||||||
|
"Rotation": "0.001526296,0.001149135,0.7618573,-0.647737",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "a860ea26-f03d-48f9-9039-daf136730a1a",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "hand_R",
|
||||||
|
"Position": "7.70503,0.001723886,-0.0003260374",
|
||||||
|
"Rotation": "-0.02671666,0.04907504,0.04178038,-0.9975337",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "98a9377b-d445-40a7-ae54-25fca52d42c1",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "hold_R",
|
||||||
|
"Position": "5.359564,0.6235515,-3.394599",
|
||||||
|
"Rotation": "0.5764175,-0.3928525,-0.1704,-0.6959082",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "6de045f3-a8e5-491b-94ab-f61b6b1aa4ed",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "hand_L_to_R_ikrule",
|
||||||
|
"Position": "-7.899995,-3.201715,-21.11883",
|
||||||
|
"Rotation": "0.1409045,-0.3452918,0.00001519918,-0.9278128",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "ccb0ff52-c63f-43c2-9907-7318b9c5166f",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_thumb_0_R",
|
||||||
|
"Position": "1.126014,1.649442,-0.8676212",
|
||||||
|
"Rotation": "-0.5683893,-0.1216713,0.411671,0.7018345",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "8505adbd-ae44-4f6c-9898-dbeecee80322",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_thumb_1_R",
|
||||||
|
"Position": "1.904552,0.000449568,0.0002350211",
|
||||||
|
"Rotation": "0.00000001303852,0.1627161,-0.00000008195639,0.9866157",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "48a98f90-49f0-44a5-b01f-1bddad0d1132",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_thumb_2_R",
|
||||||
|
"Position": "2.133166,0.0006179959,0.0002120137",
|
||||||
|
"Rotation": "0.00000001490116,0.08416235,-0.00000006332994,0.9963783",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "8e12d685-e2e7-409f-8d07-7162f53e18d6",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_index_meta_R",
|
||||||
|
"Position": "2.073404,1.205412,-0.3782896",
|
||||||
|
"Rotation": "0.06033978,0.04579416,-0.1048823,-0.9915539",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "8bfd5924-6872-43f9-a225-7002c3c60d6f",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_index_0_R",
|
||||||
|
"Position": "3.066302,0.002848506,-0.00003266335",
|
||||||
|
"Rotation": "-0.003366441,-0.2651789,0.06858253,-0.9616932",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "5be460fd-9370-4863-b5de-82ff3070ae60",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_index_1_R",
|
||||||
|
"Position": "2.279522,0.002900422,-0.001230642",
|
||||||
|
"Rotation": "-0.0000001490116,-0.2334951,0.0000001788139,-0.9722833",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "215cd42e-5881-4300-8d82-74b3e573bcbb",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_index_2_R",
|
||||||
|
"Position": "1.589059,0.003142416,-0.003608108",
|
||||||
|
"Rotation": "-0.00000007450581,-0.01372504,0.0000004172325,-0.9998136",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "590202fa-d1f2-4d0a-9c4e-63cad36df0ec",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_middle_meta_R",
|
||||||
|
"Position": "2.099049,-0.1576577,-0.2863335",
|
||||||
|
"Rotation": "0.008934096,0.03483143,0.01933622,-0.9991246",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "5b7b506d-b804-48e3-8390-a37e4aee254d",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_middle_0_R",
|
||||||
|
"Position": "2.996975,0.002461806,-0.0001957417",
|
||||||
|
"Rotation": "0.0008631945,-0.2334556,-0.001294434,-0.9723077",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "3a2205b5-6ea2-414c-a342-5e11746a7f92",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_middle_1_R",
|
||||||
|
"Position": "2.556989,0.002898887,-0.001322389",
|
||||||
|
"Rotation": "-0.00000002980232,-0.2322431,0.0000002384186,-0.9725818",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "a1465f74-c03d-4c07-9562-5fb1e9f5266c",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_middle_2_R",
|
||||||
|
"Position": "1.6782,0.002957284,-0.003669441",
|
||||||
|
"Rotation": "-0.0000001639128,-0.04820885,0.000000320375,-0.9987424",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "1fc09b08-cbeb-438b-8b80-8b1e5d07c5d5",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_ring_meta_R",
|
||||||
|
"Position": "2.103528,-1.44299,-0.2234823",
|
||||||
|
"Rotation": "-0.06374952,-0.02917719,0.1306494,-0.9889046",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "629acca2-ec4d-49b2-9826-1d36149c4afc",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_ring_0_R",
|
||||||
|
"Position": "2.821856,0.001830548,-0.0005825162",
|
||||||
|
"Rotation": "0.004488915,-0.1855044,-0.05619501,-0.9809677",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "64c370c9-18ee-4737-a78d-4b765073f922",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_ring_1_R",
|
||||||
|
"Position": "2.193966,0.002415007,-0.001737997",
|
||||||
|
"Rotation": "-0.00004330277,-0.2565853,0.00004337728,-0.9664457",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "0662b27e-6b7f-42b2-9ad9-070074c10bf2",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "finger_ring_2_R",
|
||||||
|
"Position": "1.531064,0.002551214,-0.004439533",
|
||||||
|
"Rotation": "-0.0000001788139,-0.05036671,0.0000002086163,-0.9986366",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "f5cb25ae-c6a0-4e26-becd-9b5a5915faac",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_lower_R_twist1",
|
||||||
|
"Position": "3.850192,0.001937687,-0.001579106",
|
||||||
|
"Rotation": "-0.01740326,0.00000005960464,0,-0.9998282",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "05ad9f39-b8f6-4dce-af85-d6451bb4886f",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_upper_R_twist1",
|
||||||
|
"Position": "5.020006,0.0005286336,-0.001421452",
|
||||||
|
"Rotation": "-0.009256572,0.00000002980232,-0.00000002980232,-0.9999448",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "859eff5e-e24e-4094-adc6-193925b607ef",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "arm_upper_R_twist0",
|
||||||
|
"Position": "-0.002349854,0.00006580353,-0.001583099",
|
||||||
|
"Rotation": "-0.06013197,-0.00000002980232,-0.00000002980232,-0.9981781",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "b3a3a804-a9dd-4e63-b317-6dc98ef9d8a4",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "neck_clothing",
|
||||||
|
"Position": "5.820335,-0.09347534,-0.003288269",
|
||||||
|
"Rotation": "0.0000089854,-0.0002160072,0.01479772,-0.9998878",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "c7082eb0-7445-455f-bea9-8c19435161a2",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_upper_R",
|
||||||
|
"Position": "-0.2881527,-0.4264507,-4.427382",
|
||||||
|
"Rotation": "0.02125055,0.9980782,-0.05431545,0.02094065",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "b32f3291-da30-407d-be75-11bb1f67ae52",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_lower_R",
|
||||||
|
"Position": "14.47042,-0.00000333786,0.000003814697",
|
||||||
|
"Rotation": "0.004711121,-0.00006237626,0.178974,-0.9838427",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "482b21bc-f0ce-409d-823e-b8d6d2269469",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "ankle_R",
|
||||||
|
"Position": "12.51555,-0.000001907349,0.000001907349",
|
||||||
|
"Rotation": "-0.03533651,0.009895742,-0.4673119,-0.8833309",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "96edbe5f-7adf-4361-a639-6c8fe09bc4ea",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "ball_R",
|
||||||
|
"Position": "4.429122,-0.0000140667,0.000002384186",
|
||||||
|
"Rotation": "0.0000002272427,-0.000000461936,-0.3905396,-0.9205871",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "523f8614-bc95-4442-abb0-e1ae05fb1654",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_lower_R_twist0",
|
||||||
|
"Rotation": "0.00000005960464,0.0000001192093,-0.00000008940697,-1",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "1cb339a4-fa36-4cad-bd3d-542c1fa102f1",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_lower_R_twist1",
|
||||||
|
"Position": "6.25779,-0.00001907349,-0.000004768372",
|
||||||
|
"Rotation": "-0.02398723,0,0.00000001490116,-0.9997125",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "4d69aeee-db99-4768-b4bb-1cf7d03259c2",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_knee_helper_R",
|
||||||
|
"Position": "-0.007190704,0.05285455,0.0002584457",
|
||||||
|
"Rotation": "-0.001560916,0.001812547,-0.7461287,-0.6657979",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "bbe8f2e8-e480-4ab3-9dc0-20f8fa200059",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_upper_R_twist1",
|
||||||
|
"Position": "7.235819,-0.00001811981,-0.000003814697",
|
||||||
|
"Rotation": "0.005437598,0,0,-0.9999852",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "37ec1971-f2bf-4e61-bcbb-5e385e417200",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_upper_R_twist0",
|
||||||
|
"Rotation": "0.03533095,-0.00000002980232,-0.00000002980232,-0.9993757",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "d46108e1-4cc8-4a5d-a4fc-11efb1ce3820",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_glute_helper_R",
|
||||||
|
"Rotation": "-0.0000002980232,-0.0000003241003,0.7070966,-0.7071172",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "afc7ee64-84d0-478b-b845-dbffc38db7dc",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_upper_L",
|
||||||
|
"Position": "-0.2881393,-0.4264393,4.427385",
|
||||||
|
"Rotation": "-0.007433116,0.9984711,0.05426106,0.007487625",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "69d94113-1d92-4570-a461-9b8f626ac512",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_lower_L",
|
||||||
|
"Position": "14.47038,0.000004768372,0.000008583069",
|
||||||
|
"Rotation": "0.004010305,-0.00003439188,0.1198097,-0.9927889",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "66e60c1d-f2bd-4378-b9b6-3fdd3fc5d9fe",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "ankle_L",
|
||||||
|
"Position": "12.51555,-0.000001430511,0.000002861023",
|
||||||
|
"Rotation": "0.02723786,-0.008950412,-0.4382423,-0.8983996",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "862b07fd-7c61-474d-a24b-03bf3b697f20",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "ball_L",
|
||||||
|
"Position": "4.429139,-0.000002622604,-0.000003814697",
|
||||||
|
"Rotation": "-0.00000008568168,0.0000003129244,0.3907111,0.9205113",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "1b62659b-781f-49ab-a38c-bc4918c2f243",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_lower_L_twist0",
|
||||||
|
"Rotation": "-0.00000008940697,-0.0000002980232,-0.00000004470348,-0.9999992",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "f215b579-d99b-4a73-a82b-41c25c97acae",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_lower_L_twist1",
|
||||||
|
"Position": "6.257804,-0.00002193451,0.000001907349",
|
||||||
|
"Rotation": "0.01818442,0.00000002980232,0.00000002980232,-0.9998348",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "bcb4f9d6-b22f-43f6-8bee-be2026635707",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_knee_helper_L",
|
||||||
|
"Position": "-0.00188446,0.03569415,0.0001401901",
|
||||||
|
"Rotation": "0.001566295,-0.001615524,0.7499412,0.6615008",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "872c631e-66d0-491e-a5d3-18703c10bb82",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_upper_L_twist1",
|
||||||
|
"Position": "7.235796,-0.00002574921,0",
|
||||||
|
"Rotation": "-0.0054297,-0.00000001490116,-0.00000004470348,-0.9999853",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "ab710057-1eb5-4c83-a428-d79899eec4df",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_upper_L_twist0",
|
||||||
|
"Rotation": "-0.03528263,0,0.00000002980232,-0.9993776",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "1319a98f-6a9e-4434-b355-6311d621c89c",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "leg_glute_helper_L",
|
||||||
|
"Rotation": "-0.0000002682209,-0.0000002249144,0.7070962,-0.7071172",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "119ce4a2-be0f-4dea-9d7e-7ca2e5bf2834",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "root_IK",
|
||||||
|
"Position": "1.180664,0.000006914139,0.00001496077",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "5f6e553c-71cf-47d8-a2a8-085fa016a462",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "hand_R_IK_target",
|
||||||
|
"Position": "-2.719624,-11.35815,33.26634",
|
||||||
|
"Rotation": "0.4582616,0.3513036,-0.6075084,0.5454503",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "f4dd759e-5fb0-4065-b438-39d2233d982f",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "hand_L_IK_target",
|
||||||
|
"Position": "-2.719516,11.35806,33.26635",
|
||||||
|
"Rotation": "0.5454503,0.6075078,-0.3513034,0.4582625",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "5f8c54a4-c53b-4523-a10e-ded075d50d2c",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "aim_matrix_02a",
|
||||||
|
"Position": "4.638925,-0.0000008343591,9.8425",
|
||||||
|
"Enabled": true,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "f67b6696-c5d8-454c-adf1-ca932644a8c4",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "aim_matrix_02b",
|
||||||
|
"Position": "3.937002,-0.0000004822496,-0.0000009536743",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "68eac2de-d762-42ad-aec1-2e6ddac68b31",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "aim_matrix_01",
|
||||||
|
"Position": "4.638925,-0.0000008343591,11.811",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "0c2813a3-57fd-49c5-8133-fc4ea6b5eb0d",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "foot_R_IK_target",
|
||||||
|
"Position": "-0.773421,-4.402194,3.807818",
|
||||||
|
"Rotation": "0.672557,0.2183617,-0.3318372,0.6243953",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "fa33beab-3dce-4e46-84c5-80c8fff6815b",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "foot_L_IK_target",
|
||||||
|
"Position": "-0.769591,4.402877,3.80613",
|
||||||
|
"Rotation": "0.6243098,0.3319235,-0.2184912,0.6725516",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"__variables": [],
|
||||||
|
"__properties": {
|
||||||
|
"FixedUpdateFrequency": 50,
|
||||||
|
"MaxFixedUpdates": 5,
|
||||||
|
"NetworkFrequency": 30,
|
||||||
|
"NetworkInterpolation": true,
|
||||||
|
"PhysicsSubSteps": 1,
|
||||||
|
"ThreadedAnimation": true,
|
||||||
|
"TimeScale": 1,
|
||||||
|
"UseFixedUpdate": true,
|
||||||
|
"Metadata": {},
|
||||||
|
"NavMesh": {
|
||||||
|
"Enabled": false,
|
||||||
|
"IncludeStaticBodies": true,
|
||||||
|
"IncludeKeyframedBodies": true,
|
||||||
|
"EditorAutoUpdate": true,
|
||||||
|
"AgentHeight": 64,
|
||||||
|
"AgentRadius": 16,
|
||||||
|
"AgentStepSize": 18,
|
||||||
|
"AgentMaxSlope": 40,
|
||||||
|
"ExcludedBodies": "",
|
||||||
|
"IncludedBodies": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ShowInMenu": false,
|
||||||
|
"MenuPath": null,
|
||||||
|
"MenuIcon": null,
|
||||||
|
"DontBreakAsTemplate": false,
|
||||||
|
"ResourceVersion": 1,
|
||||||
|
"__references": [],
|
||||||
|
"__version": 1
|
||||||
|
}
|
386
Assets/scenes/minimal.scene
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
{
|
||||||
|
"__guid": "325a4042-0696-43dd-a79d-dcc314299ba3",
|
||||||
|
"GameObjects": [
|
||||||
|
{
|
||||||
|
"__guid": "2563f4af-75f3-40e1-9370-d548bbfe7a6e",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "NetworkManager",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.SceneInformation",
|
||||||
|
"__guid": "76de2a71-7d23-4f8a-a425-e4ceb539cfae",
|
||||||
|
"Description": "",
|
||||||
|
"SceneTags": "",
|
||||||
|
"Title": "minimal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.NetworkHelper",
|
||||||
|
"__guid": "f98c20e4-aa1c-4737-a771-e8391b397d2a",
|
||||||
|
"PlayerPrefab": {
|
||||||
|
"_type": "gameobject",
|
||||||
|
"prefab": "prefabs/player.prefab"
|
||||||
|
},
|
||||||
|
"SpawnPoints": [],
|
||||||
|
"StartServer": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "bfc59c12-1ed2-4f91-8956-a95a315eac3c",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Sun",
|
||||||
|
"Rotation": "-0.0729315,0.4822396,0.1305433,0.8631827",
|
||||||
|
"Tags": "light_directional,light",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.DirectionalLight",
|
||||||
|
"__guid": "d3659344-a90d-48fa-927a-095f70fe041f",
|
||||||
|
"FogMode": "Enabled",
|
||||||
|
"FogStrength": 1,
|
||||||
|
"LightColor": "0.94419,0.97767,1,1",
|
||||||
|
"Shadows": true,
|
||||||
|
"SkyColor": "0.2532,0.32006,0.35349,1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "00344a8c-fa5e-45ae-b12a-10bb781a1dc3",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "2D Skybox",
|
||||||
|
"Tags": "skybox",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.SkyBox2D",
|
||||||
|
"__guid": "de79e9e0-5c37-4c54-ac67-bfcdb1d5483b",
|
||||||
|
"SkyIndirectLighting": true,
|
||||||
|
"SkyMaterial": "materials/skybox/skybox_day_01.vmat",
|
||||||
|
"Tint": "1,1,1,1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.EnvmapProbe",
|
||||||
|
"__guid": "f3e304db-baab-4c1a-a4ec-8442585c2d62",
|
||||||
|
"Texture": "textures/cubemaps/default2.vtex",
|
||||||
|
"Bounds": {
|
||||||
|
"Mins": "-512,-512,-512",
|
||||||
|
"Maxs": "512,512,512"
|
||||||
|
},
|
||||||
|
"DelayBetweenUpdates": 0.1,
|
||||||
|
"Feathering": 0.02,
|
||||||
|
"FrameInterval": 5,
|
||||||
|
"MaxDistance": 512,
|
||||||
|
"MultiBounce": false,
|
||||||
|
"Projection": "Sphere",
|
||||||
|
"RenderDynamically": false,
|
||||||
|
"TintColor": "1,1,1,1",
|
||||||
|
"UpdateStrategy": "OnEnabled",
|
||||||
|
"ZFar": 4096,
|
||||||
|
"ZNear": 16
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "6ad70641-3c6c-4402-9c85-9a4969af4764",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Plane",
|
||||||
|
"Scale": "5,5,5",
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.ModelRenderer",
|
||||||
|
"__guid": "0b6a18bf-fdb8-4661-970e-ef635bfa9baa",
|
||||||
|
"BodyGroups": 18446744073709551615,
|
||||||
|
"MaterialOverride": "materials/default.vmat",
|
||||||
|
"Model": "models/dev/plane.vmdl",
|
||||||
|
"RenderOptions": {
|
||||||
|
"GameLayer": true,
|
||||||
|
"OverlayLayer": false,
|
||||||
|
"BloomLayer": false,
|
||||||
|
"AfterUILayer": false
|
||||||
|
},
|
||||||
|
"RenderType": "On",
|
||||||
|
"Tint": "0.39546,0.51163,0.27128,1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.BoxCollider",
|
||||||
|
"__guid": "0715cb55-1733-4f5e-8560-c288b8695631",
|
||||||
|
"Center": "0,0,-5",
|
||||||
|
"IsTrigger": false,
|
||||||
|
"Scale": "100,100,10",
|
||||||
|
"Static": false,
|
||||||
|
"SurfaceVelocity": "0,0,0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "3c2490ef-54a0-49bb-8f13-490e40aa51d1",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Cube",
|
||||||
|
"Position": "-18.53616,-147.7339,86.60748",
|
||||||
|
"Rotation": "0.00000001819328,-0.00000000000000008235059,0.3052325,0.952278",
|
||||||
|
"Scale": "0.5632889,0.5632889,0.5632889",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.ModelRenderer",
|
||||||
|
"__guid": "b9121ffa-617c-4ccc-a2aa-8acc98727590",
|
||||||
|
"BodyGroups": 18446744073709551615,
|
||||||
|
"MaterialOverride": "materials/default.vmat",
|
||||||
|
"Model": "models/dev/box.vmdl",
|
||||||
|
"RenderOptions": {
|
||||||
|
"GameLayer": true,
|
||||||
|
"OverlayLayer": false,
|
||||||
|
"BloomLayer": false,
|
||||||
|
"AfterUILayer": false
|
||||||
|
},
|
||||||
|
"RenderType": "On",
|
||||||
|
"Tint": "1,0,0.93333,1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.BoxCollider",
|
||||||
|
"__guid": "8bb3ebcf-1ec9-4b20-bf31-4aece0950008",
|
||||||
|
"Center": "0,0,0",
|
||||||
|
"IsTrigger": false,
|
||||||
|
"Scale": "50,50,50",
|
||||||
|
"Static": false,
|
||||||
|
"SurfaceVelocity": "0,0,0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Rigidbody",
|
||||||
|
"__guid": "4aaa0334-6785-4716-9bae-869559ea6e10",
|
||||||
|
"AngularDamping": 0,
|
||||||
|
"Gravity": true,
|
||||||
|
"LinearDamping": 0,
|
||||||
|
"Locking": {},
|
||||||
|
"MassCenterOverride": "0,0,0",
|
||||||
|
"MassOverride": 0,
|
||||||
|
"MotionEnabled": true,
|
||||||
|
"OverrideMassCenter": false,
|
||||||
|
"RigidbodyFlags": 0,
|
||||||
|
"StartAsleep": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "523e3e8f-a4ec-4ec1-af9a-d86ffc9c17e1",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Cube (1)",
|
||||||
|
"Position": "40.81348,46.97572,14.40159",
|
||||||
|
"Rotation": "0.00000001819328,-0.00000000000000008235059,0.3052325,0.952278",
|
||||||
|
"Scale": "0.5632889,0.5632889,0.5632889",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.ModelRenderer",
|
||||||
|
"__guid": "9e8a546d-a41d-44b5-9906-22cea00e1066",
|
||||||
|
"BodyGroups": 18446744073709551615,
|
||||||
|
"MaterialOverride": "materials/default.vmat",
|
||||||
|
"Model": "models/dev/box.vmdl",
|
||||||
|
"RenderOptions": {
|
||||||
|
"GameLayer": true,
|
||||||
|
"OverlayLayer": false,
|
||||||
|
"BloomLayer": false,
|
||||||
|
"AfterUILayer": false
|
||||||
|
},
|
||||||
|
"RenderType": "On",
|
||||||
|
"Tint": "1,0,0.93333,1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.BoxCollider",
|
||||||
|
"__guid": "adf22580-7a25-4d7f-b1c3-3fb8fabf1612",
|
||||||
|
"Center": "0,0,0",
|
||||||
|
"IsTrigger": false,
|
||||||
|
"Scale": "50,50,50",
|
||||||
|
"Static": false,
|
||||||
|
"SurfaceVelocity": "0,0,0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Rigidbody",
|
||||||
|
"__guid": "e53bfcb0-7f44-41d0-8d51-263bdc173a57",
|
||||||
|
"AngularDamping": 0,
|
||||||
|
"Gravity": true,
|
||||||
|
"LinearDamping": 0,
|
||||||
|
"Locking": {},
|
||||||
|
"MassCenterOverride": "0,0,0",
|
||||||
|
"MassOverride": 0,
|
||||||
|
"MotionEnabled": true,
|
||||||
|
"OverrideMassCenter": false,
|
||||||
|
"RigidbodyFlags": 0,
|
||||||
|
"StartAsleep": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "5b483a09-bbf2-4949-98c7-a73b789d0ee7",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Cube (2)",
|
||||||
|
"Position": "49.53706,34.08897,128.0143",
|
||||||
|
"Rotation": "0.00000001819328,-0.00000000000000008235059,0.3052325,0.952278",
|
||||||
|
"Scale": "0.5632889,0.5632889,0.5632889",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.ModelRenderer",
|
||||||
|
"__guid": "ac284ab8-cdb7-4ba6-92de-d9be36088b1b",
|
||||||
|
"BodyGroups": 18446744073709551615,
|
||||||
|
"MaterialOverride": "materials/default.vmat",
|
||||||
|
"Model": "models/dev/box.vmdl",
|
||||||
|
"RenderOptions": {
|
||||||
|
"GameLayer": true,
|
||||||
|
"OverlayLayer": false,
|
||||||
|
"BloomLayer": false,
|
||||||
|
"AfterUILayer": false
|
||||||
|
},
|
||||||
|
"RenderType": "On",
|
||||||
|
"Tint": "1,0,0.93333,1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.BoxCollider",
|
||||||
|
"__guid": "ca4eb284-231e-4c84-9bc4-7ba89962f307",
|
||||||
|
"Center": "0,0,0",
|
||||||
|
"IsTrigger": false,
|
||||||
|
"Scale": "50,50,50",
|
||||||
|
"Static": false,
|
||||||
|
"SurfaceVelocity": "0,0,0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Rigidbody",
|
||||||
|
"__guid": "61ef15dd-3eb2-4f52-8b9a-315f477f79b7",
|
||||||
|
"AngularDamping": 0,
|
||||||
|
"Gravity": true,
|
||||||
|
"LinearDamping": 0,
|
||||||
|
"Locking": {},
|
||||||
|
"MassCenterOverride": "0,0,0",
|
||||||
|
"MassOverride": 0,
|
||||||
|
"MotionEnabled": true,
|
||||||
|
"OverrideMassCenter": false,
|
||||||
|
"RigidbodyFlags": 0,
|
||||||
|
"StartAsleep": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "3ee1c9f4-07be-4e0b-8b23-67bee2d8ec8a",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Camera",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.CameraComponent",
|
||||||
|
"__guid": "cf3cbf96-22b6-4be4-a5d0-672a96c17f9f",
|
||||||
|
"BackgroundColor": "0.33333,0.46275,0.52157,1",
|
||||||
|
"ClearFlags": "All",
|
||||||
|
"FieldOfView": 60,
|
||||||
|
"IsMainCamera": true,
|
||||||
|
"Orthographic": false,
|
||||||
|
"OrthographicHeight": 1204,
|
||||||
|
"Priority": 1,
|
||||||
|
"RenderExcludeTags": "",
|
||||||
|
"RenderTags": "",
|
||||||
|
"TargetEye": "None",
|
||||||
|
"Viewport": "0,0,1,1",
|
||||||
|
"ZFar": 10000,
|
||||||
|
"ZNear": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Bloom",
|
||||||
|
"__guid": "d73ef723-c888-41d4-802e-f797c79318be",
|
||||||
|
"BloomColor": {
|
||||||
|
"color": [
|
||||||
|
{
|
||||||
|
"c": "1,1,1,1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": 1,
|
||||||
|
"c": "1,1,1,1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"alpha": []
|
||||||
|
},
|
||||||
|
"BloomCurve": [
|
||||||
|
{
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Mode": "Additive",
|
||||||
|
"Strength": 0.5,
|
||||||
|
"Threshold": 0.5,
|
||||||
|
"ThresholdWidth": 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Tonemapping",
|
||||||
|
"__guid": "9d76f362-7227-40eb-a189-69353c780c46",
|
||||||
|
"__version": 1,
|
||||||
|
"AutoExposureEnabled": true,
|
||||||
|
"ExposureBias": 2,
|
||||||
|
"ExposureCompensation": 0,
|
||||||
|
"ExposureMethod": "RGB",
|
||||||
|
"MaximumExposure": 2,
|
||||||
|
"MinimumExposure": 1,
|
||||||
|
"Mode": "Legacy",
|
||||||
|
"Rate": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Sharpen",
|
||||||
|
"__guid": "0bffee5e-19f2-41c4-88f9-faefbcce6bf4",
|
||||||
|
"Scale": 0.2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "cf125021-fa85-46d4-9ad8-6ea4ac3cc1e9",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "mmm",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.MapInstance",
|
||||||
|
"__guid": "6e911feb-4dd7-4be6-9729-e48480e2ed2a",
|
||||||
|
"__version": 1,
|
||||||
|
"EnableCollision": true,
|
||||||
|
"MapName": "maps/nunu.vmap",
|
||||||
|
"NoOrigin": false,
|
||||||
|
"OnMapLoaded": null,
|
||||||
|
"OnMapUnloaded": null,
|
||||||
|
"UseMapFromLaunch": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Children": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SceneProperties": {
|
||||||
|
"FixedUpdateFrequency": 50,
|
||||||
|
"MaxFixedUpdates": 5,
|
||||||
|
"NetworkFrequency": 60,
|
||||||
|
"NetworkInterpolation": true,
|
||||||
|
"PhysicsSubSteps": 1,
|
||||||
|
"ThreadedAnimation": true,
|
||||||
|
"TimeScale": 1,
|
||||||
|
"UseFixedUpdate": true,
|
||||||
|
"Metadata": {
|
||||||
|
"Title": "minimal"
|
||||||
|
},
|
||||||
|
"NavMesh": {
|
||||||
|
"Enabled": false,
|
||||||
|
"IncludeStaticBodies": true,
|
||||||
|
"IncludeKeyframedBodies": true,
|
||||||
|
"EditorAutoUpdate": true,
|
||||||
|
"AgentHeight": 64,
|
||||||
|
"AgentRadius": 16,
|
||||||
|
"AgentStepSize": 18,
|
||||||
|
"AgentMaxSlope": 40,
|
||||||
|
"ExcludedBodies": "",
|
||||||
|
"IncludedBodies": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ResourceVersion": 2,
|
||||||
|
"Title": "minimal",
|
||||||
|
"Description": null,
|
||||||
|
"__references": [],
|
||||||
|
"__version": 2
|
||||||
|
}
|
22
Assets/scenes/test.vmap.meta
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"publish": {
|
||||||
|
"Enabled": false,
|
||||||
|
"ProjectConfig": {
|
||||||
|
"Title": "test",
|
||||||
|
"Type": "map",
|
||||||
|
"Org": "local",
|
||||||
|
"Ident": "test",
|
||||||
|
"Schema": 0,
|
||||||
|
"IncludeSourceFiles": false,
|
||||||
|
"Resources": null,
|
||||||
|
"PackageReferences": [],
|
||||||
|
"EditorReferences": [
|
||||||
|
"matek.dev_checker_light#46462"
|
||||||
|
],
|
||||||
|
"IsWhitelistDisabled": false,
|
||||||
|
"Metadata": {
|
||||||
|
"SingleAssetSource": "scenes/test.vmap"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
Assets/untitled.motivate
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"Portraits": [
|
||||||
|
"photo_2024-10-16_19-53-34.jpg"
|
||||||
|
],
|
||||||
|
"Messages": [
|
||||||
|
"\u0415\u0431\u0430\u0448, \u0434\u0430 \u043D\u0435 \u0432\u044B\u0435\u0431\u0430\u043D \u0431\u0443\u0434\u0435\u0448\u044C"
|
||||||
|
],
|
||||||
|
"__references": [],
|
||||||
|
"__version": 0
|
||||||
|
}
|
20
Assets/untitled.motivate.meta
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"publish": {
|
||||||
|
"Enabled": true,
|
||||||
|
"ProjectConfig": {
|
||||||
|
"Title": "untitled",
|
||||||
|
"Type": "motivate",
|
||||||
|
"Org": "local",
|
||||||
|
"Ident": "untitled",
|
||||||
|
"Schema": 0,
|
||||||
|
"IncludeSourceFiles": true,
|
||||||
|
"Resources": null,
|
||||||
|
"PackageReferences": null,
|
||||||
|
"EditorReferences": null,
|
||||||
|
"IsWhitelistDisabled": false,
|
||||||
|
"Metadata": {
|
||||||
|
"SingleAssetSource": "untitled.motivate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Code/Assembly.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
global using Sandbox;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.Linq;
|
101
Code/Kal.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
using Sandbox.Citizen;
|
||||||
|
using ShrimpleCharacterController;
|
||||||
|
|
||||||
|
public sealed class Kal : Component
|
||||||
|
{
|
||||||
|
[RequireComponent]
|
||||||
|
public ShrimpleCharacterController.ShrimpleCharacterController Controller { get; set; }
|
||||||
|
|
||||||
|
[RequireComponent]
|
||||||
|
public CitizenAnimationHelper AnimationHelper { get; set; }
|
||||||
|
public SkinnedModelRenderer Renderer { get; set; }
|
||||||
|
public GameObject Camera { get; set; }
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(1f, 200f, 1f)]
|
||||||
|
public float CamOffsetX { get; set; }
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(1f, 200f, 1f)]
|
||||||
|
public float CamOffsetZ { get; set; }
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(50f, 200f, 10f)]
|
||||||
|
public float WalkSpeed { get; set; } = 100f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(100f, 500f, 20f)]
|
||||||
|
public float RunSpeed { get; set; } = 300f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(25f, 100f, 5f)]
|
||||||
|
public float DuckSpeed { get; set; } = 50f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(200f, 500f, 20f)]
|
||||||
|
public float JumpStrength { get; set; } = 350f;
|
||||||
|
|
||||||
|
public Angles EyeAngles { get; set; }
|
||||||
|
|
||||||
|
protected override void OnStart()
|
||||||
|
{
|
||||||
|
base.OnStart();
|
||||||
|
|
||||||
|
if ( !Network.IsOwner ) return;
|
||||||
|
|
||||||
|
Renderer = Components.Get<SkinnedModelRenderer>(FindMode.EverythingInSelfAndDescendants);
|
||||||
|
Camera = new GameObject(true, "Camera");
|
||||||
|
Camera.SetParent(GameObject);
|
||||||
|
var cameraComponent = Camera.Components.Create<CameraComponent>();
|
||||||
|
cameraComponent.ZFar = 32768f;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFixedUpdate()
|
||||||
|
{
|
||||||
|
base.OnFixedUpdate();
|
||||||
|
|
||||||
|
if ( !Network.IsOwner ) return;
|
||||||
|
|
||||||
|
var wishDirection = Input.AnalogMove.Normal * Rotation.FromYaw(EyeAngles.yaw);
|
||||||
|
var isDucking = Input.Down("Duck");
|
||||||
|
var isRunning = Input.Down("Run");
|
||||||
|
var wishSpeed = isDucking ? DuckSpeed :
|
||||||
|
isRunning ? RunSpeed : WalkSpeed;
|
||||||
|
|
||||||
|
Controller.WishVelocity = wishDirection * wishSpeed;
|
||||||
|
|
||||||
|
Controller.Move();
|
||||||
|
|
||||||
|
if (Input.Pressed("Jump") && Controller.IsOnGround)
|
||||||
|
{
|
||||||
|
Controller.Punch(Vector3.Up * JumpStrength * 10f);
|
||||||
|
AnimationHelper?.TriggerJump();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AnimationHelper.IsValid()) return;
|
||||||
|
|
||||||
|
AnimationHelper.WithWishVelocity(Controller.WishVelocity);
|
||||||
|
AnimationHelper.WithVelocity(Controller.Velocity);
|
||||||
|
AnimationHelper.DuckLevel = isDucking ? 1f : 0f;
|
||||||
|
AnimationHelper.IsGrounded = Controller.IsOnGround;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
base.OnUpdate();
|
||||||
|
|
||||||
|
Log.Info(Controller.WishVelocity);
|
||||||
|
|
||||||
|
if ( !Network.IsOwner ) return;
|
||||||
|
|
||||||
|
Log.Info(Controller.WishVelocity);
|
||||||
|
|
||||||
|
EyeAngles += Input.AnalogLook;
|
||||||
|
EyeAngles = EyeAngles.WithPitch(MathX.Clamp(EyeAngles.pitch, -10f, 40f));
|
||||||
|
Renderer.WorldRotation = Rotation.Slerp(Renderer.WorldRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 5f);
|
||||||
|
|
||||||
|
var cameraOffset = Vector3.Up * CamOffsetZ + Vector3.Backward * CamOffsetX;
|
||||||
|
Camera.WorldRotation = EyeAngles.ToRotation();
|
||||||
|
Camera.LocalPosition = cameraOffset * Camera.WorldRotation;
|
||||||
|
}
|
||||||
|
}
|
9
Code/MyComponent.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
public sealed class MyComponent : Component
|
||||||
|
{
|
||||||
|
[Property] public string StringProperty { get; set; }
|
||||||
|
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
4
Editor/Assembly.cs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
global using Sandbox;
|
||||||
|
global using Editor;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.Linq;
|
8
Editor/MyEditorMenu.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
public static class MyEditorMenu
|
||||||
|
{
|
||||||
|
[Menu("Editor", "$title/My Menu Option")]
|
||||||
|
public static void OpenMyMenu()
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("It worked!", "This is being called from your library's editor code!");
|
||||||
|
}
|
||||||
|
}
|
4
Libraries/badandbest.youcandoit/.bin/manifest.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[
|
||||||
|
"package.base",
|
||||||
|
"package.badandbest.youcandoit"
|
||||||
|
]
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>package.badandbest.youcandoit</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
</members>
|
||||||
|
</doc>
|
BIN
Libraries/badandbest.youcandoit/.bin/package.base.cll
Normal file
1
Libraries/badandbest.youcandoit/.version
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.0.73517
|
After Width: | Height: | Size: 64 KiB |
BIN
Libraries/badandbest.youcandoit/Assets/Portraits/bubble.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
Libraries/badandbest.youcandoit/Assets/Portraits/heart.png
Normal file
After Width: | Height: | Size: 97 KiB |
BIN
Libraries/badandbest.youcandoit/Assets/Portraits/physgun.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
Libraries/badandbest.youcandoit/Assets/Portraits/pumped.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
Libraries/badandbest.youcandoit/Assets/Portraits/suspicious.png
Normal file
After Width: | Height: | Size: 64 KiB |
20
Libraries/badandbest.youcandoit/Assets/chill.motivate
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"Portraits": [
|
||||||
|
"portraits/physgun.png",
|
||||||
|
"portraits/suspicious.png"
|
||||||
|
],
|
||||||
|
"Messages": [
|
||||||
|
"very good.",
|
||||||
|
"congratulations.",
|
||||||
|
"keep it up!",
|
||||||
|
"that\u0027s smart.",
|
||||||
|
"I like your thinking.",
|
||||||
|
"that\u0027s a good idea.",
|
||||||
|
"neat.",
|
||||||
|
"interesting..",
|
||||||
|
"very clever."
|
||||||
|
],
|
||||||
|
"__references": [],
|
||||||
|
"IsValid": true,
|
||||||
|
"__version": 0
|
||||||
|
}
|
BIN
Libraries/badandbest.youcandoit/Assets/maps/test.vmap
Normal file
27
Libraries/badandbest.youcandoit/Assets/mean.motivate
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"Portraits": [
|
||||||
|
"portraits/arms_crossed.png"
|
||||||
|
],
|
||||||
|
"Messages": [
|
||||||
|
"Hmph!",
|
||||||
|
"Baka!",
|
||||||
|
"Do better!",
|
||||||
|
"\u003E:C",
|
||||||
|
"*pout*",
|
||||||
|
"Idiot!",
|
||||||
|
"Stupid head!",
|
||||||
|
"It\u0027s not like\nI\u0027m proud of you\nor anything!",
|
||||||
|
"It\u0027s not like\nI care about your\nwork or anything!",
|
||||||
|
"Finish it already!",
|
||||||
|
"Geez, stop pushing\nyourself!",
|
||||||
|
"Could you be any\nmore clueless?",
|
||||||
|
"It doesn\u0027t work!",
|
||||||
|
"Finish it faster!",
|
||||||
|
"Blehh!",
|
||||||
|
"You suck! (\u25D4_\u25D4)",
|
||||||
|
"Useless!"
|
||||||
|
],
|
||||||
|
"__references": [],
|
||||||
|
"IsValid": true,
|
||||||
|
"__version": 0
|
||||||
|
}
|
27
Libraries/badandbest.youcandoit/Assets/nice.motivate
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"Portraits": [
|
||||||
|
"portraits/pumped.png",
|
||||||
|
"portraits/heart.png"
|
||||||
|
],
|
||||||
|
"Messages": [
|
||||||
|
"good work! :3",
|
||||||
|
"keep at it! c:",
|
||||||
|
"rawr! so cool!!",
|
||||||
|
"WOW!",
|
||||||
|
"need some hewp?",
|
||||||
|
"um.. w-what are\nyou working on?",
|
||||||
|
"that\u0027s amazing!\n(\u2217\u2022\u03C9\u2022\u2217)",
|
||||||
|
"s-sorryy.. am i\ninterrupt?",
|
||||||
|
"you can do it!!",
|
||||||
|
"you sure you don\u0027t\nneed a break? (\u00B4\uFF65\u03C9\uFF65\u0060)",
|
||||||
|
"this is gonna be\nsoo cool!",
|
||||||
|
"keep working hard\nsenpai!",
|
||||||
|
"can you teach me?",
|
||||||
|
"just a little more!",
|
||||||
|
"i love it!",
|
||||||
|
"are you oki?"
|
||||||
|
],
|
||||||
|
"__references": [],
|
||||||
|
"IsValid": true,
|
||||||
|
"__version": 0
|
||||||
|
}
|
3
Libraries/badandbest.youcandoit/Code/FailSafe.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
global using Sandbox;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.Linq;
|
31
Libraries/badandbest.youcandoit/Editor/MotivationManager.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Sandbox;
|
||||||
|
using System;
|
||||||
|
namespace Editor;
|
||||||
|
|
||||||
|
public static class MotivationManager
|
||||||
|
{
|
||||||
|
static RealTimeUntil Cooldown;
|
||||||
|
|
||||||
|
static MotivationManager()
|
||||||
|
{
|
||||||
|
Game.SetRandomSeed( DateTime.Now.Second );
|
||||||
|
Cooldown = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
[EditorEvent.FrameAttribute]
|
||||||
|
public static void Frame()
|
||||||
|
{
|
||||||
|
if ( !Cooldown )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var notice = new MotivationNotice();
|
||||||
|
NoticeManager.Remove( notice, 30 );
|
||||||
|
|
||||||
|
const int MIN_MINUTES = 15;
|
||||||
|
const int MAX_MINUTES = 30;
|
||||||
|
|
||||||
|
Cooldown = 60 * Game.Random.Next( MIN_MINUTES, MAX_MINUTES );
|
||||||
|
}
|
||||||
|
}
|
37
Libraries/badandbest.youcandoit/Editor/MotivationNotice.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Sandbox;
|
||||||
|
using System.Linq;
|
||||||
|
using static Sandbox.ResourceLibrary;
|
||||||
|
namespace Editor;
|
||||||
|
|
||||||
|
public class MotivationNotice : NoticeWidget
|
||||||
|
{
|
||||||
|
public string Portrait { get; init; }
|
||||||
|
public string Message { get; init; }
|
||||||
|
|
||||||
|
public string Bubble => FileSystem.Mounted.GetFullPath( "portraits/bubble.png" );
|
||||||
|
|
||||||
|
protected override Vector2 SizeHint() => new( 512, 384 );
|
||||||
|
|
||||||
|
public MotivationNotice()
|
||||||
|
{
|
||||||
|
var personality = Game.Random.FromArray( GetAll<MotivationResource>().ToArray() );
|
||||||
|
|
||||||
|
Portrait = personality.GetPortrait();
|
||||||
|
Message = personality.GetMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaint()
|
||||||
|
{
|
||||||
|
Paint.SetPen( Theme.Black );
|
||||||
|
Paint.SetDefaultFont( 16 );
|
||||||
|
|
||||||
|
var rect = LocalRect.Align( 350, TextFlag.LeftBottom );
|
||||||
|
Paint.Draw( rect, Portrait );
|
||||||
|
|
||||||
|
rect = LocalRect.Align( 250, TextFlag.RightTop );
|
||||||
|
Paint.Draw( rect, Bubble );
|
||||||
|
|
||||||
|
rect = rect.Shrink( 0, 0, 0, 55 );
|
||||||
|
Paint.DrawText( rect, Message );
|
||||||
|
}
|
||||||
|
}
|
31
Libraries/badandbest.youcandoit/Editor/MotivationResource.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Sandbox;
|
||||||
|
namespace Editor;
|
||||||
|
|
||||||
|
[GameResource( "Motivation", "motivate", "Citizens motivate you every 15-30 minutes.", Icon = "support_agent", Category = "Editor", IconBgColor = "#E4E2E4", IconFgColor = "#93BDDD" )]
|
||||||
|
public class MotivationResource : GameResource
|
||||||
|
{
|
||||||
|
[ImageAssetPath]
|
||||||
|
public string[] Portraits { get; set; }
|
||||||
|
|
||||||
|
public string[] Messages { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Selects a random citizen portrait from this type.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Portrait file path</returns>
|
||||||
|
public string GetPortrait()
|
||||||
|
{
|
||||||
|
var portraitPath = Game.Random.FromArray( Portraits );
|
||||||
|
|
||||||
|
return FileSystem.Mounted.GetFullPath( portraitPath );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Selects a random motivational response from this type.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Response with linebreaks</returns>
|
||||||
|
public string GetMessage()
|
||||||
|
{
|
||||||
|
return Game.Random.FromArray( Messages );
|
||||||
|
}
|
||||||
|
}
|
25
Libraries/badandbest.youcandoit/youcandoit.sbproj
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"Title": "You Can Do It!",
|
||||||
|
"Type": "library",
|
||||||
|
"Org": "badandbest",
|
||||||
|
"Ident": "youcandoit",
|
||||||
|
"Schema": 1,
|
||||||
|
"IncludeSourceFiles": true,
|
||||||
|
"Resources": null,
|
||||||
|
"PackageReferences": [],
|
||||||
|
"EditorReferences": null,
|
||||||
|
"IsWhitelistDisabled": false,
|
||||||
|
"Metadata": {
|
||||||
|
"CsProjName": "You Can Do It",
|
||||||
|
"Compiler": {
|
||||||
|
"RootNamespace": "Sandbox",
|
||||||
|
"DefineConstants": "SANDBOX;ADDON;DEBUG",
|
||||||
|
"NoWarn": "1701;1702;1591;2255;",
|
||||||
|
"WarningsAsErrors": "",
|
||||||
|
"Whitelist": true,
|
||||||
|
"AssemblyReferences": [],
|
||||||
|
"IgnoreFolders": [],
|
||||||
|
"DistinctAssemblyReferences": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
Libraries/fish.scc/.bin/manifest.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[
|
||||||
|
"package.base",
|
||||||
|
"package.fish.scc"
|
||||||
|
]
|
BIN
Libraries/fish.scc/.bin/package.base.cll
Normal file
BIN
Libraries/fish.scc/.bin/package.fish.scc.cll
Normal file
BIN
Libraries/fish.scc/.bin/package.fish.scc.dll
Normal file
287
Libraries/fish.scc/.bin/package.fish.scc.xml
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>package.fish.scc</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.ManuallyUpdate">
|
||||||
|
<summary>
|
||||||
|
Manually update this by calling Move() or let it always be simulated
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.ScaleAgainstWalls">
|
||||||
|
<summary>
|
||||||
|
If pushing against a wall, scale the velocity based on the wall's angle (False is useful for NPCs that get stuck on corners)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.TraceWidth">
|
||||||
|
<summary>
|
||||||
|
Width of our trace
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.TraceHeight">
|
||||||
|
<summary>
|
||||||
|
Height of our trace
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.IgnoreTags">
|
||||||
|
<summary>
|
||||||
|
Which tags it should ignore
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.MaxBounces">
|
||||||
|
<summary>
|
||||||
|
Max amount of trace calls whenever the simulation doesn't reach its target (Slide and collide bounces)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GroundAcceleration">
|
||||||
|
<summary>
|
||||||
|
How fast you accelerate while on the ground (Units per second)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GroundDeceleration">
|
||||||
|
<summary>
|
||||||
|
How fast you decelerate while on the ground (Units per second)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.AirAcceleration">
|
||||||
|
<summary>
|
||||||
|
How fast you accelerate while in the air (Units per second)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.AirDeceleration">
|
||||||
|
<summary>
|
||||||
|
How fast you decelerate while in the air (Units per second)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.IgnoreGroundSurface">
|
||||||
|
<summary>
|
||||||
|
Do we ignore the friction of the surface you're standing on or not?
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.IgnoreZ">
|
||||||
|
<summary>
|
||||||
|
Is this MoveHelper meant for horizontal grounded movement? (false = For flying or noclip)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.IgnoreZWhenZero">
|
||||||
|
<summary>
|
||||||
|
Do we ignore Z when it's near 0 (So that gravity affects you when not moving)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.WallTolerance">
|
||||||
|
<summary>
|
||||||
|
Tolerance from a 90° surface before it's considered a wall (Ex. Tolerance 1 = Between 89° and 91° can be a wall, 0.1 = 89.9° to 90.1°)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GripFactorReduction">
|
||||||
|
<summary>
|
||||||
|
Player feels like it's gripping walls too much? Try more Grip Factor Reduction!
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GroundStickEnabled">
|
||||||
|
<summary>
|
||||||
|
Stick the MoveHelper to the ground (IsOnGround will default to false if disabled)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.MaxGroundAngle">
|
||||||
|
<summary>
|
||||||
|
How steep terrain can be for you to stand on without slipping
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GroundStickDistance">
|
||||||
|
<summary>
|
||||||
|
How far from the ground the MoveHelper is going to stick (Useful for going down stairs!)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.StepsEnabled">
|
||||||
|
<summary>
|
||||||
|
Enable steps climbing (+1 Trace call)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.StepHeight">
|
||||||
|
<summary>
|
||||||
|
How high steps can be for you to climb on
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.StepDepth">
|
||||||
|
<summary>
|
||||||
|
How deep it checks for steps (Minimum depth)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.StepTolerance">
|
||||||
|
<summary>
|
||||||
|
Tolerance from a 90° surface before it's considered a valid step (Ex. Tolerance 1 = Between 89° and 91° can be a step, 0.1 = 89.9° to 90.1°)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.PseudoStepsEnabled">
|
||||||
|
<summary>
|
||||||
|
Enable to ability to walk on a surface that's too steep if it's equal or smaller than a step (+1 Trace call when on steep terrain)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.PushEnabled">
|
||||||
|
<summary>
|
||||||
|
Instead of colliding with these tags the MoveHelper will be pushed away (Make sure the tags are in IgnoreTags as well!)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.PushTagsWeight">
|
||||||
|
<summary>
|
||||||
|
Which tags will push this MoveHelper away and with how much force (Make sure they are also included in IgnoreTags!) (+1 Trace call)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GravityEnabled">
|
||||||
|
<summary>
|
||||||
|
Apply gravity to this MoveHelper when not on the ground
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.UseSceneGravity">
|
||||||
|
<summary>
|
||||||
|
Use the scene's gravity or our own
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.Gravity">
|
||||||
|
<summary>
|
||||||
|
Units per second squared (Default is -850f)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.UnstuckEnabled">
|
||||||
|
<summary>
|
||||||
|
Check if the MoveHelper is stuck and try to get it to unstuck (+Trace calls if stuck)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.MaxUnstuckTries">
|
||||||
|
<summary>
|
||||||
|
How many trace calls it will attempt to get the MoveHelper unstuck
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.WishVelocity">
|
||||||
|
<summary>
|
||||||
|
The simulated target velocity for our MoveHelper (Units per second, we apply Time.Delta inside)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.Velocity">
|
||||||
|
<summary>
|
||||||
|
The resulting velocity after the simulation is done (Units per second)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.IsOnGround">
|
||||||
|
<summary>
|
||||||
|
Is the MoveHelper currently touching the ground
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<!-- Badly formed XML comment ignored for member "P:ShrimpleCharacterController.ShrimpleCharacterController.GroundNormal" -->
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GroundAngle">
|
||||||
|
<summary>
|
||||||
|
The current ground angle you're standing on (Always 0f if IsOnGround false)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GroundSurface">
|
||||||
|
<summary>
|
||||||
|
The current surface you're standing on
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.GroundObject">
|
||||||
|
<summary>
|
||||||
|
The gameobject you're currently standing on
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.IsPushingAgainstWall">
|
||||||
|
<summary>
|
||||||
|
Is the MoveHelper currently pushing against a wall
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.WallNormal">
|
||||||
|
<summary>
|
||||||
|
The current wall normal you're pushing against (Always Vector3.Zero if IsPushingAgainstWall false)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.WallObject">
|
||||||
|
<summary>
|
||||||
|
The gameobject you're currently pushing on
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.IsSlipping">
|
||||||
|
<summary>
|
||||||
|
Is the MoveHelper standing on a terrain too steep to stand on (Always false if IsOnGround false)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.IsStuck">
|
||||||
|
<summary>
|
||||||
|
The MoveHelper is stuck and we can't get it out
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:ShrimpleCharacterController.ShrimpleCharacterController.SkinWidth">
|
||||||
|
<summary>
|
||||||
|
To avoid getting stuck due to imprecision we shrink the bounds before checking and compensate for it later
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ShrimpleCharacterController.ShrimpleCharacterController.Bounds">
|
||||||
|
<summary>
|
||||||
|
The bounds of this MoveHelper generated from the TraceWidth and TraceHeight
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:ShrimpleCharacterController.ShrimpleCharacterController.UnstuckTarget">
|
||||||
|
<summary>
|
||||||
|
If another MoveHelper moved at the same time and they're stuck, let this one know that the other already unstuck for us
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ShrimpleCharacterController.ShrimpleCharacterController.BuildTrace(BBox,Vector3,Vector3)">
|
||||||
|
<summary>
|
||||||
|
Casts the current bounds from to and returns the scene trace result
|
||||||
|
</summary>
|
||||||
|
<param name="bounds"></param>
|
||||||
|
<param name="from"></param>
|
||||||
|
<param name="to"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:ShrimpleCharacterController.ShrimpleCharacterController.Punch(Vector3@)">
|
||||||
|
<summary>
|
||||||
|
Detach the MoveHelper from the ground and launch it somewhere (Units per second)
|
||||||
|
</summary>
|
||||||
|
<param name="amount"></param>
|
||||||
|
</member>
|
||||||
|
<member name="M:ShrimpleCharacterController.ShrimpleCharacterController.Move(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Apply the WishVelocity, update the Velocity and the Position of the GameObject by simulating the MoveHelper
|
||||||
|
</summary>
|
||||||
|
<param name="manualUpdate">Just calculate but don't update position</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:ShrimpleCharacterController.ShrimpleCharacterController.Move(System.Single,System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Apply the WishVelocity, update the Velocity and the Position of the GameObject by simulating the MoveHelper
|
||||||
|
</summary>
|
||||||
|
<param name="delta">The time step</param>
|
||||||
|
<param name="manualUpdate">Just calculate but don't update position</param>
|
||||||
|
</member>
|
||||||
|
<member name="T:ShrimpleCharacterController.ShrimpleCharacterController.MoveHelperResult">
|
||||||
|
<summary>
|
||||||
|
Sometimes we have to update only the position but not the velocity (Like when climbing steps or getting unstuck) so we can't have Position rely only on Velocity
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ShrimpleCharacterController.ShrimpleCharacterController.TestPosition(Vector3,System.String)">
|
||||||
|
<summary>
|
||||||
|
Debug don't use
|
||||||
|
</summary>
|
||||||
|
<param name="position"></param>
|
||||||
|
<param name="title"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:ShrimpleCharacterController.Vector3Extensions.MoveTowards(Vector3,Vector3,System.Single)">
|
||||||
|
<summary>
|
||||||
|
Move a vector3 towards a goal by a fixed distance
|
||||||
|
</summary>
|
||||||
|
<param name="value"></param>
|
||||||
|
<param name="target"></param>
|
||||||
|
<param name="travelSpeed"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:ShrimpleCharacterController.Vector3Extensions.ProjectAndScale(Vector3,Vector3)">
|
||||||
|
<summary>
|
||||||
|
Project a vector along a plane (normal) and scale it back to its original length
|
||||||
|
</summary>
|
||||||
|
<param name="value"></param>
|
||||||
|
<param name="normal"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
57
Libraries/fish.scc/.sbox/project.json
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"scene.lastopened": {
|
||||||
|
"Value": "[\u0022scenes/walker_example.scene\u0022]",
|
||||||
|
"Timeout": 1732563082,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"gizmo.settings": {
|
||||||
|
"Value": "{\u0022EditMode\u0022:\u0022position\u0022,\u0022Selection\u0022:true,\u0022ViewMode\u0022:\u00223d\u0022,\u0022GizmosEnabled\u0022:true,\u0022GizmoScale\u0022:1,\u0022GridSpacing\u0022:8,\u0022SnapToGrid\u0022:true,\u0022SnapToAngles\u0022:true,\u0022AngleSpacing\u0022:15,\u0022GlobalSpace\u0022:false,\u0022DebugActionGraphs\u0022:false}",
|
||||||
|
"Timeout": 1732563082,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"scenes/flyer_example.scene.Viewport0": {
|
||||||
|
"Value": "{\u0022CameraPosition\u0022:\u0022-7143.974,-7143.975,10902.61\u0022,\u0022CameraRotation\u0022:\u0022-0.1464466,0.3535534,0.3535534,0.8535534\u0022,\u0022CameraOrthoHeight\u0022:1000}",
|
||||||
|
"Timeout": 1732471236,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"scenes/walker_example.scene.Viewport0": {
|
||||||
|
"Value": "{\u0022CameraPosition\u0022:\u00224.097099,268.366,496.7835\u0022,\u0022CameraRotation\u0022:\u00220.2423258,0.2017571,-0.7292984,0.6072035\u0022,\u0022CameraOrthoHeight\u0022:1000}",
|
||||||
|
"Timeout": 1732563138,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
".Viewport0": {
|
||||||
|
"Value": "{\u0022CameraPosition\u0022:\u002266.49246,-768.0743,49.54514\u0022,\u0022CameraRotation\u0022:\u00220.1079748,0.1108001,-0.689514,0.7075558\u0022,\u0022CameraOrthoHeight\u0022:1000}",
|
||||||
|
"Timeout": 1732471755,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"AssetBrowser.History.AssetsBrowser.ViewMode": {
|
||||||
|
"Value": "0",
|
||||||
|
"Timeout": 1732471206,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"AssetBrowser.History.AssetsBrowser.ShowJunkFiles": {
|
||||||
|
"Value": "false",
|
||||||
|
"Timeout": 1732471206,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"AssetBrowser.History.AssetsBrowser.ShowRecursiveFiles": {
|
||||||
|
"Value": "false",
|
||||||
|
"Timeout": 1732471206,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"expand.dad296d6-935e-4779-b5ae-67a3a0d28ab6.MissingComponent": {
|
||||||
|
"Value": "false",
|
||||||
|
"Timeout": 1732471755,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"SceneView.Viewport0.Settings": {
|
||||||
|
"Value": "{\u0022CameraPosition\u0022:\u00224.097099,268.366,496.7835\u0022,\u0022CameraRotation\u0022:\u00220.2423258,0.2017571,-0.7292984,0.6072035\u0022,\u0022View\u0022:0,\u0022RenderMode\u0022:0,\u0022WireframeMode\u0022:false,\u0022EnablePostProcessing\u0022:true,\u0022ShowGrid\u0022:true,\u0022GridOpacity\u0022:0.2,\u0022GridAxis\u0022:0,\u0022CameraOrthoHeight\u0022:1000}",
|
||||||
|
"Timeout": 1732563138,
|
||||||
|
"DeleteAt": 0
|
||||||
|
},
|
||||||
|
"SceneView.Layout": {
|
||||||
|
"Value": "{\u0022Layout\u0022:0,\u0022SplitterState\u0022:[]}",
|
||||||
|
"Timeout": 1732563082,
|
||||||
|
"DeleteAt": 0
|
||||||
|
}
|
||||||
|
}
|
1
Libraries/fish.scc/.version
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.0.75465
|
19349
Libraries/fish.scc/Assets/prefabs/debug_world.prefab
Normal file
BIN
Libraries/fish.scc/Assets/prefabs/shrimp.png
Normal file
After Width: | Height: | Size: 254 KiB |
121
Libraries/fish.scc/Assets/scenes/flyer_example.scene
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
{
|
||||||
|
"__guid": "e78370eb-4e25-4b7f-bbf8-89f0fcbaa68b",
|
||||||
|
"GameObjects": [
|
||||||
|
{
|
||||||
|
"__guid": "048573b1-fa80-406a-a30d-93881e2b19c9",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "debug_world",
|
||||||
|
"Enabled": true,
|
||||||
|
"__Prefab": "prefabs/debug_world.prefab",
|
||||||
|
"__PrefabVariables": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "dad296d6-935e-4779-b5ae-67a3a0d28ab6",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Player",
|
||||||
|
"Position": "-171.0225,-113.5377,171.9933",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "ShrimpleCharacterController.ShrimpleCharacterController",
|
||||||
|
"__guid": "fa127e8d-b05d-4e14-894d-d2977361591d",
|
||||||
|
"AirAcceleration": 1500,
|
||||||
|
"AirDeceleration": 700,
|
||||||
|
"Gravity": -850,
|
||||||
|
"GravityEnabled": false,
|
||||||
|
"GroundAcceleration": 1000,
|
||||||
|
"GroundDeceleration": 1500,
|
||||||
|
"GroundStickDistance": 12,
|
||||||
|
"GroundStickEnabled": false,
|
||||||
|
"IgnoreGroundSurface": false,
|
||||||
|
"IgnoreTags": "",
|
||||||
|
"IgnoreZ": false,
|
||||||
|
"IgnoreZWhenZero": true,
|
||||||
|
"ManuallyUpdate": true,
|
||||||
|
"MaxBounces": 5,
|
||||||
|
"MaxGroundAngle": 60,
|
||||||
|
"MaxUnstuckTries": 20,
|
||||||
|
"PushEnabled": false,
|
||||||
|
"PushTagsWeight": {
|
||||||
|
"player": 1
|
||||||
|
},
|
||||||
|
"ScaleAgainstWalls": true,
|
||||||
|
"StepDepth": 2,
|
||||||
|
"StepHeight": 12,
|
||||||
|
"StepsEnabled": false,
|
||||||
|
"TraceHeight": 72,
|
||||||
|
"TraceWidth": 16,
|
||||||
|
"UnstuckEnabled": true,
|
||||||
|
"UseSceneGravity": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "ShrimpleCharacterController.ShrimpleFlyer",
|
||||||
|
"__guid": "e79bdc25-5a6f-4eb2-8a49-5f7aac27f8cd",
|
||||||
|
"RunSpeed": 2400,
|
||||||
|
"WalkSpeed": 800
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Citizen.CitizenAnimationHelper",
|
||||||
|
"__guid": "6bb6e1f8-1402-4b7b-9006-ea4866eb9e64",
|
||||||
|
"BodyWeight": 1,
|
||||||
|
"EyesWeight": 1,
|
||||||
|
"HeadWeight": 1,
|
||||||
|
"LookAtEnabled": false,
|
||||||
|
"Target": {
|
||||||
|
"_type": "component",
|
||||||
|
"component_id": "75a0dedf-07bc-4a29-9027-9e88625f7ba0",
|
||||||
|
"go": "768529ee-5ecc-4ddb-a81e-73fdb775baec",
|
||||||
|
"component_type": "SkinnedModelRenderer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "768529ee-5ecc-4ddb-a81e-73fdb775baec",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Model",
|
||||||
|
"Position": "0,0,0",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.SkinnedModelRenderer",
|
||||||
|
"__guid": "75a0dedf-07bc-4a29-9027-9e88625f7ba0",
|
||||||
|
"BodyGroups": 341,
|
||||||
|
"CreateBoneObjects": false,
|
||||||
|
"Model": "models/citizen/citizen.vmdl",
|
||||||
|
"RenderType": "On",
|
||||||
|
"Tint": "1,1,1,1",
|
||||||
|
"UseAnimGraph": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SceneProperties": {
|
||||||
|
"FixedUpdateFrequency": 50,
|
||||||
|
"MaxFixedUpdates": 5,
|
||||||
|
"NetworkFrequency": 30,
|
||||||
|
"NetworkInterpolation": true,
|
||||||
|
"ThreadedAnimation": true,
|
||||||
|
"TimeScale": 1,
|
||||||
|
"UseFixedUpdate": true,
|
||||||
|
"NavMesh": {
|
||||||
|
"Enabled": false,
|
||||||
|
"IncludeStaticBodies": true,
|
||||||
|
"IncludeKeyframedBodies": true,
|
||||||
|
"EditorAutoUpdate": true,
|
||||||
|
"AgentHeight": 64,
|
||||||
|
"AgentRadius": 16,
|
||||||
|
"AgentStepSize": 18,
|
||||||
|
"AgentMaxSlope": 40,
|
||||||
|
"ExcludedBodies": "",
|
||||||
|
"IncludedBodies": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Title": "walker_example",
|
||||||
|
"Description": "",
|
||||||
|
"ResourceVersion": 1,
|
||||||
|
"__references": [],
|
||||||
|
"__version": 1
|
||||||
|
}
|
146
Libraries/fish.scc/Assets/scenes/roller_example.scene
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
{
|
||||||
|
"__guid": "e78370eb-4e25-4b7f-bbf8-89f0fcbaa68b",
|
||||||
|
"GameObjects": [
|
||||||
|
{
|
||||||
|
"__guid": "048573b1-fa80-406a-a30d-93881e2b19c9",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "debug_world",
|
||||||
|
"Enabled": true,
|
||||||
|
"__Prefab": "prefabs/debug_world.prefab",
|
||||||
|
"__PrefabVariables": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "dad296d6-935e-4779-b5ae-67a3a0d28ab6",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Player",
|
||||||
|
"Position": "0,-49.46404,176.2773",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "ShrimpleCharacterController.ShrimpleCharacterController",
|
||||||
|
"__guid": "fa127e8d-b05d-4e14-894d-d2977361591d",
|
||||||
|
"AirAcceleration": 250,
|
||||||
|
"AirDeceleration": 100,
|
||||||
|
"Gravity": -850,
|
||||||
|
"GravityEnabled": true,
|
||||||
|
"GroundAcceleration": 1000,
|
||||||
|
"GroundDeceleration": 2000,
|
||||||
|
"GroundStickDistance": 12,
|
||||||
|
"GroundStickEnabled": false,
|
||||||
|
"IgnoreGroundSurface": false,
|
||||||
|
"IgnoreTags": "",
|
||||||
|
"IgnoreZ": true,
|
||||||
|
"IgnoreZWhenZero": true,
|
||||||
|
"ManuallyUpdate": true,
|
||||||
|
"MaxBounces": 5,
|
||||||
|
"MaxGroundAngle": 60,
|
||||||
|
"MaxUnstuckTries": 20,
|
||||||
|
"PushEnabled": false,
|
||||||
|
"PushTagsWeight": {
|
||||||
|
"player": 1
|
||||||
|
},
|
||||||
|
"ScaleAgainstWalls": true,
|
||||||
|
"StepDepth": 2,
|
||||||
|
"StepHeight": 12,
|
||||||
|
"StepsEnabled": true,
|
||||||
|
"TraceHeight": 64,
|
||||||
|
"TraceWidth": 64,
|
||||||
|
"UnstuckEnabled": true,
|
||||||
|
"UseSceneGravity": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "ShrimpleCharacterController.ShrimpleRoller",
|
||||||
|
"__guid": "c557f267-05dd-4185-be90-7d60757118ef",
|
||||||
|
"JumpStrength": 350,
|
||||||
|
"RunSpeed": 3000,
|
||||||
|
"WalkSpeed": 1000
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "768529ee-5ecc-4ddb-a81e-73fdb775baec",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Model",
|
||||||
|
"Position": "0,0,32",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.ModelRenderer",
|
||||||
|
"__guid": "13202fec-761f-46b0-9517-21a8662c39f3",
|
||||||
|
"BodyGroups": 18446744073709551615,
|
||||||
|
"MaterialOverride": "materials/editor/black_grid_8_doublesided.vmat",
|
||||||
|
"Model": "models/dev/sphere.vmdl",
|
||||||
|
"RenderType": "On",
|
||||||
|
"Tint": "1,1,1,1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.TrailRenderer",
|
||||||
|
"__guid": "0c954483-095d-48f1-bb1c-47d90bbb6ae6",
|
||||||
|
"BlendMode": "Normal",
|
||||||
|
"CastShadows": false,
|
||||||
|
"Color": {
|
||||||
|
"color": [
|
||||||
|
{
|
||||||
|
"c": "1,1,1,0.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": 1,
|
||||||
|
"c": "1,1,1,0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"alpha": []
|
||||||
|
},
|
||||||
|
"LifeTime": 3,
|
||||||
|
"MaxPoints": 256,
|
||||||
|
"Opaque": false,
|
||||||
|
"PointDistance": 4,
|
||||||
|
"Texturing": {
|
||||||
|
"WorldSpace": true,
|
||||||
|
"UnitsPerTexture": 10,
|
||||||
|
"Scale": 1
|
||||||
|
},
|
||||||
|
"Width": {
|
||||||
|
"rangey": "0,64",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Wireframe": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SceneProperties": {
|
||||||
|
"FixedUpdateFrequency": 50,
|
||||||
|
"MaxFixedUpdates": 5,
|
||||||
|
"NetworkFrequency": 30,
|
||||||
|
"NetworkInterpolation": true,
|
||||||
|
"ThreadedAnimation": true,
|
||||||
|
"TimeScale": 1,
|
||||||
|
"UseFixedUpdate": true,
|
||||||
|
"NavMesh": {
|
||||||
|
"Enabled": false,
|
||||||
|
"IncludeStaticBodies": true,
|
||||||
|
"IncludeKeyframedBodies": true,
|
||||||
|
"EditorAutoUpdate": true,
|
||||||
|
"AgentHeight": 64,
|
||||||
|
"AgentRadius": 16,
|
||||||
|
"AgentStepSize": 18,
|
||||||
|
"AgentMaxSlope": 40,
|
||||||
|
"ExcludedBodies": "",
|
||||||
|
"IncludedBodies": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Title": "walker_example",
|
||||||
|
"Description": "",
|
||||||
|
"ResourceVersion": 1,
|
||||||
|
"__references": [],
|
||||||
|
"__version": 1
|
||||||
|
}
|
123
Libraries/fish.scc/Assets/scenes/walker_example.scene
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
{
|
||||||
|
"__guid": "e78370eb-4e25-4b7f-bbf8-89f0fcbaa68b",
|
||||||
|
"GameObjects": [
|
||||||
|
{
|
||||||
|
"__guid": "048573b1-fa80-406a-a30d-93881e2b19c9",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "debug_world",
|
||||||
|
"Enabled": true,
|
||||||
|
"__Prefab": "prefabs/debug_world.prefab",
|
||||||
|
"__PrefabVariables": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__guid": "dad296d6-935e-4779-b5ae-67a3a0d28ab6",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Player",
|
||||||
|
"Position": "-171.0225,-113.5377,171.9933",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "ShrimpleCharacterController.ShrimpleCharacterController",
|
||||||
|
"__guid": "fa127e8d-b05d-4e14-894d-d2977361591d",
|
||||||
|
"AirAcceleration": 300,
|
||||||
|
"AirDeceleration": 0,
|
||||||
|
"Gravity": -850,
|
||||||
|
"GravityEnabled": true,
|
||||||
|
"GroundAcceleration": 1000,
|
||||||
|
"GroundDeceleration": 1500,
|
||||||
|
"GroundStickDistance": 12,
|
||||||
|
"GroundStickEnabled": true,
|
||||||
|
"IgnoreGroundSurface": false,
|
||||||
|
"IgnoreTags": "",
|
||||||
|
"IgnoreZ": true,
|
||||||
|
"IgnoreZWhenZero": true,
|
||||||
|
"ManuallyUpdate": true,
|
||||||
|
"MaxBounces": 5,
|
||||||
|
"MaxGroundAngle": 60,
|
||||||
|
"MaxUnstuckTries": 20,
|
||||||
|
"PushEnabled": false,
|
||||||
|
"PushTagsWeight": {
|
||||||
|
"player": 1
|
||||||
|
},
|
||||||
|
"ScaleAgainstWalls": true,
|
||||||
|
"StepDepth": 2,
|
||||||
|
"StepHeight": 12,
|
||||||
|
"StepsEnabled": true,
|
||||||
|
"TraceHeight": 72,
|
||||||
|
"TraceWidth": 16,
|
||||||
|
"UnstuckEnabled": true,
|
||||||
|
"UseSceneGravity": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.Citizen.CitizenAnimationHelper",
|
||||||
|
"__guid": "6bb6e1f8-1402-4b7b-9006-ea4866eb9e64",
|
||||||
|
"BodyWeight": 1,
|
||||||
|
"EyesWeight": 1,
|
||||||
|
"HeadWeight": 1,
|
||||||
|
"LookAtEnabled": false,
|
||||||
|
"Target": {
|
||||||
|
"_type": "component",
|
||||||
|
"component_id": "75a0dedf-07bc-4a29-9027-9e88625f7ba0",
|
||||||
|
"go": "768529ee-5ecc-4ddb-a81e-73fdb775baec",
|
||||||
|
"component_type": "SkinnedModelRenderer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type": "ShrimpleCharacterController.ShrimpleWalker",
|
||||||
|
"__guid": "21e48f2b-e808-42b7-83e6-83282972f187",
|
||||||
|
"DuckSpeed": 50,
|
||||||
|
"JumpStrength": 350,
|
||||||
|
"RunSpeed": 300,
|
||||||
|
"WalkSpeed": 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"__guid": "768529ee-5ecc-4ddb-a81e-73fdb775baec",
|
||||||
|
"Flags": 0,
|
||||||
|
"Name": "Model",
|
||||||
|
"Position": "0,0,0",
|
||||||
|
"Enabled": true,
|
||||||
|
"Components": [
|
||||||
|
{
|
||||||
|
"__type": "Sandbox.SkinnedModelRenderer",
|
||||||
|
"__guid": "75a0dedf-07bc-4a29-9027-9e88625f7ba0",
|
||||||
|
"BodyGroups": 341,
|
||||||
|
"CreateBoneObjects": false,
|
||||||
|
"Model": "models/citizen/citizen.vmdl",
|
||||||
|
"RenderType": "On",
|
||||||
|
"Tint": "1,1,1,1",
|
||||||
|
"UseAnimGraph": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SceneProperties": {
|
||||||
|
"FixedUpdateFrequency": 50,
|
||||||
|
"MaxFixedUpdates": 5,
|
||||||
|
"NetworkFrequency": 30,
|
||||||
|
"NetworkInterpolation": true,
|
||||||
|
"ThreadedAnimation": true,
|
||||||
|
"TimeScale": 1,
|
||||||
|
"UseFixedUpdate": true,
|
||||||
|
"NavMesh": {
|
||||||
|
"Enabled": false,
|
||||||
|
"IncludeStaticBodies": true,
|
||||||
|
"IncludeKeyframedBodies": true,
|
||||||
|
"EditorAutoUpdate": true,
|
||||||
|
"AgentHeight": 64,
|
||||||
|
"AgentRadius": 16,
|
||||||
|
"AgentStepSize": 18,
|
||||||
|
"AgentMaxSlope": 40,
|
||||||
|
"ExcludedBodies": "",
|
||||||
|
"IncludedBodies": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Title": "walker_example",
|
||||||
|
"Description": "",
|
||||||
|
"ResourceVersion": 1,
|
||||||
|
"__references": [],
|
||||||
|
"__version": 1
|
||||||
|
}
|
5
Libraries/fish.scc/Code/Assembly.cs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
global using Sandbox;
|
||||||
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.Linq;
|
||||||
|
namespace ShrimpleCharacterController;
|
68
Libraries/fish.scc/Code/Examples/ShrimpleFlyer.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using Sandbox.Citizen;
|
||||||
|
|
||||||
|
namespace ShrimpleCharacterController;
|
||||||
|
|
||||||
|
[Hide]
|
||||||
|
public sealed class ShrimpleFlyer : Component
|
||||||
|
{
|
||||||
|
[RequireComponent]
|
||||||
|
public ShrimpleCharacterController Controller { get; set; }
|
||||||
|
|
||||||
|
[RequireComponent]
|
||||||
|
public CitizenAnimationHelper AnimationHelper { get; set; }
|
||||||
|
public SkinnedModelRenderer Renderer { get; set; }
|
||||||
|
public GameObject Camera { get; set; }
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(400f, 1600f, 20f)]
|
||||||
|
public float WalkSpeed { get; set; } = 800f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(800f, 4000f, 80f)]
|
||||||
|
public float RunSpeed { get; set; } = 2400f;
|
||||||
|
|
||||||
|
public Angles EyeAngles { get; set; }
|
||||||
|
|
||||||
|
protected override void OnStart()
|
||||||
|
{
|
||||||
|
base.OnStart();
|
||||||
|
|
||||||
|
Renderer = AnimationHelper.Target;
|
||||||
|
Camera = new GameObject(true, "Camera");
|
||||||
|
Camera.SetParent(GameObject);
|
||||||
|
var cameraComponent = Camera.Components.Create<CameraComponent>();
|
||||||
|
cameraComponent.ZFar = 32768f;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFixedUpdate()
|
||||||
|
{
|
||||||
|
base.OnFixedUpdate();
|
||||||
|
|
||||||
|
var isDucking = Input.Down("Duck");
|
||||||
|
var isRunning = Input.Down("Run");
|
||||||
|
var ascending = Input.Down("Jump") ? 1f : 0f;
|
||||||
|
var descending = Input.Down("Duck") ? -1f : 0f;
|
||||||
|
var wishSpeed = isRunning ? RunSpeed : WalkSpeed;
|
||||||
|
var wishDirection = (Input.AnalogMove + Vector3.Up * (ascending + descending)).Normal * EyeAngles.ToRotation();
|
||||||
|
|
||||||
|
Controller.WishVelocity = wishDirection * wishSpeed;
|
||||||
|
Controller.Move();
|
||||||
|
|
||||||
|
AnimationHelper.WithWishVelocity(Controller.WishVelocity);
|
||||||
|
AnimationHelper.WithVelocity(Controller.Velocity);
|
||||||
|
AnimationHelper.IsGrounded = Controller.IsOnGround;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
base.OnUpdate();
|
||||||
|
|
||||||
|
EyeAngles += Input.AnalogLook;
|
||||||
|
EyeAngles = EyeAngles.WithPitch(MathX.Clamp(EyeAngles.pitch, -10f, 40f));
|
||||||
|
Renderer.WorldRotation = Rotation.Slerp(Renderer.WorldRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 5f);
|
||||||
|
|
||||||
|
var cameraOffset = Vector3.Up * 70f + Vector3.Backward * 220f;
|
||||||
|
Camera.WorldRotation = EyeAngles.ToRotation();
|
||||||
|
Camera.LocalPosition = cameraOffset * Camera.WorldRotation;
|
||||||
|
}
|
||||||
|
}
|
71
Libraries/fish.scc/Code/Examples/ShrimpleRoller.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
namespace ShrimpleCharacterController;
|
||||||
|
|
||||||
|
[Hide]
|
||||||
|
public sealed class ShrimpleRoller : Component
|
||||||
|
{
|
||||||
|
[RequireComponent]
|
||||||
|
public ShrimpleCharacterController Controller { get; set; }
|
||||||
|
|
||||||
|
public ModelRenderer Renderer { get; set; }
|
||||||
|
public GameObject Camera { get; set; }
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(500f, 2000f, 100f)]
|
||||||
|
public float WalkSpeed { get; set; } = 1000f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(1000f, 5000f, 200f)]
|
||||||
|
public float RunSpeed { get; set; } = 3000f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(200f, 500f, 20f)]
|
||||||
|
public float JumpStrength { get; set; } = 350f;
|
||||||
|
|
||||||
|
public Angles EyeAngles { get; set; }
|
||||||
|
|
||||||
|
protected override void OnStart()
|
||||||
|
{
|
||||||
|
base.OnStart();
|
||||||
|
|
||||||
|
Renderer = Components.Get<ModelRenderer>(FindMode.EnabledInSelfAndDescendants);
|
||||||
|
|
||||||
|
Camera = new GameObject(true, "Camera");
|
||||||
|
Camera.SetParent(GameObject);
|
||||||
|
var cameraComponent = Camera.Components.Create<CameraComponent>();
|
||||||
|
cameraComponent.ZFar = 32768f;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFixedUpdate()
|
||||||
|
{
|
||||||
|
base.OnFixedUpdate();
|
||||||
|
|
||||||
|
var wishDirection = Input.AnalogMove.Normal * Rotation.FromYaw(EyeAngles.yaw);
|
||||||
|
var isDucking = Input.Down("Duck");
|
||||||
|
var isRunning = Input.Down("Run");
|
||||||
|
var wishSpeed = isRunning ? RunSpeed : WalkSpeed;
|
||||||
|
|
||||||
|
Controller.WishVelocity = wishDirection * wishSpeed;
|
||||||
|
Controller.Move();
|
||||||
|
|
||||||
|
if (Input.Pressed("Jump") && Controller.IsOnGround)
|
||||||
|
Controller.Punch(Vector3.Up * JumpStrength);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
base.OnUpdate();
|
||||||
|
|
||||||
|
EyeAngles += Input.AnalogLook;
|
||||||
|
EyeAngles = EyeAngles.WithPitch(MathX.Clamp(EyeAngles.pitch, -10f, 40f));
|
||||||
|
|
||||||
|
float pitchRotation = Controller.Velocity.x * Time.Delta;
|
||||||
|
float rollRotation = -Controller.Velocity.y * Time.Delta;
|
||||||
|
var ballPitch = Rotation.FromPitch(pitchRotation);
|
||||||
|
var ballRoll = Rotation.FromRoll(rollRotation);
|
||||||
|
Renderer.WorldRotation = ballPitch * ballRoll * Renderer.WorldRotation;
|
||||||
|
|
||||||
|
var cameraOffset = Vector3.Up * 70f + Vector3.Backward * 260f;
|
||||||
|
Camera.WorldRotation = EyeAngles.ToRotation();
|
||||||
|
Camera.LocalPosition = cameraOffset * Camera.WorldRotation;
|
||||||
|
}
|
||||||
|
}
|
84
Libraries/fish.scc/Code/Examples/ShrimpleWalker.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
using Sandbox.Citizen;
|
||||||
|
|
||||||
|
namespace ShrimpleCharacterController;
|
||||||
|
|
||||||
|
[Hide]
|
||||||
|
public sealed class ShrimpleWalker : Component
|
||||||
|
{
|
||||||
|
[RequireComponent]
|
||||||
|
public ShrimpleCharacterController Controller { get; set; }
|
||||||
|
|
||||||
|
[RequireComponent]
|
||||||
|
public CitizenAnimationHelper AnimationHelper { get; set; }
|
||||||
|
public SkinnedModelRenderer Renderer { get; set; }
|
||||||
|
public GameObject Camera { get; set; }
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(50f, 200f, 10f)]
|
||||||
|
public float WalkSpeed { get; set; } = 100f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(100f, 500f, 20f)]
|
||||||
|
public float RunSpeed { get; set; } = 300f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(25f, 100f, 5f)]
|
||||||
|
public float DuckSpeed { get; set; } = 50f;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
[Range(200f, 500f, 20f)]
|
||||||
|
public float JumpStrength { get; set; } = 350f;
|
||||||
|
|
||||||
|
public Angles EyeAngles { get; set; }
|
||||||
|
|
||||||
|
protected override void OnStart()
|
||||||
|
{
|
||||||
|
base.OnStart();
|
||||||
|
|
||||||
|
Renderer = Components.Get<SkinnedModelRenderer>(FindMode.EverythingInSelfAndDescendants);
|
||||||
|
Camera = new GameObject(true, "Camera");
|
||||||
|
Camera.SetParent(GameObject);
|
||||||
|
var cameraComponent = Camera.Components.Create<CameraComponent>();
|
||||||
|
cameraComponent.ZFar = 32768f;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFixedUpdate()
|
||||||
|
{
|
||||||
|
base.OnFixedUpdate();
|
||||||
|
|
||||||
|
var wishDirection = Input.AnalogMove.Normal * Rotation.FromYaw(EyeAngles.yaw);
|
||||||
|
var isDucking = Input.Down("Duck");
|
||||||
|
var isRunning = Input.Down("Run");
|
||||||
|
var wishSpeed = isDucking ? DuckSpeed :
|
||||||
|
isRunning ? RunSpeed : WalkSpeed;
|
||||||
|
|
||||||
|
Controller.WishVelocity = wishDirection * wishSpeed;
|
||||||
|
Controller.Move();
|
||||||
|
|
||||||
|
if (Input.Pressed("Jump") && Controller.IsOnGround)
|
||||||
|
{
|
||||||
|
Controller.Punch(Vector3.Up * JumpStrength);
|
||||||
|
AnimationHelper?.TriggerJump();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AnimationHelper.IsValid()) return;
|
||||||
|
|
||||||
|
AnimationHelper.WithWishVelocity(Controller.WishVelocity);
|
||||||
|
AnimationHelper.WithVelocity(Controller.Velocity);
|
||||||
|
AnimationHelper.DuckLevel = isDucking ? 1f : 0f;
|
||||||
|
AnimationHelper.IsGrounded = Controller.IsOnGround;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
base.OnUpdate();
|
||||||
|
|
||||||
|
EyeAngles += Input.AnalogLook;
|
||||||
|
EyeAngles = EyeAngles.WithPitch(MathX.Clamp(EyeAngles.pitch, -10f, 40f));
|
||||||
|
Renderer.WorldRotation = Rotation.Slerp(Renderer.WorldRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 5f);
|
||||||
|
|
||||||
|
var cameraOffset = Vector3.Up * 70f + Vector3.Backward * 220f;
|
||||||
|
Camera.WorldRotation = EyeAngles.ToRotation();
|
||||||
|
Camera.LocalPosition = cameraOffset * Camera.WorldRotation;
|
||||||
|
}
|
||||||
|
}
|
755
Libraries/fish.scc/Code/ShrimpleCharacterController.cs
Normal file
@ -0,0 +1,755 @@
|
|||||||
|
namespace ShrimpleCharacterController;
|
||||||
|
|
||||||
|
[Icon("nordic_walking")]
|
||||||
|
public class ShrimpleCharacterController : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manually update this by calling Move() or let it always be simulated
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Options")]
|
||||||
|
public bool ManuallyUpdate { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If pushing against a wall, scale the velocity based on the wall's angle (False is useful for NPCs that get stuck on corners)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Options")]
|
||||||
|
public bool ScaleAgainstWalls { get; set; } = true;
|
||||||
|
|
||||||
|
[Sync]
|
||||||
|
float _traceWidth { get; set; } = 16f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Width of our trace
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Trace")]
|
||||||
|
[Range(1f, 64f, 1f, true, true)]
|
||||||
|
public float TraceWidth
|
||||||
|
{
|
||||||
|
get => _traceWidth;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_traceWidth = value;
|
||||||
|
Bounds = BuildBounds();
|
||||||
|
_shrunkenBounds = Bounds.Grow(-SkinWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Sync]
|
||||||
|
float _traceHeight { get; set; } = 72f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Height of our trace
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Trace")]
|
||||||
|
[Range(1f, 256f, 1f, true, true)]
|
||||||
|
public float TraceHeight
|
||||||
|
{
|
||||||
|
get => _traceHeight;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_traceHeight = value;
|
||||||
|
Bounds = BuildBounds();
|
||||||
|
_shrunkenBounds = Bounds.Grow(-SkinWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Which tags it should ignore
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Trace")]
|
||||||
|
public TagSet IgnoreTags { get; set; } = new TagSet();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Max amount of trace calls whenever the simulation doesn't reach its target (Slide and collide bounces)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Trace")]
|
||||||
|
[Range(1, 20, 1, true, true)]
|
||||||
|
public int MaxBounces { get; set; } = 5;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How fast you accelerate while on the ground (Units per second)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Movement")]
|
||||||
|
[Range(0f, 3000f, 10f, false)]
|
||||||
|
[HideIf("GroundStickEnabled", false)]
|
||||||
|
public float GroundAcceleration { get; set; } = 1000f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How fast you decelerate while on the ground (Units per second)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Movement")]
|
||||||
|
[Range(0f, 3000f, 10f, false)]
|
||||||
|
[HideIf("GroundStickEnabled", false)]
|
||||||
|
public float GroundDeceleration { get; set; } = 1500f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How fast you accelerate while in the air (Units per second)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Movement")]
|
||||||
|
[Range(0f, 3000f, 10f, false)]
|
||||||
|
public float AirAcceleration { get; set; } = 300f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How fast you decelerate while in the air (Units per second)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Movement")]
|
||||||
|
[Range(0f, 3000f, 10f, false)]
|
||||||
|
public float AirDeceleration { get; set; } = 0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Do we ignore the friction of the surface you're standing on or not?
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Movement")]
|
||||||
|
public bool IgnoreGroundSurface { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this MoveHelper meant for horizontal grounded movement? (false = For flying or noclip)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("Movement")]
|
||||||
|
public bool IgnoreZ { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Do we ignore Z when it's near 0 (So that gravity affects you when not moving)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Title("Ignore Z When Zero")]
|
||||||
|
[Group("Movement")]
|
||||||
|
[HideIf("IgnoreZ", true)]
|
||||||
|
public bool IgnoreZWhenZero { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tolerance from a 90° surface before it's considered a wall (Ex. Tolerance 1 = Between 89° and 91° can be a wall, 0.1 = 89.9° to 90.1°)
|
||||||
|
/// </summary>
|
||||||
|
[Group("Movement")]
|
||||||
|
[Property]
|
||||||
|
[Range(0f, 10f, 0.1f, false)]
|
||||||
|
public float WallTolerance { get; set; } = 1f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Player feels like it's gripping walls too much? Try more Grip Factor Reduction!
|
||||||
|
/// </summary>
|
||||||
|
[Group("Movement")]
|
||||||
|
[Property]
|
||||||
|
[Range(1f, 10f, 0.1f, true)]
|
||||||
|
public float GripFactorReduction { get; set; } = 1f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stick the MoveHelper to the ground (IsOnGround will default to false if disabled)
|
||||||
|
/// </summary>
|
||||||
|
[ToggleGroup("GroundStickEnabled")]
|
||||||
|
[Property]
|
||||||
|
public bool GroundStickEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How steep terrain can be for you to stand on without slipping
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("GroundStickEnabled")]
|
||||||
|
[Range(0f, 89f, 1f, true, true)]
|
||||||
|
public float MaxGroundAngle { get; set; } = 60f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How far from the ground the MoveHelper is going to stick (Useful for going down stairs!)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("GroundStickEnabled")]
|
||||||
|
[Range(1f, 32f, 1f, false)]
|
||||||
|
public float GroundStickDistance { get; set; } = 12f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable steps climbing (+1 Trace call)
|
||||||
|
/// </summary>
|
||||||
|
[ToggleGroup("StepsEnabled")]
|
||||||
|
[Property]
|
||||||
|
public bool StepsEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How high steps can be for you to climb on
|
||||||
|
/// </summary>
|
||||||
|
[Group("StepsEnabled")]
|
||||||
|
[Property]
|
||||||
|
[Range(1f, 32f, 1f, false)]
|
||||||
|
public float StepHeight { get; set; } = 12f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How deep it checks for steps (Minimum depth)
|
||||||
|
/// </summary>
|
||||||
|
[Group("StepsEnabled")]
|
||||||
|
[Property]
|
||||||
|
[Range(0.1f, 8f, 0.1f, false)]
|
||||||
|
public float StepDepth { get; set; } = 2f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tolerance from a 90° surface before it's considered a valid step (Ex. Tolerance 1 = Between 89° and 91° can be a step, 0.1 = 89.9° to 90.1°)
|
||||||
|
/// </summary>
|
||||||
|
[Group("StepsEnabled")]
|
||||||
|
[Property]
|
||||||
|
[Range(0f, 10f, 0.1f, false)]
|
||||||
|
public float StepTolerance { get; set; } = 1f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable to ability to walk on a surface that's too steep if it's equal or smaller than a step (+1 Trace call when on steep terrain)
|
||||||
|
/// </summary>
|
||||||
|
[Group("StepsEnabled")]
|
||||||
|
[Property]
|
||||||
|
public bool PseudoStepsEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instead of colliding with these tags the MoveHelper will be pushed away (Make sure the tags are in IgnoreTags as well!)
|
||||||
|
/// </summary>
|
||||||
|
[ToggleGroup("PushEnabled")]
|
||||||
|
[Property]
|
||||||
|
public bool PushEnabled { get; set; } = false;
|
||||||
|
|
||||||
|
[Sync]
|
||||||
|
Dictionary<string, float> _pushTagsWeight { get; set; } = new Dictionary<string, float>() { { "player", 1f } };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Which tags will push this MoveHelper away and with how much force (Make sure they are also included in IgnoreTags!) (+1 Trace call)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("PushEnabled")]
|
||||||
|
public Dictionary<string, float> PushTagsWeight
|
||||||
|
{
|
||||||
|
get => _pushTagsWeight;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_pushTagsWeight = value;
|
||||||
|
_pushTags = BuildPushTags();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply gravity to this MoveHelper when not on the ground
|
||||||
|
/// </summary>
|
||||||
|
[ToggleGroup("GravityEnabled")]
|
||||||
|
[Property]
|
||||||
|
public bool GravityEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use the scene's gravity or our own
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("GravityEnabled")]
|
||||||
|
public bool UseSceneGravity { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Units per second squared (Default is -850f)
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("GravityEnabled")]
|
||||||
|
[Range(-2000, 2000, 1, false)]
|
||||||
|
[HideIf("UseSceneGravity", true)]
|
||||||
|
public float Gravity { get; set; } = -850f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the MoveHelper is stuck and try to get it to unstuck (+Trace calls if stuck)
|
||||||
|
/// </summary>
|
||||||
|
[ToggleGroup("UnstuckEnabled")]
|
||||||
|
[Property]
|
||||||
|
public bool UnstuckEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many trace calls it will attempt to get the MoveHelper unstuck
|
||||||
|
/// </summary>
|
||||||
|
[Property]
|
||||||
|
[Group("UnstuckEnabled")]
|
||||||
|
[Range(1, 50, 1, false)]
|
||||||
|
public int MaxUnstuckTries { get; set; } = 20;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The simulated target velocity for our MoveHelper (Units per second, we apply Time.Delta inside)
|
||||||
|
/// </summary>
|
||||||
|
[Sync] public Vector3 WishVelocity { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The resulting velocity after the simulation is done (Units per second)
|
||||||
|
/// </summary>
|
||||||
|
[Sync] public Vector3 Velocity { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the MoveHelper currently touching the ground
|
||||||
|
/// </summary>
|
||||||
|
[Sync] public bool IsOnGround { get; set; }
|
||||||
|
|
||||||
|
/// The current ground normal you're standing on (Always Vector3.Zero if IsOnGround false)
|
||||||
|
/// </summary>
|
||||||
|
public Vector3 GroundNormal { get; private set; } = Vector3.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current ground angle you're standing on (Always 0f if IsOnGround false)
|
||||||
|
/// </summary>
|
||||||
|
public float GroundAngle => Vector3.GetAngle(GroundNormal, Vector3.Up);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current surface you're standing on
|
||||||
|
/// </summary>
|
||||||
|
public Surface GroundSurface { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The gameobject you're currently standing on
|
||||||
|
/// </summary>
|
||||||
|
public GameObject GroundObject { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the MoveHelper currently pushing against a wall
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPushingAgainstWall { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current wall normal you're pushing against (Always Vector3.Zero if IsPushingAgainstWall false)
|
||||||
|
/// </summary>
|
||||||
|
public Vector3 WallNormal { get; private set; } = Vector3.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The gameobject you're currently pushing on
|
||||||
|
/// </summary>
|
||||||
|
public GameObject WallObject { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the MoveHelper standing on a terrain too steep to stand on (Always false if IsOnGround false)
|
||||||
|
/// </summary>
|
||||||
|
[Sync] public bool IsSlipping { get; private set; } // TODO IMPLEMENT
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The MoveHelper is stuck and we can't get it out
|
||||||
|
/// </summary>
|
||||||
|
[Sync] public bool IsStuck { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// To avoid getting stuck due to imprecision we shrink the bounds before checking and compensate for it later
|
||||||
|
/// </summary>
|
||||||
|
public float SkinWidth;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The bounds of this MoveHelper generated from the TraceWidth and TraceHeight
|
||||||
|
/// </summary>
|
||||||
|
public BBox Bounds { get; set; }
|
||||||
|
private BBox _shrunkenBounds;
|
||||||
|
private string[] _pushTags;
|
||||||
|
private Vector3 _lastVelocity;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If another MoveHelper moved at the same time and they're stuck, let this one know that the other already unstuck for us
|
||||||
|
/// </summary>
|
||||||
|
public ShrimpleCharacterController UnstuckTarget;
|
||||||
|
|
||||||
|
protected override void OnStart()
|
||||||
|
{
|
||||||
|
SkinWidth = Math.Min(Math.Max(0.1f, TraceWidth * 0.05f), GroundStickDistance); // SkinWidth is 5% of the total width
|
||||||
|
Bounds = BuildBounds();
|
||||||
|
_shrunkenBounds = Bounds.Grow(-SkinWidth);
|
||||||
|
_pushTags = BuildPushTags();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void DrawGizmos()
|
||||||
|
{
|
||||||
|
if (Gizmo.IsSelected)
|
||||||
|
{
|
||||||
|
Gizmo.GizmoDraw draw = Gizmo.Draw;
|
||||||
|
draw.Color = Color.Blue;
|
||||||
|
draw.LineBBox(BuildBounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BBox BuildBounds()
|
||||||
|
{
|
||||||
|
return new BBox(new Vector3(-TraceWidth / 2, -TraceWidth / 2f, 0f), new Vector3(TraceWidth / 2f, TraceWidth / 2f, TraceHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string[] BuildPushTags()
|
||||||
|
{
|
||||||
|
return PushTagsWeight.Keys.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Casts the current bounds from to and returns the scene trace result
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bounds"></param>
|
||||||
|
/// <param name="from"></param>
|
||||||
|
/// <param name="to"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public SceneTraceResult BuildTrace(BBox bounds, Vector3 from, Vector3 to)
|
||||||
|
{
|
||||||
|
return Game.SceneTrace.Box(bounds, from, to)
|
||||||
|
.IgnoreGameObjectHierarchy(GameObject)
|
||||||
|
.WithoutTags(IgnoreTags)
|
||||||
|
.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SceneTraceResult BuildPushTrace(BBox bounds, Vector3 from, Vector3 to)
|
||||||
|
{
|
||||||
|
return Game.SceneTrace.Box(bounds, from, to)
|
||||||
|
.IgnoreGameObjectHierarchy(GameObject)
|
||||||
|
.WithAnyTags(_pushTags) // Check for only the push tags
|
||||||
|
.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Detach the MoveHelper from the ground and launch it somewhere (Units per second)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="amount"></param>
|
||||||
|
public void Punch(in Vector3 amount)
|
||||||
|
{
|
||||||
|
if (amount.z < 10f) return; // Get out with that weak crap
|
||||||
|
|
||||||
|
IsOnGround = false;
|
||||||
|
Velocity += amount;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply the WishVelocity, update the Velocity and the Position of the GameObject by simulating the MoveHelper
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="manualUpdate">Just calculate but don't update position</param>
|
||||||
|
public MoveHelperResult Move(bool manualUpdate = false) => Move(Time.Delta, manualUpdate);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply the WishVelocity, update the Velocity and the Position of the GameObject by simulating the MoveHelper
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="delta">The time step</param>
|
||||||
|
/// <param name="manualUpdate">Just calculate but don't update position</param>
|
||||||
|
public MoveHelperResult Move(float delta, bool manualUpdate = false)
|
||||||
|
{
|
||||||
|
var goalVelocity = CalculateGoalVelocity(delta); // Calculate the goal velocity using our Acceleration and Deceleration values
|
||||||
|
|
||||||
|
// KNOWN ISSUE: Velocity starts to build up to massive amounts when trying to climb terrain too steep?
|
||||||
|
|
||||||
|
// SIMULATE PUSH FORCES //
|
||||||
|
if (PushEnabled)
|
||||||
|
{
|
||||||
|
var pushTrace = BuildPushTrace(Bounds, WorldPosition, WorldPosition); // Build a trace but using the Push tags instead of the Ignore tags
|
||||||
|
|
||||||
|
if (pushTrace.Hit) // We're inside any of the push tags
|
||||||
|
{
|
||||||
|
foreach (var tag in pushTrace.GameObject.Tags)
|
||||||
|
{
|
||||||
|
if (PushTagsWeight.TryGetValue(tag, out var tagWeight))
|
||||||
|
{
|
||||||
|
var otherPosition = pushTrace.GameObject.WorldPosition.WithZ(WorldPosition.z); // Only horizontal pushing
|
||||||
|
var pushDirection = (otherPosition - WorldPosition).Normal;
|
||||||
|
var pushVelocity = pushDirection * tagWeight * 50f; // I find 50 u/s to be a good amount to push if the weight is 1.0 (!!!)
|
||||||
|
|
||||||
|
goalVelocity -= pushVelocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var moveHelperResult = CollideAndSlide(goalVelocity, WorldPosition, delta); // Simulate the MoveHelper
|
||||||
|
|
||||||
|
var finalPosition = moveHelperResult.Position;
|
||||||
|
var finalVelocity = moveHelperResult.Velocity;
|
||||||
|
|
||||||
|
// SIMULATE GRAVITY //
|
||||||
|
if (GravityEnabled && Gravity != 0f)
|
||||||
|
{
|
||||||
|
if (!IsOnGround || IsSlipping || !GroundStickEnabled)
|
||||||
|
{
|
||||||
|
var gravityAmount = UseSceneGravity ? Scene.PhysicsWorld.Gravity.z : Gravity;
|
||||||
|
var gravity = gravityAmount * Vector3.Up * delta;
|
||||||
|
var gravityResult = CollideAndSlide(gravity, moveHelperResult.Position, delta, gravityPass: true); // Apply and simulate the gravity step
|
||||||
|
|
||||||
|
finalPosition = gravityResult.Position;
|
||||||
|
finalVelocity += gravityResult.Velocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastVelocity = Velocity * delta;
|
||||||
|
|
||||||
|
if (!manualUpdate)
|
||||||
|
{
|
||||||
|
Velocity = finalVelocity;
|
||||||
|
WorldPosition = finalPosition; // Actually updating the position is "expensive" so we only do it once at the end
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MoveHelperResult(finalPosition, finalVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sometimes we have to update only the position but not the velocity (Like when climbing steps or getting unstuck) so we can't have Position rely only on Velocity
|
||||||
|
/// </summary>
|
||||||
|
public struct MoveHelperResult
|
||||||
|
{
|
||||||
|
public Vector3 Position;
|
||||||
|
public Vector3 Velocity;
|
||||||
|
|
||||||
|
public MoveHelperResult(Vector3 position, Vector3 velocity)
|
||||||
|
{
|
||||||
|
Position = position;
|
||||||
|
Velocity = velocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MoveHelperResult CollideAndSlide(Vector3 velocity, Vector3 position, float delta, int depth = 0, bool gravityPass = false) =>
|
||||||
|
CollideAndSlide(new MoveHelperResult(position, velocity), delta, depth, gravityPass);
|
||||||
|
|
||||||
|
private MoveHelperResult CollideAndSlide(MoveHelperResult current, float delta, int depth = 0, bool gravityPass = false)
|
||||||
|
{
|
||||||
|
if (depth >= MaxBounces)
|
||||||
|
return current;
|
||||||
|
|
||||||
|
var velocity = current.Velocity * delta; // I like to set Velocity as units/second but we have to deal with units/tick here
|
||||||
|
var position = current.Position;
|
||||||
|
|
||||||
|
// GROUND AND UNSTUCK CHECK //
|
||||||
|
if (depth == 0) // Only check for the first step since it's impossible to get stuck on other steps
|
||||||
|
{
|
||||||
|
var groundTrace = BuildTrace(_shrunkenBounds, position, position + Vector3.Down * GroundStickDistance);
|
||||||
|
|
||||||
|
if (groundTrace.StartedSolid)
|
||||||
|
{
|
||||||
|
IsStuck = true;
|
||||||
|
if (UnstuckEnabled)
|
||||||
|
{
|
||||||
|
if (UnstuckTarget == null)
|
||||||
|
{
|
||||||
|
IsStuck = !TryUnstuck(position, out var result);
|
||||||
|
|
||||||
|
if (!IsStuck)
|
||||||
|
{
|
||||||
|
position = result; // Update the new position
|
||||||
|
|
||||||
|
if (groundTrace.GameObject != null)
|
||||||
|
if (groundTrace.GameObject.Components.TryGet<ShrimpleCharacterController>(out var otherHelper))
|
||||||
|
otherHelper.UnstuckTarget = this; // We already solved this, no need to unstuck the other helper
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new MoveHelperResult(position, Vector3.Zero); // Mission failed, bail out!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UnstuckTarget = null; // Alright the other MoveHelper got us unstuck so just do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var hasLanded = !IsOnGround && Velocity.z <= 0f && groundTrace.Hit && groundTrace.Distance <= SkinWidth * 2f; // Wasn't on the ground and now is
|
||||||
|
var isGrounded = IsOnGround && groundTrace.Hit; // Was already on the ground and still is, this helps stick when going down stairs
|
||||||
|
|
||||||
|
IsOnGround = hasLanded || isGrounded;
|
||||||
|
GroundSurface = IsOnGround ? groundTrace.Surface : null;
|
||||||
|
GroundNormal = IsOnGround ? groundTrace.Normal : Vector3.Up;
|
||||||
|
GroundObject = IsOnGround ? groundTrace.GameObject : null;
|
||||||
|
IsSlipping = IsOnGround && GroundAngle > MaxGroundAngle;
|
||||||
|
|
||||||
|
if (IsSlipping && !gravityPass && velocity.z > 0f)
|
||||||
|
velocity = velocity.WithZ(0f); // If we're slipping ignore any extra velocity we had
|
||||||
|
|
||||||
|
if (IsOnGround && GroundStickEnabled && !IsSlipping)
|
||||||
|
{
|
||||||
|
position = groundTrace.EndPosition + Vector3.Up * SkinWidth; // Place on the ground
|
||||||
|
velocity = Vector3.VectorPlaneProject(velocity, GroundNormal); // Follow the ground you're on without projecting Z
|
||||||
|
}
|
||||||
|
|
||||||
|
IsStuck = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (velocity.IsNearlyZero(0.01f)) // Not worth continuing, reduces small stutter
|
||||||
|
{
|
||||||
|
return new MoveHelperResult(position, Vector3.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
var toTravel = velocity.Length + SkinWidth;
|
||||||
|
var targetPosition = position + velocity.Normal * toTravel;
|
||||||
|
var travelTrace = BuildTrace(_shrunkenBounds, position, targetPosition);
|
||||||
|
|
||||||
|
if (travelTrace.Hit)
|
||||||
|
{
|
||||||
|
var travelled = velocity.Normal * Math.Max(travelTrace.Distance - SkinWidth, 0f);
|
||||||
|
|
||||||
|
var leftover = velocity - travelled; // How much leftover velocity still needs to be simulated
|
||||||
|
var angle = Vector3.GetAngle(Vector3.Up, travelTrace.Normal);
|
||||||
|
if (toTravel >= SkinWidth && travelTrace.Distance < SkinWidth)
|
||||||
|
travelled = Vector3.Zero;
|
||||||
|
|
||||||
|
if (angle <= MaxGroundAngle) // Terrain we can walk on
|
||||||
|
{
|
||||||
|
if (gravityPass || !IsOnGround)
|
||||||
|
leftover = Vector3.VectorPlaneProject(leftover, travelTrace.Normal); // Don't project the vertical velocity after landing else it boosts your horizontal velocity
|
||||||
|
else
|
||||||
|
leftover = leftover.ProjectAndScale(travelTrace.Normal); // Project the velocity along the terrain
|
||||||
|
IsPushingAgainstWall = false;
|
||||||
|
WallObject = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var climbedStair = false;
|
||||||
|
|
||||||
|
if (angle >= 90f - WallTolerance && angle <= 90f + WallTolerance) // Check for walls
|
||||||
|
IsPushingAgainstWall = true; // We're pushing against a wall
|
||||||
|
|
||||||
|
if (StepsEnabled)
|
||||||
|
{
|
||||||
|
var isStep = angle >= 90f - StepTolerance && angle <= 90f + StepTolerance;
|
||||||
|
|
||||||
|
if (isStep || PseudoStepsEnabled) // Check for steps
|
||||||
|
{
|
||||||
|
if (IsOnGround) // Stairs VVV
|
||||||
|
{
|
||||||
|
var stepHorizontal = velocity.WithZ(0f).Normal * StepDepth; // How far in front we're looking for steps
|
||||||
|
var stepVertical = Vector3.Up * StepHeight; // How high we're looking for steps
|
||||||
|
var stepTrace = BuildTrace(_shrunkenBounds, travelTrace.EndPosition + stepHorizontal + stepVertical, travelTrace.EndPosition + stepHorizontal);
|
||||||
|
var stepAngle = Vector3.GetAngle(stepTrace.Normal, Vector3.Up);
|
||||||
|
|
||||||
|
if (!stepTrace.StartedSolid && stepTrace.Hit && stepAngle <= MaxGroundAngle) // We found a step!
|
||||||
|
{
|
||||||
|
if (isStep || !IsSlipping && PseudoStepsEnabled)
|
||||||
|
{
|
||||||
|
var stepDistance = stepTrace.EndPosition - travelTrace.EndPosition;
|
||||||
|
var stepTravelled = Vector3.Up * stepDistance;
|
||||||
|
position += stepTravelled; // Offset our position by the height of the step climbed
|
||||||
|
climbedStair = true;
|
||||||
|
|
||||||
|
IsPushingAgainstWall = false; // Nevermind, we're not against a wall, we climbed a step!
|
||||||
|
WallObject = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsPushingAgainstWall)
|
||||||
|
{
|
||||||
|
// Scale our leftover velocity based on the angle of approach relative to the wall
|
||||||
|
// (Perpendicular = 0%, Parallel = 100%)
|
||||||
|
var scale = ScaleAgainstWalls ? 1f - Vector3.Dot(-travelTrace.Normal.Normal / GripFactorReduction, velocity.Normal) : 1f;
|
||||||
|
var wallLeftover = ScaleAgainstWalls ? Vector3.VectorPlaneProject(leftover, travelTrace.Normal.Normal) : leftover.ProjectAndScale(travelTrace.Normal.Normal);
|
||||||
|
leftover = (wallLeftover * scale).WithZ(wallLeftover.z);
|
||||||
|
|
||||||
|
WallObject = travelTrace.GameObject;
|
||||||
|
WallNormal = travelTrace.Normal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!climbedStair)
|
||||||
|
{
|
||||||
|
var scale = IsSlipping ? 1f : 1f - Vector3.Dot(-travelTrace.Normal / GripFactorReduction, velocity.Normal);
|
||||||
|
leftover = ScaleAgainstWalls ? Vector3.VectorPlaneProject(leftover, travelTrace.Normal) * scale : leftover.ProjectAndScale(travelTrace.Normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (travelled.Length <= 0.01f && leftover.Length <= 0.01f)
|
||||||
|
return new MoveHelperResult(position + travelled, travelled / delta);
|
||||||
|
|
||||||
|
var newResult = CollideAndSlide(new MoveHelperResult(position + travelled, leftover / delta), delta, depth + 1, gravityPass); // Simulate another bounce for the leftover velocity from the latest position
|
||||||
|
var currentResult = new MoveHelperResult(newResult.Position, travelled / delta + newResult.Velocity); // Use the new bounce's position and combine the velocities
|
||||||
|
|
||||||
|
return currentResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth == 0 && !gravityPass)
|
||||||
|
{
|
||||||
|
IsPushingAgainstWall = false;
|
||||||
|
WallObject = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MoveHelperResult(position + velocity, velocity / delta); // We didn't hit anything? Ok just keep going then :-)
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateGoalSpeed(Vector3 wishVelocity, Vector3 velocity, bool isAccelerating, float delta)
|
||||||
|
{
|
||||||
|
float goalSpeed;
|
||||||
|
|
||||||
|
var isSameDirection = velocity.IsNearlyZero(1f) || Vector3.Dot(wishVelocity.WithZ(0f).Normal, velocity.WithZ(0f).Normal) >= 0f; // Is our wishVelocity roughly moving towards our velocity already?
|
||||||
|
|
||||||
|
var acceleration = IsOnGround ? GroundAcceleration : AirAcceleration;
|
||||||
|
var deceleration = IsOnGround ? GroundDeceleration : AirDeceleration;
|
||||||
|
|
||||||
|
if (isAccelerating)
|
||||||
|
goalSpeed = acceleration;
|
||||||
|
else
|
||||||
|
goalSpeed = !isSameDirection ? Math.Max(acceleration, deceleration) : deceleration; // Makes movement more responsive especially for flying or rolling
|
||||||
|
|
||||||
|
if (!IgnoreGroundSurface && GroundSurface != null)
|
||||||
|
goalSpeed *= GroundSurface.Friction; // Take into account the ground's friction
|
||||||
|
|
||||||
|
goalSpeed *= delta;
|
||||||
|
|
||||||
|
return goalSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector3 CalculateGoalVelocity(float delta)
|
||||||
|
{
|
||||||
|
bool shouldIgnoreZ = IgnoreZ || (IgnoreZWhenZero && WishVelocity.z.AlmostEqual(0f));
|
||||||
|
var wishVelocity = shouldIgnoreZ ? (WishVelocity.Normal * WishVelocity.Length).WithZ(Velocity.z) : WishVelocity;
|
||||||
|
var isAccelerating = shouldIgnoreZ ? wishVelocity.WithZ(0f).Length >= Velocity.WithZ(0f).Length : wishVelocity.Length >= Velocity.Length;
|
||||||
|
|
||||||
|
var goalSpeed = CalculateGoalSpeed(wishVelocity, Velocity, isAccelerating, delta);
|
||||||
|
var goalVelocity = Velocity.MoveTowards(wishVelocity, goalSpeed);
|
||||||
|
|
||||||
|
return shouldIgnoreZ ? goalVelocity.WithZ(Velocity.z) : goalVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool TryUnstuck(Vector3 position, out Vector3 result)
|
||||||
|
{
|
||||||
|
var velocityLength = _lastVelocity.Length + SkinWidth;
|
||||||
|
var startPos = position - _lastVelocity.Normal * velocityLength; // Try undoing the last velocity 1st
|
||||||
|
var endPos = position;
|
||||||
|
|
||||||
|
for (int i = 0; i < MaxUnstuckTries + 1; i++)
|
||||||
|
{
|
||||||
|
if (i == 1)
|
||||||
|
startPos = position + Vector3.Up * 2f; // Try going up 2nd
|
||||||
|
|
||||||
|
if (i > 1)
|
||||||
|
startPos = position + Vector3.Random.Normal * ((float)i / 2f); // Start randomly checking 3rd
|
||||||
|
|
||||||
|
var unstuckTrace = BuildTrace(_shrunkenBounds, startPos, endPos);
|
||||||
|
|
||||||
|
if (!unstuckTrace.StartedSolid)
|
||||||
|
{
|
||||||
|
result = unstuckTrace.EndPosition - _lastVelocity.Normal * SkinWidth;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = position;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Debug don't use
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <param name="title"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private bool TestPosition(Vector3 position, string title)
|
||||||
|
{
|
||||||
|
var testTrace = BuildTrace(_shrunkenBounds, position, position);
|
||||||
|
|
||||||
|
if (testTrace.StartedSolid)
|
||||||
|
{
|
||||||
|
Log.Info($"[{RealTime.Now}]{title} {GameObject.Name} started solid at {position} against {testTrace.GameObject}");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFixedUpdate()
|
||||||
|
{
|
||||||
|
base.OnFixedUpdate();
|
||||||
|
|
||||||
|
if (!ManuallyUpdate && Active)
|
||||||
|
Move();
|
||||||
|
}
|
||||||
|
}
|
40
Libraries/fish.scc/Code/Util/Extensions/Vector3Extensions.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
namespace ShrimpleCharacterController;
|
||||||
|
|
||||||
|
public static class Vector3Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Move a vector3 towards a goal by a fixed distance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="target"></param>
|
||||||
|
/// <param name="travelSpeed"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Vector3 MoveTowards( this Vector3 value, Vector3 target, float travelSpeed )
|
||||||
|
{
|
||||||
|
var difference = target - value;
|
||||||
|
var distance = difference.Length;
|
||||||
|
var normal = difference.Normal;
|
||||||
|
|
||||||
|
if ( distance <= travelSpeed || distance == 0f )
|
||||||
|
{
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value + normal * travelSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Project a vector along a plane (normal) and scale it back to its original length
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="normal"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Vector3 ProjectAndScale( this Vector3 value, Vector3 normal )
|
||||||
|
{
|
||||||
|
var length = value.Length;
|
||||||
|
value = Vector3.VectorPlaneProject( value, normal ).Normal;
|
||||||
|
value *= length;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
21
Libraries/fish.scc/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Small Fish
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
34
Libraries/fish.scc/ProjectSettings/Collision.config
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"Defaults": {
|
||||||
|
"solid": "Collide",
|
||||||
|
"trigger": "Trigger",
|
||||||
|
"ladder": "Ignore",
|
||||||
|
"water": "Trigger"
|
||||||
|
},
|
||||||
|
"Pairs": [
|
||||||
|
{
|
||||||
|
"a": "solid",
|
||||||
|
"b": "solid",
|
||||||
|
"r": "Collide"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "trigger",
|
||||||
|
"b": "playerclip",
|
||||||
|
"r": "Ignore"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "trigger",
|
||||||
|
"b": "solid",
|
||||||
|
"r": "Trigger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "playerclip",
|
||||||
|
"b": "solid",
|
||||||
|
"r": "Collide"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"__guid": "3f8027f2-5728-4178-a563-2be1da260457",
|
||||||
|
"__schema": "configdata",
|
||||||
|
"__type": "CollisionRules",
|
||||||
|
"__version": 1
|
||||||
|
}
|
194
Libraries/fish.scc/ProjectSettings/Input.config
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
{
|
||||||
|
"Actions": [
|
||||||
|
{
|
||||||
|
"Name": "Forward",
|
||||||
|
"KeyboardCode": "W",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Backward",
|
||||||
|
"KeyboardCode": "S",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Left",
|
||||||
|
"KeyboardCode": "A",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Right",
|
||||||
|
"KeyboardCode": "D",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Jump",
|
||||||
|
"KeyboardCode": "space",
|
||||||
|
"GamepadCode": "A",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Run",
|
||||||
|
"KeyboardCode": "shift",
|
||||||
|
"GamepadCode": "LeftJoystickButton",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Walk",
|
||||||
|
"KeyboardCode": "alt",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Duck",
|
||||||
|
"KeyboardCode": "ctrl",
|
||||||
|
"GamepadCode": "B",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "attack1",
|
||||||
|
"KeyboardCode": "mouse1",
|
||||||
|
"GamepadCode": "RightTrigger",
|
||||||
|
"GroupName": "Actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "attack2",
|
||||||
|
"KeyboardCode": "mouse2",
|
||||||
|
"GamepadCode": "LeftTrigger",
|
||||||
|
"GroupName": "Actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "reload",
|
||||||
|
"KeyboardCode": "r",
|
||||||
|
"GamepadCode": "X",
|
||||||
|
"GroupName": "Actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "use",
|
||||||
|
"KeyboardCode": "e",
|
||||||
|
"GamepadCode": "Y",
|
||||||
|
"GroupName": "Actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot1",
|
||||||
|
"KeyboardCode": "1",
|
||||||
|
"GamepadCode": "DpadWest",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot2",
|
||||||
|
"KeyboardCode": "2",
|
||||||
|
"GamepadCode": "DpadEast",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot3",
|
||||||
|
"KeyboardCode": "3",
|
||||||
|
"GamepadCode": "DpadSouth",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot4",
|
||||||
|
"KeyboardCode": "4",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot5",
|
||||||
|
"KeyboardCode": "5",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot6",
|
||||||
|
"KeyboardCode": "6",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot7",
|
||||||
|
"KeyboardCode": "7",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot8",
|
||||||
|
"KeyboardCode": "8",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot9",
|
||||||
|
"KeyboardCode": "9",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot0",
|
||||||
|
"KeyboardCode": "0",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "SlotPrev",
|
||||||
|
"KeyboardCode": "mouse4",
|
||||||
|
"GamepadCode": "SwitchLeftBumper",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "SlotNext",
|
||||||
|
"KeyboardCode": "mouse5",
|
||||||
|
"GamepadCode": "SwitchRightBumper",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "View",
|
||||||
|
"KeyboardCode": "C",
|
||||||
|
"GamepadCode": "RightJoystickButton",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Voice",
|
||||||
|
"KeyboardCode": "v",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Drop",
|
||||||
|
"KeyboardCode": "g",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Flashlight",
|
||||||
|
"KeyboardCode": "f",
|
||||||
|
"GamepadCode": "DpadNorth",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Score",
|
||||||
|
"KeyboardCode": "tab",
|
||||||
|
"GamepadCode": "SwitchLeftMenu",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Menu",
|
||||||
|
"KeyboardCode": "Q",
|
||||||
|
"GamepadCode": "SwitchRightMenu",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Chat",
|
||||||
|
"KeyboardCode": "enter",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"__guid": "2b0cbf43-3f45-425d-8560-9eaecf2ed2a3",
|
||||||
|
"__schema": "configdata",
|
||||||
|
"__type": "InputSettings",
|
||||||
|
"__version": 1
|
||||||
|
}
|
41
Libraries/fish.scc/README.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# Shrimple Character Controller
|
||||||
|
|
||||||
|
https://github.com/user-attachments/assets/374eea5b-7106-4c3e-8cb6-9bb56a1ff511
|
||||||
|
|
||||||
|
A shrimple yet versatile Character Controller/Move Helper that performs great.
|
||||||
|
Performs 60%-200% better than standard Character Controller.
|
||||||
|
|
||||||
|
|
||||||
|
You can find example scenes for the Walker, Roller, and Flyer here: [Controller Example Scenes](https://github.com/Small-Fish-Dev/shrimple_character_controller/tree/main/Assets/scenes)
|
||||||
|
|
||||||
|
Made from scratch using the classic [Collide and Slide](https://www.peroxide.dk/papers/collision/collision.pdf) method.
|
||||||
|
|
||||||
|
For any issues please report them here: [Github Issues](https://github.com/Small-Fish-Dev/shrimple_character_controller/issues)
|
||||||
|
|
||||||
|
# How to use
|
||||||
|
You can find code examples for the Walker, Roller, and Flyer here: [Example Controllers](https://github.com/Small-Fish-Dev/shrimple_character_controller/tree/main/code/Examples)
|
||||||
|
|
||||||
|
It all boils down to:
|
||||||
|
|
||||||
|
```
|
||||||
|
Controller.WishVelocity = Vector3.Forward;
|
||||||
|
Controller.Move();
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll have to call `.Move()` only if your Controller options "Manual Update" is set to true. Otherwise you can set it to false and it will always be simulated.
|
||||||
|
|
||||||
|
You are also able to manually update the GameObject's transform rather than letting the Controller do it:
|
||||||
|
```
|
||||||
|
Controller.WishVelocity = wishDirection * wishSpeed;
|
||||||
|
var controllerResult = Controller.Move( false );
|
||||||
|
|
||||||
|
if ( controllerResult.Position.z <= 999f ) // Out of bounds!
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Transform.Position = controllerResult.Position;
|
||||||
|
MyVelocity = controllerResult.Velocity;
|
||||||
|
}
|
||||||
|
```
|
15
Libraries/fish.scc/scc.sbproj
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"Title": "Shrimple Character Controller",
|
||||||
|
"Type": "library",
|
||||||
|
"Org": "fish",
|
||||||
|
"Ident": "scc",
|
||||||
|
"Schema": 1,
|
||||||
|
"IncludeSourceFiles": false,
|
||||||
|
"Resources": null,
|
||||||
|
"PackageReferences": [],
|
||||||
|
"EditorReferences": null,
|
||||||
|
"IsWhitelistDisabled": false,
|
||||||
|
"Metadata": {
|
||||||
|
"CsProjName": ""
|
||||||
|
}
|
||||||
|
}
|
34
ProjectSettings/Collision.config
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"Defaults": {
|
||||||
|
"solid": "Collide",
|
||||||
|
"trigger": "Trigger",
|
||||||
|
"ladder": "Ignore",
|
||||||
|
"water": "Trigger"
|
||||||
|
},
|
||||||
|
"Pairs": [
|
||||||
|
{
|
||||||
|
"a": "solid",
|
||||||
|
"b": "solid",
|
||||||
|
"r": "Collide"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "trigger",
|
||||||
|
"b": "playerclip",
|
||||||
|
"r": "Ignore"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "trigger",
|
||||||
|
"b": "solid",
|
||||||
|
"r": "Trigger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "playerclip",
|
||||||
|
"b": "solid",
|
||||||
|
"r": "Collide"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"__guid": "c82378d5-1642-441e-91ec-098ea88ad35e",
|
||||||
|
"__schema": "configdata",
|
||||||
|
"__type": "CollisionRules",
|
||||||
|
"__version": 1
|
||||||
|
}
|
194
ProjectSettings/Input.config
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
{
|
||||||
|
"Actions": [
|
||||||
|
{
|
||||||
|
"Name": "Forward",
|
||||||
|
"KeyboardCode": "W",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Backward",
|
||||||
|
"KeyboardCode": "S",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Left",
|
||||||
|
"KeyboardCode": "A",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Right",
|
||||||
|
"KeyboardCode": "D",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Jump",
|
||||||
|
"KeyboardCode": "space",
|
||||||
|
"GamepadCode": "A",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Run",
|
||||||
|
"KeyboardCode": "shift",
|
||||||
|
"GamepadCode": "LeftJoystickButton",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Walk",
|
||||||
|
"KeyboardCode": "alt",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Duck",
|
||||||
|
"KeyboardCode": "ctrl",
|
||||||
|
"GamepadCode": "B",
|
||||||
|
"GroupName": "Movement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "attack1",
|
||||||
|
"KeyboardCode": "mouse1",
|
||||||
|
"GamepadCode": "RightTrigger",
|
||||||
|
"GroupName": "Actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "attack2",
|
||||||
|
"KeyboardCode": "mouse2",
|
||||||
|
"GamepadCode": "LeftTrigger",
|
||||||
|
"GroupName": "Actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "reload",
|
||||||
|
"KeyboardCode": "r",
|
||||||
|
"GamepadCode": "X",
|
||||||
|
"GroupName": "Actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "use",
|
||||||
|
"KeyboardCode": "e",
|
||||||
|
"GamepadCode": "Y",
|
||||||
|
"GroupName": "Actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot1",
|
||||||
|
"KeyboardCode": "1",
|
||||||
|
"GamepadCode": "DpadWest",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot2",
|
||||||
|
"KeyboardCode": "2",
|
||||||
|
"GamepadCode": "DpadEast",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot3",
|
||||||
|
"KeyboardCode": "3",
|
||||||
|
"GamepadCode": "DpadSouth",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot4",
|
||||||
|
"KeyboardCode": "4",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot5",
|
||||||
|
"KeyboardCode": "5",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot6",
|
||||||
|
"KeyboardCode": "6",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot7",
|
||||||
|
"KeyboardCode": "7",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot8",
|
||||||
|
"KeyboardCode": "8",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot9",
|
||||||
|
"KeyboardCode": "9",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Slot0",
|
||||||
|
"KeyboardCode": "0",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "SlotPrev",
|
||||||
|
"KeyboardCode": "mouse4",
|
||||||
|
"GamepadCode": "SwitchLeftBumper",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "SlotNext",
|
||||||
|
"KeyboardCode": "mouse5",
|
||||||
|
"GamepadCode": "SwitchRightBumper",
|
||||||
|
"GroupName": "Inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "View",
|
||||||
|
"KeyboardCode": "C",
|
||||||
|
"GamepadCode": "RightJoystickButton",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Voice",
|
||||||
|
"KeyboardCode": "v",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Drop",
|
||||||
|
"KeyboardCode": "g",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Flashlight",
|
||||||
|
"KeyboardCode": "f",
|
||||||
|
"GamepadCode": "DpadNorth",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Score",
|
||||||
|
"KeyboardCode": "tab",
|
||||||
|
"GamepadCode": "SwitchLeftMenu",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Menu",
|
||||||
|
"KeyboardCode": "Q",
|
||||||
|
"GamepadCode": "SwitchRightMenu",
|
||||||
|
"GroupName": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Chat",
|
||||||
|
"KeyboardCode": "enter",
|
||||||
|
"GamepadCode": "None",
|
||||||
|
"GroupName": "Other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"__guid": "0227f25a-537a-4f15-a72a-90f6af33742f",
|
||||||
|
"__schema": "configdata",
|
||||||
|
"__type": "InputSettings",
|
||||||
|
"__version": 1
|
||||||
|
}
|
29
kakozuzo_2.sbproj
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"Title": "kakozuzo_2",
|
||||||
|
"Type": "game",
|
||||||
|
"Org": "koptilnya",
|
||||||
|
"Ident": "kakozuzo_2",
|
||||||
|
"Schema": 1,
|
||||||
|
"IncludeSourceFiles": false,
|
||||||
|
"Resources": null,
|
||||||
|
"PackageReferences": [],
|
||||||
|
"EditorReferences": null,
|
||||||
|
"IsWhitelistDisabled": false,
|
||||||
|
"Metadata": {
|
||||||
|
"MaxPlayers": 64,
|
||||||
|
"MinPlayers": 1,
|
||||||
|
"TickRate": 50,
|
||||||
|
"GameNetworkType": "Multiplayer",
|
||||||
|
"MapSelect": "Unrestricted",
|
||||||
|
"MapList": [
|
||||||
|
"facepunch.flatgrass"
|
||||||
|
],
|
||||||
|
"RankType": "None",
|
||||||
|
"PerMapRanking": false,
|
||||||
|
"LeaderboardType": "None",
|
||||||
|
"CsProjName": "",
|
||||||
|
"StartupScene": "scenes/minimal.scene",
|
||||||
|
"MapStartupScene": "scenes/minimal.scene",
|
||||||
|
"LaunchMode": "Normal"
|
||||||
|
}
|
||||||
|
}
|
4
kakozuzo_2.sln.DotSettings.user
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005Chamit_005Fba31xcg_005CDocuments_005Cs_0026box_0020projects_005Ckakozuzo_005F2_005CLibraries_005Cfish_002Escc_005Ccode_005CAssembly_002Ecs/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005Chamit_005Fba31xcg_005CDocuments_005Cs_0026box_0020projects_005Ckakozuzo_005F2_005CLibraries_005Cfish_002Escc_005Cscc_002Esbproj/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
</wpf:ResourceDictionary>
|