mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-25 22:23:42 +08:00
Merge branch 'spine-ue4'
This commit is contained in:
commit
0de00d6178
9
.gitignore
vendored
9
.gitignore
vendored
@ -104,3 +104,12 @@ spine-turbulenz/spine-js/spine.js
|
||||
spine-threejs/spine-js/spine.js
|
||||
|
||||
spine-ts/.vscode/*
|
||||
|
||||
spine-ue4/Binaries
|
||||
spine-ue4/Intermediate
|
||||
spine-ue4/Saved
|
||||
spine-ue4/SpineUE4.xcworkspace
|
||||
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/spine-c
|
||||
spine-ue4/Plugins/SpinePlugin/Binaries
|
||||
spine-ue4/SpineUE4.VC.opendb
|
||||
spine-ue4/SpineUE4.sln
|
||||
|
||||
5
spine-ue4/Config/DefaultEditor.ini
Normal file
5
spine-ue4/Config/DefaultEditor.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[EditoronlyBP]
|
||||
bAllowClassAndBlueprintPinMatching=true
|
||||
bReplaceBlueprintWithClass=true
|
||||
bDontLoadBlueprintOutsideEditor=true
|
||||
bBlueprintIsNotBlueprintType=true
|
||||
9
spine-ue4/Config/DefaultEngine.ini
Normal file
9
spine-ue4/Config/DefaultEngine.ini
Normal file
@ -0,0 +1,9 @@
|
||||
[URL]
|
||||
|
||||
[/Script/HardwareTargeting.HardwareTargetingSettings]
|
||||
TargetedHardwareClass=Desktop
|
||||
AppliedTargetedHardwareClass=Desktop
|
||||
DefaultGraphicsPerformance=Maximum
|
||||
AppliedDefaultGraphicsPerformance=Maximum
|
||||
|
||||
|
||||
2
spine-ue4/Config/DefaultGame.ini
Normal file
2
spine-ue4/Config/DefaultGame.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[/Script/EngineSettings.GeneralProjectSettings]
|
||||
ProjectID=A32BDAC45F432EB90DF445842A670D58
|
||||
BIN
spine-ue4/Content/GettingStarted/01-basic-animation.umap
Normal file
BIN
spine-ue4/Content/GettingStarted/01-basic-animation.umap
Normal file
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/01-basic-animation_2.uasset
Normal file
BIN
spine-ue4/Content/GettingStarted/01-basic-animation_2.uasset
Normal file
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/02-complex-animation.umap
Normal file
BIN
spine-ue4/Content/GettingStarted/02-complex-animation.umap
Normal file
Binary file not shown.
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/04-basic-controls.umap
Normal file
BIN
spine-ue4/Content/GettingStarted/04-basic-controls.umap
Normal file
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/05-driving-bones.umap
Normal file
BIN
spine-ue4/Content/GettingStarted/05-driving-bones.umap
Normal file
Binary file not shown.
279
spine-ue4/Content/GettingStarted/Assets/Doi/Doi-atlas.atlas
Normal file
279
spine-ue4/Content/GettingStarted/Assets/Doi/Doi-atlas.atlas
Normal file
@ -0,0 +1,279 @@
|
||||
|
||||
Doi.png
|
||||
size: 646,520
|
||||
format: RGBA8888
|
||||
filter: Linear,Linear
|
||||
repeat: none
|
||||
armL
|
||||
rotate: false
|
||||
xy: 1, 46
|
||||
size: 163, 133
|
||||
orig: 163, 133
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
armR
|
||||
rotate: true
|
||||
xy: 165, 46
|
||||
size: 133, 109
|
||||
orig: 133, 109
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
arrow
|
||||
rotate: true
|
||||
xy: 467, 1
|
||||
size: 64, 85
|
||||
orig: 64, 85
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
body
|
||||
rotate: false
|
||||
xy: 1, 180
|
||||
size: 274, 339
|
||||
orig: 274, 339
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
bootR
|
||||
rotate: false
|
||||
xy: 499, 258
|
||||
size: 91, 84
|
||||
orig: 91, 84
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
browL
|
||||
rotate: false
|
||||
xy: 228, 23
|
||||
size: 40, 22
|
||||
orig: 40, 22
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
browR
|
||||
rotate: true
|
||||
xy: 591, 287
|
||||
size: 32, 25
|
||||
orig: 32, 25
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
eyelids closed
|
||||
rotate: false
|
||||
xy: 276, 201
|
||||
size: 183, 92
|
||||
orig: 183, 92
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
eyelids open
|
||||
rotate: true
|
||||
xy: 499, 343
|
||||
size: 176, 89
|
||||
orig: 176, 89
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hairL
|
||||
rotate: false
|
||||
xy: 589, 459
|
||||
size: 54, 60
|
||||
orig: 54, 60
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hairL2
|
||||
rotate: false
|
||||
xy: 553, 4
|
||||
size: 71, 76
|
||||
orig: 71, 76
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hairM
|
||||
rotate: true
|
||||
xy: 467, 66
|
||||
size: 96, 77
|
||||
orig: 96, 77
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hairM blob
|
||||
rotate: true
|
||||
xy: 133, 15
|
||||
size: 30, 45
|
||||
orig: 30, 45
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hairM blobS
|
||||
rotate: false
|
||||
xy: 545, 142
|
||||
size: 16, 20
|
||||
orig: 16, 20
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hairR
|
||||
rotate: true
|
||||
xy: 1, 4
|
||||
size: 41, 83
|
||||
orig: 41, 83
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hairR2
|
||||
rotate: true
|
||||
xy: 460, 163
|
||||
size: 94, 101
|
||||
orig: 94, 101
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hairSide
|
||||
rotate: false
|
||||
xy: 179, 21
|
||||
size: 48, 24
|
||||
orig: 48, 24
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
head
|
||||
rotate: false
|
||||
xy: 276, 294
|
||||
size: 222, 225
|
||||
orig: 222, 225
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
indexL
|
||||
rotate: true
|
||||
xy: 405, 7
|
||||
size: 24, 36
|
||||
orig: 24, 36
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
indexR
|
||||
rotate: false
|
||||
xy: 296, 3
|
||||
size: 34, 28
|
||||
orig: 34, 28
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
inmouth
|
||||
rotate: false
|
||||
xy: 589, 403
|
||||
size: 46, 55
|
||||
orig: 46, 55
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
irisL
|
||||
rotate: true
|
||||
xy: 85, 11
|
||||
size: 34, 47
|
||||
orig: 34, 47
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
irisL flatspec
|
||||
rotate: false
|
||||
xy: 625, 70
|
||||
size: 19, 10
|
||||
orig: 19, 10
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
irisL spec
|
||||
rotate: true
|
||||
xy: 624, 384
|
||||
size: 18, 21
|
||||
orig: 18, 21
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
irisR
|
||||
rotate: false
|
||||
xy: 589, 355
|
||||
size: 34, 47
|
||||
orig: 34, 47
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
irisR flatspec
|
||||
rotate: true
|
||||
xy: 445, 178
|
||||
size: 22, 11
|
||||
orig: 22, 11
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
irisR spec
|
||||
rotate: false
|
||||
xy: 545, 124
|
||||
size: 16, 17
|
||||
orig: 16, 17
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
middleL
|
||||
rotate: true
|
||||
xy: 331, 5
|
||||
size: 26, 36
|
||||
orig: 26, 36
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
middleR
|
||||
rotate: true
|
||||
xy: 591, 320
|
||||
size: 34, 26
|
||||
orig: 34, 26
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth
|
||||
rotate: true
|
||||
xy: 562, 168
|
||||
size: 89, 83
|
||||
orig: 89, 83
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
nose
|
||||
rotate: false
|
||||
xy: 545, 113
|
||||
size: 11, 10
|
||||
orig: 11, 10
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
pinkyL
|
||||
rotate: false
|
||||
xy: 442, 4
|
||||
size: 24, 27
|
||||
orig: 24, 27
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
pony1
|
||||
rotate: false
|
||||
xy: 394, 32
|
||||
size: 72, 105
|
||||
orig: 72, 105
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
pony2
|
||||
rotate: true
|
||||
xy: 562, 81
|
||||
size: 86, 83
|
||||
orig: 86, 83
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
ringL
|
||||
rotate: false
|
||||
xy: 269, 1
|
||||
size: 26, 30
|
||||
orig: 26, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rotate
|
||||
rotate: true
|
||||
xy: 275, 32
|
||||
size: 105, 118
|
||||
orig: 105, 118
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
strap
|
||||
rotate: true
|
||||
xy: 276, 138
|
||||
size: 62, 168
|
||||
orig: 62, 168
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
thumbL
|
||||
rotate: false
|
||||
xy: 460, 265
|
||||
size: 37, 28
|
||||
orig: 37, 28
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
thumbR
|
||||
rotate: false
|
||||
xy: 368, 6
|
||||
size: 36, 25
|
||||
orig: 36, 25
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
BIN
spine-ue4/Content/GettingStarted/Assets/Doi/Doi-atlas.uasset
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Doi/Doi-atlas.uasset
Normal file
Binary file not shown.
2526
spine-ue4/Content/GettingStarted/Assets/Doi/Doi-data.json
Normal file
2526
spine-ue4/Content/GettingStarted/Assets/Doi/Doi-data.json
Normal file
File diff suppressed because one or more lines are too long
BIN
spine-ue4/Content/GettingStarted/Assets/Doi/Doi-data.uasset
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Doi/Doi-data.uasset
Normal file
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/Assets/Doi/Doi.png
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Doi/Doi.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
BIN
spine-ue4/Content/GettingStarted/Assets/Doi/Textures/Doi.uasset
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Doi/Textures/Doi.uasset
Normal file
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 487 KiB |
Binary file not shown.
@ -0,0 +1,251 @@
|
||||
|
||||
raptor.png
|
||||
size: 1022,1022
|
||||
format: RGBA8888
|
||||
filter: Linear,Linear
|
||||
repeat: none
|
||||
back_arm
|
||||
rotate: false
|
||||
xy: 410, 545
|
||||
size: 46, 29
|
||||
orig: 46, 29
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
back_bracer
|
||||
rotate: false
|
||||
xy: 540, 548
|
||||
size: 39, 28
|
||||
orig: 39, 28
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
back_hand
|
||||
rotate: true
|
||||
xy: 504, 538
|
||||
size: 36, 34
|
||||
orig: 36, 34
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
back_knee
|
||||
rotate: false
|
||||
xy: 299, 478
|
||||
size: 49, 67
|
||||
orig: 49, 67
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
back_thigh
|
||||
rotate: true
|
||||
xy: 140, 247
|
||||
size: 39, 24
|
||||
orig: 39, 24
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
eyes_open
|
||||
rotate: true
|
||||
xy: 2, 2
|
||||
size: 47, 45
|
||||
orig: 47, 45
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_arm
|
||||
rotate: false
|
||||
xy: 360, 544
|
||||
size: 48, 30
|
||||
orig: 48, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_bracer
|
||||
rotate: false
|
||||
xy: 538, 578
|
||||
size: 41, 29
|
||||
orig: 41, 29
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_hand
|
||||
rotate: false
|
||||
xy: 538, 609
|
||||
size: 41, 38
|
||||
orig: 41, 38
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_open_hand
|
||||
rotate: false
|
||||
xy: 894, 782
|
||||
size: 43, 44
|
||||
orig: 43, 44
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_thigh
|
||||
rotate: false
|
||||
xy: 942, 849
|
||||
size: 57, 29
|
||||
orig: 57, 29
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
gun
|
||||
rotate: false
|
||||
xy: 785, 774
|
||||
size: 107, 103
|
||||
orig: 107, 103
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
gun_nohand
|
||||
rotate: false
|
||||
xy: 614, 703
|
||||
size: 105, 102
|
||||
orig: 105, 102
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
head
|
||||
rotate: false
|
||||
xy: 2, 137
|
||||
size: 136, 149
|
||||
orig: 136, 149
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
lower_leg
|
||||
rotate: true
|
||||
xy: 780, 699
|
||||
size: 73, 98
|
||||
orig: 73, 98
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth_smile
|
||||
rotate: true
|
||||
xy: 49, 2
|
||||
size: 47, 30
|
||||
orig: 47, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
neck
|
||||
rotate: true
|
||||
xy: 1001, 860
|
||||
size: 18, 21
|
||||
orig: 18, 21
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_arm_back
|
||||
rotate: false
|
||||
xy: 940, 936
|
||||
size: 82, 86
|
||||
orig: 82, 86
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_body
|
||||
rotate: false
|
||||
xy: 2, 737
|
||||
size: 610, 285
|
||||
orig: 610, 285
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_front_arm
|
||||
rotate: true
|
||||
xy: 195, 464
|
||||
size: 81, 102
|
||||
orig: 81, 102
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_front_leg
|
||||
rotate: false
|
||||
xy: 2, 478
|
||||
size: 191, 257
|
||||
orig: 191, 257
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_hindleg_back
|
||||
rotate: false
|
||||
xy: 614, 807
|
||||
size: 169, 215
|
||||
orig: 169, 215
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_horn
|
||||
rotate: false
|
||||
xy: 360, 655
|
||||
size: 182, 80
|
||||
orig: 182, 80
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_horn_back
|
||||
rotate: false
|
||||
xy: 360, 576
|
||||
size: 176, 77
|
||||
orig: 176, 77
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_jaw
|
||||
rotate: false
|
||||
xy: 785, 879
|
||||
size: 153, 143
|
||||
orig: 153, 143
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_saddle_noshadow
|
||||
rotate: false
|
||||
xy: 2, 288
|
||||
size: 163, 188
|
||||
orig: 163, 188
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_saddle_strap_front
|
||||
rotate: false
|
||||
xy: 721, 710
|
||||
size: 57, 95
|
||||
orig: 57, 95
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_saddle_strap_rear
|
||||
rotate: true
|
||||
xy: 940, 880
|
||||
size: 54, 74
|
||||
orig: 54, 74
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_saddle_w_shadow
|
||||
rotate: false
|
||||
xy: 195, 547
|
||||
size: 163, 188
|
||||
orig: 163, 188
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor_tongue
|
||||
rotate: true
|
||||
xy: 544, 649
|
||||
size: 86, 64
|
||||
orig: 86, 64
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
stirrup_back
|
||||
rotate: false
|
||||
xy: 458, 539
|
||||
size: 44, 35
|
||||
orig: 44, 35
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
stirrup_front
|
||||
rotate: true
|
||||
xy: 81, 4
|
||||
size: 45, 50
|
||||
orig: 45, 50
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
stirrup_strap
|
||||
rotate: true
|
||||
xy: 894, 828
|
||||
size: 49, 46
|
||||
orig: 49, 46
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
torso
|
||||
rotate: true
|
||||
xy: 610, 647
|
||||
size: 54, 91
|
||||
orig: 54, 91
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
visor
|
||||
rotate: false
|
||||
xy: 2, 51
|
||||
size: 131, 84
|
||||
orig: 131, 84
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Binary file not shown.
2750
spine-ue4/Content/GettingStarted/Assets/Raptor/raptor-data.json
Normal file
2750
spine-ue4/Content/GettingStarted/Assets/Raptor/raptor-data.json
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/Assets/Sounds/Footstep.uasset
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Sounds/Footstep.uasset
Normal file
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/Assets/Sounds/Footstep.wav
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Sounds/Footstep.wav
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,216 @@
|
||||
|
||||
spineboy-hover.png
|
||||
size: 1024,1024
|
||||
format: RGBA8888
|
||||
filter: Linear,Linear
|
||||
repeat: none
|
||||
eye_indifferent
|
||||
rotate: true
|
||||
xy: 648, 629
|
||||
size: 93, 89
|
||||
orig: 93, 89
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
eye_surprised
|
||||
rotate: true
|
||||
xy: 233, 179
|
||||
size: 93, 89
|
||||
orig: 93, 89
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_bracer
|
||||
rotate: false
|
||||
xy: 245, 2
|
||||
size: 58, 80
|
||||
orig: 58, 80
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_fist_closed
|
||||
rotate: false
|
||||
xy: 168, 45
|
||||
size: 75, 82
|
||||
orig: 75, 82
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_fist_open
|
||||
rotate: false
|
||||
xy: 844, 646
|
||||
size: 86, 87
|
||||
orig: 86, 87
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_foot
|
||||
rotate: true
|
||||
xy: 310, 326
|
||||
size: 126, 69
|
||||
orig: 126, 69
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_foot_bend1
|
||||
rotate: true
|
||||
xy: 951, 894
|
||||
size: 128, 70
|
||||
orig: 128, 70
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_foot_bend2
|
||||
rotate: false
|
||||
xy: 2, 33
|
||||
size: 108, 93
|
||||
orig: 108, 93
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_shin
|
||||
rotate: true
|
||||
xy: 739, 735
|
||||
size: 82, 184
|
||||
orig: 82, 184
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_thigh
|
||||
rotate: false
|
||||
xy: 381, 340
|
||||
size: 48, 112
|
||||
orig: 48, 112
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_upper_arm
|
||||
rotate: false
|
||||
xy: 112, 29
|
||||
size: 54, 97
|
||||
orig: 54, 97
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
goggles
|
||||
rotate: false
|
||||
xy: 156, 454
|
||||
size: 261, 166
|
||||
orig: 261, 166
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
gun
|
||||
rotate: false
|
||||
xy: 739, 819
|
||||
size: 210, 203
|
||||
orig: 210, 203
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
head
|
||||
rotate: false
|
||||
xy: 466, 724
|
||||
size: 271, 298
|
||||
orig: 271, 298
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hoverboard_board
|
||||
rotate: true
|
||||
xy: 2, 128
|
||||
size: 492, 152
|
||||
orig: 492, 152
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hoverboard_thruster
|
||||
rotate: false
|
||||
xy: 602, 558
|
||||
size: 60, 64
|
||||
orig: 60, 64
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hoverglow_small
|
||||
rotate: true
|
||||
xy: 156, 178
|
||||
size: 274, 75
|
||||
orig: 274, 75
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth_grind
|
||||
rotate: true
|
||||
xy: 951, 799
|
||||
size: 93, 59
|
||||
orig: 93, 59
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth_oooo
|
||||
rotate: true
|
||||
xy: 245, 84
|
||||
size: 93, 59
|
||||
orig: 93, 59
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth_smile
|
||||
rotate: false
|
||||
xy: 925, 738
|
||||
size: 93, 59
|
||||
orig: 93, 59
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle
|
||||
rotate: false
|
||||
xy: 2, 622
|
||||
size: 462, 400
|
||||
orig: 462, 400
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
neck
|
||||
rotate: false
|
||||
xy: 168, 2
|
||||
size: 36, 41
|
||||
orig: 36, 41
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_bracer
|
||||
rotate: false
|
||||
xy: 932, 664
|
||||
size: 56, 72
|
||||
orig: 56, 72
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_foot
|
||||
rotate: false
|
||||
xy: 487, 562
|
||||
size: 113, 60
|
||||
orig: 113, 60
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_foot_bend1
|
||||
rotate: true
|
||||
xy: 419, 503
|
||||
size: 117, 66
|
||||
orig: 117, 66
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_foot_bend2
|
||||
rotate: false
|
||||
xy: 739, 650
|
||||
size: 103, 83
|
||||
orig: 103, 83
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_shin
|
||||
rotate: false
|
||||
xy: 233, 274
|
||||
size: 75, 178
|
||||
orig: 75, 178
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_thigh
|
||||
rotate: true
|
||||
xy: 487, 495
|
||||
size: 65, 104
|
||||
orig: 65, 104
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_upper_arm
|
||||
rotate: true
|
||||
xy: 156, 129
|
||||
size: 47, 87
|
||||
orig: 47, 87
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
torso
|
||||
rotate: true
|
||||
xy: 466, 624
|
||||
size: 98, 180
|
||||
orig: 98, 180
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
@ -0,0 +1,960 @@
|
||||
{
|
||||
"skeleton": {
|
||||
"hash": "Vw3hWCw+PV8Q6kMU7bcyWS2a+uw",
|
||||
"spine": "3.5.03-beta",
|
||||
"width": 511.47,
|
||||
"height": 739.87,
|
||||
"fps": 30,
|
||||
"images": "./images/"
|
||||
},
|
||||
"bones": [
|
||||
{ "name": "root" },
|
||||
{ "name": "hip", "parent": "root", "x": -49.89, "y": 290.95 },
|
||||
{ "name": "hoverboard", "parent": "root", "length": 72.32, "x": 9.9, "y": 57.05 },
|
||||
{ "name": "rear_foot_ik", "parent": "hoverboard", "rotation": -0.97, "x": 83.75, "y": 21.7, "color": "ff3f00ff" },
|
||||
{ "name": "rear_ankle_ik", "parent": "rear_foot_ik", "x": -33.9, "y": 37.33, "color": "ff3f00ff" },
|
||||
{ "name": "rear_thigh", "parent": "hip", "length": 85.7, "rotation": -72.54, "x": 8.9, "y": -5.61, "color": "ff000dff" },
|
||||
{ "name": "rear_shin", "parent": "rear_thigh", "length": 121.87, "rotation": -19.82, "x": 86.09, "y": -1.32, "color": "ff000dff" },
|
||||
{ "name": "rear_foot", "parent": "rear_shin", "length": 51.58, "rotation": 45.77, "x": 121.44, "y": -0.75, "color": "ff000dff" },
|
||||
{ "name": "rear_toe_ik", "parent": "hoverboard", "rotation": -0.97, "x": 135.05, "y": 20.47, "color": "ff3f00ff" },
|
||||
{ "name": "back_foot_tip", "parent": "rear_foot", "length": 50.29, "rotation": 46.61, "x": 51.15, "y": 0.23, "color": "ff000dff" },
|
||||
{ "name": "exhaust1", "parent": "hoverboard", "rotation": 3.19, "x": -249.74, "y": 52.63 },
|
||||
{ "name": "exhaust2", "parent": "hoverboard", "rotation": 26.5, "x": -191.57, "y": -23.5 },
|
||||
{ "name": "front_foot_ik", "parent": "hoverboard", "rotation": -16.95, "x": -100.29, "y": 23.95, "color": "ff3f00ff" },
|
||||
{ "name": "front_ankle_ik", "parent": "front_foot_ik", "x": -28.38, "y": 29.05, "color": "ff3f00ff" },
|
||||
{ "name": "torso", "parent": "hip", "length": 127.55, "rotation": 64.59, "x": -1.61, "y": 4.9, "color": "e0da19ff" },
|
||||
{ "name": "front_upper_arm", "parent": "torso", "length": 69.44, "rotation": 125.79, "x": 103.75, "y": 19.31, "color": "00ff04ff" },
|
||||
{
|
||||
"name": "front_bracer",
|
||||
"parent": "front_upper_arm",
|
||||
"length": 40.56,
|
||||
"rotation": 18.29,
|
||||
"x": 68.8,
|
||||
"y": -0.68,
|
||||
"color": "00ff04ff"
|
||||
},
|
||||
{ "name": "front_fist", "parent": "front_bracer", "length": 65.37, "rotation": 12.43, "x": 40.56, "y": 0.18, "color": "00ff04ff" },
|
||||
{ "name": "front_thigh", "parent": "hip", "length": 74.8, "rotation": -95.51, "x": -17.45, "y": -11.64, "color": "00ff04ff" },
|
||||
{ "name": "front_shin", "parent": "front_thigh", "length": 128.75, "rotation": -2.21, "x": 78.69, "y": 1.6, "color": "00ff04ff" },
|
||||
{ "name": "front_foot", "parent": "front_shin", "length": 41, "rotation": 51.25, "x": 128.75, "y": -0.33, "color": "00ff04ff" },
|
||||
{ "name": "front_toe_ik", "parent": "hoverboard", "rotation": -0.97, "x": -44.59, "y": 21.98, "color": "ff3f00ff" },
|
||||
{
|
||||
"name": "front_foot_tip",
|
||||
"parent": "front_foot",
|
||||
"length": 56.02,
|
||||
"rotation": 44.29,
|
||||
"x": 41.41,
|
||||
"y": -0.07,
|
||||
"color": "00ff04ff"
|
||||
},
|
||||
{ "name": "rear_upper_arm", "parent": "torso", "length": 51.93, "rotation": -153.6, "x": 92.34, "y": -19.21, "color": "ff000dff" },
|
||||
{ "name": "rear_bracer", "parent": "rear_upper_arm", "length": 34.54, "rotation": 43.56, "x": 51.34, "color": "ff000dff" },
|
||||
{ "name": "gun", "parent": "rear_bracer", "length": 43.09, "rotation": 17.61, "x": 34.41, "y": -0.44, "color": "ff000dff" },
|
||||
{ "name": "gunTip", "parent": "gun", "rotation": 6.82, "x": 201.03, "y": 52.13, "color": "ff000dff" },
|
||||
{ "name": "neck", "parent": "torso", "length": 25.45, "rotation": -31.53, "x": 127.48, "y": -0.3, "color": "e0da19ff" },
|
||||
{ "name": "head", "parent": "neck", "length": 131.78, "rotation": 51.9, "x": 27.65, "y": -0.25, "color": "e0da19ff" },
|
||||
{ "name": "hair1", "parent": "head", "length": 47.22, "rotation": -49.09, "x": 149.82, "y": -59.77, "color": "e0da19ff" },
|
||||
{ "name": "hair2", "parent": "hair1", "length": 55.56, "rotation": 50.4, "x": 47.22, "y": 0.18, "color": "e0da19ff" },
|
||||
{ "name": "hair3", "parent": "head", "length": 62.22, "rotation": -32.15, "x": 164.13, "y": 3.68, "color": "e0da19ff" },
|
||||
{ "name": "hair4", "parent": "hair3", "length": 80.27, "rotation": 83.69, "x": 62.22, "y": -0.02, "color": "e0da19ff" },
|
||||
{
|
||||
"name": "hoverboard_thruster_front",
|
||||
"parent": "hoverboard",
|
||||
"rotation": -29.03,
|
||||
"x": 95.77,
|
||||
"y": -2.7,
|
||||
"transform": "noRotationOrReflection"
|
||||
},
|
||||
{
|
||||
"name": "hoverboard_thruster_rear",
|
||||
"parent": "hoverboard",
|
||||
"rotation": -29.03,
|
||||
"x": -76.46,
|
||||
"y": -5.11,
|
||||
"transform": "noRotationOrReflection"
|
||||
},
|
||||
{ "name": "hoverglow_front", "parent": "hoverboard_thruster_front", "x": -1.88, "y": -37.77 },
|
||||
{ "name": "hoverglow_rear", "parent": "hoverboard_thruster_rear", "x": 0.94, "y": -35.65 }
|
||||
],
|
||||
"slots": [
|
||||
{ "name": "hoverboard_thruster_rear", "bone": "hoverboard_thruster_rear", "attachment": "hoverboard_thruster" },
|
||||
{ "name": "hoverboard_thruster_front", "bone": "hoverboard_thruster_front", "attachment": "hoverboard_thruster" },
|
||||
{ "name": "hoverboard_board", "bone": "hoverboard", "attachment": "hoverboard_board" },
|
||||
{ "name": "rear_upper_arm", "bone": "rear_upper_arm", "attachment": "rear_upper_arm" },
|
||||
{ "name": "rear_bracer", "bone": "rear_bracer", "attachment": "rear_bracer" },
|
||||
{ "name": "gun", "bone": "gun", "attachment": "gun" },
|
||||
{ "name": "rear_foot", "bone": "rear_foot", "attachment": "rear_foot" },
|
||||
{ "name": "rear_thigh", "bone": "rear_thigh", "attachment": "rear_thigh" },
|
||||
{ "name": "rear_shin", "bone": "rear_shin", "attachment": "rear_shin" },
|
||||
{ "name": "neck", "bone": "neck", "attachment": "neck" },
|
||||
{ "name": "torso", "bone": "torso", "attachment": "torso" },
|
||||
{ "name": "front_upper_arm", "bone": "front_upper_arm", "attachment": "front_upper_arm" },
|
||||
{ "name": "head", "bone": "head", "attachment": "head" },
|
||||
{ "name": "eye", "bone": "head", "attachment": "eye_indifferent" },
|
||||
{ "name": "front_thigh", "bone": "front_thigh", "attachment": "front_thigh" },
|
||||
{ "name": "front_foot", "bone": "front_foot", "attachment": "front_foot" },
|
||||
{ "name": "front_shin", "bone": "front_shin", "attachment": "front_shin" },
|
||||
{ "name": "mouth", "bone": "head", "attachment": "mouth_smile" },
|
||||
{ "name": "goggles", "bone": "head", "attachment": "goggles" },
|
||||
{ "name": "front_bracer", "bone": "front_bracer", "attachment": "front_bracer" },
|
||||
{ "name": "front_fist", "bone": "front_fist", "attachment": "front_fist_closed" },
|
||||
{ "name": "muzzle", "bone": "gunTip", "blend": "additive" },
|
||||
{ "name": "head-bb", "bone": "head" },
|
||||
{ "name": "hoverglow_front", "bone": "hoverglow_front", "attachment": "hoverglow_small", "blend": "additive" },
|
||||
{ "name": "hoverglow_rear", "bone": "hoverglow_rear", "attachment": "hoverglow_small", "blend": "additive" },
|
||||
{ "name": "exhaust1", "bone": "exhaust2", "color": "ffffff98", "attachment": "hoverglow_small", "blend": "additive" },
|
||||
{ "name": "exhaust2", "bone": "exhaust1", "color": "ffffff98", "attachment": "hoverglow_small", "blend": "additive" }
|
||||
],
|
||||
"ik": [
|
||||
{
|
||||
"name": "front_ankle_ik",
|
||||
"order": 0,
|
||||
"bones": [ "front_thigh", "front_shin" ],
|
||||
"target": "front_ankle_ik",
|
||||
"bendPositive": false
|
||||
},
|
||||
{
|
||||
"name": "front_foot_ik",
|
||||
"order": 1,
|
||||
"bones": [ "front_foot" ],
|
||||
"target": "front_foot_ik"
|
||||
},
|
||||
{
|
||||
"name": "front_toe_ik",
|
||||
"order": 2,
|
||||
"bones": [ "front_foot_tip" ],
|
||||
"target": "front_toe_ik"
|
||||
},
|
||||
{
|
||||
"name": "rear_ankle_ik",
|
||||
"order": 3,
|
||||
"bones": [ "rear_thigh", "rear_shin" ],
|
||||
"target": "rear_ankle_ik",
|
||||
"bendPositive": false
|
||||
},
|
||||
{
|
||||
"name": "rear_foot_ik",
|
||||
"order": 4,
|
||||
"bones": [ "rear_foot" ],
|
||||
"target": "rear_foot_ik"
|
||||
},
|
||||
{
|
||||
"name": "rear_toe_ik",
|
||||
"order": 5,
|
||||
"bones": [ "back_foot_tip" ],
|
||||
"target": "rear_toe_ik"
|
||||
}
|
||||
],
|
||||
"skins": {
|
||||
"default": {
|
||||
"exhaust1": {
|
||||
"hoverglow_small": { "scaleX": 0.462, "scaleY": 0.812, "rotation": -83.09, "width": 274, "height": 75 }
|
||||
},
|
||||
"exhaust2": {
|
||||
"hoverglow_small": { "y": -0.76, "scaleX": 0.413, "scaleY": 0.487, "rotation": -89.24, "width": 274, "height": 75 }
|
||||
},
|
||||
"eye": {
|
||||
"eye_indifferent": {
|
||||
"type": "mesh",
|
||||
"uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ],
|
||||
"triangles": [ 1, 3, 0, 1, 2, 3 ],
|
||||
"vertices": [ 59.15, -86.8, 28.30999, 0.92, 112.26, 30.44, 143.11, -57.27 ],
|
||||
"hull": 4,
|
||||
"edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ],
|
||||
"width": 93,
|
||||
"height": 89
|
||||
},
|
||||
"eye_surprised": { "x": 85.72, "y": -28.18, "rotation": -70.62, "width": 93, "height": 89 }
|
||||
},
|
||||
"front_bracer": {
|
||||
"front_bracer": { "x": 12.02, "y": -1.66, "rotation": 79.58, "width": 58, "height": 80 }
|
||||
},
|
||||
"front_fist": {
|
||||
"front_fist_closed": { "x": 35.49, "y": 6, "rotation": 67.16, "width": 75, "height": 82 },
|
||||
"front_fist_open": { "x": 39.56, "y": 7.76, "rotation": 67.16, "width": 86, "height": 87 }
|
||||
},
|
||||
"front_foot": {
|
||||
"front_foot": {
|
||||
"type": "mesh",
|
||||
"uvs": [ 0.59416, 0.2342, 0.62256, 0.30335, 0.65008, 0.37035, 0.67637, 0.38403, 0.72067, 0.40709, 0.76263, 0.42893, 1, 0.70375, 1, 1, 0.65517, 1, 0.36439, 1, 0, 1, 0, 0.39195, 0, 0, 0.17845, 0, 0.49794, 0 ],
|
||||
"triangles": [ 8, 9, 3, 4, 8, 3, 8, 4, 5, 8, 5, 6, 8, 6, 7, 11, 12, 13, 11, 1, 10, 13, 14, 0, 0, 11, 13, 1, 11, 0, 2, 9, 10, 2, 10, 1, 9, 2, 3 ],
|
||||
"vertices": [ 2, 20, 18.17, 41.56, 0.72254, 22, 12.46, 46.04, 0.27744, 2, 20, 24.06999, 40.75, 0.57406, 22, 16.12, 41.34, 0.42592, 2, 20, 29.79, 39.97, 0.47663, 22, 19.67, 36.77, 0.52336, 2, 20, 32.79, 41.65, 0.37452, 22, 22.97999, 35.88, 0.62546, 2, 20, 37.86, 44.5, 0.24772, 22, 28.6, 34.4, 0.75226, 2, 20, 42.65, 47.2, 0.17781, 22, 33.9, 32.97, 0.82216, 1, 22, 64.15, 14.56, 1, 1, 22, 64.51, -5.86, 1, 1, 22, 21.05999, -6.63, 1, 2, 20, 35.38, -16.14999, 0.99997, 22, -15.52999, -7.28, 0, 1, 20, 3.08999, -48.81, 1, 1, 20, -26.70999, -19.29999, 1, 1, 20, -45.95, -0.28, 1, 1, 20, -30.12999, 15.68, 1, 2, 20, -1.84, 44.31, 0.91509, 22, 0.05, 61.97, 0.08488 ],
|
||||
"hull": 15,
|
||||
"edges": [ 14, 16, 16, 18, 18, 20, 4, 18, 20, 22, 22, 24, 24, 26, 26, 28, 22, 26, 12, 14, 10, 12, 2, 4, 2, 20, 4, 6, 6, 16, 2, 0, 0, 28, 6, 8, 8, 10 ],
|
||||
"width": 126,
|
||||
"height": 69
|
||||
},
|
||||
"front_foot_bend1": { "x": 22.86, "y": 20.23, "rotation": 45.31, "width": 128, "height": 70 },
|
||||
"front_foot_bend2": { "x": 8.15, "y": 19.56, "rotation": 45.31, "width": 108, "height": 93 }
|
||||
},
|
||||
"front_shin": {
|
||||
"front_shin": { "x": 60.91, "y": -3.9, "rotation": 96.58, "width": 82, "height": 184 }
|
||||
},
|
||||
"front_thigh": {
|
||||
"front_thigh": { "x": 42.47, "y": 4.44, "rotation": 84.86, "width": 48, "height": 112 }
|
||||
},
|
||||
"front_upper_arm": {
|
||||
"front_upper_arm": { "x": 28.29, "y": 7.36, "rotation": 97.88, "width": 54, "height": 97 }
|
||||
},
|
||||
"goggles": {
|
||||
"goggles": {
|
||||
"type": "mesh",
|
||||
"uvs": [ 0.53653, 0.04112, 0.72921, 0.16034, 0.91666, 0.33221, 0.97045, 0.31328, 1, 0.48052, 0.95754, 0.57328, 0.88824, 0.63279, 0.86877, 0.78961, 0.77403, 0.86748, 0.72627, 1, 0.60712, 0.93861, 0.49599, 0.88138, 0.41556, 0.75025, 0.32547, 0.70083, 0.2782, 0.58256, 0.17208, 0.6328, 0.17227, 0.75071, 0.10779, 0.79896, 0, 0.32304, 0, 0.12475, 0.07372, 0.07343, 0.15422, 0.10733, 0.23164, 0.13993, 0.30313, 0.02256, 0.34801, 0, 0.42978, 0.69182, 0.39474, 0.51041, 0.39487, 0.3151, 0.45877, 0.23196, 0.56501, 0.28108, 0.69959, 0.39215, 0.82038, 0.54202, 0.85737, 0.62342, 0.91106, 0.51406, 0.72637, 0.32146, 0.58762, 0.19608, 0.48074, 0.11268, 0.37821, 0.055, 0.32868, 0.17866, 0.31898, 0.30498, 0.36035, 0.53798, 0.40327, 0.70072, 0.30057, 0.55836, 0.21955, 0.2815, 0.09962, 0.28942, 0.56862, 0.4368, 0.4911, 0.37156, 0.51183, 0.52091, 0.67018, 0.59302, 0.7619, 0.68573, 0.73295, 0.43353 ],
|
||||
"triangles": [ 49, 8, 48, 9, 48, 8, 12, 25, 11, 48, 9, 10, 47, 48, 10, 47, 10, 25, 25, 10, 11, 8, 49, 7, 17, 15, 16, 17, 18, 15, 49, 32, 7, 7, 32, 6, 41, 42, 40, 12, 41, 25, 41, 12, 42, 13, 14, 42, 12, 13, 42, 41, 40, 25, 40, 26, 25, 25, 26, 47, 49, 31, 32, 31, 49, 50, 18, 44, 15, 42, 14, 44, 14, 15, 44, 5, 6, 33, 6, 32, 33, 32, 31, 33, 47, 45, 48, 49, 48, 50, 50, 45, 30, 50, 48, 45, 42, 44, 43, 5, 33, 4, 42, 39, 40, 42, 43, 39, 31, 50, 33, 40, 39, 26, 45, 47, 46, 33, 2, 4, 2, 33, 34, 47, 26, 46, 26, 27, 46, 26, 39, 27, 2, 3, 4, 30, 45, 29, 30, 34, 50, 33, 50, 34, 45, 46, 29, 30, 29, 34, 27, 28, 46, 46, 28, 29, 18, 19, 44, 29, 35, 34, 2, 34, 1, 34, 35, 1, 28, 27, 38, 27, 39, 38, 39, 43, 38, 44, 19, 21, 44, 21, 43, 21, 19, 20, 43, 22, 38, 43, 21, 22, 29, 28, 35, 28, 36, 35, 28, 38, 36, 36, 0, 35, 35, 0, 1, 22, 23, 38, 38, 37, 36, 37, 23, 24, 37, 38, 23, 36, 37, 0, 37, 24, 0 ],
|
||||
"vertices": [ 172.08, 22.79999, 170.08, -31.19, 159.41, -86.8, 167.02, -99, 143.38998, -115.48, 125.19, -110.12999, 109.87, -96.33999, 83.62999, -100.19, 63.25, -81.15, 38.36, -76.69, 37.65, -43.97, 37, -13.47, 50.56, 13.52999, 50.5, 38.45, 64.94, 56.59, 47.88, 79.94, 29.45, 73.41, 16.29999, 86.62, 81.5, 139.38, 112.55, 150.27998, 126.97, 134.97, 128.63, 113.26999, 130.22, 92.43, 154.77998, 81.29, 162.21, 71.48, 60.95, 13.26, 86.33, 31.87, 116.91, 42.59, 135.47, 31.44, 136.97, 2.56999, 131.22, -36.65, 118.22, -74.65, 108.68, -88.23, 130.44, -95.43, 144.61, -39.36, 152.24, 1.69, 156.05, 32.59, 156.21, 61, 132.55, 66.4, 111.94, 61.83, 79.01999, 38.83, 57.27, 19.29, 70.66, 52.40999, 107.01, 87.61, 95.37999, 116.69, 112.91, -6.86, 116.41, 15.8, 94.80999, 2.47, 97.23, -40.47, 90.66, -68.16, 127.62999, -47.15 ],
|
||||
"hull": 25,
|
||||
"edges": [ 36, 34, 34, 32, 32, 30, 30, 28, 28, 26, 26, 24, 24, 22, 18, 16, 16, 14, 14, 12, 12, 10, 10, 8, 8, 6, 6, 4, 4, 2, 2, 0, 0, 48, 48, 46, 46, 44, 36, 38, 40, 38, 24, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 62, 64, 64, 12, 8, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 76, 78, 78, 80, 80, 82, 82, 24, 24, 84, 84, 86, 86, 44, 40, 42, 42, 44, 42, 88, 88, 30, 58, 90, 90, 92, 92, 94, 18, 20, 20, 22, 94, 20, 18, 96, 96, 98, 60, 100, 100, 62, 98, 100 ],
|
||||
"width": 261,
|
||||
"height": 166
|
||||
}
|
||||
},
|
||||
"gun": {
|
||||
"gun": { "x": 77.3, "y": 16.39, "rotation": 60.81, "width": 210, "height": 203 }
|
||||
},
|
||||
"head": {
|
||||
"head": {
|
||||
"type": "mesh",
|
||||
"uvs": [ 0.75918, 0.06106, 0.88392, 0.17892, 0.90174, 0.30856, 0.94222, 0.1966, 1, 0.26583, 1, 0.42199, 0.95863, 0.46992, 0.92118, 0.51332, 0.85957, 0.53469, 0.78387, 0.65605, 0.74383, 0.74838, 0.85114, 0.75151, 0.84828, 0.82563, 0.81779, 0.85367, 0.75598, 0.85905, 0.76235, 0.90467, 0.65874, 1, 0.38335, 1, 0.18579, 0.85403, 0.1274, 0.81089, 0.06024, 0.69208, 0, 0.58551, 0, 0.41021, 0.08528, 0.2069, 0.24243, 0.14504, 0.49998, 0.14208, 0.50322, 0.07433, 0.41738, 0, 0.57612, 0, 0.85058, 0.36085, 0.7343, 0.43206, 0.6848, 0.3127, 0.72163, 0.16717, 0.55931, 0.04152, 0.44762, 0.22893, 0.23925, 0.26559, 0.71271, 0.44034, 0.56992, 0.38299, 0.41677, 0.33509, 0.29298, 0.31496, 0.70801, 0.44501, 0.56676, 0.38975, 0.41519, 0.34415, 0.28753, 0.33017, 0.88988, 0.50176, 0.30388, 0.73461, 0.2646, 0.65674, 0.21413, 0.61583, 0.14611, 0.62193, 0.10315, 0.66636, 0.10356, 0.72556, 0.14505, 0.79163, 0.20262, 0.81354, 0.27871, 0.80158, 0.34946, 0.7376, 0.23072, 0.57072, 0.08878, 0.60706, 0.2946, 0.8129, 0.73005, 0.87883, 0.69804, 0.87348, 0.66165, 0.7968 ],
|
||||
"triangles": [ 16, 58, 15, 16, 59, 58, 59, 16, 60, 18, 57, 17, 57, 54, 17, 16, 17, 60, 17, 54, 60, 58, 14, 15, 58, 59, 14, 59, 60, 14, 60, 10, 14, 14, 10, 13, 18, 53, 57, 18, 52, 53, 19, 51, 18, 18, 51, 52, 13, 10, 12, 12, 10, 11, 53, 52, 45, 57, 45, 54, 57, 53, 45, 20, 50, 19, 46, 45, 52, 47, 46, 50, 50, 48, 47, 19, 50, 51, 46, 52, 51, 54, 41, 60, 10, 60, 9, 60, 41, 40, 46, 51, 50, 9, 60, 40, 55, 42, 41, 54, 55, 41, 46, 54, 45, 20, 49, 50, 50, 49, 48, 20, 56, 49, 20, 21, 56, 49, 56, 48, 47, 55, 46, 42, 55, 43, 55, 54, 46, 9, 40, 8, 47, 48, 55, 55, 48, 56, 55, 56, 22, 56, 21, 22, 55, 22, 43, 8, 44, 7, 40, 36, 8, 8, 36, 44, 7, 44, 6, 41, 37, 40, 40, 37, 36, 43, 22, 39, 22, 23, 35, 41, 42, 38, 43, 39, 42, 42, 39, 38, 38, 39, 34, 39, 22, 35, 39, 35, 34, 35, 24, 34, 35, 23, 24, 34, 24, 25, 36, 30, 44, 44, 30, 6, 30, 29, 6, 30, 36, 31, 36, 37, 31, 30, 31, 29, 37, 41, 38, 31, 37, 34, 31, 32, 29, 37, 38, 34, 34, 25, 31, 2, 32, 1, 31, 25, 32, 33, 32, 25, 33, 25, 26, 32, 0, 1, 32, 33, 0, 0, 33, 28, 26, 27, 33, 33, 27, 28, 6, 29, 5, 29, 2, 5, 2, 4, 5, 2, 29, 32, 2, 3, 4 ],
|
||||
"vertices": [ 1, 32, 41.97, -41.79, 1, 3, 30, 73.44999, 27.54, 0.18925, 32, -5.75, -51.7, 0.72417, 31, 112.98, -11.43, 0.08656, 3, 30, 38.22, 10.97, 0.84284, 32, -41, -35.22, 0.09705, 31, 92.72, -44.65999, 0.0601, 1, 30, 73.33999, 10.89, 1, 1, 30, 58.59, -10.38, 1, 2, 30, 14.35, -24.79, 0.89741, 29, 75.48, -4.55, 0.10256, 2, 30, -2.69, -18.55999, 0.58265, 29, 59.81, -13.72, 0.41734, 1, 28, 163.05, -108.68, 1, 1, 28, 151.52, -95.04, 1, 1, 28, 110.58999, -87.69, 1, 1, 28, 81.05, -86.58, 1, 1, 28, 89.8, -114.30999, 1, 1, 28, 68.72, -120.91, 1, 1, 28, 58.09, -115.87999, 1, 1, 28, 51.02, -100.62, 1, 1, 28, 38.77, -106.76, 1, 1, 28, 2.67, -89.69, 1, 1, 28, -22.05999, -19.29, 1, 1, 28, 1.19, 45.61, 1, 1, 28, 8.06, 64.8, 1, 1, 28, 35.43, 93.72, 1, 1, 28, 59.97, 119.66, 1, 1, 28, 109.25, 136.97, 1, 1, 28, 174.07, 135.27, 1, 2, 31, -16.79, 104.62, 0.16235, 28, 205.58, 101.22, 0.83762, 2, 32, 58.93, 30.5, 0.60734, 31, 38.36, 61.88, 0.39263, 2, 32, 75.55, 19, 0.94502, 31, 51.61, 77.15, 0.05496, 1, 32, 106.69, 26.88999, 1, 1, 32, 83.76999, -9.5, 1, 4, 30, 19.12, 19.31999, 0.58066, 32, -46.81, -15.18, 0.07453, 31, 72.16, -48.24, 0.14877, 29, 44.52, 27.22999, 0.196, 2, 31, 34.31, -45.24, 0.20795, 29, 7.42, 19.06999, 0.79202, 1, 31, 45.93, -9.06, 1, 1, 32, 20.62, -16.35, 1, 1, 32, 75.73, 0.93, 1, 3, 32, 44.58, 56.29, 0.14948, 31, 11.14999, 50.45, 0.36829, 28, 200.44, 40.47, 0.48219, 1, 28, 171.41, 90.11, 1, 2, 31, 28.19, -43.54, 0.20795, 29, 1.07, 18.93, 0.79202, 3, 31, 8.52999, -6.07, 0.75382, 29, -28.62, 49.02, 0.13132, 28, 168.13, -6.01, 0.11484, 2, 31, -15.06, 30.88999, 0.72898, 28, 167.82, 37.86, 0.27101, 1, 28, 162.36, 71.5, 1, 1, 28, 163.1, -47.43, 1, 1, 28, 165.94, -5.86, 1, 1, 28, 165.13, 37.36, 1, 1, 28, 157.6, 71.37999, 1, 1, 28, 163.5, -99.51999, 1, 1, 28, 45.36, 27.22999, 1, 1, 28, 63.72, 44.97, 1, 1, 28, 70.69, 61.90999, 1, 1, 28, 62.86, 78.69, 1, 1, 28, 46.52, 85.3, 1, 1, 28, 29.92, 79.33, 1, 1, 28, 15.06, 62.2, 1, 1, 28, 14.09, 45.31, 1, 1, 28, 24.29, 27.04, 1, 1, 28, 48.63, 15.27999, 1, 1, 28, 84.87, 62.13, 1, 1, 28, 61.9, 94.83, 1, 1, 28, 22.54, 21.87, 1, 1, 28, 43.13, -95.94, 1, 1, 28, 41.77, -87.23, 1, 1, 28, 60.04, -70.33999, 1 ],
|
||||
"hull": 29,
|
||||
"edges": [ 10, 8, 8, 6, 6, 4, 4, 2, 2, 0, 0, 56, 54, 56, 54, 52, 52, 50, 50, 48, 48, 46, 46, 44, 42, 44, 32, 34, 4, 58, 58, 60, 62, 64, 64, 66, 66, 54, 50, 68, 68, 70, 70, 44, 60, 72, 62, 74, 72, 74, 74, 76, 76, 78, 78, 44, 16, 80, 80, 82, 82, 84, 84, 86, 86, 44, 14, 88, 88, 72, 14, 16, 10, 12, 12, 14, 12, 60, 90, 92, 92, 94, 94, 96, 96, 98, 98, 100, 100, 102, 102, 104, 104, 106, 106, 90, 108, 110, 110, 112, 38, 40, 40, 42, 112, 40, 34, 36, 36, 38, 36, 114, 114, 108, 30, 32, 30, 28, 24, 26, 28, 26, 22, 24, 22, 20, 20, 18, 18, 16, 28, 116, 116, 118, 118, 120, 120, 20 ],
|
||||
"width": 271,
|
||||
"height": 298
|
||||
}
|
||||
},
|
||||
"head-bb": {
|
||||
"head": {
|
||||
"type": "boundingbox",
|
||||
"vertexCount": 6,
|
||||
"vertices": [ -19.13999, -70.3, 40.79999, -118.06999, 257.77, -115.61, 285.16, 57.18, 120.76999, 164.95, -5.05999, 76.94 ]
|
||||
}
|
||||
},
|
||||
"hoverboard_board": {
|
||||
"hoverboard_board": { "x": -11.6, "y": 25.63, "rotation": 0.17, "width": 492, "height": 152 }
|
||||
},
|
||||
"hoverboard_thruster_front": {
|
||||
"hoverboard_thruster": { "y": -7.07, "width": 60, "height": 64 }
|
||||
},
|
||||
"hoverboard_thruster_rear": {
|
||||
"hoverboard_thruster": { "x": 1.08, "y": -6.28, "width": 60, "height": 64 }
|
||||
},
|
||||
"hoverglow_front": {
|
||||
"hoverglow_small": { "x": 2.13, "y": -2, "scaleX": 0.303, "scaleY": 0.495, "rotation": 0.15, "width": 274, "height": 75 }
|
||||
},
|
||||
"hoverglow_rear": {
|
||||
"hoverglow_small": { "x": 1.38, "y": -2.08, "scaleX": 0.303, "scaleY": 0.495, "rotation": 0.6, "width": 274, "height": 75 }
|
||||
},
|
||||
"mouth": {
|
||||
"mouth_grind": {
|
||||
"type": "mesh",
|
||||
"uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ],
|
||||
"triangles": [ 1, 3, 0, 1, 2, 3 ],
|
||||
"vertices": [ 11.27, -85.87, -19.54999, 1.84, 36.09, 21.39999, 66.93, -66.3 ],
|
||||
"hull": 4,
|
||||
"edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ],
|
||||
"width": 93,
|
||||
"height": 59
|
||||
},
|
||||
"mouth_oooo": { "x": 23.68, "y": -32.22, "rotation": -70.62, "width": 93, "height": 59 },
|
||||
"mouth_smile": { "x": 23.68, "y": -32.22, "rotation": -70.62, "width": 93, "height": 59 }
|
||||
},
|
||||
"muzzle": {
|
||||
"muzzle": { "x": 18.25, "y": 5.44, "rotation": 0.15, "width": 462, "height": 400 }
|
||||
},
|
||||
"neck": {
|
||||
"neck": { "x": 9.76, "y": -3, "rotation": -55.22, "width": 36, "height": 41 }
|
||||
},
|
||||
"rear_bracer": {
|
||||
"rear_bracer": { "x": 11.14, "y": -2.2, "rotation": 66.16, "width": 56, "height": 72 }
|
||||
},
|
||||
"rear_foot": {
|
||||
"rear_foot": {
|
||||
"type": "mesh",
|
||||
"uvs": [ 0.48368, 0.13869, 0.5199, 0.21423, 0.55098, 0.27906, 0.58837, 0.29815, 0.63488, 0.3219, 0.77341, 0.39265, 1, 0.73346, 1, 1, 0.59434, 1, 0.31159, 1, 0, 1, 0, 0.41396, 0.13629, 0, 0.41716, 0 ],
|
||||
"triangles": [ 4, 8, 3, 5, 8, 4, 6, 8, 5, 8, 6, 7, 11, 1, 10, 12, 13, 0, 0, 11, 12, 1, 11, 0, 2, 9, 10, 2, 10, 1, 9, 2, 3, 8, 9, 3 ],
|
||||
"vertices": [ 2, 7, 10.43999, 29.39999, 0.88823, 9, -6.73, 49.61, 0.11174, 2, 7, 16.54, 29.27, 0.83161, 9, -2.65, 45.08, 0.16834, 2, 7, 21.79, 29.13999, 0.78305, 9, 0.85, 41.18, 0.21694, 2, 7, 25.53, 31.43, 0.67843, 9, 5.07, 40.04, 0.32155, 2, 7, 30.17, 34.27, 0.5483, 9, 10.31999, 38.61, 0.45166, 2, 7, 44, 42.72, 0.16068, 9, 25.95999, 34.36, 0.83929, 1, 9, 51.56, 13.89, 1, 1, 9, 51.54, -2.07999, 1, 2, 7, 56.58, 2.98, 0.02958, 9, 5.71, -2.03999, 0.97039, 1, 7, 34.63, -20.20999, 0.99997, 1, 7, 10.43, -45.79, 0.99997, 1, 7, -15.1, -21.62999, 1, 1, 7, -22.54999, 6.61, 0.99997, 2, 7, -0.75, 29.67, 0.99219, 9, -14.25, 57.93, 0.00779 ],
|
||||
"hull": 14,
|
||||
"edges": [ 14, 12, 10, 12, 14, 16, 16, 18, 18, 20, 4, 18, 20, 22, 24, 26, 22, 24, 4, 2, 2, 20, 4, 6, 6, 16, 6, 8, 8, 10, 2, 0, 0, 26 ],
|
||||
"width": 113,
|
||||
"height": 60
|
||||
},
|
||||
"rear_foot_bend1": { "x": 29.61, "y": 18.12, "rotation": 46.59, "width": 117, "height": 66 },
|
||||
"rear_foot_bend2": { "x": 22.81, "y": 23.69, "rotation": 46.59, "width": 103, "height": 83 }
|
||||
},
|
||||
"rear_shin": {
|
||||
"rear_shin": { "x": 58.29, "y": -2.75, "rotation": 92.37, "width": 75, "height": 178 }
|
||||
},
|
||||
"rear_thigh": {
|
||||
"rear_thigh": { "x": 33.09, "y": -4.11, "rotation": 72.54, "width": 65, "height": 104 }
|
||||
},
|
||||
"rear_upper_arm": {
|
||||
"rear_upper_arm": { "x": 21.12, "y": 4.07, "rotation": 89.31, "width": 47, "height": 87 }
|
||||
},
|
||||
"torso": {
|
||||
"torso": {
|
||||
"type": "mesh",
|
||||
"uvs": [ 0.62509, 0.12671, 1, 0.26359, 1, 0.2887, 1, 0.66021, 1, 0.68244, 0.92322, 0.69257, 0.95115, 0.84965, 0.77122, 1, 0.49654, 1, 0.2718, 1, 0.13842, 0.77196, 0, 0.45614, 0, 0.19436, 0.14462, 0, 0.27801, 0, 0.72523, 0.27834, 0.7609, 0.46215, 0.84887, 0.67962, 0.68256, 0.63248, 0.53984, 0.38468, 0.25442, 0.32168, 0.30061, 0.55172, 0.39552, 0.79505, 0.26388, 0.17005, 0.52408, 0.18672 ],
|
||||
"triangles": [ 6, 17, 5, 6, 7, 17, 8, 18, 7, 7, 18, 17, 9, 22, 8, 8, 22, 18, 9, 10, 22, 10, 21, 22, 22, 21, 18, 10, 11, 21, 4, 5, 3, 5, 17, 3, 3, 17, 16, 17, 18, 16, 16, 2, 3, 21, 19, 18, 18, 19, 16, 11, 20, 21, 21, 20, 19, 19, 15, 16, 16, 15, 2, 11, 12, 20, 20, 24, 19, 19, 24, 15, 20, 23, 24, 20, 12, 23, 15, 1, 2, 24, 0, 15, 15, 0, 1, 12, 13, 23, 0, 24, 14, 14, 24, 13, 24, 23, 13 ],
|
||||
"vertices": [ 129.61, -10.38, 102.16, -45.06, 97.66, -44.7, 31, -39.45, 27.01, -39.13, 25.78, -31.47999, -2.59999, -31.97999, -28.2, -12.27999, -26.06999, 14.52999, -24.34, 36.5, 17.59, 46.29, 75.33, 55.34, 122.3, 51.63, 156.07, 34.75, 155.02998, 21.70999, 101.62999, -18.02, 68.37, -18.88999, 28.68, -24.39999, 38.40999, -8.81999, 83.98, 1.59, 97.5, 28.56999, 55.86, 27.31999, 11.47, 21.51, 124.62, 25.51, 119.62, 0.31 ],
|
||||
"hull": 15,
|
||||
"edges": [ 14, 12, 12, 10, 10, 8, 18, 20, 20, 22, 22, 24, 26, 28, 24, 26, 2, 4, 30, 4, 30, 32, 32, 34, 4, 6, 6, 8, 34, 6, 34, 36, 36, 38, 38, 40, 40, 24, 36, 14, 40, 42, 42, 44, 14, 16, 16, 18, 44, 16, 40, 46, 38, 48, 48, 30, 2, 0, 0, 28, 48, 0, 48, 26 ],
|
||||
"width": 98,
|
||||
"height": 180
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"footstep": {},
|
||||
"headAttach": { "int": 3, "float": 4 },
|
||||
"headBehind": { "int": 5, "float": 6, "string": "setup" },
|
||||
"headPop": { "int": 1, "float": 2 }
|
||||
},
|
||||
"animations": {
|
||||
"fly": {
|
||||
"slots": {
|
||||
"exhaust1": {
|
||||
"color": [
|
||||
{
|
||||
"time": 0,
|
||||
"color": "ffffff98",
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.3333,
|
||||
"color": "ffffffff",
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.5666,
|
||||
"color": "ffffffb0",
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "color": "ffffff98" }
|
||||
]
|
||||
},
|
||||
"exhaust2": {
|
||||
"color": [
|
||||
{
|
||||
"time": 0,
|
||||
"color": "ffffff98",
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.3333,
|
||||
"color": "ffffffff",
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.5666,
|
||||
"color": "ffffffb0",
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "color": "ffffff98" }
|
||||
]
|
||||
},
|
||||
"front_fist": {
|
||||
"attachment": [
|
||||
{ "time": 0, "name": "front_fist_open" }
|
||||
]
|
||||
},
|
||||
"hoverglow_front": {
|
||||
"color": [
|
||||
{ "time": 0, "color": "ffffff8d" },
|
||||
{ "time": 0.5, "color": "ffffffff" },
|
||||
{ "time": 1.3333, "color": "ffffff8d" }
|
||||
]
|
||||
},
|
||||
"hoverglow_rear": {
|
||||
"color": [
|
||||
{ "time": 0, "color": "ffffff8d" },
|
||||
{ "time": 0.5, "color": "ffffffff" },
|
||||
{ "time": 1.3333, "color": "ffffff8d" }
|
||||
]
|
||||
},
|
||||
"mouth": {
|
||||
"attachment": [
|
||||
{ "time": 0, "name": "mouth_grind" },
|
||||
{ "time": 1.3333, "name": "mouth_grind" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"bones": {
|
||||
"hip": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{
|
||||
"time": 0,
|
||||
"x": 4.72,
|
||||
"y": -29.18,
|
||||
"curve": [ 0.155, 0.18, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.1,
|
||||
"x": 4.72,
|
||||
"y": -34.45,
|
||||
"curve": [ 0.191, -0.39, 0.719, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.4333,
|
||||
"x": 23.48,
|
||||
"y": 14.72,
|
||||
"curve": [ 0.311, 0.02, 0.795, 0.98 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8333,
|
||||
"x": 71.9,
|
||||
"y": 28.45,
|
||||
"curve": [ 0.319, 0, 0.824, 0.84 ]
|
||||
},
|
||||
{ "time": 1.3333, "x": 4.72, "y": -29.18 }
|
||||
]
|
||||
},
|
||||
"torso": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": -5.34,
|
||||
"curve": [ 0.247, 0, 0.629, 0.52 ]
|
||||
},
|
||||
{
|
||||
"time": 0.3,
|
||||
"angle": -4.14,
|
||||
"curve": [ 0.221, 0.11, 0.747, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.6999,
|
||||
"angle": 22.54,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": -5.34 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"neck": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 0.65,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.3,
|
||||
"angle": -1.58,
|
||||
"curve": [ 0.45, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.6999,
|
||||
"angle": -12.82,
|
||||
"curve": [ 0.25, 0, 0.625, 0.5 ]
|
||||
},
|
||||
{
|
||||
"time": 1.0666,
|
||||
"angle": -6.71,
|
||||
"curve": [ 0.375, 0.5, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 0.65 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"head": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 8.04 },
|
||||
{ "time": 0.3, "angle": -1.58 },
|
||||
{ "time": 0.6999, "angle": -12.82 },
|
||||
{ "time": 1.0666, "angle": 3.26 },
|
||||
{ "time": 1.3333, "angle": 8.04 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hair1": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 6.48 },
|
||||
{ "time": 0.1333, "angle": 7.25 },
|
||||
{ "time": 0.2666, "angle": 3.81 },
|
||||
{ "time": 0.3666, "angle": 5.38 },
|
||||
{ "time": 0.4666, "angle": 4.42 },
|
||||
{ "time": 0.6333, "angle": 0.75 },
|
||||
{ "time": 0.8, "angle": 0.58 },
|
||||
{ "time": 0.8999, "angle": 3.76 },
|
||||
{ "time": 1.0666, "angle": 4.09 },
|
||||
{ "time": 1.2333, "angle": 7.48 },
|
||||
{ "time": 1.3333, "angle": 6.48 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hair3": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 9.46 },
|
||||
{ "time": 0.1333, "angle": 10.24 },
|
||||
{ "time": 0.2666, "angle": 6.79 },
|
||||
{ "time": 0.3666, "angle": 8.36 },
|
||||
{ "time": 0.4666, "angle": 7.41 },
|
||||
{ "time": 0.6333, "angle": 3.73 },
|
||||
{ "time": 0.8, "angle": 3.56 },
|
||||
{ "time": 0.8999, "angle": 6.74 },
|
||||
{ "time": 1.0666, "angle": 7.07 },
|
||||
{ "time": 1.2333, "angle": 10.46 },
|
||||
{ "time": 1.3333, "angle": 9.46 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hair2": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -0.25 },
|
||||
{ "time": 0.1333, "angle": 6.78 },
|
||||
{ "time": 0.2666, "angle": 9.6 },
|
||||
{ "time": 0.3666, "angle": 15.86 },
|
||||
{ "time": 0.4666, "angle": 19.6 },
|
||||
{ "time": 0.6333, "angle": 3.35 },
|
||||
{ "time": 0.8, "angle": -9.4 },
|
||||
{ "time": 0.8999, "angle": -5.61 },
|
||||
{ "time": 1.0666, "angle": -4.26 },
|
||||
{ "time": 1.2333, "angle": 0.14 },
|
||||
{ "time": 1.3333, "angle": -0.25 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hair4": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 6.9 },
|
||||
{ "time": 0.1333, "angle": 7.86 },
|
||||
{ "time": 0.2333, "angle": 5.54 },
|
||||
{ "time": 0.3666, "angle": 11.19 },
|
||||
{ "time": 0.5, "angle": 12.62 },
|
||||
{ "time": 0.6, "angle": 17.84 },
|
||||
{ "time": 0.6999, "angle": 20.53 },
|
||||
{ "time": 0.8666, "angle": 11.84 },
|
||||
{ "time": 1.0333, "angle": 6.65 },
|
||||
{ "time": 1.1333, "angle": 8.52 },
|
||||
{ "time": 1.2999, "angle": 6.66 },
|
||||
{ "time": 1.3333, "angle": 6.9 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.2333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_fist": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 24.72,
|
||||
"curve": [ 0.259, 0, 0.618, 0.44 ]
|
||||
},
|
||||
{
|
||||
"time": 0.4,
|
||||
"angle": 35.93,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8333,
|
||||
"angle": 18.74,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 1.1666,
|
||||
"angle": 31.47,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 24.72 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hoverboard": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 0,
|
||||
"curve": [ 0.257, 0, 0.618, 0.45 ]
|
||||
},
|
||||
{
|
||||
"time": 0.3333,
|
||||
"angle": 15.41,
|
||||
"curve": [ 0.195, 0.35, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8333,
|
||||
"angle": -16.01,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{
|
||||
"time": 0,
|
||||
"x": 25.22,
|
||||
"y": 7.84,
|
||||
"curve": [ 0.553, 0.02, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.5,
|
||||
"x": 67.8,
|
||||
"y": 62.57,
|
||||
"curve": [ 0.246, 0, 0.737, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "x": 25.22, "y": 7.84 }
|
||||
]
|
||||
},
|
||||
"front_foot_ik": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -22.24 },
|
||||
{ "time": 0.5, "angle": 9.33 },
|
||||
{ "time": 1.3333, "angle": -22.24 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_thigh": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_toe_ik": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hoverboard_thruster_front": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 0,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.3333,
|
||||
"angle": 26.79,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8333,
|
||||
"angle": 41.42,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hoverboard_thruster_rear": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 0,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.3333,
|
||||
"angle": 26.79,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8333,
|
||||
"angle": 41.42,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"rear_foot_ik": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"rear_thigh": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"rear_toe_ik": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_ankle_ik": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_shin": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_upper_arm": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -6.56 },
|
||||
{
|
||||
"time": 0.6999,
|
||||
"angle": -45.47,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": -6.56 }
|
||||
],
|
||||
"translate": [
|
||||
{
|
||||
"time": 0,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.4333,
|
||||
"x": 4.01,
|
||||
"y": 1.45,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"rear_ankle_ik": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"rear_shin": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"rear_upper_arm": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 0,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8,
|
||||
"angle": -22.48,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_bracer": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 53,
|
||||
"curve": [ 0.259, 0, 0.618, 0.44 ]
|
||||
},
|
||||
{
|
||||
"time": 0.6999,
|
||||
"angle": 27.8,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 1,
|
||||
"angle": 56.88,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 53 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_foot": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"rear_bracer": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0 },
|
||||
{
|
||||
"time": 0.8,
|
||||
"angle": 16.99,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"rear_foot": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"back_foot_tip": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"front_foot_tip": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"gun": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 20.28,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8,
|
||||
"angle": 3.84,
|
||||
"curve": [ 0.25, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 1.3333, "angle": 20.28 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"gunTip": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3333, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hoverglow_front": {
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1 },
|
||||
{ "time": 0.5, "x": 1, "y": 1.565 },
|
||||
{ "time": 1.3333, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"hoverglow_rear": {
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1 },
|
||||
{ "time": 0.5, "x": 1, "y": 1.565 },
|
||||
{ "time": 1.3333, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"exhaust1": {
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1 },
|
||||
{ "time": 0.3333, "x": 1.597, "y": 1 },
|
||||
{ "time": 0.5666, "x": 1.223, "y": 1 },
|
||||
{ "time": 1.3333, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"exhaust2": {
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1 },
|
||||
{ "time": 0.3333, "x": 1.597, "y": 1 },
|
||||
{ "time": 0.5666, "x": 1.223, "y": 1 },
|
||||
{ "time": 1.3333, "x": 1, "y": 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 678 KiB |
Binary file not shown.
195
spine-ue4/Content/GettingStarted/Assets/Spineboy/spineboy.atlas
Normal file
195
spine-ue4/Content/GettingStarted/Assets/Spineboy/spineboy.atlas
Normal file
@ -0,0 +1,195 @@
|
||||
|
||||
spineboy.png
|
||||
size: 1022,1022
|
||||
format: RGBA8888
|
||||
filter: Linear,Linear
|
||||
repeat: none
|
||||
eye_indifferent
|
||||
rotate: false
|
||||
xy: 549, 694
|
||||
size: 93, 89
|
||||
orig: 93, 89
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
eye_surprised
|
||||
rotate: false
|
||||
xy: 834, 857
|
||||
size: 93, 89
|
||||
orig: 93, 89
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_bracer
|
||||
rotate: true
|
||||
xy: 375, 432
|
||||
size: 58, 80
|
||||
orig: 58, 80
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_fist_closed
|
||||
rotate: true
|
||||
xy: 466, 593
|
||||
size: 75, 82
|
||||
orig: 75, 82
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_fist_open
|
||||
rotate: false
|
||||
xy: 447, 504
|
||||
size: 86, 87
|
||||
orig: 86, 87
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_foot
|
||||
rotate: false
|
||||
xy: 549, 785
|
||||
size: 126, 69
|
||||
orig: 126, 69
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_foot_bend1
|
||||
rotate: true
|
||||
xy: 375, 492
|
||||
size: 128, 70
|
||||
orig: 128, 70
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_foot_bend2
|
||||
rotate: true
|
||||
xy: 275, 330
|
||||
size: 108, 93
|
||||
orig: 108, 93
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_shin
|
||||
rotate: false
|
||||
xy: 466, 670
|
||||
size: 81, 184
|
||||
orig: 82, 184
|
||||
offset: 1, 0
|
||||
index: -1
|
||||
front_thigh
|
||||
rotate: false
|
||||
xy: 214, 208
|
||||
size: 48, 112
|
||||
orig: 48, 112
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front_upper_arm
|
||||
rotate: false
|
||||
xy: 214, 109
|
||||
size: 54, 97
|
||||
orig: 54, 97
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
goggles
|
||||
rotate: false
|
||||
xy: 466, 856
|
||||
size: 261, 166
|
||||
orig: 261, 166
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
gun
|
||||
rotate: false
|
||||
xy: 2, 117
|
||||
size: 210, 203
|
||||
orig: 210, 203
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
head
|
||||
rotate: false
|
||||
xy: 2, 322
|
||||
size: 271, 298
|
||||
orig: 271, 298
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth_grind
|
||||
rotate: false
|
||||
xy: 929, 896
|
||||
size: 93, 59
|
||||
orig: 93, 59
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth_oooo
|
||||
rotate: false
|
||||
xy: 929, 835
|
||||
size: 93, 59
|
||||
orig: 93, 59
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth_smile
|
||||
rotate: true
|
||||
xy: 550, 599
|
||||
size: 93, 59
|
||||
orig: 93, 59
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle
|
||||
rotate: false
|
||||
xy: 2, 622
|
||||
size: 462, 400
|
||||
orig: 462, 400
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
neck
|
||||
rotate: false
|
||||
xy: 64, 6
|
||||
size: 35, 41
|
||||
orig: 36, 41
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_bracer
|
||||
rotate: false
|
||||
xy: 677, 782
|
||||
size: 55, 72
|
||||
orig: 56, 72
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_foot
|
||||
rotate: true
|
||||
xy: 2, 2
|
||||
size: 113, 60
|
||||
orig: 113, 60
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_foot_bend1
|
||||
rotate: false
|
||||
xy: 64, 49
|
||||
size: 117, 66
|
||||
orig: 117, 66
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_foot_bend2
|
||||
rotate: false
|
||||
xy: 729, 863
|
||||
size: 103, 83
|
||||
orig: 103, 83
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear_shin
|
||||
rotate: true
|
||||
xy: 729, 948
|
||||
size: 74, 178
|
||||
orig: 75, 178
|
||||
offset: 1, 0
|
||||
index: -1
|
||||
rear_thigh
|
||||
rotate: true
|
||||
xy: 909, 957
|
||||
size: 65, 103
|
||||
orig: 65, 104
|
||||
offset: 0, 1
|
||||
index: -1
|
||||
rear_upper_arm
|
||||
rotate: false
|
||||
xy: 370, 343
|
||||
size: 47, 87
|
||||
orig: 47, 87
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
torso
|
||||
rotate: false
|
||||
xy: 275, 440
|
||||
size: 98, 180
|
||||
orig: 98, 180
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
4562
spine-ue4/Content/GettingStarted/Assets/Spineboy/spineboy.json
Normal file
4562
spine-ue4/Content/GettingStarted/Assets/Spineboy/spineboy.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
spine-ue4/Content/GettingStarted/Assets/Spineboy/spineboy.png
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Spineboy/spineboy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 585 KiB |
BIN
spine-ue4/Content/GettingStarted/Assets/Spineboy/spineboy.uasset
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Spineboy/spineboy.uasset
Normal file
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/Assets/Textures/Doi.uasset
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Textures/Doi.uasset
Normal file
Binary file not shown.
BIN
spine-ue4/Content/GettingStarted/Assets/Textures/raptor.uasset
Normal file
BIN
spine-ue4/Content/GettingStarted/Assets/Textures/raptor.uasset
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
27
spine-ue4/LICENSE
Normal file
27
spine-ue4/LICENSE
Normal file
@ -0,0 +1,27 @@
|
||||
Spine Runtimes Software License v2.5
|
||||
|
||||
Copyright (c) 2013-2016, Esoteric Software
|
||||
All rights reserved.
|
||||
|
||||
You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
non-transferable license to use, install, execute, and perform the Spine
|
||||
Runtimes software and derivative works solely for personal or internal
|
||||
use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
or other intellectual property or proprietary rights notices on or in the
|
||||
Software, including any copy thereof. Redistributions in binary or source
|
||||
form must include this license and terms.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
spine-ue4/Plugins/SpinePlugin/Resources/Icon128.png
Normal file
BIN
spine-ue4/Plugins/SpinePlugin/Resources/Icon128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,145 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineEditorPluginPrivatePCH.h"
|
||||
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "AssetToolsModule.h"
|
||||
#include "PackageTools.h"
|
||||
#include "Developer/DesktopPlatform/Public/IDesktopPlatform.h"
|
||||
#include "Developer/DesktopPlatform/Public/DesktopPlatformModule.h"
|
||||
#include "spine/spine.h"
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
USpineAtlasAssetFactory::USpineAtlasAssetFactory (const FObjectInitializer& objectInitializer): Super(objectInitializer) {
|
||||
bCreateNew = false;
|
||||
bEditAfterNew = true;
|
||||
bEditorImport = true;
|
||||
SupportedClass = USpineAtlasAsset::StaticClass();
|
||||
|
||||
Formats.Add(TEXT("atlas;Spine atlas file"));
|
||||
}
|
||||
|
||||
FText USpineAtlasAssetFactory::GetToolTip () const {
|
||||
return LOCTEXT("SpineAtlasAssetFactory", "Animations exported from Spine");
|
||||
}
|
||||
|
||||
bool USpineAtlasAssetFactory::FactoryCanImport (const FString& Filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
UObject* USpineAtlasAssetFactory::FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) {
|
||||
FString rawString;
|
||||
if (!FFileHelper::LoadFileToString(rawString, *Filename)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FString currentSourcePath, filenameNoExtension, unusedExtension;
|
||||
const FString longPackagePath = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetPathName());
|
||||
FPaths::Split(UFactory::GetCurrentFilename(), currentSourcePath, filenameNoExtension, unusedExtension);
|
||||
FString name(InName.ToString());
|
||||
name.Append("-atlas");
|
||||
|
||||
USpineAtlasAsset* asset = NewObject<USpineAtlasAsset>(InParent, InClass, FName(*name), Flags);
|
||||
asset->SetRawData(rawString);
|
||||
asset->SetAtlasFileName(FName(*Filename));
|
||||
LoadAtlas(asset, currentSourcePath, longPackagePath);
|
||||
return asset;
|
||||
}
|
||||
|
||||
bool USpineAtlasAssetFactory::CanReimport (UObject* Obj, TArray<FString>& OutFilenames) {
|
||||
USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
|
||||
if (!asset) return false;
|
||||
|
||||
FString filename = asset->GetAtlasFileName().ToString();
|
||||
if (!filename.IsEmpty())
|
||||
OutFilenames.Add(filename);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void USpineAtlasAssetFactory::SetReimportPaths (UObject* Obj, const TArray<FString>& NewReimportPaths) {
|
||||
USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
|
||||
|
||||
if (asset && ensure(NewReimportPaths.Num() == 1))
|
||||
asset->SetAtlasFileName(FName(*NewReimportPaths[0]));
|
||||
}
|
||||
|
||||
EReimportResult::Type USpineAtlasAssetFactory::Reimport (UObject* Obj) {
|
||||
USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
|
||||
FString rawString;
|
||||
if (!FFileHelper::LoadFileToString(rawString, *asset->GetAtlasFileName().ToString())) return EReimportResult::Failed;
|
||||
asset->SetRawData(rawString);
|
||||
|
||||
FString currentSourcePath, filenameNoExtension, unusedExtension;
|
||||
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
||||
FPaths::Split(UFactory::GetCurrentFilename(), currentSourcePath, filenameNoExtension, unusedExtension);
|
||||
|
||||
LoadAtlas(asset, currentSourcePath, longPackagePath);
|
||||
|
||||
if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
|
||||
else Obj->MarkPackageDirty();
|
||||
|
||||
return EReimportResult::Succeeded;
|
||||
}
|
||||
|
||||
UTexture2D* resolveTexture (USpineAtlasAsset* Asset, const FString& PageFileName, const FString& TargetSubPath) {
|
||||
FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
|
||||
|
||||
TArray<FString> fileNames;
|
||||
fileNames.Add(PageFileName);
|
||||
|
||||
TArray<UObject*> importedAsset = AssetToolsModule.Get().ImportAssets(fileNames, TargetSubPath);
|
||||
UTexture2D* texture = (importedAsset.Num() > 0) ? Cast<UTexture2D>(importedAsset[0]) : nullptr;
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
void USpineAtlasAssetFactory::LoadAtlas (USpineAtlasAsset* Asset, const FString& CurrentSourcePath, const FString& LongPackagePath) {
|
||||
spAtlas* atlas = Asset->GetAtlas(true);
|
||||
Asset->atlasPages.Empty();
|
||||
|
||||
const FString targetTexturePath = LongPackagePath / TEXT("Textures");
|
||||
|
||||
spAtlasPage* page = atlas->pages;
|
||||
while (page) {
|
||||
const FString sourceTextureFilename = FPaths::Combine(*CurrentSourcePath, UTF8_TO_TCHAR(page->name));
|
||||
UTexture2D* texture = resolveTexture(Asset, sourceTextureFilename, targetTexturePath);
|
||||
page = page->next;
|
||||
Asset->atlasPages.Add(texture);
|
||||
}
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,49 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineEditorPluginPrivatePCH.h"
|
||||
#include "spine/spine.h"
|
||||
|
||||
|
||||
class FSpineEditorPlugin: public ISpineEditorPlugin {
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
|
||||
IMPLEMENT_MODULE(FSpineEditorPlugin, ISpineEditorPlugin)
|
||||
|
||||
|
||||
|
||||
void FSpineEditorPlugin::StartupModule () { }
|
||||
|
||||
void FSpineEditorPlugin::ShutdownModule () { }
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineEditorPlugin.h"
|
||||
#include "SpinePlugin.h"
|
||||
#include "SpineAtlasImportFactory.h"
|
||||
#include "SpineSkeletonImportFactory.h"
|
||||
@ -0,0 +1,121 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineEditorPluginPrivatePCH.h"
|
||||
|
||||
#include "SpineSkeletonDataAsset.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "AssetToolsModule.h"
|
||||
#include "PackageTools.h"
|
||||
#include "Developer/DesktopPlatform/Public/IDesktopPlatform.h"
|
||||
#include "Developer/DesktopPlatform/Public/DesktopPlatformModule.h"
|
||||
#include "spine/spine.h"
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
USpineSkeletonAssetFactory::USpineSkeletonAssetFactory (const FObjectInitializer& objectInitializer): Super(objectInitializer) {
|
||||
bCreateNew = false;
|
||||
bEditAfterNew = true;
|
||||
bEditorImport = true;
|
||||
SupportedClass = USpineSkeletonDataAsset::StaticClass();
|
||||
|
||||
Formats.Add(TEXT("json;Spine skeleton file"));
|
||||
Formats.Add(TEXT("skel;Spine skeleton file"));
|
||||
}
|
||||
|
||||
FText USpineSkeletonAssetFactory::GetToolTip () const {
|
||||
return LOCTEXT("USpineSkeletonAssetFactory", "Animations exported from Spine");
|
||||
}
|
||||
|
||||
bool USpineSkeletonAssetFactory::FactoryCanImport (const FString& Filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoadAtlas (const FString& Filename, const FString& TargetPath) {
|
||||
FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
|
||||
|
||||
FString skelFile = Filename.Replace(TEXT(".skel"), TEXT(".atlas")).Replace(TEXT(".json"), TEXT(".atlas"));
|
||||
if (!FPaths::FileExists(skelFile)) return;
|
||||
|
||||
TArray<FString> fileNames;
|
||||
fileNames.Add(skelFile);
|
||||
AssetToolsModule.Get().ImportAssets(fileNames, TargetPath);
|
||||
}
|
||||
|
||||
UObject* USpineSkeletonAssetFactory::FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) {
|
||||
FString name(InName.ToString());
|
||||
name.Append("-data");
|
||||
|
||||
USpineSkeletonDataAsset* asset = NewObject<USpineSkeletonDataAsset>(InParent, InClass, FName(*name), Flags);
|
||||
if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *Filename, 0)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
asset->SetSkeletonDataFileName(FName(*Filename));
|
||||
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
||||
LoadAtlas(Filename, longPackagePath);
|
||||
return asset;
|
||||
}
|
||||
|
||||
bool USpineSkeletonAssetFactory::CanReimport (UObject* Obj, TArray<FString>& OutFilenames) {
|
||||
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
|
||||
if (!asset) return false;
|
||||
|
||||
FString filename = asset->GetSkeletonDataFileName().ToString();
|
||||
if (!filename.IsEmpty())
|
||||
OutFilenames.Add(filename);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void USpineSkeletonAssetFactory::SetReimportPaths (UObject* Obj, const TArray<FString>& NewReimportPaths) {
|
||||
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
|
||||
|
||||
if (asset && ensure(NewReimportPaths.Num() == 1))
|
||||
asset->SetSkeletonDataFileName(FName(*NewReimportPaths[0]));
|
||||
}
|
||||
|
||||
EReimportResult::Type USpineSkeletonAssetFactory::Reimport (UObject* Obj) {
|
||||
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
|
||||
if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *asset->GetSkeletonDataFileName().ToString(), 0)) return EReimportResult::Failed;
|
||||
|
||||
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
||||
LoadAtlas(*asset->GetSkeletonDataFileName().ToString(), longPackagePath);
|
||||
|
||||
if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
|
||||
else Obj->MarkPackageDirty();
|
||||
|
||||
return EReimportResult::Succeeded;
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "UnrealEd.h"
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "SpineAtlasImportFactory.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class USpineAtlasAssetFactory: public UFactory, public FReimportHandler {
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual FText GetToolTip() const override;
|
||||
|
||||
virtual bool FactoryCanImport(const FString& Filename) override;
|
||||
virtual UObject* FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) override;
|
||||
|
||||
virtual bool CanReimport(UObject* Obj, TArray<FString>& OutFilenames) override;
|
||||
virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override;
|
||||
virtual EReimportResult::Type Reimport(UObject* Obj) override;
|
||||
|
||||
void LoadAtlas(USpineAtlasAsset* Asset, const FString& CurrentSourcePath, const FString& LongPackagePath);
|
||||
};
|
||||
@ -0,0 +1,46 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ModuleManager.h"
|
||||
|
||||
class ISpineEditorPlugin : public IModuleInterface {
|
||||
|
||||
public:
|
||||
static inline ISpineEditorPlugin& Get() {
|
||||
return FModuleManager::LoadModuleChecked< ISpineEditorPlugin >( "SpineEditorPlugin" );
|
||||
}
|
||||
|
||||
static inline bool IsAvailable() {
|
||||
return FModuleManager::Get().IsModuleLoaded( "SpineEditorPlugin" );
|
||||
}
|
||||
};
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "UnrealEd.h"
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "SpineSkeletonImportFactory.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class USpineSkeletonAssetFactory : public UFactory, public FReimportHandler {
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual FText GetToolTip () const override;
|
||||
virtual bool FactoryCanImport (const FString& Filename) override;
|
||||
virtual UObject* FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) override;
|
||||
|
||||
virtual bool CanReimport (UObject* Obj, TArray<FString>& OutFilenames) override;
|
||||
virtual void SetReimportPaths (UObject* Obj, const TArray<FString>& NewReimportPaths) override;
|
||||
virtual EReimportResult::Type Reimport (UObject* Obj) override;
|
||||
};
|
||||
@ -0,0 +1,32 @@
|
||||
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
namespace UnrealBuildTool.Rules
|
||||
{
|
||||
public class SpineEditorPlugin : ModuleRules
|
||||
{
|
||||
public SpineEditorPlugin(TargetInfo Target)
|
||||
{
|
||||
PublicIncludePaths.AddRange(new string[] { "SpineEditorPlugin/Public" });
|
||||
|
||||
PrivateIncludePaths.AddRange(new string[] { "SpineEditorPlugin/Private" });
|
||||
|
||||
PublicDependencyModuleNames.AddRange(new string[] {
|
||||
"Core",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"UnrealEd",
|
||||
"SpinePlugin"
|
||||
});
|
||||
|
||||
PublicIncludePathModuleNames.AddRange(new string[] {
|
||||
"AssetTools",
|
||||
"AssetRegistry"
|
||||
});
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(new string[] {
|
||||
"AssetTools",
|
||||
"AssetRegistry"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
#include "spine/spine.h"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
FString USpineAtlasAsset::GetRawData () const {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
FName USpineAtlasAsset::GetAtlasFileName () const {
|
||||
#if WITH_EDITORONLY_DATA
|
||||
TArray<FString> files;
|
||||
if (importData) importData->ExtractFilenames(files);
|
||||
if (files.Num() > 0) return FName(*files[0]);
|
||||
else return atlasFileName;
|
||||
#else
|
||||
return atlasFileName;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
void USpineAtlasAsset::SetRawData (const FString &RawData) {
|
||||
this->rawData = RawData;
|
||||
}
|
||||
|
||||
void USpineAtlasAsset::SetAtlasFileName (const FName &AtlasFileName) {
|
||||
importData->UpdateFilenameOnly(AtlasFileName.ToString());
|
||||
TArray<FString> files;
|
||||
importData->ExtractFilenames(files);
|
||||
if (files.Num() > 0) atlasFileName = FName(*files[0]);
|
||||
}
|
||||
|
||||
void USpineAtlasAsset::PostInitProperties () {
|
||||
if (!HasAnyFlags(RF_ClassDefaultObject)) importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
Super::PostInitProperties();
|
||||
}
|
||||
|
||||
void USpineAtlasAsset::GetAssetRegistryTags (TArray<FAssetRegistryTag>& OutTags) const {
|
||||
if (importData) {
|
||||
OutTags.Add(FAssetRegistryTag(SourceFileTagName(), importData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) );
|
||||
}
|
||||
|
||||
Super::GetAssetRegistryTags(OutTags);
|
||||
}
|
||||
|
||||
void USpineAtlasAsset::Serialize (FArchive& Ar) {
|
||||
Super::Serialize(Ar);
|
||||
if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
|
||||
importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
}
|
||||
|
||||
void USpineAtlasAsset::BeginDestroy () {
|
||||
if (atlas) {
|
||||
spAtlas_dispose(atlas);
|
||||
atlas = nullptr;
|
||||
}
|
||||
Super::BeginDestroy();
|
||||
}
|
||||
|
||||
spAtlas* USpineAtlasAsset::GetAtlas (bool ForceReload) {
|
||||
if (!atlas || ForceReload) {
|
||||
if (atlas) {
|
||||
spAtlas_dispose(atlas);
|
||||
atlas = nullptr;
|
||||
}
|
||||
std::string t = TCHAR_TO_UTF8(*rawData);
|
||||
atlas = spAtlas_create(t.c_str(), strlen(t.c_str()), "", nullptr);
|
||||
spAtlasPage* page = atlas->pages;
|
||||
int i = 0;
|
||||
while (page) {
|
||||
int num = atlasPages.Num();
|
||||
if (atlasPages.Num() > 0 && atlasPages.Num() > i)
|
||||
page->rendererObject = atlasPages[i++];
|
||||
page = page->next;
|
||||
}
|
||||
}
|
||||
return this->atlas;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,64 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
|
||||
USpineBoneDriverComponent::USpineBoneDriverComponent () {
|
||||
bWantsBeginPlay = true;
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::BeginPlay () {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::BeforeUpdateWorldTransform(USpineSkeletonComponent* skeleton) {
|
||||
AActor* owner = GetOwner();
|
||||
if (owner && skeleton == lastBoundComponent) {
|
||||
skeleton->SetBoneWorldPosition(BoneName, owner->GetActorLocation() );
|
||||
}
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
if (Target) {
|
||||
USpineSkeletonComponent* skeleton = static_cast<USpineSkeletonComponent*>(Target->GetComponentByClass(USpineSkeletonComponent::StaticClass()));
|
||||
if (skeleton != lastBoundComponent) {
|
||||
// if (lastBoundComponent) lastBoundComponent->BeforeUpdateWorldTransform.RemoveAll(this);
|
||||
if (!skeleton->BeforeUpdateWorldTransform.GetAllObjects().Contains(this))
|
||||
skeleton->BeforeUpdateWorldTransform.AddDynamic(this, &USpineBoneDriverComponent::BeforeUpdateWorldTransform);
|
||||
lastBoundComponent = skeleton;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
|
||||
USpineBoneFollowerComponent::USpineBoneFollowerComponent () {
|
||||
bWantsBeginPlay = true;
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
void USpineBoneFollowerComponent::BeginPlay () {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineBoneFollowerComponent::TickComponent ( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) {
|
||||
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
|
||||
|
||||
AActor* owner = GetOwner();
|
||||
if (Target && owner) {
|
||||
USpineSkeletonComponent* skeleton = static_cast<USpineSkeletonComponent*>(Target->GetComponentByClass(USpineSkeletonComponent::StaticClass()));
|
||||
if (skeleton) {
|
||||
FTransform transform = skeleton->GetBoneWorldTransform(BoneName);
|
||||
if (UsePosition) owner->SetActorLocation(transform.GetLocation());
|
||||
if (UseRotation) owner->SetActorRotation(transform.GetRotation());
|
||||
if (UseScale) owner->SetActorScale3D(transform.GetScale3D());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
|
||||
class FSpinePlugin : public SpinePlugin {
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
|
||||
IMPLEMENT_MODULE( FSpinePlugin, SpinePlugin )
|
||||
|
||||
void FSpinePlugin::StartupModule() { }
|
||||
|
||||
|
||||
void FSpinePlugin::ShutdownModule() { }
|
||||
|
||||
// These are not used in the Spine UE4 plugin, see SpineAtlasAsset on how atlas page textures
|
||||
// are loaded, See SpineSkeletonRendererComponent on how these textures are used for rendering.
|
||||
extern "C" {
|
||||
void _spAtlasPage_createTexture (spAtlasPage* self, const char* path) { }
|
||||
void _spAtlasPage_disposeTexture (spAtlasPage* self) { }
|
||||
char* _spUtil_readFile (const char* path, int* length) { return 0; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePlugin.h"
|
||||
#include "SpineSkeletonDataAsset.h"
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "SpineSkeletonComponent.h"
|
||||
#include "SpineSkeletonAnimationComponent.h"
|
||||
#include "SpineSkeletonRendererComponent.h"
|
||||
#include "SpineBoneFollowerComponent.h"
|
||||
#include "SpineBoneDriverComponent.h"
|
||||
@ -0,0 +1,228 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
void UTrackEntry::SetTrackEntry(spTrackEntry* entry) {
|
||||
this->entry = entry;
|
||||
if (entry) entry->rendererObject = (void*)this;
|
||||
}
|
||||
|
||||
void callback(spAnimationState* state, spEventType type, spTrackEntry* entry, spEvent* event) {
|
||||
USpineSkeletonAnimationComponent* component = (USpineSkeletonAnimationComponent*)state->rendererObject;
|
||||
|
||||
if (entry->rendererObject) {
|
||||
UTrackEntry* uEntry = (UTrackEntry*)entry->rendererObject;
|
||||
if (type == SP_ANIMATION_START) {
|
||||
component->AnimationStart.Broadcast(uEntry);
|
||||
uEntry->AnimationStart.Broadcast(uEntry);
|
||||
}
|
||||
else if (type == SP_ANIMATION_INTERRUPT) {
|
||||
component->AnimationInterrupt.Broadcast(uEntry);
|
||||
uEntry->AnimationInterrupt.Broadcast(uEntry);
|
||||
} else if (type == SP_ANIMATION_EVENT) {
|
||||
FSpineEvent evt;
|
||||
evt.SetEvent(event);
|
||||
component->AnimationEvent.Broadcast(uEntry, evt);
|
||||
uEntry->AnimationEvent.Broadcast(uEntry, evt);
|
||||
}
|
||||
else if (type == SP_ANIMATION_COMPLETE) {
|
||||
component->AnimationComplete.Broadcast(uEntry);
|
||||
uEntry->AnimationComplete.Broadcast(uEntry);
|
||||
}
|
||||
else if (type == SP_ANIMATION_END) {
|
||||
component->AnimationEnd.Broadcast(uEntry);
|
||||
uEntry->AnimationEnd.Broadcast(uEntry);
|
||||
}
|
||||
else if (type == SP_ANIMATION_DISPOSE) {
|
||||
component->AnimationDispose.Broadcast(uEntry);
|
||||
uEntry->AnimationDispose.Broadcast(uEntry);
|
||||
uEntry->SetTrackEntry(nullptr);
|
||||
component->GCTrackEntry(uEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
USpineSkeletonAnimationComponent::USpineSkeletonAnimationComponent () {
|
||||
bWantsBeginPlay = true;
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
trackEntries.Empty();
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
|
||||
Super::Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
InternalTick(DeltaTime);
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime, bool CallDelegates) {
|
||||
CheckState();
|
||||
|
||||
if (state) {
|
||||
spAnimationState_update(state, DeltaTime);
|
||||
spAnimationState_apply(state, skeleton);
|
||||
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||
spSkeleton_updateWorldTransform(skeleton);
|
||||
if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::CheckState () {
|
||||
if (lastAtlas != Atlas || lastData != SkeletonData) {
|
||||
DisposeState();
|
||||
|
||||
if (Atlas && SkeletonData) {
|
||||
spSkeletonData* data = SkeletonData->GetSkeletonData(Atlas->GetAtlas(false), false);
|
||||
skeleton = spSkeleton_create(data);
|
||||
spAnimationStateData* stateData = SkeletonData->GetAnimationStateData(Atlas->GetAtlas(false));
|
||||
state = spAnimationState_create(stateData);
|
||||
state->rendererObject = (void*)this;
|
||||
state->listener = callback;
|
||||
trackEntries.Empty();
|
||||
}
|
||||
|
||||
lastAtlas = Atlas;
|
||||
lastData = SkeletonData;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::DisposeState () {
|
||||
if (state) {
|
||||
spAnimationState_dispose(state);
|
||||
state = nullptr;
|
||||
}
|
||||
|
||||
if (skeleton) {
|
||||
spSkeleton_dispose(skeleton);
|
||||
skeleton = nullptr;
|
||||
}
|
||||
|
||||
trackEntries.Empty();
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::FinishDestroy () {
|
||||
DisposeState();
|
||||
Super::FinishDestroy();
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::SetTimeScale(float timeScale) {
|
||||
CheckState();
|
||||
if (state) state->timeScale = timeScale;
|
||||
}
|
||||
|
||||
float USpineSkeletonAnimationComponent::GetTimeScale() {
|
||||
CheckState();
|
||||
if (state) return state->timeScale;
|
||||
return 1;
|
||||
}
|
||||
|
||||
UTrackEntry* USpineSkeletonAnimationComponent::SetAnimation (int trackIndex, FString animationName, bool loop) {
|
||||
CheckState();
|
||||
if (state && spSkeletonData_findAnimation(skeleton->data, TCHAR_TO_UTF8(*animationName))) {
|
||||
spTrackEntry* entry = spAnimationState_setAnimationByName(state, trackIndex, TCHAR_TO_UTF8(*animationName), loop ? 1 : 0);
|
||||
UTrackEntry* uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else return NewObject<UTrackEntry>();
|
||||
|
||||
}
|
||||
|
||||
UTrackEntry* USpineSkeletonAnimationComponent::AddAnimation (int trackIndex, FString animationName, bool loop, float delay) {
|
||||
CheckState();
|
||||
if (state && spSkeletonData_findAnimation(skeleton->data, TCHAR_TO_UTF8(*animationName))) {
|
||||
spTrackEntry* entry = spAnimationState_addAnimationByName(state, trackIndex, TCHAR_TO_UTF8(*animationName), loop ? 1 : 0, delay);
|
||||
UTrackEntry* uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry* USpineSkeletonAnimationComponent::SetEmptyAnimation (int trackIndex, float mixDuration) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
spTrackEntry* entry = spAnimationState_setEmptyAnimation(state, trackIndex, mixDuration);
|
||||
UTrackEntry* uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry* USpineSkeletonAnimationComponent::AddEmptyAnimation (int trackIndex, float mixDuration, float delay) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
spTrackEntry* entry = spAnimationState_addEmptyAnimation(state, trackIndex, mixDuration, delay);
|
||||
UTrackEntry* uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry* USpineSkeletonAnimationComponent::GetCurrent (int trackIndex) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
spTrackEntry* entry = spAnimationState_getCurrent(state, trackIndex);
|
||||
if (entry->rendererObject) {
|
||||
return (UTrackEntry*)entry->rendererObject;
|
||||
} else {
|
||||
UTrackEntry* uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
}
|
||||
} else return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::ClearTracks () {
|
||||
CheckState();
|
||||
if (state) {
|
||||
spAnimationState_clearTracks(state);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::ClearTrack (int trackIndex) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
spAnimationState_clearTrack(state, trackIndex);
|
||||
}
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,207 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
USpineSkeletonComponent::USpineSkeletonComponent () {
|
||||
bWantsBeginPlay = true;
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::SetSkin(const FString& skinName) {
|
||||
CheckState();
|
||||
if (skeleton) return spSkeleton_setSkinByName(skeleton, TCHAR_TO_UTF8(*skinName)) != 0;
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::SetAttachment (const FString& slotName, const FString& attachmentName) {
|
||||
CheckState();
|
||||
if (skeleton) return spSkeleton_setAttachment(skeleton, TCHAR_TO_UTF8(*slotName), TCHAR_TO_UTF8(*attachmentName)) != 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
FTransform USpineSkeletonComponent::GetBoneWorldTransform (const FString& BoneName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName));
|
||||
if (!bone) return FTransform();
|
||||
if (!bone->appliedValid) this->InternalTick(0, false);
|
||||
|
||||
// Need to fetch the renderer component to get world transform of actor plus
|
||||
// offset by renderer component and its parent component(s). If no renderer
|
||||
// component is found, this components owner's transform is used as a fallback
|
||||
FTransform baseTransform;
|
||||
AActor* owner = GetOwner();
|
||||
if (owner) {
|
||||
USpineSkeletonRendererComponent* rendererComponent = static_cast<USpineSkeletonRendererComponent*>(owner->GetComponentByClass(USpineSkeletonRendererComponent::StaticClass()));
|
||||
if (rendererComponent) baseTransform = rendererComponent->GetComponentTransform();
|
||||
else baseTransform = owner->GetActorTransform();
|
||||
}
|
||||
|
||||
FVector position(bone->worldX, 0, bone->worldY);
|
||||
FMatrix localTransform;
|
||||
localTransform.SetIdentity();
|
||||
localTransform.SetAxis(2, FVector(bone->a, 0, bone->c));
|
||||
localTransform.SetAxis(0, FVector(bone->b, 0, bone->d));
|
||||
localTransform.SetOrigin(FVector(bone->worldX, 0, bone->worldY));
|
||||
localTransform = localTransform * baseTransform.ToMatrixWithScale();
|
||||
|
||||
FTransform result;
|
||||
result.SetFromMatrix(localTransform);
|
||||
return result;
|
||||
}
|
||||
return FTransform();
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetBoneWorldPosition (const FString& BoneName, const FVector& position) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName));
|
||||
if (!bone) return;
|
||||
if (!bone->appliedValid) this->InternalTick(0, false);
|
||||
|
||||
// Need to fetch the renderer component to get world transform of actor plus
|
||||
// offset by renderer component and its parent component(s). If no renderer
|
||||
// component is found, this components owner's transform is used as a fallback
|
||||
FTransform baseTransform;
|
||||
AActor* owner = GetOwner();
|
||||
if (owner) {
|
||||
USpineSkeletonRendererComponent* rendererComponent = static_cast<USpineSkeletonRendererComponent*>(owner->GetComponentByClass(USpineSkeletonRendererComponent::StaticClass()));
|
||||
if (rendererComponent) baseTransform = rendererComponent->GetComponentTransform();
|
||||
else baseTransform = owner->GetActorTransform();
|
||||
}
|
||||
|
||||
baseTransform = baseTransform.Inverse();
|
||||
FVector localPosition = baseTransform.TransformPosition(position);
|
||||
float localX = 0, localY = 0;
|
||||
if (bone->parent) {
|
||||
spBone_worldToLocal(bone->parent, localPosition.X, localPosition.Z, &localX, &localY);
|
||||
} else {
|
||||
spBone_worldToLocal(bone, localPosition.X, localPosition.Z, &localX, &localY);
|
||||
}
|
||||
bone->x = localX;
|
||||
bone->y = localY;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::UpdateWorldTransform() {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spSkeleton_updateWorldTransform(skeleton);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetToSetupPose () {
|
||||
CheckState();
|
||||
if (skeleton) spSkeleton_setToSetupPose(skeleton);
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetBonesToSetupPose () {
|
||||
CheckState();
|
||||
if (skeleton) spSkeleton_setBonesToSetupPose(skeleton);
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetSlotsToSetupPose () {
|
||||
CheckState();
|
||||
if (skeleton) spSkeleton_setSlotsToSetupPose(skeleton);
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetFlipX (bool flipX) {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->flipX = flipX ? 1 : 0;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::GetFlipX() {
|
||||
CheckState();
|
||||
if (skeleton) return skeleton->flipX != 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetFlipY(bool flipY) {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->flipY = flipY ? 1 : 0;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::GetFlipY() {
|
||||
CheckState();
|
||||
if (skeleton) return skeleton->flipY != 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
InternalTick(DeltaTime);
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::InternalTick(float DeltaTime, bool CallDelegates) {
|
||||
CheckState();
|
||||
|
||||
if (skeleton) {
|
||||
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||
spSkeleton_updateWorldTransform(skeleton);
|
||||
if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::CheckState () {
|
||||
if (lastAtlas != Atlas || lastData != SkeletonData) {
|
||||
DisposeState();
|
||||
|
||||
if (Atlas && SkeletonData) {
|
||||
spSkeletonData* data = SkeletonData->GetSkeletonData(Atlas->GetAtlas(false), false);
|
||||
skeleton = spSkeleton_create(data);
|
||||
}
|
||||
|
||||
lastAtlas = Atlas;
|
||||
lastData = SkeletonData;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::DisposeState () {
|
||||
if (skeleton) {
|
||||
spSkeleton_dispose(skeleton);
|
||||
skeleton = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::FinishDestroy () {
|
||||
DisposeState();
|
||||
Super::FinishDestroy();
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,155 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
#include "spine/spine.h"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
FName USpineSkeletonDataAsset::GetSkeletonDataFileName () const {
|
||||
#if WITH_EDITORONLY_DATA
|
||||
TArray<FString> files;
|
||||
if (importData) importData->ExtractFilenames(files);
|
||||
if (files.Num() > 0) return FName(*files[0]);
|
||||
else return skeletonDataFileName;
|
||||
#else
|
||||
return skeletonDataFileName;
|
||||
#endif
|
||||
}
|
||||
|
||||
TArray<uint8>& USpineSkeletonDataAsset::GetRawData () {
|
||||
return this->rawData;
|
||||
}
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
void USpineSkeletonDataAsset::SetSkeletonDataFileName (const FName &SkeletonDataFileName) {
|
||||
importData->UpdateFilenameOnly(SkeletonDataFileName.ToString());
|
||||
TArray<FString> files;
|
||||
importData->ExtractFilenames(files);
|
||||
if (files.Num() > 0) this->skeletonDataFileName = FName(*files[0]);
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::PostInitProperties () {
|
||||
if (!HasAnyFlags(RF_ClassDefaultObject)) importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
Super::PostInitProperties();
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::GetAssetRegistryTags (TArray<FAssetRegistryTag>& OutTags) const {
|
||||
if (importData) {
|
||||
OutTags.Add(FAssetRegistryTag(SourceFileTagName(), importData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) );
|
||||
}
|
||||
|
||||
Super::GetAssetRegistryTags(OutTags);
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::Serialize (FArchive& Ar) {
|
||||
Super::Serialize(Ar);
|
||||
if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
|
||||
importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::BeginDestroy () {
|
||||
if (this->skeletonData) {
|
||||
spSkeletonData_dispose(this->skeletonData);
|
||||
this->skeletonData = nullptr;
|
||||
}
|
||||
if (this->animationStateData) {
|
||||
spAnimationStateData_dispose(this->animationStateData);
|
||||
this->animationStateData = nullptr;
|
||||
}
|
||||
Super::BeginDestroy();
|
||||
}
|
||||
|
||||
spSkeletonData* USpineSkeletonDataAsset::GetSkeletonData (spAtlas* Atlas, bool ForceReload) {
|
||||
if (!skeletonData || ForceReload) {
|
||||
if (skeletonData) {
|
||||
spSkeletonData_dispose(skeletonData);
|
||||
skeletonData = nullptr;
|
||||
}
|
||||
int dataLen = rawData.Num();
|
||||
if (skeletonDataFileName.GetPlainNameString().Contains(TEXT(".json"))) {
|
||||
spSkeletonJson* json = spSkeletonJson_create(Atlas);
|
||||
this->skeletonData = spSkeletonJson_readSkeletonData(json, (const char*)rawData.GetData());
|
||||
spSkeletonJson_dispose(json);
|
||||
} else {
|
||||
spSkeletonBinary* binary = spSkeletonBinary_create(Atlas);
|
||||
this->skeletonData = spSkeletonBinary_readSkeletonData(binary, (const unsigned char*)rawData.GetData(), (int)rawData.Num());
|
||||
spSkeletonBinary_dispose(binary);
|
||||
}
|
||||
if (animationStateData) {
|
||||
spAnimationStateData_dispose(animationStateData);
|
||||
GetAnimationStateData(Atlas);
|
||||
}
|
||||
lastAtlas = Atlas;
|
||||
}
|
||||
return this->skeletonData;
|
||||
}
|
||||
|
||||
spAnimationStateData* USpineSkeletonDataAsset::GetAnimationStateData(spAtlas* atlas) {
|
||||
if (!animationStateData) {
|
||||
spSkeletonData* skeletonData = GetSkeletonData(atlas, false);
|
||||
animationStateData = spAnimationStateData_create(skeletonData);
|
||||
}
|
||||
for (auto& data : MixData) {
|
||||
if (!data.From.IsEmpty() && !data.To.IsEmpty()) {
|
||||
const char* fromChar = TCHAR_TO_UTF8(*data.From);
|
||||
const char* toChar = TCHAR_TO_UTF8(*data.To);
|
||||
spAnimationStateData_setMixByName(animationStateData, fromChar, toChar, data.Mix);
|
||||
}
|
||||
}
|
||||
animationStateData->defaultMix = DefaultMix;
|
||||
return this->animationStateData;
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::SetMix(const FString& from, const FString& to, float mix) {
|
||||
FSpineAnimationStateMixData data;
|
||||
data.From = from;
|
||||
data.To = to;
|
||||
data.Mix = mix;
|
||||
this->MixData.Add(data);
|
||||
if (lastAtlas) {
|
||||
GetAnimationStateData(lastAtlas);
|
||||
}
|
||||
}
|
||||
|
||||
float USpineSkeletonDataAsset::GetMix(const FString& from, const FString& to) {
|
||||
for (auto& data : MixData) {
|
||||
if (data.From.Equals(from) && data.To.Equals(to)) return data.Mix;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,326 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
#include "Engine.h"
|
||||
#include "spine/spine.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
USpineSkeletonRendererComponent::USpineSkeletonRendererComponent (const FObjectInitializer& ObjectInitializer)
|
||||
: UProceduralMeshComponent(ObjectInitializer) {
|
||||
bWantsBeginPlay = true;
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> NormalMaterialRef(TEXT("/SpinePlugin/SpineUnlitNormalMaterial"));
|
||||
NormalBlendMaterial = NormalMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> AdditiveMaterialRef(TEXT("/SpinePlugin/SpineUnlitAdditiveMaterial"));
|
||||
AdditiveBlendMaterial = AdditiveMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> MultiplyMaterialRef(TEXT("/SpinePlugin/SpineUnlitMultiplyMaterial"));
|
||||
MultiplyBlendMaterial = MultiplyMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> ScreenMaterialRef(TEXT("/SpinePlugin/SpineUnlitScreenMaterial"));
|
||||
ScreenBlendMaterial = ScreenMaterialRef.Object;
|
||||
|
||||
|
||||
TextureParameterName = FName(TEXT("SpriteTexture"));
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::BeginPlay () {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
AActor* owner = GetOwner();
|
||||
if (owner) {
|
||||
UClass* skeletonClass = USpineSkeletonComponent::StaticClass();
|
||||
USpineSkeletonComponent* skeleton = Cast<USpineSkeletonComponent>(owner->GetComponentByClass(skeletonClass));
|
||||
|
||||
if (skeleton && !skeleton->IsBeingDestroyed() && skeleton->GetSkeleton() && skeleton->Atlas) {
|
||||
if (atlasNormalBlendMaterials.Num() != skeleton->Atlas->atlasPages.Num()) {
|
||||
atlasNormalBlendMaterials.SetNum(0);
|
||||
pageToNormalBlendMaterial.Empty();
|
||||
atlasAdditiveBlendMaterials.SetNum(0);
|
||||
pageToAdditiveBlendMaterial.Empty();
|
||||
atlasMultiplyBlendMaterials.SetNum(0);
|
||||
pageToMultiplyBlendMaterial.Empty();
|
||||
atlasScreenBlendMaterials.SetNum(0);
|
||||
pageToScreenBlendMaterial.Empty();
|
||||
|
||||
spAtlasPage* currPage = skeleton->Atlas->GetAtlas(false)->pages;
|
||||
for (int i = 0; i < skeleton->Atlas->atlasPages.Num(); i++) {
|
||||
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, owner);
|
||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||
atlasNormalBlendMaterials.Add(material);
|
||||
pageToNormalBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(AdditiveBlendMaterial, owner);
|
||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||
atlasAdditiveBlendMaterials.Add(material);
|
||||
pageToAdditiveBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(MultiplyBlendMaterial, owner);
|
||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||
atlasMultiplyBlendMaterials.Add(material);
|
||||
pageToMultiplyBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(ScreenBlendMaterial, owner);
|
||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||
atlasScreenBlendMaterials.Add(material);
|
||||
pageToScreenBlendMaterial.Add(currPage, material);
|
||||
|
||||
currPage = currPage->next;
|
||||
}
|
||||
} else {
|
||||
pageToNormalBlendMaterial.Empty();
|
||||
pageToAdditiveBlendMaterial.Empty();
|
||||
pageToMultiplyBlendMaterial.Empty();
|
||||
pageToScreenBlendMaterial.Empty();
|
||||
|
||||
spAtlasPage* currPage = skeleton->Atlas->GetAtlas(false)->pages;
|
||||
for (int i = 0; i < skeleton->Atlas->atlasPages.Num(); i++) {
|
||||
UTexture2D* texture = skeleton->Atlas->atlasPages[i];
|
||||
UTexture* oldTexture = nullptr;
|
||||
|
||||
UMaterialInstanceDynamic* current = atlasNormalBlendMaterials[i];
|
||||
if(!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, owner);
|
||||
material->SetTextureParameterValue(TextureParameterName, texture);
|
||||
atlasNormalBlendMaterials[i] = material;
|
||||
}
|
||||
pageToNormalBlendMaterial.Add(currPage, atlasNormalBlendMaterials[i]);
|
||||
|
||||
current = atlasAdditiveBlendMaterials[i];
|
||||
if(!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(AdditiveBlendMaterial, owner);
|
||||
material->SetTextureParameterValue(TextureParameterName, texture);
|
||||
atlasAdditiveBlendMaterials[i] = material;
|
||||
}
|
||||
pageToAdditiveBlendMaterial.Add(currPage, atlasAdditiveBlendMaterials[i]);
|
||||
|
||||
current = atlasMultiplyBlendMaterials[i];
|
||||
if(!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(MultiplyBlendMaterial, owner);
|
||||
material->SetTextureParameterValue(TextureParameterName, texture);
|
||||
atlasMultiplyBlendMaterials[i] = material;
|
||||
}
|
||||
pageToMultiplyBlendMaterial.Add(currPage, atlasMultiplyBlendMaterials[i]);
|
||||
|
||||
current = atlasScreenBlendMaterials[i];
|
||||
if(!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(ScreenBlendMaterial, owner);
|
||||
material->SetTextureParameterValue(TextureParameterName, texture);
|
||||
atlasScreenBlendMaterials[i] = material;
|
||||
}
|
||||
pageToScreenBlendMaterial.Add(currPage, atlasScreenBlendMaterials[i]);
|
||||
|
||||
currPage = currPage->next;
|
||||
}
|
||||
}
|
||||
UpdateMesh(skeleton->GetSkeleton());
|
||||
} else {
|
||||
ClearAllMeshSections();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::Flush (int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, UMaterialInstanceDynamic* Material) {
|
||||
if (Vertices.Num() == 0) return;
|
||||
SetMaterial(Idx, Material);
|
||||
CreateMeshSection(Idx, Vertices, Indices, TArray<FVector>(), Uvs, Colors, TArray<FProcMeshTangent>(), false);
|
||||
Vertices.SetNum(0);
|
||||
Indices.SetNum(0);
|
||||
Uvs.SetNum(0);
|
||||
Colors.SetNum(0);
|
||||
Idx++;
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* Skeleton) {
|
||||
TArray<FVector> vertices;
|
||||
TArray<int32> indices;
|
||||
TArray<FVector2D> uvs;
|
||||
TArray<FColor> colors;
|
||||
|
||||
TArray<float> worldVertices;
|
||||
worldVertices.SetNumUninitialized(2 * 1024);
|
||||
int idx = 0;
|
||||
int meshSection = 0;
|
||||
UMaterialInstanceDynamic* lastMaterial = nullptr;
|
||||
|
||||
ClearAllMeshSections();
|
||||
|
||||
float depthOffset = 0;
|
||||
|
||||
for (int i = 0; i < Skeleton->slotsCount; ++i) {
|
||||
spSlot* slot = Skeleton->drawOrder[i];
|
||||
spAttachment* attachment = slot->attachment;
|
||||
if (!attachment) continue;
|
||||
|
||||
if (attachment->type == SP_ATTACHMENT_REGION) {
|
||||
spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment;
|
||||
spAtlasRegion* region = (spAtlasRegion*)regionAttachment->rendererObject;
|
||||
|
||||
UMaterialInstanceDynamic* material = nullptr;
|
||||
|
||||
// if the user switches the atlas data while not having switched
|
||||
// to the correct skeleton data yet, we won't find any regions.
|
||||
// ignore regions for which we can't find a material
|
||||
switch(slot->data->blendMode) {
|
||||
case SP_BLEND_MODE_NORMAL:
|
||||
if (!pageToNormalBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToNormalBlendMaterial[region->page];
|
||||
break;
|
||||
case SP_BLEND_MODE_ADDITIVE:
|
||||
if (!pageToAdditiveBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToAdditiveBlendMaterial[region->page];
|
||||
break;
|
||||
case SP_BLEND_MODE_MULTIPLY:
|
||||
if (!pageToMultiplyBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToMultiplyBlendMaterial[region->page];
|
||||
break;
|
||||
case SP_BLEND_MODE_SCREEN:
|
||||
if (!pageToScreenBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToScreenBlendMaterial[region->page];
|
||||
break;
|
||||
default:
|
||||
if (!pageToNormalBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToNormalBlendMaterial[region->page];
|
||||
}
|
||||
|
||||
if (lastMaterial != material) {
|
||||
Flush(meshSection, vertices, indices, uvs, colors, lastMaterial);
|
||||
lastMaterial = material;
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, worldVertices.GetData());
|
||||
|
||||
uint8 r = static_cast<uint8>(Skeleton->r * slot->r * 255);
|
||||
uint8 g = static_cast<uint8>(Skeleton->g * slot->g * 255);
|
||||
uint8 b = static_cast<uint8>(Skeleton->b * slot->b * 255);
|
||||
uint8 a = static_cast<uint8>(Skeleton->a * slot->a * 255);
|
||||
|
||||
colors.Add(FColor(r, g, b, a));
|
||||
vertices.Add(FVector(worldVertices[0], depthOffset, worldVertices[1]));
|
||||
uvs.Add(FVector2D(regionAttachment->uvs[0], regionAttachment->uvs[1]));
|
||||
|
||||
colors.Add(FColor(r, g, b, a));
|
||||
vertices.Add(FVector(worldVertices[2], depthOffset, worldVertices[3]));
|
||||
uvs.Add(FVector2D(regionAttachment->uvs[2], regionAttachment->uvs[3]));
|
||||
|
||||
colors.Add(FColor(r, g, b, a));
|
||||
vertices.Add(FVector(worldVertices[4], depthOffset, worldVertices[5]));
|
||||
uvs.Add(FVector2D(regionAttachment->uvs[4], regionAttachment->uvs[5]));
|
||||
|
||||
colors.Add(FColor(r, g, b, a));
|
||||
vertices.Add(FVector(worldVertices[6], depthOffset, worldVertices[7]));
|
||||
uvs.Add(FVector2D(regionAttachment->uvs[6], regionAttachment->uvs[7]));
|
||||
|
||||
indices.Add(idx + 0);
|
||||
indices.Add(idx + 1);
|
||||
indices.Add(idx + 2);
|
||||
indices.Add(idx + 0);
|
||||
indices.Add(idx + 2);
|
||||
indices.Add(idx + 3);
|
||||
idx += 4;
|
||||
depthOffset += this->DepthOffset;
|
||||
} else if (attachment->type == SP_ATTACHMENT_MESH) {
|
||||
spMeshAttachment* mesh = (spMeshAttachment*)attachment;
|
||||
spAtlasRegion* region = (spAtlasRegion*)mesh->rendererObject;
|
||||
UMaterialInstanceDynamic* material = nullptr;
|
||||
|
||||
// if the user switches the atlas data while not having switched
|
||||
// to the correct skeleton data yet, we won't find any regions.
|
||||
// ignore regions for which we can't find a material
|
||||
switch(slot->data->blendMode) {
|
||||
case SP_BLEND_MODE_NORMAL:
|
||||
if (!pageToNormalBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToNormalBlendMaterial[region->page];
|
||||
break;
|
||||
case SP_BLEND_MODE_ADDITIVE:
|
||||
if (!pageToAdditiveBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToAdditiveBlendMaterial[region->page];
|
||||
break;
|
||||
case SP_BLEND_MODE_MULTIPLY:
|
||||
if (!pageToMultiplyBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToMultiplyBlendMaterial[region->page];
|
||||
break;
|
||||
case SP_BLEND_MODE_SCREEN:
|
||||
if (!pageToScreenBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToScreenBlendMaterial[region->page];
|
||||
break;
|
||||
default:
|
||||
if (!pageToNormalBlendMaterial.Contains(region->page)) continue;
|
||||
material = pageToNormalBlendMaterial[region->page];
|
||||
}
|
||||
|
||||
if (lastMaterial != material) {
|
||||
Flush(meshSection, vertices, indices, uvs, colors, lastMaterial);
|
||||
lastMaterial = material;
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
if (mesh->super.worldVerticesLength> worldVertices.Num()) {
|
||||
worldVertices.SetNum(mesh->super.worldVerticesLength);
|
||||
}
|
||||
spMeshAttachment_computeWorldVertices(mesh, slot, worldVertices.GetData());
|
||||
|
||||
uint8 r = static_cast<uint8>(Skeleton->r * slot->r * 255);
|
||||
uint8 g = static_cast<uint8>(Skeleton->g * slot->g * 255);
|
||||
uint8 b = static_cast<uint8>(Skeleton->b * slot->b * 255);
|
||||
uint8 a = static_cast<uint8>(Skeleton->a * slot->a * 255);
|
||||
|
||||
for (int j = 0; j < mesh->super.worldVerticesLength; j += 2) {
|
||||
colors.Add(FColor(r, g, b, a));
|
||||
vertices.Add(FVector(worldVertices[j], depthOffset, worldVertices[j + 1]));
|
||||
uvs.Add(FVector2D(mesh->uvs[j], mesh->uvs[j + 1]));
|
||||
}
|
||||
|
||||
for (int j = 0; j < mesh->trianglesCount; j++) {
|
||||
indices.Add(idx + mesh->triangles[j]);
|
||||
}
|
||||
idx += mesh->super.worldVerticesLength >> 1;
|
||||
depthOffset += this->DepthOffset;
|
||||
SetMaterial(meshSection, material);
|
||||
}
|
||||
}
|
||||
|
||||
Flush(meshSection, vertices, indices, uvs, colors, lastMaterial);
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,76 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine.h"
|
||||
#include "spine/spine.h"
|
||||
#include "SpineAtlasAsset.generated.h"
|
||||
|
||||
UCLASS(ClassGroup=(Spine))
|
||||
class SPINEPLUGIN_API USpineAtlasAsset: public UObject {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
spAtlas* GetAtlas (bool ForceReload = false);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TArray<UTexture2D*> atlasPages;
|
||||
|
||||
FString GetRawData () const;
|
||||
|
||||
FName GetAtlasFileName () const;
|
||||
|
||||
virtual void BeginDestroy () override;
|
||||
|
||||
protected:
|
||||
spAtlas* atlas = nullptr;
|
||||
|
||||
UPROPERTY()
|
||||
FString rawData;
|
||||
|
||||
UPROPERTY()
|
||||
FName atlasFileName;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
public:
|
||||
void SetRawData (const FString &RawData);
|
||||
void SetAtlasFileName (const FName &AtlasFileName);
|
||||
|
||||
protected:
|
||||
UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings)
|
||||
class UAssetImportData* importData;
|
||||
|
||||
virtual void PostInitProperties ( ) override;
|
||||
virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const override;
|
||||
virtual void Serialize (FArchive& Ar) override;
|
||||
#endif
|
||||
};
|
||||
@ -0,0 +1,69 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SpineBoneDriverComponent.generated.h"
|
||||
|
||||
class USpineSkeletonComponent;
|
||||
|
||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineBoneDriverComponent : public UActorComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
AActor* Target = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString BoneName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UsePosition = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseRotation = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseScale = true;
|
||||
|
||||
USpineBoneDriverComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
|
||||
|
||||
protected:
|
||||
UFUNCTION()
|
||||
void BeforeUpdateWorldTransform(USpineSkeletonComponent* skeleton);
|
||||
|
||||
USpineSkeletonComponent* lastBoundComponent = nullptr;
|
||||
};
|
||||
@ -0,0 +1,62 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SpineBoneFollowerComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineBoneFollowerComponent : public UActorComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
AActor* Target = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString BoneName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UsePosition = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseRotation = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseScale = true;
|
||||
|
||||
USpineBoneFollowerComponent ();
|
||||
|
||||
virtual void BeginPlay () override;
|
||||
|
||||
virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
};
|
||||
@ -0,0 +1,47 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ModuleManager.h"
|
||||
|
||||
class SPINEPLUGIN_API SpinePlugin : public IModuleInterface {
|
||||
|
||||
public:
|
||||
|
||||
static inline SpinePlugin& Get() {
|
||||
return FModuleManager::LoadModuleChecked< SpinePlugin >( "SpinePlugin" );
|
||||
}
|
||||
|
||||
static inline bool IsAvailable() {
|
||||
return FModuleManager::Get().IsModuleLoaded( "SpinePlugin" );
|
||||
}
|
||||
};
|
||||
|
||||
@ -0,0 +1,278 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SpineSkeletonComponent.h"
|
||||
#include "spine/spine.h"
|
||||
#include "SpineSkeletonAnimationComponent.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType, Category="Spine")
|
||||
struct SPINEPLUGIN_API FSpineEvent {
|
||||
GENERATED_BODY();
|
||||
|
||||
public:
|
||||
void SetEvent(spEvent* event) {
|
||||
Name = FString(UTF8_TO_TCHAR(event->data->name));
|
||||
if (event->stringValue) {
|
||||
StringValue = FString(UTF8_TO_TCHAR(event->stringValue));
|
||||
}
|
||||
this->IntValue = event->intValue;
|
||||
this->FloatValue = event->floatValue;
|
||||
this->Time = event->time;
|
||||
}
|
||||
|
||||
UPROPERTY(BlueprintReadonly)
|
||||
FString Name;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FString StringValue;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
int IntValue;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
float FloatValue;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
float Time;
|
||||
};
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationStartDelegate, UTrackEntry*, entry);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FSpineAnimationEventDelegate, UTrackEntry*, entry, FSpineEvent, evt);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationInterruptDelegate, UTrackEntry*, entry);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationCompleteDelegate, UTrackEntry*, entry);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationEndDelegate, UTrackEntry*, entry);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationDisposeDelegate, UTrackEntry*, entry);
|
||||
|
||||
UCLASS(ClassGroup=(Spine), meta=(BlueprintSpawnableComponent), BlueprintType)
|
||||
class SPINEPLUGIN_API UTrackEntry: public UObject {
|
||||
GENERATED_BODY ()
|
||||
|
||||
public:
|
||||
|
||||
UTrackEntry () { }
|
||||
|
||||
void SetTrackEntry (spTrackEntry* entry);
|
||||
spTrackEntry* GetTrackEntry();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
int GetTrackIndex () { return entry ? entry->trackIndex : 0; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
bool GetLoop () { return entry ? entry->loop != 0 : false; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetLoop (bool loop) { if (entry) entry->loop = loop ? 1 : 0; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetEventThreshold () { return entry ? entry->eventThreshold : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetEventThreshold(float eventThreshold) { if (entry) entry->eventThreshold = eventThreshold; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetAttachmentThreshold() { return entry ? entry->attachmentThreshold : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetAttachmentThreshold(float attachmentThreshold) { if (entry) entry->attachmentThreshold = attachmentThreshold; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetDrawOrderThreshold() { return entry ? entry->drawOrderThreshold : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetDrawOrderThreshold(float drawOrderThreshold) { if (entry) entry->drawOrderThreshold = drawOrderThreshold; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetAnimationStart() { return entry ? entry->animationStart : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetAnimationStart(float animationStart) { if (entry) entry->animationStart = animationStart; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetAnimationEnd() { return entry ? entry->animationEnd : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetAnimationEnd(float animationEnd) { if (entry) entry->animationEnd = animationEnd; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetAnimationLast() { return entry ? entry->animationLast : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetAnimationLast(float animationLast) { if (entry) entry->animationLast = animationLast; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetNextAnimationLast() { return entry ? entry->nextAnimationLast : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetNextAnimationLast(float nextAnimationLast) { if (entry) entry->nextAnimationLast = nextAnimationLast; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetDelay() { return entry ? entry->delay : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetDelay(float delay) { if (entry) entry->delay = delay; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetTrackTime() { return entry ? entry->trackTime : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetTrackTime(float trackTime) { if (entry) entry->trackTime = trackTime; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetTrackLast() { return entry ? entry->trackLast : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetTrackLast(float trackLast) { if (entry) entry->trackLast = trackLast; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetNextTrackLast() { return entry ? entry->nextTrackLast : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetNextTrackLast(float nextTrackLast) { if (entry) entry->nextTrackLast = nextTrackLast; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetTrackEnd() { return entry ? entry->trackEnd : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetTrackEnd(float trackEnd) { if (entry) entry->trackEnd = trackEnd; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetTimeScale() { return entry ? entry->timeScale : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetTimeScale(float timeScale) { if (entry) entry->timeScale = timeScale; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetAlpha() { return entry ? entry->alpha : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetAlpha(float alpha) { if (entry) entry->alpha = alpha; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetMixTime() { return entry ? entry->mixTime : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetMixTime(float mixTime) { if (entry) entry->mixTime = mixTime; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetMixDuration() { return entry ? entry->mixDuration : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetMixDuration(float mixDuration) { if (entry) entry->mixDuration = mixDuration; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
float GetMixAlpha() { return entry ? entry->mixAlpha : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetMixAlpha(float mixAlpha) { if (entry) entry->mixAlpha = mixAlpha; }
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationStartDelegate AnimationStart;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationInterruptDelegate AnimationInterrupt;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationEventDelegate AnimationEvent;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationCompleteDelegate AnimationComplete;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationEndDelegate AnimationEnd;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationDisposeDelegate AnimationDispose;
|
||||
|
||||
protected:
|
||||
spTrackEntry* entry = nullptr;
|
||||
};
|
||||
|
||||
class USpineAtlasAsset;
|
||||
UCLASS(ClassGroup=(Spine), meta=(BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineSkeletonAnimationComponent: public USpineSkeletonComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
spAnimationState* GetAnimationState () { return state; };
|
||||
|
||||
USpineSkeletonAnimationComponent ();
|
||||
|
||||
virtual void BeginPlay () override;
|
||||
|
||||
virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
virtual void FinishDestroy () override;
|
||||
|
||||
// Blueprint functions
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
void SetTimeScale(float timeScale);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
float GetTimeScale();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
UTrackEntry* SetAnimation (int trackIndex, FString animationName, bool loop);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
UTrackEntry* AddAnimation (int trackIndex, FString animationName, bool loop, float delay);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
UTrackEntry* SetEmptyAnimation (int trackIndex, float mixDuration);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
UTrackEntry* AddEmptyAnimation (int trackIndex, float mixDuration, float delay);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
UTrackEntry* GetCurrent (int trackIndex);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
void ClearTracks ();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|Animation")
|
||||
void ClearTrack (int trackIndex);
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category="Components|Spine|Animation")
|
||||
FSpineAnimationStartDelegate AnimationStart;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category="Components|Spine|Animation")
|
||||
FSpineAnimationInterruptDelegate AnimationInterrupt;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category="Components|Spine|Animation")
|
||||
FSpineAnimationEventDelegate AnimationEvent;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category="Components|Spine|Animation")
|
||||
FSpineAnimationCompleteDelegate AnimationComplete;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category="Components|Spine|Animation")
|
||||
FSpineAnimationEndDelegate AnimationEnd;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category="Components|Spine|Animation")
|
||||
FSpineAnimationDisposeDelegate AnimationDispose;
|
||||
|
||||
// used in C event callback. Needs to be public as we can't call
|
||||
// protected methods from plain old C function.
|
||||
void GCTrackEntry(UTrackEntry* entry) { trackEntries.Remove(entry); }
|
||||
protected:
|
||||
virtual void CheckState () override;
|
||||
virtual void InternalTick(float DeltaTime, bool CallDelegates = true) override;
|
||||
virtual void DisposeState () override;
|
||||
|
||||
spAnimationState* state;
|
||||
|
||||
// keep track of track entries so they won't get GCed while
|
||||
// in transit within a blueprint
|
||||
UPROPERTY()
|
||||
TSet<UTrackEntry*> trackEntries;
|
||||
};
|
||||
@ -0,0 +1,114 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "spine/spine.h"
|
||||
#include "SpineSkeletonComponent.generated.h"
|
||||
|
||||
class USpineSkeletonComponent;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineBeforeUpdateWorldTransformDelegate, USpineSkeletonComponent*, skeleton);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAfterUpdateWorldTransformDelegate, USpineSkeletonComponent*, skeleton);
|
||||
|
||||
class USpineAtlasAsset;
|
||||
UCLASS(ClassGroup=(Spine), meta=(BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineSkeletonComponent: public UActorComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||
USpineAtlasAsset* Atlas;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||
USpineSkeletonDataAsset* SkeletonData;
|
||||
|
||||
spSkeleton* GetSkeleton () { return skeleton; };
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetSkin (const FString& SkinName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetAttachment (const FString& slotName, const FString& attachmentName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
FTransform GetBoneWorldTransform (const FString& BoneName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetBoneWorldPosition (const FString& BoneName, const FVector& position);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void UpdateWorldTransform();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetToSetupPose ();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetBonesToSetupPose ();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetSlotsToSetupPose();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetFlipX(bool flipX);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool GetFlipX();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetFlipY(bool flipY);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool GetFlipY();
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton")
|
||||
FSpineBeforeUpdateWorldTransformDelegate BeforeUpdateWorldTransform;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton")
|
||||
FSpineAfterUpdateWorldTransformDelegate AfterUpdateWorldTransform;
|
||||
|
||||
USpineSkeletonComponent ();
|
||||
|
||||
virtual void BeginPlay () override;
|
||||
|
||||
virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
virtual void FinishDestroy () override;
|
||||
|
||||
protected:
|
||||
virtual void CheckState ();
|
||||
virtual void InternalTick(float DeltaTime, bool CallDelegates = true);
|
||||
virtual void DisposeState ();
|
||||
|
||||
spSkeleton* skeleton;
|
||||
USpineAtlasAsset* lastAtlas = nullptr;
|
||||
USpineSkeletonDataAsset* lastData = nullptr;
|
||||
};
|
||||
@ -0,0 +1,97 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine.h"
|
||||
#include "spine/spine.h"
|
||||
#include "SpineSkeletonDataAsset.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType, Category = "Spine")
|
||||
struct SPINEPLUGIN_API FSpineAnimationStateMixData {
|
||||
GENERATED_BODY();
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString From;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString To;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
float Mix = 0;
|
||||
};
|
||||
|
||||
UCLASS(ClassGroup=(Spine))
|
||||
class SPINEPLUGIN_API USpineSkeletonDataAsset: public UObject {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
spSkeletonData* GetSkeletonData(spAtlas* Atlas, bool ForceReload = false);
|
||||
|
||||
spAnimationStateData* GetAnimationStateData(spAtlas* atlas);
|
||||
void SetMix(const FString& from, const FString& to, float mix);
|
||||
float GetMix(const FString& from, const FString& to);
|
||||
|
||||
FName GetSkeletonDataFileName () const;
|
||||
TArray<uint8>& GetRawData ();
|
||||
|
||||
virtual void BeginDestroy () override;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
float DefaultMix = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TArray<FSpineAnimationStateMixData> MixData;
|
||||
|
||||
protected:
|
||||
UPROPERTY()
|
||||
TArray<uint8> rawData;
|
||||
|
||||
UPROPERTY()
|
||||
FName skeletonDataFileName;
|
||||
|
||||
spSkeletonData* skeletonData;
|
||||
spAnimationStateData* animationStateData;
|
||||
spAtlas* lastAtlas;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
public:
|
||||
void SetSkeletonDataFileName (const FName &skeletonDataFileName);
|
||||
|
||||
protected:
|
||||
UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings)
|
||||
class UAssetImportData* importData;
|
||||
|
||||
virtual void PostInitProperties ( ) override;
|
||||
virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const override;
|
||||
virtual void Serialize (FArchive& Ar) override;
|
||||
#endif
|
||||
};
|
||||
@ -0,0 +1,89 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "ProceduralMeshComponent.h"
|
||||
#include "SpineSkeletonAnimationComponent.h"
|
||||
#include "SpineSkeletonRendererComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS(ClassGroup=(Spine), meta=(BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineSkeletonRendererComponent: public UProceduralMeshComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
USpineSkeletonRendererComponent (const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
virtual void BeginPlay () override;
|
||||
|
||||
virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface* NormalBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface* AdditiveBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface* MultiplyBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface* ScreenBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
float DepthOffset = 0.1f;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
FName TextureParameterName;
|
||||
|
||||
protected:
|
||||
void UpdateMesh (spSkeleton* Skeleton);
|
||||
|
||||
void Flush (int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, UMaterialInstanceDynamic* Material);
|
||||
|
||||
// Need to hold on to the dynamic instances, or the GC will kill us while updating them
|
||||
UPROPERTY()
|
||||
TArray<UMaterialInstanceDynamic*> atlasNormalBlendMaterials;
|
||||
TMap<spAtlasPage*, UMaterialInstanceDynamic*> pageToNormalBlendMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UMaterialInstanceDynamic*> atlasAdditiveBlendMaterials;
|
||||
TMap<spAtlasPage*, UMaterialInstanceDynamic*> pageToAdditiveBlendMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UMaterialInstanceDynamic*> atlasMultiplyBlendMaterials;
|
||||
TMap<spAtlasPage*, UMaterialInstanceDynamic*> pageToMultiplyBlendMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UMaterialInstanceDynamic*> atlasScreenBlendMaterials;
|
||||
TMap<spAtlasPage*, UMaterialInstanceDynamic*> pageToScreenBlendMaterial;
|
||||
};
|
||||
@ -0,0 +1,15 @@
|
||||
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
namespace UnrealBuildTool.Rules
|
||||
{
|
||||
public class SpinePlugin : ModuleRules
|
||||
{
|
||||
public SpinePlugin(TargetInfo Target)
|
||||
{
|
||||
PublicIncludePaths.AddRange(new string[] { "SpinePlugin/Public", "SpinePlugin/Public/spine-c/include" });
|
||||
PrivateIncludePaths.AddRange(new string[] { "SpinePlugin/Private", "SpinePlugin/Public/spine-c/include" });
|
||||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "RHI", "RenderCore", "ShaderCore", "ProceduralMeshComponent" });
|
||||
OptimizeCode = CodeOptimization.Never;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
spine-ue4/Plugins/SpinePlugin/SpinePlugin.uplugin
Normal file
29
spine-ue4/Plugins/SpinePlugin/SpinePlugin.uplugin
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"FileVersion" : 3,
|
||||
"Version" : 1,
|
||||
"VersionName" : "1.0",
|
||||
"FriendlyName" : "Spine Plugin",
|
||||
"Description" : "A plugin to load and render Spine animations in Unreal Engine",
|
||||
"Category" : "2D",
|
||||
"CreatedBy" : "Esoteric Software",
|
||||
"CreatedByURL" : "http://esotericsoftware.com",
|
||||
"DocsURL" : "",
|
||||
"MarketplaceURL" : "",
|
||||
"SupportURL" : "",
|
||||
"EnabledByDefault" : true,
|
||||
"CanContainContent" : true,
|
||||
"IsBetaVersion" : false,
|
||||
"Installed" : false,
|
||||
"Modules" :
|
||||
[
|
||||
{
|
||||
"Name" : "SpinePlugin",
|
||||
"Type" : "Runtime",
|
||||
"LoadingPhase" : "PreDefault"
|
||||
},
|
||||
{
|
||||
"Name" : "SpineEditorPlugin",
|
||||
"Type" : "Editor"
|
||||
}
|
||||
]
|
||||
}
|
||||
35
spine-ue4/README.md
Normal file
35
spine-ue4/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# spine-ue4
|
||||
The spine-ue4 runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Unreal Engine 4](https://www.unrealengine.com/). spine-ue4 is based on [spine-c](https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-c).
|
||||
|
||||
## Licensing
|
||||
|
||||
This Spine Runtime may only be used for personal or internal use, typically to evaluate Spine before purchasing. If you would like to incorporate a Spine Runtime into your applications, distribute software containing a Spine Runtime, or modify a Spine Runtime, then you will need a valid [Spine license](https://esotericsoftware.com/spine-purchase). Please see the [Spine Runtimes Software License](https://github.com/EsotericSoftware/spine-runtimes/blob/master/LICENSE) for detailed information.
|
||||
|
||||
The Spine Runtimes are developed with the intent to be used with data exported from Spine. By purchasing Spine, `Section 2` of the [Spine Software License](https://esotericsoftware.com/files/license.txt) grants the right to create and distribute derivative works of the Spine Runtimes.
|
||||
|
||||
## Spine version
|
||||
|
||||
spine-ue4 works with data exported from Spine 3.4.02.
|
||||
|
||||
spine-ue4 supports all Spine features.
|
||||
|
||||
spine-ue4 does not support multiply and screen blending. spine-ue4 does not support pre-multiplied alpha atlases.
|
||||
|
||||
## Usage
|
||||
### [Please see the spine-ue4 guide for full documentation](http://esotericsoftware.com/spine-ue4)
|
||||
|
||||
1. Create a new Unreal Engine code project. You don't need to write C++, but the code project is needed for the plugin to compile. See the [Unreal Engine documentation](https://docs.unrealengine.com/latest/INT/) or have a look at the example in this repository.
|
||||
2. Download the Spine Runtimes source using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip)
|
||||
3. Copy the `Plugins` folder from this directory to your new project's root directory.
|
||||
4. Copy the `spine-c` folder from this repositories root directory to your project's `Plugins/SpinePlugin/Sources/SpinePlugin/Public/` directory.
|
||||
5. Open the Unreal Project in the Unreal Editor
|
||||
|
||||
See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documentation#runtimesTitle) on how to use the APIs or check out the Spine UE4 example.
|
||||
|
||||
## Example
|
||||
### [Please see the spine-ue4 guide for full documentation](http://esotericsoftware.com/spine-ue4)
|
||||
|
||||
The Spine UE4 example works on all platforms supported by Unreal Engine.
|
||||
|
||||
1. Copy the `spine-c` folder from this repositories root directory to your `Plugins/SpinePlugin/Sources/SpinePlugin/Public/` directory.
|
||||
2. Open the SpineUE4.uproject file with Unreal Editor
|
||||
25
spine-ue4/Source/SpineUE4.Target.cs
Normal file
25
spine-ue4/Source/SpineUE4.Target.cs
Normal file
@ -0,0 +1,25 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class SpineUE4Target : TargetRules
|
||||
{
|
||||
public SpineUE4Target(TargetInfo Target)
|
||||
{
|
||||
Type = TargetType.Game;
|
||||
}
|
||||
|
||||
//
|
||||
// TargetRules interface.
|
||||
//
|
||||
|
||||
public override void SetupBinaries(
|
||||
TargetInfo Target,
|
||||
ref List<UEBuildBinaryConfiguration> OutBuildBinaryConfigurations,
|
||||
ref List<string> OutExtraModuleNames
|
||||
)
|
||||
{
|
||||
OutExtraModuleNames.AddRange( new string[] { "SpineUE4" } );
|
||||
}
|
||||
}
|
||||
21
spine-ue4/Source/SpineUE4/SpineUE4.Build.cs
Normal file
21
spine-ue4/Source/SpineUE4/SpineUE4.Build.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class SpineUE4 : ModuleRules
|
||||
{
|
||||
public SpineUE4(TargetInfo Target)
|
||||
{
|
||||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ProceduralMeshComponent" });
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(new string[] { });
|
||||
|
||||
// Uncomment if you are using Slate UI
|
||||
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
|
||||
|
||||
// Uncomment if you are using online features
|
||||
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
|
||||
|
||||
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
|
||||
}
|
||||
}
|
||||
5
spine-ue4/Source/SpineUE4/SpineUE4.cpp
Normal file
5
spine-ue4/Source/SpineUE4/SpineUE4.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "SpineUE4.h"
|
||||
|
||||
IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, SpineUE4, "SpineUE4" );
|
||||
6
spine-ue4/Source/SpineUE4/SpineUE4.h
Normal file
6
spine-ue4/Source/SpineUE4/SpineUE4.h
Normal file
@ -0,0 +1,6 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine.h"
|
||||
|
||||
8
spine-ue4/Source/SpineUE4/SpineUE4GameMode.cpp
Normal file
8
spine-ue4/Source/SpineUE4/SpineUE4GameMode.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "SpineUE4.h"
|
||||
#include "SpineUE4GameMode.h"
|
||||
|
||||
|
||||
|
||||
|
||||
19
spine-ue4/Source/SpineUE4/SpineUE4GameMode.h
Normal file
19
spine-ue4/Source/SpineUE4/SpineUE4GameMode.h
Normal file
@ -0,0 +1,19 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameFramework/GameMode.h"
|
||||
#include "SpineUE4GameMode.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class SPINEUE4_API ASpineUE4GameMode : public AGameMode
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
25
spine-ue4/Source/SpineUE4Editor.Target.cs
Normal file
25
spine-ue4/Source/SpineUE4Editor.Target.cs
Normal file
@ -0,0 +1,25 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class SpineUE4EditorTarget : TargetRules
|
||||
{
|
||||
public SpineUE4EditorTarget(TargetInfo Target)
|
||||
{
|
||||
Type = TargetType.Editor;
|
||||
}
|
||||
|
||||
//
|
||||
// TargetRules interface.
|
||||
//
|
||||
|
||||
public override void SetupBinaries(
|
||||
TargetInfo Target,
|
||||
ref List<UEBuildBinaryConfiguration> OutBuildBinaryConfigurations,
|
||||
ref List<string> OutExtraModuleNames
|
||||
)
|
||||
{
|
||||
OutExtraModuleNames.AddRange( new string[] { "SpineUE4" } );
|
||||
}
|
||||
}
|
||||
16
spine-ue4/SpineUE4.uproject
Normal file
16
spine-ue4/SpineUE4.uproject
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"EngineAssociation": "4.14",
|
||||
"Category": "",
|
||||
"Description": "",
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "SpineUE4",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default",
|
||||
"AdditionalDependencies": [
|
||||
"Engine"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user