mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
Merge branch '4.1' into 4.2-beta
This commit is contained in:
commit
08b56ea1ca
8
.github/workflows/spine-godot-v4.yml
vendored
8
.github/workflows/spine-godot-v4.yml
vendored
@ -13,8 +13,8 @@ env:
|
|||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
AWS_EC2_METADATA_DISABLED: true
|
AWS_EC2_METADATA_DISABLED: true
|
||||||
EM_VERSION: 3.1.18
|
EM_VERSION: 3.1.18
|
||||||
GODOT_TAG: 4.0-stable
|
GODOT_TAG: 4.0.1-stable
|
||||||
GODOT_VERSION: 4.0.stable
|
GODOT_VERSION: 4.0.1.stable
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ jobs:
|
|||||||
path: spine-godot/godot/bin/godot.windows.editor.x86_64.exe
|
path: spine-godot/godot/bin/godot.windows.editor.x86_64.exe
|
||||||
|
|
||||||
godot-editor-linux:
|
godot-editor-linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
@ -135,7 +135,7 @@ jobs:
|
|||||||
path: spine-godot/godot/bin/macos.zip
|
path: spine-godot/godot/bin/macos.zip
|
||||||
|
|
||||||
godot-template-linux:
|
godot-template-linux:
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
6
.github/workflows/spine-godot.yml
vendored
6
.github/workflows/spine-godot.yml
vendored
@ -13,8 +13,8 @@ env:
|
|||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
AWS_EC2_METADATA_DISABLED: true
|
AWS_EC2_METADATA_DISABLED: true
|
||||||
EM_VERSION: 3.1.14
|
EM_VERSION: 3.1.14
|
||||||
GODOT_TAG: 3.5.1-stable
|
GODOT_TAG: 3.5.2-stable
|
||||||
GODOT_VERSION: 3.5.1.stable
|
GODOT_VERSION: 3.5.2.stable
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ jobs:
|
|||||||
path: spine-godot/godot/bin/osx.zip
|
path: spine-godot/godot/bin/osx.zip
|
||||||
|
|
||||||
godot-template-linux:
|
godot-template-linux:
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
@ -26,12 +26,10 @@ if((${SPINE_SFML}) OR (${CMAKE_CURRENT_BINARY_DIR} MATCHES "spine-sfml"))
|
|||||||
set(ONLY_ACTIVE_ARCH NO)
|
set(ONLY_ACTIVE_ARCH NO)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(spine-c)
|
add_subdirectory(spine-c)
|
||||||
add_subdirectory(spine-sfml/c)
|
|
||||||
add_subdirectory(spine-cpp)
|
add_subdirectory(spine-cpp)
|
||||||
|
add_subdirectory(spine-sfml/c)
|
||||||
add_subdirectory(spine-sfml/cpp)
|
add_subdirectory(spine-sfml/cpp)
|
||||||
endif()
|
elseif((${SPINE_SDL}) OR (${CMAKE_CURRENT_BINARY_DIR} MATCHES "spine-sdl"))
|
||||||
|
|
||||||
if((${SPINE_SDL}) OR (${CMAKE_CURRENT_BINARY_DIR} MATCHES "spine-sdl"))
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
set(CMAKE_OSX_ARCHITECTURES x86_64;arm64)
|
set(CMAKE_OSX_ARCHITECTURES x86_64;arm64)
|
||||||
set(ONLY_ACTIVE_ARCH NO)
|
set(ONLY_ACTIVE_ARCH NO)
|
||||||
@ -39,7 +37,8 @@ if((${SPINE_SDL}) OR (${CMAKE_CURRENT_BINARY_DIR} MATCHES "spine-sdl"))
|
|||||||
add_subdirectory(spine-c)
|
add_subdirectory(spine-c)
|
||||||
add_subdirectory(spine-cpp)
|
add_subdirectory(spine-cpp)
|
||||||
add_subdirectory(spine-sdl)
|
add_subdirectory(spine-sdl)
|
||||||
|
else()
|
||||||
|
add_subdirectory(spine-c)
|
||||||
|
add_subdirectory(spine-cpp)
|
||||||
|
add_subdirectory(spine-cpp/spine-cpp-unit-tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# add_subdirectory(spine-c/spine-c-unit-tests)
|
|
||||||
add_subdirectory(spine-cpp/spine-cpp-unit-tests)
|
|
||||||
|
|||||||
@ -374,12 +374,10 @@ cp -f ../coin/export/coin-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
|||||||
cp -f ../coin/export/coin-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
cp -f ../coin/export/coin-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
cp -f ../coin/export/coin-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
cp -f ../coin/export/coin-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
|
||||||
cp -f ../stretchyman/export/stretchyman-pro.json "$ROOT/spine-ts/spine-phaser/example/assets/"
|
|
||||||
cp -f ../stretchyman/export/stretchyman-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
cp -f ../stretchyman/export/stretchyman-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
cp -f ../stretchyman/export/stretchyman-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
cp -f ../stretchyman/export/stretchyman-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
cp -f ../stretchyman/export/stretchyman-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
cp -f ../stretchyman/export/stretchyman-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
|
||||||
cp -f ../mix-and-match/export/mix-and-match-pro.json "$ROOT/spine-ts/spine-phaser/example/assets/"
|
|
||||||
cp -f ../mix-and-match/export/mix-and-match-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
cp -f ../mix-and-match/export/mix-and-match-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
cp -f ../mix-and-match/export/mix-and-match-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
cp -f ../mix-and-match/export/mix-and-match-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
cp -f ../mix-and-match/export/mix-and-match-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
cp -f ../mix-and-match/export/mix-and-match-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
|||||||
@ -3,14 +3,17 @@ stretchyman-pma.png
|
|||||||
filter: Linear, Linear
|
filter: Linear, Linear
|
||||||
pma: true
|
pma: true
|
||||||
back-arm
|
back-arm
|
||||||
bounds: 149, 45, 72, 202
|
bounds: 679, 173, 72, 202
|
||||||
|
rotate: 90
|
||||||
back-leg
|
back-leg
|
||||||
bounds: 312, 4, 100, 318
|
bounds: 2, 2, 100, 318
|
||||||
rotate: 90
|
rotate: 90
|
||||||
body
|
body
|
||||||
bounds: 223, 106, 141, 452
|
bounds: 2, 104, 141, 452
|
||||||
rotate: 90
|
rotate: 90
|
||||||
front-arm
|
front-arm
|
||||||
bounds: 2, 26, 145, 221
|
bounds: 456, 100, 145, 221
|
||||||
|
rotate: 90
|
||||||
head
|
head
|
||||||
bounds: 223, 2, 87, 102
|
bounds: 322, 15, 87, 102
|
||||||
|
rotate: 90
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 90 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -2,14 +2,17 @@ stretchyman.png
|
|||||||
size: 1024, 256
|
size: 1024, 256
|
||||||
filter: Linear, Linear
|
filter: Linear, Linear
|
||||||
back-arm
|
back-arm
|
||||||
bounds: 149, 45, 72, 202
|
bounds: 679, 173, 72, 202
|
||||||
|
rotate: 90
|
||||||
back-leg
|
back-leg
|
||||||
bounds: 312, 4, 100, 318
|
bounds: 2, 2, 100, 318
|
||||||
rotate: 90
|
rotate: 90
|
||||||
body
|
body
|
||||||
bounds: 223, 106, 141, 452
|
bounds: 2, 104, 141, 452
|
||||||
rotate: 90
|
rotate: 90
|
||||||
front-arm
|
front-arm
|
||||||
bounds: 2, 26, 145, 221
|
bounds: 456, 100, 145, 221
|
||||||
|
rotate: 90
|
||||||
head
|
head
|
||||||
bounds: 223, 2, 87, 102
|
bounds: 322, 15, 87, 102
|
||||||
|
rotate: 90
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
Binary file not shown.
@ -114,7 +114,7 @@ static int readInt(_dataInput *input) {
|
|||||||
|
|
||||||
static int readVarint(_dataInput *input, int /*bool*/ optimizePositive) {
|
static int readVarint(_dataInput *input, int /*bool*/ optimizePositive) {
|
||||||
unsigned char b = readByte(input);
|
unsigned char b = readByte(input);
|
||||||
uint32_t value = b & 0x7F;
|
int32_t value = b & 0x7F;
|
||||||
if (b & 0x80) {
|
if (b & 0x80) {
|
||||||
b = readByte(input);
|
b = readByte(input);
|
||||||
value |= (b & 0x7F) << 7;
|
value |= (b & 0x7F) << 7;
|
||||||
@ -124,13 +124,12 @@ static int readVarint(_dataInput *input, int /*bool*/ optimizePositive) {
|
|||||||
if (b & 0x80) {
|
if (b & 0x80) {
|
||||||
b = readByte(input);
|
b = readByte(input);
|
||||||
value |= (b & 0x7F) << 21;
|
value |= (b & 0x7F) << 21;
|
||||||
if (b & 0x80) value |= (uint32_t) (readByte(input) & 0x7F) << 28;
|
if (b & 0x80) value |= (readByte(input) & 0x7F) << 28;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!optimizePositive)
|
if (!optimizePositive) value = (((unsigned int) value >> 1) ^ -(value & 1));
|
||||||
value = ((unsigned int) value >> 1) ^ (~(value & 1));
|
return value;
|
||||||
return (int) value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float readFloat(_dataInput *input) {
|
float readFloat(_dataInput *input) {
|
||||||
@ -1031,9 +1030,10 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
|
|||||||
{
|
{
|
||||||
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name,
|
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name,
|
||||||
path, sequence);
|
path, sequence);
|
||||||
|
spRegionAttachment *region = NULL;
|
||||||
if (!attachment)
|
if (!attachment)
|
||||||
return NULL;
|
return NULL;
|
||||||
spRegionAttachment *region = SUB_CAST(spRegionAttachment, attachment);
|
region = SUB_CAST(spRegionAttachment, attachment);
|
||||||
region->path = path;
|
region->path = path;
|
||||||
region->rotation = rotation;
|
region->rotation = rotation;
|
||||||
region->x = x;
|
region->x = x;
|
||||||
@ -1053,9 +1053,10 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
|
|||||||
int vertexCount = readVarint(input, 1);
|
int vertexCount = readVarint(input, 1);
|
||||||
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0,
|
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0,
|
||||||
NULL);
|
NULL);
|
||||||
|
spVertexAttachment *vertexAttachment = NULL;
|
||||||
if (!attachment)
|
if (!attachment)
|
||||||
return NULL;
|
return NULL;
|
||||||
spVertexAttachment *vertexAttachment = SUB_CAST(spVertexAttachment, attachment);
|
vertexAttachment = SUB_CAST(spVertexAttachment, attachment);
|
||||||
_readVertices(self, input, &vertexAttachment->bonesCount, &vertexAttachment->bones,
|
_readVertices(self, input, &vertexAttachment->bonesCount, &vertexAttachment->bones,
|
||||||
&vertexAttachment->verticesCount, &vertexAttachment->vertices,
|
&vertexAttachment->verticesCount, &vertexAttachment->vertices,
|
||||||
&vertexAttachment->worldVerticesLength, vertexCount);
|
&vertexAttachment->worldVerticesLength, vertexCount);
|
||||||
@ -1106,9 +1107,10 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
|
|||||||
|
|
||||||
{
|
{
|
||||||
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path, sequence);
|
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path, sequence);
|
||||||
|
spMeshAttachment *mesh = NULL;
|
||||||
if (!attachment)
|
if (!attachment)
|
||||||
return NULL;
|
return NULL;
|
||||||
spMeshAttachment *mesh = SUB_CAST(spMeshAttachment, attachment);
|
mesh = SUB_CAST(spMeshAttachment, attachment);
|
||||||
mesh->path = path;
|
mesh->path = path;
|
||||||
spColor_setFromColor(&mesh->color, &color);
|
spColor_setFromColor(&mesh->color, &color);
|
||||||
mesh->regionUVs = regionUVs;
|
mesh->regionUVs = regionUVs;
|
||||||
@ -1157,9 +1159,10 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
|
|||||||
|
|
||||||
{
|
{
|
||||||
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path, sequence);
|
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path, sequence);
|
||||||
|
spMeshAttachment *mesh = NULL;
|
||||||
if (!attachment)
|
if (!attachment)
|
||||||
return NULL;
|
return NULL;
|
||||||
spMeshAttachment *mesh = SUB_CAST(spMeshAttachment, attachment);
|
mesh = SUB_CAST(spMeshAttachment, attachment);
|
||||||
mesh->path = path;
|
mesh->path = path;
|
||||||
spColor_setFromColor(&mesh->color, &color);
|
spColor_setFromColor(&mesh->color, &color);
|
||||||
mesh->sequence = sequence;
|
mesh->sequence = sequence;
|
||||||
@ -1172,11 +1175,13 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
|
|||||||
case SP_ATTACHMENT_PATH: {
|
case SP_ATTACHMENT_PATH: {
|
||||||
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0,
|
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0,
|
||||||
NULL);
|
NULL);
|
||||||
|
spPathAttachment *path = NULL;
|
||||||
|
spVertexAttachment *vertexAttachment = NULL;
|
||||||
|
int vertexCount = 0;
|
||||||
if (!attachment)
|
if (!attachment)
|
||||||
return NULL;
|
return NULL;
|
||||||
spPathAttachment *path = SUB_CAST(spPathAttachment, attachment);
|
path = SUB_CAST(spPathAttachment, attachment);
|
||||||
spVertexAttachment *vertexAttachment = SUPER(path);
|
vertexAttachment = SUPER(path);
|
||||||
int vertexCount = 0;
|
|
||||||
path->closed = readBoolean(input);
|
path->closed = readBoolean(input);
|
||||||
path->constantSpeed = readBoolean(input);
|
path->constantSpeed = readBoolean(input);
|
||||||
vertexCount = readVarint(input, 1);
|
vertexCount = readVarint(input, 1);
|
||||||
@ -1197,9 +1202,10 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
|
|||||||
case SP_ATTACHMENT_POINT: {
|
case SP_ATTACHMENT_POINT: {
|
||||||
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0,
|
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0,
|
||||||
NULL);
|
NULL);
|
||||||
|
spPointAttachment *point = NULL;
|
||||||
if (!attachment)
|
if (!attachment)
|
||||||
return NULL;
|
return NULL;
|
||||||
spPointAttachment *point = SUB_CAST(spPointAttachment, attachment);
|
point = SUB_CAST(spPointAttachment, attachment);
|
||||||
point->rotation = readFloat(input);
|
point->rotation = readFloat(input);
|
||||||
point->x = readFloat(input) * self->scale;
|
point->x = readFloat(input) * self->scale;
|
||||||
point->y = readFloat(input) * self->scale;
|
point->y = readFloat(input) * self->scale;
|
||||||
@ -1215,10 +1221,12 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
|
|||||||
int vertexCount = readVarint(input, 1);
|
int vertexCount = readVarint(input, 1);
|
||||||
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0,
|
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0,
|
||||||
NULL);
|
NULL);
|
||||||
|
spClippingAttachment *clip = NULL;
|
||||||
|
spVertexAttachment *vertexAttachment = NULL;
|
||||||
if (!attachment)
|
if (!attachment)
|
||||||
return NULL;
|
return NULL;
|
||||||
spClippingAttachment *clip = SUB_CAST(spClippingAttachment, attachment);
|
clip = SUB_CAST(spClippingAttachment, attachment);
|
||||||
spVertexAttachment *vertexAttachment = SUPER(clip);
|
vertexAttachment = SUPER(clip);
|
||||||
_readVertices(self, input, &vertexAttachment->bonesCount, &vertexAttachment->bones,
|
_readVertices(self, input, &vertexAttachment->bonesCount, &vertexAttachment->bones,
|
||||||
&vertexAttachment->verticesCount, &vertexAttachment->vertices,
|
&vertexAttachment->verticesCount, &vertexAttachment->vertices,
|
||||||
&vertexAttachment->worldVerticesLength, vertexCount);
|
&vertexAttachment->worldVerticesLength, vertexCount);
|
||||||
|
|||||||
@ -1,18 +1,9 @@
|
|||||||
project(spine_cpp_unit_test)
|
project(spine_cpp_unit_test)
|
||||||
|
|
||||||
set(CMAKE_INSTALL_PREFIX "./")
|
set(SRC src/main.cpp)
|
||||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
||||||
|
|
||||||
include_directories(../spine-cpp/include teamcity minicppunit tests memory)
|
|
||||||
|
|
||||||
set(SRC
|
|
||||||
src/main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(spine_cpp_unit_test ${SRC})
|
add_executable(spine_cpp_unit_test ${SRC})
|
||||||
target_link_libraries(spine_cpp_unit_test spine-cpp)
|
target_link_libraries(spine_cpp_unit_test spine-cpp)
|
||||||
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# copy resources to build output directory
|
# copy resources to build output directory
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||||
pushd $dir > /dev/null
|
pushd "$dir" > /dev/null
|
||||||
|
|
||||||
if [ ! "$#" -eq 1 ]; then
|
if [ ! "$#" -eq 1 ]; then
|
||||||
echo "Usage: ./build-templates.sh <platform>"
|
echo "Usage: ./build-templates.sh <platform>"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||||
pushd $dir > /dev/null
|
pushd "$dir" > /dev/null
|
||||||
|
|
||||||
if [ ! "$#" -eq 1 ]; then
|
if [ ! "$#" -eq 1 ]; then
|
||||||
echo "Usage: ./build-templates.sh <platform>"
|
echo "Usage: ./build-templates.sh <platform>"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||||
pushd $dir > /dev/null
|
pushd "$dir" > /dev/null
|
||||||
|
|
||||||
if [ ! -d ../godot ]; then
|
if [ ! -d ../godot ]; then
|
||||||
echo "No Godot clone found. Run ./setup.sh <Godot branch or tag> <dev> first."
|
echo "No Godot clone found. Run ./setup.sh <Godot branch or tag> <dev> first."
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||||
pushd $dir > /dev/null
|
pushd "$dir" > /dev/null
|
||||||
|
|
||||||
if [ ! "$#" -eq 1 ]; then
|
if [ ! "$#" -eq 1 ]; then
|
||||||
echo "Usage: ./build.sh <target>"
|
echo "Usage: ./build.sh <target>"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||||
pushd $dir > /dev/null
|
pushd "$dir" > /dev/null
|
||||||
|
|
||||||
if [ ! "$#" -eq 2 ]; then
|
if [ ! "$#" -eq 2 ]; then
|
||||||
echo "Usage: ./setup.sh <Godot branch or tag> <dev:true|false>"
|
echo "Usage: ./setup.sh <Godot branch or tag> <dev:true|false>"
|
||||||
|
|||||||
@ -19,19 +19,20 @@
|
|||||||
<li>Phaser</li>
|
<li>Phaser</li>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/spine-phaser/example/basic-example.html">Basic example</a></li>
|
<li><a href="/spine-phaser/example/basic-example.html">Basic example</a></li>
|
||||||
|
<li><a href="/spine-phaser/example/events-example.html">Events example</a></li>
|
||||||
|
<li><a href="/spine-phaser/example/mix-and-match-example.html">Mix and match example</a></li>
|
||||||
|
<li><a href="/spine-phaser/example/arcade-physics-example.html">Arcade physics example</a></li>
|
||||||
|
<li><a href="/spine-phaser/example/control-bones-example.html">Control bones example</a></li>
|
||||||
<li><a href="/spine-phaser/example/batching-test.html">Batching test</a></li>
|
<li><a href="/spine-phaser/example/batching-test.html">Batching test</a></li>
|
||||||
<li><a href="/spine-phaser/example/multi-scene-test.html">Multi-scene test</a></li>
|
<li><a href="/spine-phaser/example/multi-scene-test.html">Multi-scene test</a></li>
|
||||||
<li><a href="/spine-phaser/example/bounds-test.html">Bounds test</a></li>
|
<li><a href="/spine-phaser/example/bounds-test.html">Bounds test</a></li>
|
||||||
<li><a href="/spine-phaser/example/visibility-test.html">Visibility test</a></li>
|
<li><a href="/spine-phaser/example/visibility-test.html">Visibility test</a></li>
|
||||||
<li><a href="/spine-phaser/example/arcade-physics-test.html">Arcade physics example</a></li>
|
|
||||||
<li><a href="/spine-phaser/example/blend-test.html">Blend test</a></li>
|
<li><a href="/spine-phaser/example/blend-test.html">Blend test</a></li>
|
||||||
<li><a href="/spine-phaser/example/camera-pipeline-test.html">Camera pipeline test</a></li>
|
<li><a href="/spine-phaser/example/camera-pipeline-test.html">Camera pipeline test</a></li>
|
||||||
<li><a href="/spine-phaser/example/control-bones-test.html">Control bones</a></li>
|
|
||||||
<li><a href="/spine-phaser/example/extended-class-test.html">Extended class</a></li>
|
<li><a href="/spine-phaser/example/extended-class-test.html">Extended class</a></li>
|
||||||
<li><a href="/spine-phaser/example/canvas-test.html">Canvas test</a></li>
|
<li><a href="/spine-phaser/example/canvas-test.html">Canvas test</a></li>
|
||||||
<li><a href="/spine-phaser/example/depth-test.html">Depth test</a></li>
|
<li><a href="/spine-phaser/example/depth-test.html">Depth test</a></li>
|
||||||
<li><a href="/spine-phaser/example/render-to-texture-test.html">Render to texture test</a></li>
|
<li><a href="/spine-phaser/example/render-to-texture-test.html">Render to texture test</a></li>
|
||||||
<li><a href="/spine-phaser/example/mix-and-match.html">Mix and match</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<li>Player</li>
|
<li>Player</li>
|
||||||
<ul>
|
<ul>
|
||||||
@ -65,6 +66,7 @@
|
|||||||
<li>THREE.JS</li>
|
<li>THREE.JS</li>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/spine-threejs/example/index.html">Example</a></li>
|
<li><a href="/spine-threejs/example/index.html">Example</a></li>
|
||||||
|
<li><a href="/spine-threejs/example/coordinate-transform.html">Coordinate transform</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
"build:phaser": "npx esbuild --bundle spine-phaser/src/index.ts --tsconfig=spine-phaser/tsconfig.json --sourcemap --outfile=spine-phaser/dist/iife/spine-phaser.js --external:Phaser --alias:phaser=Phaser --format=iife --global-name=spine",
|
"build:phaser": "npx esbuild --bundle spine-phaser/src/index.ts --tsconfig=spine-phaser/tsconfig.json --sourcemap --outfile=spine-phaser/dist/iife/spine-phaser.js --external:Phaser --alias:phaser=Phaser --format=iife --global-name=spine",
|
||||||
"build:threejs": "npx esbuild --bundle spine-threejs/src/index.ts --tsconfig=spine-threejs/tsconfig.json --sourcemap --outfile=spine-threejs/dist/iife/spine-threejs.js --external:three --format=iife --global-name=spine",
|
"build:threejs": "npx esbuild --bundle spine-threejs/src/index.ts --tsconfig=spine-threejs/tsconfig.json --sourcemap --outfile=spine-threejs/dist/iife/spine-threejs.js --external:three --format=iife --global-name=spine",
|
||||||
"minify": "npx esbuild --minify spine-core/dist/iife/spine-core.js --outfile=spine-core/dist/iife/spine-core.min.js && npx esbuild --minify spine-canvas/dist/iife/spine-canvas.js --outfile=spine-canvas/dist/iife/spine-canvas.min.js && npx esbuild --minify spine-player/dist/iife/spine-player.js --outfile=spine-player/dist/iife/spine-player.min.js && npx esbuild --minify spine-phaser/dist/iife/spine-phaser.js --outfile=spine-phaser/dist/iife/spine-phaser.min.js && npx esbuild --minify spine-webgl/dist/iife/spine-webgl.js --outfile=spine-webgl/dist/iife/spine-webgl.min.js && npx esbuild --minify spine-threejs/dist/iife/spine-threejs.js --outfile=spine-threejs/dist/iife/spine-threejs.min.js",
|
"minify": "npx esbuild --minify spine-core/dist/iife/spine-core.js --outfile=spine-core/dist/iife/spine-core.min.js && npx esbuild --minify spine-canvas/dist/iife/spine-canvas.js --outfile=spine-canvas/dist/iife/spine-canvas.min.js && npx esbuild --minify spine-player/dist/iife/spine-player.js --outfile=spine-player/dist/iife/spine-player.min.js && npx esbuild --minify spine-phaser/dist/iife/spine-phaser.js --outfile=spine-phaser/dist/iife/spine-phaser.min.js && npx esbuild --minify spine-webgl/dist/iife/spine-webgl.js --outfile=spine-webgl/dist/iife/spine-webgl.min.js && npx esbuild --minify spine-threejs/dist/iife/spine-threejs.js --outfile=spine-threejs/dist/iife/spine-threejs.min.js",
|
||||||
"dev": "concurrently \"npx live-server --no-browser\" \"npm run dev:canvas\" \"npm run dev:webgl\" \"npm run dev:phaser\" \"npm run dev:player\" \"npm run dev:threejs\"",
|
"dev": "concurrently \"npx live-server\" \"npm run dev:canvas\" \"npm run dev:webgl\" \"npm run dev:phaser\" \"npm run dev:player\" \"npm run dev:threejs\"",
|
||||||
"dev:modules": "npm run build:modules -- --watch",
|
"dev:modules": "npm run build:modules -- --watch",
|
||||||
"dev:canvas": "npm run build:canvas -- --watch",
|
"dev:canvas": "npm run build:canvas -- --watch",
|
||||||
"dev:webgl": "npm run build:webgl -- --watch",
|
"dev:webgl": "npm run build:webgl -- --watch",
|
||||||
|
|||||||
61
spine-ts/spine-phaser/example/arcade-physics-example.html
Normal file
61
spine-ts/spine-phaser/example/arcade-physics-example.html
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Arcade Physics example</h1>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
class PhysicsExample extends Phaser.Scene {
|
||||||
|
preload() {
|
||||||
|
this.load.spineBinary("coin-data", "assets/coin-pro.skel");
|
||||||
|
this.load.spineAtlas("coin-atlas", "assets/coin-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
const coin = this.add.spine(400, 200, 'coin-data', "coin-atlas");
|
||||||
|
coin.animationState.setAnimation(0, "animation", true);
|
||||||
|
coin.setScale(0.3);
|
||||||
|
coin.setSize(280, 280);
|
||||||
|
|
||||||
|
this.physics.add.existing(coin);
|
||||||
|
|
||||||
|
coin.body.setOffset(0, 50);
|
||||||
|
coin.body.setVelocity(100, 200);
|
||||||
|
coin.body.setBounce(1, 1);
|
||||||
|
coin.body.setCollideWorldBounds(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
physics: {
|
||||||
|
default: 'arcade',
|
||||||
|
arcade: {
|
||||||
|
debug: true,
|
||||||
|
gravity: { y: 200 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scene: [PhysicsExample],
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const game = new Phaser.Game(config);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
|
|
||||||
<title>Spine Phaser Example</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>Arcade Physics example</h1>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
var config = {
|
|
||||||
type: Phaser.AUTO,
|
|
||||||
width: 800,
|
|
||||||
height: 600,
|
|
||||||
type: Phaser.WEBGL,
|
|
||||||
physics: {
|
|
||||||
default: 'arcade',
|
|
||||||
arcade: {
|
|
||||||
debug: true,
|
|
||||||
gravity: { y: 200 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scene: {
|
|
||||||
preload: preload,
|
|
||||||
create: create,
|
|
||||||
pack: {
|
|
||||||
files: [
|
|
||||||
{ type: "scenePlugin", key: "spine.SpinePlugin", url: "../dist/iife/spine-phaser.js", sceneKey: "spine" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
|
||||||
|
|
||||||
function preload() {
|
|
||||||
this.load.spineBinary("coin-data", "assets/coin-pro.skel");
|
|
||||||
this.load.spineAtlas("coin-atlas", "assets/coin-pma.atlas");
|
|
||||||
}
|
|
||||||
|
|
||||||
function create() {
|
|
||||||
let coin = this.add.spine(400, 200, 'coin-data', "coin-atlas");
|
|
||||||
coin.animationState.setAnimation(0, "animation", true);
|
|
||||||
coin.setScale(0.3);
|
|
||||||
coin.setSize(280, 280);
|
|
||||||
|
|
||||||
this.physics.add.existing(coin);
|
|
||||||
|
|
||||||
coin.body.setOffset(0, 50);
|
|
||||||
coin.body.setVelocity(100, 200);
|
|
||||||
coin.body.setBounce(1, 1);
|
|
||||||
coin.body.setCollideWorldBounds(true);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -3,14 +3,17 @@ stretchyman-pma.png
|
|||||||
filter: Linear, Linear
|
filter: Linear, Linear
|
||||||
pma: true
|
pma: true
|
||||||
back-arm
|
back-arm
|
||||||
bounds: 149, 45, 72, 202
|
bounds: 679, 173, 72, 202
|
||||||
|
rotate: 90
|
||||||
back-leg
|
back-leg
|
||||||
bounds: 312, 4, 100, 318
|
bounds: 2, 2, 100, 318
|
||||||
rotate: 90
|
rotate: 90
|
||||||
body
|
body
|
||||||
bounds: 223, 106, 141, 452
|
bounds: 2, 104, 141, 452
|
||||||
rotate: 90
|
rotate: 90
|
||||||
front-arm
|
front-arm
|
||||||
bounds: 2, 26, 145, 221
|
bounds: 456, 100, 145, 221
|
||||||
|
rotate: 90
|
||||||
head
|
head
|
||||||
bounds: 223, 2, 87, 102
|
bounds: 322, 15, 87, 102
|
||||||
|
rotate: 90
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 90 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -6,6 +6,7 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
|
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
<title>Spine Phaser Example</title>
|
<title>Spine Phaser Example</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -13,34 +14,31 @@
|
|||||||
<h1>Basic example</h1>
|
<h1>Basic example</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
class BasicExample extends Phaser.Scene {
|
||||||
|
preload() {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
const spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
|
spineboy.scale = 0.5;
|
||||||
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new Phaser.Game({
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
type: Phaser.WEBGL,
|
type: Phaser.WEBGL,
|
||||||
scene: {
|
scene: [BasicExample],
|
||||||
preload: preload,
|
plugins: {
|
||||||
create: create,
|
scene: [
|
||||||
pack: {
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
files: [
|
]
|
||||||
{ type: "scenePlugin", key: "spine.SpinePlugin", url: "../dist/iife/spine-phaser.js", sceneKey: "spine" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
|
||||||
|
|
||||||
function preload() {
|
|
||||||
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
|
||||||
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
|
||||||
}
|
|
||||||
|
|
||||||
function create() {
|
|
||||||
let spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
|
||||||
spineboy.scale = 0.5;
|
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@ -14,15 +14,25 @@
|
|||||||
<h1>Basic example</h1>
|
<h1>Basic example</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
class BasicExample extends Phaser.Scene {
|
||||||
|
preload() {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
const spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
|
spineboy.scale = 0.5;
|
||||||
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
type: Phaser.WEBGL,
|
type: Phaser.WEBGL,
|
||||||
scene: {
|
scene: [BasicExample],
|
||||||
preload: preload,
|
|
||||||
create: create,
|
|
||||||
},
|
|
||||||
plugins: {
|
plugins: {
|
||||||
scene: [
|
scene: [
|
||||||
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
@ -30,18 +40,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
function preload() {
|
|
||||||
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
|
||||||
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
|
||||||
}
|
|
||||||
|
|
||||||
function create() {
|
|
||||||
let spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
|
||||||
spineboy.scale = 0.5;
|
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<h1>Batching test</h1>
|
<h1>Batching test</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -30,7 +30,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
let debug;
|
let debug;
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
@ -41,12 +41,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
let plugin = this.spine;
|
const plugin = this.spine;
|
||||||
let x = 25;
|
let x = 25;
|
||||||
let y = 60;
|
let y = 60;
|
||||||
for (let j = 0; j < 10; j++, y += 600 / 10) {
|
for (let j = 0; j < 10; j++, y += 600 / 10) {
|
||||||
for (let i = 0; i < 20; i++, x += 800 / 20) {
|
for (let i = 0; i < 20; i++, x += 800 / 20) {
|
||||||
let obj = Math.random() > 0.5
|
const obj = Math.random() > 0.5
|
||||||
? this.add.spine(x, y, 'spineboy-data', "spineboy-atlas")
|
? this.add.spine(x, y, 'spineboy-data', "spineboy-atlas")
|
||||||
: this.add.spine(x, y, 'raptor-data', "raptor-atlas");
|
: this.add.spine(x, y, 'raptor-data', "raptor-atlas");
|
||||||
obj.animationState.setAnimation(0, "walk", true);
|
obj.animationState.setAnimation(0, "walk", true);
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<h1>Blend test</h1>
|
<h1>Blend test</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -32,7 +32,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
let controls;
|
let controls;
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
@ -41,14 +41,14 @@
|
|||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
for (var i = 0; i < 4; i++) {
|
for (var i = 0; i < 4; i++) {
|
||||||
let obj = this.add.spine(i * 200, 600, 'spineboy-data', 'spineboy-atlas').setScale(0.25);
|
const obj = this.add.spine(i * 200, 600, 'spineboy-data', 'spineboy-atlas').setScale(0.25);
|
||||||
obj.setScale(0.25);
|
obj.setScale(0.25);
|
||||||
obj.animationState.setAnimation(0, "idle", true);
|
obj.animationState.setAnimation(0, "idle", true);
|
||||||
obj.animationState.setAnimation(1, "shoot", true);
|
obj.animationState.setAnimation(1, "shoot", true);
|
||||||
}
|
}
|
||||||
var cursors = this.input.keyboard.createCursorKeys();
|
const cursors = this.input.keyboard.createCursorKeys();
|
||||||
|
|
||||||
var controlConfig = {
|
const controlConfig = {
|
||||||
camera: this.cameras.main,
|
camera: this.cameras.main,
|
||||||
left: cursors.left,
|
left: cursors.left,
|
||||||
right: cursors.right,
|
right: cursors.right,
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<h1>Bounds test</h1>
|
<h1>Bounds test</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -30,7 +30,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
let spineboy;
|
let spineboy;
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
@ -49,7 +49,7 @@
|
|||||||
let time = 0;
|
let time = 0;
|
||||||
function update(t, delta) {
|
function update(t, delta) {
|
||||||
time += delta / 1000;
|
time += delta / 1000;
|
||||||
let scale = 0.4 + Math.cos(time) * 0.2;
|
const scale = 0.4 + Math.cos(time) * 0.2;
|
||||||
spineboy.scale = scale;
|
spineboy.scale = scale;
|
||||||
spineboy.angle++;
|
spineboy.angle++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>Camera pipeline test</h1>
|
<h1>Camera pipeline test</h1>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -84,7 +84,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
@ -98,9 +98,9 @@
|
|||||||
// FIXME: Need a dummy sprite so the MultiPipeline sets up state
|
// FIXME: Need a dummy sprite so the MultiPipeline sets up state
|
||||||
// so rendering the Spine sprite actually works. Unsure what state
|
// so rendering the Spine sprite actually works. Unsure what state
|
||||||
// is needed.
|
// is needed.
|
||||||
var s = this.add.sprite(0, 0, 'img');
|
this.add.sprite(0, 0, 'img');
|
||||||
|
|
||||||
let spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
const spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
||||||
spineboy.scale = 0.5;
|
spineboy.scale = 0.5;
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<h1>Canvas test</h1>
|
<h1>Canvas test</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -29,7 +29,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
@ -37,7 +37,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
let spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
const spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
||||||
spineboy.scale = 0.5;
|
spineboy.scale = 0.5;
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
}
|
}
|
||||||
|
|||||||
72
spine-ts/spine-phaser/example/control-bones-example.html
Normal file
72
spine-ts/spine-phaser/example/control-bones-example.html
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Control bones</h1>
|
||||||
|
<script>
|
||||||
|
class ControlBonesExample extends Phaser.Scene {
|
||||||
|
preload() {
|
||||||
|
this.load.spineBinary("stretchyman-data", "assets/stretchyman-pro.skel");
|
||||||
|
this.load.spineAtlas("stretchyman-atlas", "assets/stretchyman-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
const stretchyman = this.add.spine(400, 580, 'stretchyman-data', "stretchyman-atlas");
|
||||||
|
stretchyman.animationState.setAnimation(0, "idle", true);
|
||||||
|
stretchyman.updatePose(0);
|
||||||
|
|
||||||
|
const controlBoneNames = ["back-arm-ik-target", "back-leg-ik-target", "front-arm-ik-target", "front-leg-ik-target"];
|
||||||
|
const controlBones = [];
|
||||||
|
for (var i = 0; i < controlBoneNames.length; i++) {
|
||||||
|
const bone = stretchyman.skeleton.findBone(controlBoneNames[i]);
|
||||||
|
const point = { x: bone.worldX, y: bone.worldY };
|
||||||
|
stretchyman.skeletonToPhaserWorldCoordinates(point);
|
||||||
|
|
||||||
|
const control = this.add.circle(point.x, point.y, 4, 0xff00ff).setData('bone', bone);
|
||||||
|
controlBones.push(control);
|
||||||
|
|
||||||
|
control.setInteractive();
|
||||||
|
this.input.setDraggable(control);
|
||||||
|
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
|
||||||
|
gameObject.x = dragX;
|
||||||
|
gameObject.y = dragY;
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
stretchyman.beforeUpdateWorldTransforms = () => {
|
||||||
|
for (let controlBone of controlBones) {
|
||||||
|
const bone = controlBone.getData('bone');
|
||||||
|
const point = { x: controlBone.x, y: controlBone.y};
|
||||||
|
stretchyman.phaserWorldCoordinatesToBone(point, bone);
|
||||||
|
bone.x = point.x;
|
||||||
|
bone.y = point.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new Phaser.Game({
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
scene: [ControlBonesExample],
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@ -1,72 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
|
|
||||||
<title>Spine Phaser Example</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>Control bones</h1>
|
|
||||||
<script>
|
|
||||||
var config = {
|
|
||||||
type: Phaser.AUTO,
|
|
||||||
width: 800,
|
|
||||||
height: 600,
|
|
||||||
type: Phaser.WEBGL,
|
|
||||||
scene: {
|
|
||||||
preload: preload,
|
|
||||||
create: create,
|
|
||||||
pack: {
|
|
||||||
files: [
|
|
||||||
{ type: "scenePlugin", key: "spine.SpinePlugin", url: "../dist/iife/spine-phaser.js", sceneKey: "spine" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
|
||||||
|
|
||||||
function preload() {
|
|
||||||
this.load.spineBinary("stretchyman-data", "assets/stretchyman-pro.skel");
|
|
||||||
this.load.spineAtlas("stretchyman-atlas", "assets/stretchyman-pma.atlas");
|
|
||||||
}
|
|
||||||
|
|
||||||
function create() {
|
|
||||||
let stretchyman = this.add.spine(400, 550, 'stretchyman-data', "stretchyman-atlas");
|
|
||||||
stretchyman.scale = 0.8;
|
|
||||||
stretchyman.skeleton.updateWorldTransform();
|
|
||||||
|
|
||||||
var controlBones = ["back-arm-ik-target", "back-leg-ik-target", "front-arm-ik-target", "front-leg-ik-target"];
|
|
||||||
for (var i = 0; i < controlBones.length; i++) {
|
|
||||||
var bone = stretchyman.skeleton.findBone(controlBones[i]);
|
|
||||||
let point = { x: bone.worldX, y: bone.worldY };
|
|
||||||
stretchyman.skeletonToPhaserWorldCoordinates(point);
|
|
||||||
|
|
||||||
var control = this.add.circle(point.x, point.y, 4, 0xff00ff).setData('bone', bone);
|
|
||||||
|
|
||||||
control.setInteractive();
|
|
||||||
this.input.setDraggable(control);
|
|
||||||
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
|
|
||||||
|
|
||||||
gameObject.x = dragX;
|
|
||||||
gameObject.y = dragY;
|
|
||||||
|
|
||||||
var bone = gameObject.getData('bone');
|
|
||||||
let point = { x: dragX, y: dragY };
|
|
||||||
stretchyman.phaserWorldCoordinatesToBone(point, bone);
|
|
||||||
|
|
||||||
bone.x = point.x;
|
|
||||||
bone.y = point.y;
|
|
||||||
bone.update();
|
|
||||||
|
|
||||||
}, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<h1>Depth test</h1>
|
<h1>Depth test</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -29,7 +29,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
this.load.image('logo', 'phaser.png');
|
this.load.image('logo', 'phaser.png');
|
||||||
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
this.add.image(400, 350, 'logo').setName('logo1').setDepth(2);
|
this.add.image(400, 350, 'logo').setName('logo1').setDepth(2);
|
||||||
let spineboy = this.add.spine(400, 600, 'spineboy-data', "spineboy-atlas");
|
const spineboy = this.add.spine(400, 600, 'spineboy-data', "spineboy-atlas");
|
||||||
spineboy.animationState.setAnimation(0, "walk", true)
|
spineboy.animationState.setAnimation(0, "walk", true)
|
||||||
spineboy.setScale(0.5)
|
spineboy.setScale(0.5)
|
||||||
spineboy.setDepth(1);
|
spineboy.setDepth(1);
|
||||||
|
|||||||
70
spine-ts/spine-phaser/example/events-example.html
Normal file
70
spine-ts/spine-phaser/example/events-example.html
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Events example</h1>
|
||||||
|
<div style="display: flex; flex-direction: column; width: 800px">
|
||||||
|
<canvas id="game" width="800" height="600"></canvas>
|
||||||
|
<textarea id="log" style="height: 10em;"></textarea>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
function log(message) {
|
||||||
|
let log = document.querySelector("#log");
|
||||||
|
log.textContent += message + "\n";
|
||||||
|
log.scrollTop = log.scrollHeight;
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventsExample extends Phaser.Scene {
|
||||||
|
preload() {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
const spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
|
spineboy.scale = 0.5;
|
||||||
|
|
||||||
|
spineboy.animationState.addListener({
|
||||||
|
start: (entry) => log(`Started animation ${entry.animation.name}`),
|
||||||
|
interrupt: (entry) => log(`Interrupted animation ${entry.animation.name}`),
|
||||||
|
end: (entry) => log(`Ended animation ${entry.animation.name}`),
|
||||||
|
dispose: (entry) => log(`Disposed animation ${entry.animation.name}`),
|
||||||
|
complete: (entry) => log(`Completed animation ${entry.animation.name}`),
|
||||||
|
})
|
||||||
|
|
||||||
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
const trackEntry = spineboy.animationState.addAnimation(0, "run", 3, true);
|
||||||
|
trackEntry.listener = {
|
||||||
|
event: (entry, event) => log(`Custom event for ${entry.animation.name}: ${event.data.name}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
canvas: document.querySelector("#game"),
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
scene: [EventsExample],
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const game = new Phaser.Game(config);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
let spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
const spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
||||||
spineboy.scale = 0.5;
|
spineboy.scale = 0.5;
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
}
|
}
|
||||||
@ -71,11 +71,11 @@
|
|||||||
create() {
|
create() {
|
||||||
this.add.image(0, 0, 'logo').setOrigin(0);
|
this.add.image(0, 0, 'logo').setOrigin(0);
|
||||||
|
|
||||||
let custom1 = new CustomSpineObject1(this, 100, 550, 'spineboy-data', 'spineboy-atlas', 'idle', true);
|
const custom1 = new CustomSpineObject1(this, 100, 550, 'spineboy-data', 'spineboy-atlas', 'idle', true);
|
||||||
custom1.spine.setScale(0.5);
|
custom1.spine.setScale(0.5);
|
||||||
let custom2 = new CustomSpineObject2(this, 350, 550, 'spineboy-data', 'spineboy-atlas', 'walk', true);
|
const custom2 = new CustomSpineObject2(this, 350, 550, 'spineboy-data', 'spineboy-atlas', 'walk', true);
|
||||||
custom2.spine.setScale(0.5);
|
custom2.spine.setScale(0.5);
|
||||||
let custom3 = new CustomSpineObject3(this, 600, 550, 'spineboy-data', 'spineboy-atlas', 'run', true);
|
const custom3 = new CustomSpineObject3(this, 600, 550, 'spineboy-data', 'spineboy-atlas', 'run', true);
|
||||||
custom3.spine.setScale(0.5);
|
custom3.spine.setScale(0.5);
|
||||||
|
|
||||||
this.add.image(400, 0, 'logo').setOrigin(0);
|
this.add.image(400, 0, 'logo').setOrigin(0);
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<h1>Mix and match</h1>
|
<h1>Mix and match</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -29,7 +29,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
this.load.spineBinary("mix-and-match-data", "assets/mix-and-match-pro.skel");
|
this.load.spineBinary("mix-and-match-data", "assets/mix-and-match-pro.skel");
|
||||||
@ -37,12 +37,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
let mixAndMatch = this.add.spine(400, 500, 'mix-and-match-data', "mix-and-match-atlas");
|
const mixAndMatch = this.add.spine(400, 500, 'mix-and-match-data', "mix-and-match-atlas");
|
||||||
mixAndMatch.scale = 0.5;
|
mixAndMatch.scale = 0.5;
|
||||||
mixAndMatch.animationState.setAnimation(0, "walk", true);
|
mixAndMatch.animationState.setAnimation(0, "walk", true);
|
||||||
|
|
||||||
let skeletonData = mixAndMatch.skeleton.data;
|
const skeletonData = mixAndMatch.skeleton.data;
|
||||||
let skin = new spine.Skin("custom");
|
const skin = new spine.Skin("custom");
|
||||||
skin.addSkin(skeletonData.findSkin("skin-base"));
|
skin.addSkin(skeletonData.findSkin("skin-base"));
|
||||||
skin.addSkin(skeletonData.findSkin("nose/short"));
|
skin.addSkin(skeletonData.findSkin("nose/short"));
|
||||||
skin.addSkin(skeletonData.findSkin("eyelids/girly"));
|
skin.addSkin(skeletonData.findSkin("eyelids/girly"));
|
||||||
@ -25,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
let spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
const spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
spineboy.scale = 0.5;
|
spineboy.scale = 0.5;
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
this.input.once('pointerdown', () => this.scene.start('Scene2'));
|
this.input.once('pointerdown', () => this.scene.start('Scene2'));
|
||||||
@ -43,14 +43,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
let raptor = this.add.spine(300, 600, 'raptor-data', "raptor-atlas");
|
const raptor = this.add.spine(300, 600, 'raptor-data', "raptor-atlas");
|
||||||
raptor.scale = 0.5;
|
raptor.scale = 0.5;
|
||||||
raptor.animationState.setAnimation(0, "walk", true);
|
raptor.animationState.setAnimation(0, "walk", true);
|
||||||
this.input.once('pointerdown', () => this.scene.start('Scene1'));
|
this.input.once('pointerdown', () => this.scene.start('Scene1'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -62,7 +62,7 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<h1>Render to texture</h1>
|
<h1>Render to texture</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -29,7 +29,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
@ -37,8 +37,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
let renderTexture = this.add.renderTexture(0, 0, 800, 600);
|
const renderTexture = this.add.renderTexture(0, 0, 800, 600);
|
||||||
let spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
const spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
||||||
spineboy.scale = 0.5;
|
spineboy.scale = 0.5;
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
this.add.text(200, 8, 'Click to stamp SpineBoy');
|
this.add.text(200, 8, 'Click to stamp SpineBoy');
|
||||||
|
|||||||
@ -1,30 +1,29 @@
|
|||||||
import {Scene} from "phaser"
|
import * as Phaser from "phaser"
|
||||||
import {SpinePlugin} from "@esotericsoftware/spine-phaser"
|
import * as spine from "@esotericsoftware/spine-phaser"
|
||||||
|
|
||||||
class SpineDemo extends Scene {
|
class SpineDemo extends Phaser.Scene {
|
||||||
preload() {
|
preload() {
|
||||||
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
let spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
const spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
this.make
|
|
||||||
spineboy.scale = 0.5;
|
spineboy.scale = 0.5;
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = {
|
const config = {
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
type: Phaser.WEBGL,
|
type: Phaser.WEBGL,
|
||||||
scene: [SpineDemo],
|
scene: [SpineDemo],
|
||||||
plugins: {
|
plugins: {
|
||||||
scene: [
|
scene: [
|
||||||
{ key: "spine.SpinePlugin", plugin: SpinePlugin, mapping: "spine" }
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
new Phaser.Game(config);
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<h1>Basic example</h1>
|
<h1>Basic example</h1>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -30,7 +30,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
@ -38,11 +38,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
let spineboy = this.add.spine(250, 500, 'spineboy-data', "spineboy-atlas");
|
const spineboy = this.add.spine(250, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
spineboy.scale = 0.5;
|
spineboy.scale = 0.5;
|
||||||
spineboy.animationState.setAnimation(0, "walk", true);
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
|
||||||
let spineboy2 = this.add.spine(550, 500, 'spineboy-data', "spineboy-atlas");
|
const spineboy2 = this.add.spine(550, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
spineboy2.scale = 0.5;
|
spineboy2.scale = 0.5;
|
||||||
spineboy2.animationState.setAnimation(0, "run", true);
|
spineboy2.animationState.setAnimation(0, "run", true);
|
||||||
|
|
||||||
|
|||||||
@ -9,10 +9,13 @@ class BaseSpineGameObject extends Phaser.GameObjects.GameObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bounds provider calculates the bounding box for a skeleton, which is then assigned as the size of the SpineGameObject. */
|
||||||
export interface SpineGameObjectBoundsProvider {
|
export interface SpineGameObjectBoundsProvider {
|
||||||
|
// Returns the bounding box for the skeleton, in skeleton space.
|
||||||
calculateBounds (gameObject: SpineGameObject): { x: number, y: number, width: number, height: number };
|
calculateBounds (gameObject: SpineGameObject): { x: number, y: number, width: number, height: number };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bounds provider that calculates the bounding box from the setup pose. */
|
||||||
export class SetupPoseBoundsProvider implements SpineGameObjectBoundsProvider {
|
export class SetupPoseBoundsProvider implements SpineGameObjectBoundsProvider {
|
||||||
calculateBounds (gameObject: SpineGameObject) {
|
calculateBounds (gameObject: SpineGameObject) {
|
||||||
if (!gameObject.skeleton) return { x: 0, y: 0, width: 0, height: 0 };
|
if (!gameObject.skeleton) return { x: 0, y: 0, width: 0, height: 0 };
|
||||||
@ -26,9 +29,14 @@ export class SetupPoseBoundsProvider implements SpineGameObjectBoundsProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bounds provider that calculates the bounding box by taking the maximumg bounding box for a combination of skins and specific animation. */
|
||||||
export class SkinsAndAnimationBoundsProvider implements SpineGameObjectBoundsProvider {
|
export class SkinsAndAnimationBoundsProvider implements SpineGameObjectBoundsProvider {
|
||||||
|
/**
|
||||||
|
* @param animation The animation to use for calculating the bounds. If null, the setup pose is used.
|
||||||
|
* @param skins The skins to use for calculating the bounds. If empty, the default skin is used.
|
||||||
|
* @param timeStep The time step to use for calculating the bounds. A smaller time step means more precision, but slower calculation.
|
||||||
|
*/
|
||||||
constructor (private animation: string, private skins: string[] = [], private timeStep: number = 0.05) {
|
constructor (private animation: string, private skins: string[] = [], private timeStep: number = 0.05) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateBounds (gameObject: SpineGameObject): { x: number; y: number; width: number; height: number; } {
|
calculateBounds (gameObject: SpineGameObject): { x: number; y: number; width: number; height: number; } {
|
||||||
@ -75,11 +83,34 @@ export class SkinsAndAnimationBoundsProvider implements SpineGameObjectBoundsPro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SpineGameObject is a Phaser {@link GameObject} that can be added to a Phaser Scene and render a Spine skeleton.
|
||||||
|
*
|
||||||
|
* The Spine GameObject is a thin wrapper around a Spine {@link Skeleton}, {@link AnimationState} and {@link AnimationStateData}. It is responsible for:
|
||||||
|
* - updating the animation state
|
||||||
|
* - applying the animation state to the skeleton's bones, slots, attachments, and draw order.
|
||||||
|
* - updating the skeleton's bone world transforms
|
||||||
|
* - rendering the skeleton
|
||||||
|
*
|
||||||
|
* See the {@link SpinePlugin} class for more information on how to create a `SpineGameObject`.
|
||||||
|
*
|
||||||
|
* The skeleton, animation state, and animation state data can be accessed via the repsective fields. They can be manually updated via {@link updatePose}.
|
||||||
|
*
|
||||||
|
* To modify the bone hierarchy before the world transforms are computed, a callback can be set via the {@link beforeUpdateWorldTransforms} field.
|
||||||
|
*
|
||||||
|
* To modify the bone hierarchy after the world transforms are computed, a callback can be set via the {@link afterUpdateWorldTransforms} field.
|
||||||
|
*
|
||||||
|
* The class also features methods to convert between the skeleton coordinate system and the Phaser coordinate system.
|
||||||
|
*
|
||||||
|
* See {@link skeletonToPhaserWorldCoordinates}, {@link phaserWorldCoordinatesToSkeleton}, and {@link phaserWorldCoordinatesToBoneLocal.}
|
||||||
|
*/
|
||||||
export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(ScrollFactorMixin(TransformMixin(VisibleMixin(AlphaMixin(BaseSpineGameObject))))))) {
|
export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(ScrollFactorMixin(TransformMixin(VisibleMixin(AlphaMixin(BaseSpineGameObject))))))) {
|
||||||
blendMode = -1;
|
blendMode = -1;
|
||||||
skeleton: Skeleton;
|
skeleton: Skeleton;
|
||||||
animationStateData: AnimationStateData;
|
animationStateData: AnimationStateData;
|
||||||
animationState: AnimationState;
|
animationState: AnimationState;
|
||||||
|
beforeUpdateWorldTransforms: (object: SpineGameObject) => void = () => { };
|
||||||
|
afterUpdateWorldTransforms: (object: SpineGameObject) => void = () => { };
|
||||||
private premultipliedAlpha = false;
|
private premultipliedAlpha = false;
|
||||||
private _displayOriginX = 0;
|
private _displayOriginX = 0;
|
||||||
private _displayOriginY = 0;
|
private _displayOriginY = 0;
|
||||||
@ -94,6 +125,7 @@ export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(Scro
|
|||||||
this.skeleton = this.plugin.createSkeleton(dataKey, atlasKey);
|
this.skeleton = this.plugin.createSkeleton(dataKey, atlasKey);
|
||||||
this.animationStateData = new AnimationStateData(this.skeleton.data);
|
this.animationStateData = new AnimationStateData(this.skeleton.data);
|
||||||
this.animationState = new AnimationState(this.animationStateData);
|
this.animationState = new AnimationState(this.animationStateData);
|
||||||
|
this.skeleton.updateWorldTransform();
|
||||||
this.updateSize();
|
this.updateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +174,7 @@ export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(Scro
|
|||||||
this.displayOriginY = -bounds.y;
|
this.displayOriginY = -bounds.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts a point from the skeleton coordinate system to the Phaser world coordinate system. */
|
||||||
skeletonToPhaserWorldCoordinates (point: { x: number, y: number }) {
|
skeletonToPhaserWorldCoordinates (point: { x: number, y: number }) {
|
||||||
let transform = this.getWorldTransformMatrix();
|
let transform = this.getWorldTransformMatrix();
|
||||||
let a = transform.a, b = transform.b, c = transform.c, d = transform.d, tx = transform.tx, ty = transform.ty;
|
let a = transform.a, b = transform.b, c = transform.c, d = transform.d, tx = transform.tx, ty = transform.ty;
|
||||||
@ -151,6 +184,7 @@ export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(Scro
|
|||||||
point.y = x * b + y * d + ty;
|
point.y = x * b + y * d + ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts a point from the Phaser world coordinate system to the skeleton coordinate system. */
|
||||||
phaserWorldCoordinatesToSkeleton (point: { x: number, y: number }) {
|
phaserWorldCoordinatesToSkeleton (point: { x: number, y: number }) {
|
||||||
let transform = this.getWorldTransformMatrix();
|
let transform = this.getWorldTransformMatrix();
|
||||||
transform = transform.invert();
|
transform = transform.invert();
|
||||||
@ -161,6 +195,7 @@ export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(Scro
|
|||||||
point.y = x * b + y * d + ty;
|
point.y = x * b + y * d + ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts a point from the Phaser world coordinate system to the bone's local coordinate system. */
|
||||||
phaserWorldCoordinatesToBone (point: { x: number, y: number }, bone: Bone) {
|
phaserWorldCoordinatesToBone (point: { x: number, y: number }, bone: Bone) {
|
||||||
this.phaserWorldCoordinatesToSkeleton(point);
|
this.phaserWorldCoordinatesToSkeleton(point);
|
||||||
if (bone.parent) {
|
if (bone.parent) {
|
||||||
@ -170,12 +205,21 @@ export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(Scro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preUpdate (time: number, delta: number) {
|
/**
|
||||||
if (!this.skeleton || !this.animationState) return;
|
* Updates the {@link AnimationState}, applies it to the {@link Skeleton}, then updates the world transforms of all bones.
|
||||||
|
* @param delta The time delta in milliseconds
|
||||||
|
*/
|
||||||
|
updatePose (delta: number) {
|
||||||
this.animationState.update(delta / 1000);
|
this.animationState.update(delta / 1000);
|
||||||
this.animationState.apply(this.skeleton);
|
this.animationState.apply(this.skeleton);
|
||||||
|
this.beforeUpdateWorldTransforms(this);
|
||||||
this.skeleton.updateWorldTransform();
|
this.skeleton.updateWorldTransform();
|
||||||
|
this.afterUpdateWorldTransforms(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
preUpdate (time: number, delta: number) {
|
||||||
|
if (!this.skeleton || !this.animationState) return;
|
||||||
|
this.updatePose(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
preDestroy () {
|
preDestroy () {
|
||||||
|
|||||||
@ -27,54 +27,69 @@
|
|||||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { SPINE_ATLAS_CACHE_KEY, SPINE_CONTAINER_TYPE, SPINE_GAME_OBJECT_TYPE, SPINE_ATLAS_TEXTURE_CACHE_KEY, SPINE_SKELETON_DATA_FILE_TYPE, SPINE_ATLAS_FILE_TYPE, SPINE_SKELETON_FILE_CACHE_KEY as SPINE_SKELETON_DATA_CACHE_KEY } from "./keys";
|
import { SPINE_ATLAS_CACHE_KEY, SPINE_CONTAINER_TYPE, SPINE_GAME_OBJECT_TYPE, SPINE_SKELETON_DATA_FILE_TYPE, SPINE_ATLAS_FILE_TYPE, SPINE_SKELETON_FILE_CACHE_KEY as SPINE_SKELETON_DATA_CACHE_KEY } from "./keys";
|
||||||
import { AtlasAttachmentLoader, Bone, GLTexture, SceneRenderer, Skeleton, SkeletonBinary, SkeletonData, SkeletonJson, TextureAtlas } from "@esotericsoftware/spine-webgl"
|
import { AtlasAttachmentLoader, GLTexture, SceneRenderer, Skeleton, SkeletonBinary, SkeletonData, SkeletonJson, TextureAtlas } from "@esotericsoftware/spine-webgl"
|
||||||
import { SpineGameObject, SpineGameObjectBoundsProvider } from "./SpineGameObject";
|
import { SpineGameObject, SpineGameObjectBoundsProvider } from "./SpineGameObject";
|
||||||
import { CanvasTexture, SkeletonRenderer } from "@esotericsoftware/spine-canvas";
|
import { CanvasTexture, SkeletonRenderer } from "@esotericsoftware/spine-canvas";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration object used when creating {@link SpineGameObject} instances via a scene's
|
||||||
|
* {@link GameObjectCreator} (`Scene.make`).
|
||||||
|
*/
|
||||||
export interface SpineGameObjectConfig extends Phaser.Types.GameObjects.GameObjectConfig {
|
export interface SpineGameObjectConfig extends Phaser.Types.GameObjects.GameObjectConfig {
|
||||||
|
/** The x-position of the object, optional, default: 0 */
|
||||||
x?: number,
|
x?: number,
|
||||||
|
/** The y-position of the object, optional, default: 0 */
|
||||||
y?: number,
|
y?: number,
|
||||||
|
/** The skeleton data key */
|
||||||
dataKey: string,
|
dataKey: string,
|
||||||
|
/** The atlas key */
|
||||||
atlasKey: string
|
atlasKey: string
|
||||||
|
/** The bounds provider, optional, default: `SetupPoseBoundsProvider` */
|
||||||
boundsProvider?: SpineGameObjectBoundsProvider
|
boundsProvider?: SpineGameObjectBoundsProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ScenePlugin} implementation adding Spine Runtime capabilities to a scene.
|
||||||
|
*
|
||||||
|
* The scene's {@link LoaderPlugin} (`Scene.load`) gets these additional functions:
|
||||||
|
* * `spineBinary(key: string, url: string, xhrSettings?: XHRSettingsObject)`: loads a skeleton binary `.skel` file from the `url`.
|
||||||
|
* * `spineJson(key: string, url: string, xhrSettings?: XHRSettingsObject)`: loads a skeleton binary `.skel` file from the `url`.
|
||||||
|
* * `spineAtlas(key: string, url: string, premultipliedAlpha: boolean = true, xhrSettings?: XHRSettingsObject)`: loads a texture atlas `.atlas` file from the `url` as well as its correponding texture atlas page images.
|
||||||
|
*
|
||||||
|
* The scene's {@link GameObjectFactory} (`Scene.add`) gets these additional functions:
|
||||||
|
* * `spine(x: number, y: number, dataKey: string, atlasKey: string, boundsProvider: SpineGameObjectBoundsProvider = SetupPoseBoundsProvider())`:
|
||||||
|
* creates a new {@link SpineGameObject} from the data and atlas at position `(x, y)`, using the {@link BoundsProvider} to calculate its bounding box. The object is automatically added to the scene.
|
||||||
|
*
|
||||||
|
* The scene's {@link GameObjectCreator} (`Scene.make`) gets these additional functions:
|
||||||
|
* * `spine(config: SpineGameObjectConfig)`: creates a new {@link SpineGameObject} from the given configuration object.
|
||||||
|
*
|
||||||
|
* The plugin has additional public methods to work with Spine Runtime core API objects:
|
||||||
|
* * `getAtlas(atlasKey: string)`: returns the {@link TextureAtlas} instance for the given atlas key.
|
||||||
|
* * `getSkeletonData(skeletonDataKey: string)`: returns the {@link SkeletonData} instance for the given skeleton data key.
|
||||||
|
* * `createSkeleton(skeletonDataKey: string, atlasKey: string, premultipliedAlpha: boolean = true)`: creates a new {@link Skeleton} instance from the given skeleton data and atlas key.
|
||||||
|
* * `isPremultipliedAlpha(atlasKey: string)`: returns `true` if the atlas with the given key has premultiplied alpha.
|
||||||
|
*/
|
||||||
export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
||||||
game: Phaser.Game;
|
game: Phaser.Game;
|
||||||
isWebGL: boolean;
|
private isWebGL: boolean;
|
||||||
gl: WebGLRenderingContext | null;
|
private gl: WebGLRenderingContext | null;
|
||||||
textureManager: Phaser.Textures.TextureManager;
|
|
||||||
phaserRenderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer | null;
|
|
||||||
webGLRenderer: SceneRenderer | null;
|
webGLRenderer: SceneRenderer | null;
|
||||||
canvasRenderer: SkeletonRenderer | null;
|
canvasRenderer: SkeletonRenderer | null;
|
||||||
skeletonDataCache: Phaser.Cache.BaseCache;
|
private skeletonDataCache: Phaser.Cache.BaseCache;
|
||||||
atlasCache: Phaser.Cache.BaseCache;
|
private atlasCache: Phaser.Cache.BaseCache;
|
||||||
|
|
||||||
constructor (scene: Phaser.Scene, pluginManager: Phaser.Plugins.PluginManager, pluginKey: string) {
|
constructor (scene: Phaser.Scene, pluginManager: Phaser.Plugins.PluginManager, pluginKey: string) {
|
||||||
super(scene, pluginManager, pluginKey);
|
super(scene, pluginManager, pluginKey);
|
||||||
var game = this.game = pluginManager.game;
|
this.game = pluginManager.game;
|
||||||
this.isWebGL = this.game.config.renderType === 2;
|
this.isWebGL = this.game.config.renderType === 2;
|
||||||
this.gl = this.isWebGL ? (this.game.renderer as Phaser.Renderer.WebGL.WebGLRenderer).gl : null;
|
this.gl = this.isWebGL ? (this.game.renderer as Phaser.Renderer.WebGL.WebGLRenderer).gl : null;
|
||||||
this.textureManager = this.game.textures;
|
|
||||||
this.phaserRenderer = this.game.renderer;
|
|
||||||
this.webGLRenderer = null;
|
this.webGLRenderer = null;
|
||||||
this.canvasRenderer = null;
|
this.canvasRenderer = null;
|
||||||
this.skeletonDataCache = this.game.cache.addCustom(SPINE_SKELETON_DATA_CACHE_KEY);
|
this.skeletonDataCache = this.game.cache.addCustom(SPINE_SKELETON_DATA_CACHE_KEY);
|
||||||
this.atlasCache = this.game.cache.addCustom(SPINE_ATLAS_CACHE_KEY);
|
this.atlasCache = this.game.cache.addCustom(SPINE_ATLAS_CACHE_KEY);
|
||||||
|
|
||||||
if (!this.phaserRenderer) {
|
|
||||||
this.phaserRenderer = {
|
|
||||||
width: game.scale.width,
|
|
||||||
height: game.scale.height,
|
|
||||||
preRender: () => { },
|
|
||||||
postRender: () => { },
|
|
||||||
render: () => { },
|
|
||||||
destroy: () => { }
|
|
||||||
} as unknown as Phaser.Renderer.Canvas.CanvasRenderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
let skeletonJsonFileCallback = function (this: any, key: string,
|
let skeletonJsonFileCallback = function (this: any, key: string,
|
||||||
url: string,
|
url: string,
|
||||||
xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
@ -84,7 +99,6 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
|||||||
};
|
};
|
||||||
pluginManager.registerFileType("spineJson", skeletonJsonFileCallback, scene);
|
pluginManager.registerFileType("spineJson", skeletonJsonFileCallback, scene);
|
||||||
|
|
||||||
|
|
||||||
let skeletonBinaryFileCallback = function (this: any, key: string,
|
let skeletonBinaryFileCallback = function (this: any, key: string,
|
||||||
url: string,
|
url: string,
|
||||||
xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
@ -94,7 +108,6 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
|||||||
};
|
};
|
||||||
pluginManager.registerFileType("spineBinary", skeletonBinaryFileCallback, scene);
|
pluginManager.registerFileType("spineBinary", skeletonBinaryFileCallback, scene);
|
||||||
|
|
||||||
|
|
||||||
let atlasFileCallback = function (this: any, key: string,
|
let atlasFileCallback = function (this: any, key: string,
|
||||||
url: string,
|
url: string,
|
||||||
premultipliedAlpha: boolean,
|
premultipliedAlpha: boolean,
|
||||||
@ -113,7 +126,7 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
|||||||
return gameObject;
|
return gameObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
let makeSpineGameObject = function (this: Phaser.GameObjects.GameObjectFactory, config: SpineGameObjectConfig, addToScene: boolean) {
|
let makeSpineGameObject = function (this: Phaser.GameObjects.GameObjectFactory, config: SpineGameObjectConfig, addToScene: boolean = false) {
|
||||||
let x = config.x ? config.x : 0;
|
let x = config.x ? config.x : 0;
|
||||||
let y = config.y ? config.y : 0;
|
let y = config.y ? config.y : 0;
|
||||||
let boundsProvider = config.boundsProvider ? config.boundsProvider : undefined;
|
let boundsProvider = config.boundsProvider ? config.boundsProvider : undefined;
|
||||||
@ -130,7 +143,7 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
|||||||
Skeleton.yDown = true;
|
Skeleton.yDown = true;
|
||||||
if (this.isWebGL) {
|
if (this.isWebGL) {
|
||||||
if (!this.webGLRenderer) {
|
if (!this.webGLRenderer) {
|
||||||
this.webGLRenderer = new SceneRenderer((this.phaserRenderer! as Phaser.Renderer.WebGL.WebGLRenderer).canvas, this.gl!, true);
|
this.webGLRenderer = new SceneRenderer((this.game.renderer! as Phaser.Renderer.WebGL.WebGLRenderer).canvas, this.gl!, true);
|
||||||
}
|
}
|
||||||
this.onResize();
|
this.onResize();
|
||||||
this.game.scale.on(Phaser.Scale.Events.RESIZE, this.onResize, this);
|
this.game.scale.on(Phaser.Scale.Events.RESIZE, this.onResize, this);
|
||||||
@ -147,7 +160,7 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onResize () {
|
onResize () {
|
||||||
var phaserRenderer = this.phaserRenderer;
|
var phaserRenderer = this.game.renderer;
|
||||||
var sceneRenderer = this.webGLRenderer;
|
var sceneRenderer = this.webGLRenderer;
|
||||||
|
|
||||||
if (phaserRenderer && sceneRenderer) {
|
if (phaserRenderer && sceneRenderer) {
|
||||||
@ -178,13 +191,8 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
|||||||
if (this.webGLRenderer) this.webGLRenderer.dispose();
|
if (this.webGLRenderer) this.webGLRenderer.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
isAtlasPremultiplied (atlasKey: string) {
|
/** Returns the TextureAtlas instance for the given key */
|
||||||
let atlasFile = this.game.cache.text.get(atlasKey);
|
getAtlas (atlasKey: string) {
|
||||||
if (!atlasFile) return false;
|
|
||||||
return atlasFile.premultipliedAlpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
createSkeleton (dataKey: string, atlasKey: string) {
|
|
||||||
let atlas: TextureAtlas;
|
let atlas: TextureAtlas;
|
||||||
if (this.atlasCache.exists(atlasKey)) {
|
if (this.atlasCache.exists(atlasKey)) {
|
||||||
atlas = this.atlasCache.get(atlasKey);
|
atlas = this.atlasCache.get(atlasKey);
|
||||||
@ -195,19 +203,32 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
|||||||
let gl = this.gl!;
|
let gl = this.gl!;
|
||||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
||||||
for (let atlasPage of atlas.pages) {
|
for (let atlasPage of atlas.pages) {
|
||||||
atlasPage.setTexture(new GLTexture(gl, this.textureManager.get(atlasKey + "!" + atlasPage.name).getSourceImage() as HTMLImageElement | ImageBitmap, false));
|
atlasPage.setTexture(new GLTexture(gl, this.game.textures.get(atlasKey + "!" + atlasPage.name).getSourceImage() as HTMLImageElement | ImageBitmap, false));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let atlasPage of atlas.pages) {
|
for (let atlasPage of atlas.pages) {
|
||||||
atlasPage.setTexture(new CanvasTexture(this.textureManager.get(atlasKey + "!" + atlasPage.name).getSourceImage() as HTMLImageElement | ImageBitmap));
|
atlasPage.setTexture(new CanvasTexture(this.game.textures.get(atlasKey + "!" + atlasPage.name).getSourceImage() as HTMLImageElement | ImageBitmap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.atlasCache.add(atlasKey, atlas);
|
this.atlasCache.add(atlasKey, atlas);
|
||||||
}
|
}
|
||||||
|
return atlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether the TextureAtlas uses premultiplied alpha */
|
||||||
|
isAtlasPremultiplied (atlasKey: string) {
|
||||||
|
let atlasFile = this.game.cache.text.get(atlasKey);
|
||||||
|
if (!atlasFile) return false;
|
||||||
|
return atlasFile.premultipliedAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the SkeletonData instance for the given data and atlas key */
|
||||||
|
getSkeletonData (dataKey: string, atlasKey: string) {
|
||||||
|
const atlas = this.getAtlas(atlasKey)
|
||||||
|
const combinedKey = dataKey + atlasKey;
|
||||||
let skeletonData: SkeletonData;
|
let skeletonData: SkeletonData;
|
||||||
if (this.skeletonDataCache.exists(dataKey)) {
|
if (this.skeletonDataCache.exists(combinedKey)) {
|
||||||
skeletonData = this.skeletonDataCache.get(dataKey);
|
skeletonData = this.skeletonDataCache.get(combinedKey);
|
||||||
} else {
|
} else {
|
||||||
if (this.game.cache.json.exists(dataKey)) {
|
if (this.game.cache.json.exists(dataKey)) {
|
||||||
let jsonFile = this.game.cache.json.get(dataKey) as any;
|
let jsonFile = this.game.cache.json.get(dataKey) as any;
|
||||||
@ -218,19 +239,23 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
|||||||
let binary = new SkeletonBinary(new AtlasAttachmentLoader(atlas));
|
let binary = new SkeletonBinary(new AtlasAttachmentLoader(atlas));
|
||||||
skeletonData = binary.readSkeletonData(new Uint8Array(binaryFile));
|
skeletonData = binary.readSkeletonData(new Uint8Array(binaryFile));
|
||||||
}
|
}
|
||||||
this.skeletonDataCache.add(dataKey, skeletonData);
|
this.skeletonDataCache.add(combinedKey, skeletonData);
|
||||||
}
|
}
|
||||||
|
return skeletonData;
|
||||||
|
}
|
||||||
|
|
||||||
return new Skeleton(skeletonData);
|
/** Creates a new Skeleton instance from the data and atlas. */
|
||||||
|
createSkeleton (dataKey: string, atlasKey: string) {
|
||||||
|
return new Skeleton(this.getSkeletonData(dataKey, atlasKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SpineSkeletonDataFileType {
|
enum SpineSkeletonDataFileType {
|
||||||
json,
|
json,
|
||||||
binary
|
binary
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SpineSkeletonDataFile extends Phaser.Loader.MultiFile {
|
class SpineSkeletonDataFile extends Phaser.Loader.MultiFile {
|
||||||
constructor (loader: Phaser.Loader.LoaderPlugin, key: string, url: string, public fileType: SpineSkeletonDataFileType, xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
constructor (loader: Phaser.Loader.LoaderPlugin, key: string, url: string, public fileType: SpineSkeletonDataFileType, xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
let file = null;
|
let file = null;
|
||||||
let isJson = fileType == SpineSkeletonDataFileType.json;
|
let isJson = fileType == SpineSkeletonDataFileType.json;
|
||||||
@ -261,7 +286,7 @@ export class SpineSkeletonDataFile extends Phaser.Loader.MultiFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SpineAtlasFile extends Phaser.Loader.MultiFile {
|
class SpineAtlasFile extends Phaser.Loader.MultiFile {
|
||||||
constructor (loader: Phaser.Loader.LoaderPlugin, key: string, url: string, public premultipliedAlpha: boolean = true, xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
constructor (loader: Phaser.Loader.LoaderPlugin, key: string, url: string, public premultipliedAlpha: boolean = true, xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
super(loader, SPINE_ATLAS_FILE_TYPE, key, [
|
super(loader, SPINE_ATLAS_FILE_TYPE, key, [
|
||||||
new Phaser.Loader.FileTypes.TextFile(loader, {
|
new Phaser.Loader.FileTypes.TextFile(loader, {
|
||||||
@ -278,7 +303,7 @@ export class SpineAtlasFile extends Phaser.Loader.MultiFile {
|
|||||||
this.pending--;
|
this.pending--;
|
||||||
|
|
||||||
if (file.type == "text") {
|
if (file.type == "text") {
|
||||||
var lines = file.data.split('\n');
|
var lines = file.data.split(/\r\n|\r|\n/);
|
||||||
let textures = [];
|
let textures = [];
|
||||||
textures.push(lines[0]);
|
textures.push(lines[0]);
|
||||||
for (var t = 1; t < lines.length; t++) {
|
for (var t = 1; t < lines.length; t++) {
|
||||||
|
|||||||
@ -28,4 +28,10 @@ declare global {
|
|||||||
spine (config: SpineGameObjectConfig, addToScene?: boolean): SpineGameObject;
|
spine (config: SpineGameObjectConfig, addToScene?: boolean): SpineGameObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Phaser {
|
||||||
|
export interface Scene {
|
||||||
|
spine: SpinePlugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
export const SPINE_SKELETON_FILE_CACHE_KEY = "esotericsoftware.spine.skeletonFile.cache";
|
export const SPINE_SKELETON_FILE_CACHE_KEY = "esotericsoftware.spine.skeletonFile.cache";
|
||||||
export const SPINE_ATLAS_CACHE_KEY = "esotericsoftware.spine.atlas.cache";
|
export const SPINE_ATLAS_CACHE_KEY = "esotericsoftware.spine.atlas.cache";
|
||||||
export const SPINE_ATLAS_TEXTURE_CACHE_KEY = "esotericsoftware.spine.atlas.texture.cache";
|
|
||||||
export const SPINE_LOADER_TYPE = "spine";
|
export const SPINE_LOADER_TYPE = "spine";
|
||||||
export const SPINE_SKELETON_DATA_FILE_TYPE = "spineSkeletonData";
|
export const SPINE_SKELETON_DATA_FILE_TYPE = "spineSkeletonData";
|
||||||
export const SPINE_ATLAS_FILE_TYPE = "spineAtlasData";
|
export const SPINE_ATLAS_FILE_TYPE = "spineAtlasData";
|
||||||
|
|||||||
155
spine-ts/spine-threejs/example/coordinate-transform.html
Normal file
155
spine-ts/spine-threejs/example/coordinate-transform.html
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>spine-threejs</title>
|
||||||
|
<script src="https://unpkg.com/three@0.141.0/build/three.js"></script>
|
||||||
|
<script src="../dist/iife/spine-threejs.js"></script>
|
||||||
|
<script src="./OrbitalControls.js"></script>
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,
|
||||||
|
html {
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
let scene, camera, renderer;
|
||||||
|
let skeletonMesh, cube, tailBone;
|
||||||
|
let assetManager;
|
||||||
|
let canvas;
|
||||||
|
let controls;
|
||||||
|
let lastFrameTime = Date.now() / 1000;
|
||||||
|
|
||||||
|
let baseUrl = "assets/";
|
||||||
|
let skeletonFile = "raptor-pro.json";
|
||||||
|
let atlasFile = skeletonFile.replace("-pro", "").replace("-ess", "").replace(".json", ".atlas");
|
||||||
|
let animation = "walk";
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
// create the THREE.JS camera, scene and renderer (WebGL)
|
||||||
|
let width = window.innerWidth, height = window.innerHeight;
|
||||||
|
camera = new THREE.PerspectiveCamera(75, width / height, 1, 3000);
|
||||||
|
camera.position.y = 200;
|
||||||
|
camera.position.z = 800;
|
||||||
|
scene = new THREE.Scene();
|
||||||
|
renderer = new THREE.WebGLRenderer();
|
||||||
|
renderer.setSize(width, height);
|
||||||
|
document.body.appendChild(renderer.domElement);
|
||||||
|
canvas = renderer.domElement;
|
||||||
|
controls = new OrbitControls(camera, renderer.domElement);
|
||||||
|
|
||||||
|
// load the assets required to display the Raptor model
|
||||||
|
assetManager = new spine.AssetManager(baseUrl);
|
||||||
|
assetManager.loadText(skeletonFile);
|
||||||
|
assetManager.loadTextureAtlas(atlasFile);
|
||||||
|
|
||||||
|
requestAnimationFrame(load);
|
||||||
|
}
|
||||||
|
|
||||||
|
function load(name, scale) {
|
||||||
|
if (assetManager.isLoadingComplete()) {
|
||||||
|
// Load the texture atlas using name.atlas and name.png from the AssetManager.
|
||||||
|
// The function passed to TextureAtlas is used to resolve relative paths.
|
||||||
|
atlas = assetManager.require(atlasFile);
|
||||||
|
|
||||||
|
// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
|
||||||
|
atlasLoader = new spine.AtlasAttachmentLoader(atlas);
|
||||||
|
|
||||||
|
// Create a SkeletonJson instance for parsing the .json file.
|
||||||
|
let skeletonJson = new spine.SkeletonJson(atlasLoader);
|
||||||
|
|
||||||
|
// Set the scale to apply during parsing, parse the file, and create a new skeleton.
|
||||||
|
skeletonJson.scale = 0.4;
|
||||||
|
let skeletonData = skeletonJson.readSkeletonData(assetManager.require(skeletonFile));
|
||||||
|
|
||||||
|
// Create a SkeletonMesh from the data and attach it to the scene
|
||||||
|
skeletonMesh = new spine.SkeletonMesh(skeletonData, (parameters) => {
|
||||||
|
parameters.depthTest = true;
|
||||||
|
parameters.depthWrite = true;
|
||||||
|
parameters.alphaTest = 0.001;
|
||||||
|
});
|
||||||
|
skeletonMesh.state.setAnimation(0, animation, true);
|
||||||
|
skeletonMesh.position.x = 120;
|
||||||
|
skeletonMesh.position.y = -20;
|
||||||
|
skeletonMesh.position.z = 10;
|
||||||
|
scene.add(skeletonMesh);
|
||||||
|
|
||||||
|
// Add a wireframe cube which will be positioned at the tail bone
|
||||||
|
geometry = new THREE.BoxGeometry(20, 20, 20);
|
||||||
|
material = new THREE.MeshBasicMaterial({ color: 0xff00, wireframe: true });
|
||||||
|
cube = new THREE.Mesh(geometry, material);
|
||||||
|
scene.add(cube);
|
||||||
|
|
||||||
|
// Get the tail bone
|
||||||
|
tailBone = skeletonMesh.skeleton.findBone("tail10");
|
||||||
|
|
||||||
|
requestAnimationFrame(render);
|
||||||
|
} else requestAnimationFrame(load);
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastTime = Date.now();
|
||||||
|
function render() {
|
||||||
|
// calculate delta time for animation purposes
|
||||||
|
let now = Date.now() / 1000;
|
||||||
|
let delta = now - lastFrameTime;
|
||||||
|
lastFrameTime = now;
|
||||||
|
|
||||||
|
// resize canvas to use full page, adjust camera/renderer
|
||||||
|
resize();
|
||||||
|
|
||||||
|
// Update orbital controls
|
||||||
|
controls.update();
|
||||||
|
|
||||||
|
// update the animation
|
||||||
|
skeletonMesh.update(delta);
|
||||||
|
|
||||||
|
// Get the tail bone coordinates in the skeleton's local coordinate space.
|
||||||
|
let position = new THREE.Vector3(tailBone.worldX, tailBone.worldY, 0);
|
||||||
|
|
||||||
|
// Convert the tail bone coordinates to world coordinates.
|
||||||
|
skeletonMesh.localToWorld(position)
|
||||||
|
|
||||||
|
// Set the tail bone coordinates as the cube's position.
|
||||||
|
cube.position.set(position.x, position.y, position.z);
|
||||||
|
|
||||||
|
// render the scene
|
||||||
|
renderer.render(scene, camera);
|
||||||
|
|
||||||
|
requestAnimationFrame(render);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
let w = window.innerWidth;
|
||||||
|
let h = window.innerHeight;
|
||||||
|
if (canvas.width != w || canvas.height != h) {
|
||||||
|
canvas.width = w;
|
||||||
|
canvas.height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
camera.aspect = w / h;
|
||||||
|
camera.updateProjectionMatrix();
|
||||||
|
|
||||||
|
renderer.setSize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
}());
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@ -198,11 +198,11 @@ namespace Spine.Unity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector2 rigidbodyDisplacement2D = new Vector2(rigidbodyDisplacement.x, rigidbodyDisplacement.y);
|
Vector2 rigidbodyDisplacement2D = new Vector2(rigidbodyDisplacement.x, rigidbodyDisplacement.y);
|
||||||
rigidBody2D.MovePosition(gravityAndVelocityMovement + new Vector2(transform.position.x, transform.position.y)
|
rigidBody2D.MovePosition(gravityAndVelocityMovement + new Vector2(rigidBody2D.position.x, rigidBody2D.position.y)
|
||||||
+ rigidbodyDisplacement2D + additionalRigidbody2DMovement);
|
+ rigidbodyDisplacement2D + additionalRigidbody2DMovement);
|
||||||
rigidBody2D.MoveRotation(rigidbody2DRotation + rigidBody2D.rotation);
|
rigidBody2D.MoveRotation(rigidbody2DRotation + rigidBody2D.rotation);
|
||||||
} else if (rigidBody != null) {
|
} else if (rigidBody != null) {
|
||||||
rigidBody.MovePosition(transform.position
|
rigidBody.MovePosition(rigidBody.position
|
||||||
+ new Vector3(rigidbodyDisplacement.x, rigidbodyDisplacement.y, rigidbodyDisplacement.z));
|
+ new Vector3(rigidbodyDisplacement.x, rigidbodyDisplacement.y, rigidbodyDisplacement.z));
|
||||||
rigidBody.MoveRotation(rigidBody.rotation * rigidbodyLocalRotation);
|
rigidBody.MoveRotation(rigidBody.rotation * rigidbodyLocalRotation);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "com.esotericsoftware.spine.spine-unity",
|
"name": "com.esotericsoftware.spine.spine-unity",
|
||||||
"displayName": "spine-unity Runtime",
|
"displayName": "spine-unity Runtime",
|
||||||
"description": "This plugin provides the spine-unity runtime core.",
|
"description": "This plugin provides the spine-unity runtime core.",
|
||||||
"version": "4.1.0",
|
"version": "4.1.10",
|
||||||
"unity": "2018.3",
|
"unity": "2018.3",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Esoteric Software",
|
"name": "Esoteric Software",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user