소스 검색

Merge branch '4.1' into 4.2-beta

Mario Zechner 2 년 전
부모
커밋
260c269a1a

+ 40 - 38
spine-ts/spine-phaser/example/arcade-physics-test.html

@@ -1,59 +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/[email protected]/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>
-var config = {
-    type: Phaser.AUTO,
-    width: 800,
-    height: 600,
-    type: Phaser.WEBGL,
-    physics: {
-        default: 'arcade',
-        arcade: {
-            debug: true,
-            gravity: { y: 200 }
+    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" }
+                ]
+            }
         }
-    },
-    scene: {
-        preload: preload,
-        create: create,
-    },
-    plugins: {
-        scene: [
-            { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-        ]
-    }
-};
+    };
 
-let game = new Phaser.Game(config);
+    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 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);
+    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);
+        this.physics.add.existing(coin);
 
-    coin.body.setOffset(0, 50);
-    coin.body.setVelocity(100, 200);
-    coin.body.setBounce(1, 1);
-    coin.body.setCollideWorldBounds(true);
-}
+        coin.body.setOffset(0, 50);
+        coin.body.setVelocity(100, 200);
+        coin.body.setBounce(1, 1);
+        coin.body.setCollideWorldBounds(true);
+    }
 </script>
+
 </html>

BIN
spine-ts/spine-phaser/example/assets/phaser.png


+ 28 - 26
spine-ts/spine-phaser/example/basic-example.html

@@ -1,44 +1,46 @@
 <!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/[email protected]/dist/phaser.js"></script>
-    <script src="../dist/iife/spine-phaser.js"></script>
     <title>Spine Phaser Example</title>
 </head>
+
 <body>
     <h1>Basic example</h1>
 </body>
 <script>
-var config = {
-    type: Phaser.AUTO,
-    width: 800,
-    height: 600,
-    type: Phaser.WEBGL,
-    scene: {
-        preload: preload,
-        create: create,
-    },
-    plugins: {
-        scene: [
-            { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-        ]
-    }
-};
+    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);
+    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 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, 300, 'spineboy-data', "spineboy-atlas");
-    spineboy.scale = 0.5;
-    spineboy.animationState.setAnimation(0, "walk", true);
-}
+    function create() {
+        let spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
+        spineboy.scale = 0.5;
+        spineboy.animationState.setAnimation(0, "walk", true);
+    }
 </script>
+
 </html>

+ 44 - 42
spine-ts/spine-phaser/example/batching-test.html

@@ -1,63 +1,65 @@
 <!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/[email protected]/dist/phaser.js"></script>
-    <script src="../dist/iife/spine-phaser.js"></script>
     <title>Spine Phaser Example</title>
 </head>
+
 <body>
     <h1>Batching test</h1>
 </body>
 <script>
-var config = {
-    type: Phaser.AUTO,
-    width: 800,
-    height: 600,
-    type: Phaser.WEBGL,
-    scene: {
-        preload: preload,
-        create: create,
-        update: update,
-    },
-    plugins: {
-        scene: [
-            { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-        ]
-    }
-};
+    var config = {
+        type: Phaser.AUTO,
+        width: 800,
+        height: 600,
+        type: Phaser.WEBGL,
+        scene: {
+            preload: preload,
+            create: create,
+            update: update,
+            pack: {
+                files: [
+                    { type: "scenePlugin", key: "spine.SpinePlugin", url: "../dist/iife/spine-phaser.js", sceneKey: "spine" }
+                ]
+            }
+        }
+    };
 
-let game = new Phaser.Game(config);
-let debug;
+    let game = new Phaser.Game(config);
+    let debug;
 
-function preload () {
-    this.load.spineJson("raptor-data", "assets/raptor-pro.json");
-    this.load.spineAtlas("raptor-atlas", "assets/raptor-pma.atlas");
-    this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
-    this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
-}
+    function preload() {
+        this.load.spineJson("raptor-data", "assets/raptor-pro.json");
+        this.load.spineAtlas("raptor-atlas", "assets/raptor-pma.atlas");
+        this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
+        this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
+    }
 
-function create () {
-    let plugin = this.spine;
-    let x = 25;
-    let y = 60;
-    for (let j = 0; j < 10; j++, y+= 600 / 10) {
-        for (let i = 0; i < 20; i++, x += 800 / 20) {
-            let obj = Math.random() > 0.5
-                ? this.add.spine(x, y, 'spineboy-data', "spineboy-atlas")
-                : this.add.spine(x, y, 'raptor-data', "raptor-atlas");
-            obj.animationState.setAnimation(0, "walk", true);
-            obj.scale = 0.1;
+    function create() {
+        let plugin = this.spine;
+        let x = 25;
+        let y = 60;
+        for (let j = 0; j < 10; j++, y += 600 / 10) {
+            for (let i = 0; i < 20; i++, x += 800 / 20) {
+                let obj = Math.random() > 0.5
+                    ? this.add.spine(x, y, 'spineboy-data', "spineboy-atlas")
+                    : this.add.spine(x, y, 'raptor-data', "raptor-atlas");
+                obj.animationState.setAnimation(0, "walk", true);
+                obj.scale = 0.1;
+            }
+            x = 25;
         }
-        x = 25;
+        debug = this.add.text(0, 600 - 40, "FPS: ");
     }
-    debug = this.add.text(0, 600 - 40, "FPS: ");
-}
 
-function update () {
-    debug.setText("draw calls: " + spine.PolygonBatcher.getAndResetGlobalDrawCalls() + "\ndelta: " + game.loop.delta);
-}
+    function update() {
+        debug.setText("draw calls: " + spine.PolygonBatcher.getAndResetGlobalDrawCalls() + "\ndelta: " + game.loop.delta);
+    }
 </script>
+
 </html>

+ 51 - 49
spine-ts/spine-phaser/example/blend-test.html

@@ -1,70 +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/[email protected]/dist/phaser.js"></script>
-    <script src="../dist/iife/spine-phaser.js"></script>
     <title>Spine Phaser Example</title>
 </head>
+
 <body>
     <h1>Blend test</h1>
 </body>
 <script>
-var config = {
-    type: Phaser.AUTO,
-    width: 800,
-    height: 600,
-    type: Phaser.WEBGL,
-    backgroundColor: '#cdcdcd',
-    scene: {
-        preload: preload,
-        create: create,
-        update: update
-    },
-    plugins: {
-        scene: [
-            { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-        ]
-    }
-};
-
-let controls;
-let game = new Phaser.Game(config);
+    var config = {
+        type: Phaser.AUTO,
+        width: 800,
+        height: 600,
+        type: Phaser.WEBGL,
+        backgroundColor: '#cdcdcd',
+        scene: {
+            preload: preload,
+            create: create,
+            update: update,
+            pack: {
+                files: [
+                    { type: "scenePlugin", key: "spine.SpinePlugin", url: "../dist/iife/spine-phaser.js", sceneKey: "spine" }
+                ]
+            }
+        }
+    };
 
-function preload () {
-    this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
-    this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
-}
+    let controls;
+    let game = new Phaser.Game(config);
 
-function create () {
-    for (var i = 0; i < 4; i++) {
-        let obj = this.add.spine(i * 200, 600, 'spineboy-data', 'spineboy-atlas').setScale(0.25);
-        obj.setScale(0.25);
-        obj.animationState.setAnimation(0, "idle", true);
-        obj.animationState.setAnimation(1, "shoot", true);
+    function preload() {
+        this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
+        this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
     }
-    var cursors = this.input.keyboard.createCursorKeys();
 
-    var controlConfig = {
-        camera: this.cameras.main,
-        left: cursors.left,
-        right: cursors.right,
-        up: cursors.up,
-        down: cursors.down,
-        zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q),
-        zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E),
-        acceleration: 0.35,
-        drag: 0.01,
-        maxSpeed: 1.2
-    };
+    function create() {
+        for (var i = 0; i < 4; i++) {
+            let obj = this.add.spine(i * 200, 600, 'spineboy-data', 'spineboy-atlas').setScale(0.25);
+            obj.setScale(0.25);
+            obj.animationState.setAnimation(0, "idle", true);
+            obj.animationState.setAnimation(1, "shoot", true);
+        }
+        var cursors = this.input.keyboard.createCursorKeys();
+
+        var controlConfig = {
+            camera: this.cameras.main,
+            left: cursors.left,
+            right: cursors.right,
+            up: cursors.up,
+            down: cursors.down,
+            zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q),
+            zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E),
+            acceleration: 0.35,
+            drag: 0.01,
+            maxSpeed: 1.2
+        };
 
-    controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
-}
+        controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
+    }
 
-function update (time, delta) {
-    controls.update(delta);
-}
+    function update(time, delta) {
+        controls.update(delta);
+    }
 </script>
+
 </html>

+ 39 - 37
spine-ts/spine-phaser/example/bounds-test.html

@@ -1,56 +1,58 @@
 <!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/[email protected]/dist/phaser.js"></script>
-    <script src="../dist/iife/spine-phaser.js"></script>
     <title>Spine Phaser Example</title>
 </head>
+
 <body>
     <h1>Bounds test</h1>
 </body>
 <script>
-var config = {
-    type: Phaser.AUTO,
-    width: 800,
-    height: 600,
-    type: Phaser.WEBGL,
-    scene: {
-        preload: preload,
-        create: create,
-        update: update,
-    },
-    plugins: {
-        scene: [
-            { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-        ]
-    }
-};
+    var config = {
+        type: Phaser.AUTO,
+        width: 800,
+        height: 600,
+        type: Phaser.WEBGL,
+        scene: {
+            preload: preload,
+            create: create,
+            update: update,
+            pack: {
+                files: [
+                    { type: "scenePlugin", key: "spine.SpinePlugin", url: "../dist/iife/spine-phaser.js", sceneKey: "spine" }
+                ]
+            }
+        }
+    };
 
-let game = new Phaser.Game(config);
-let spineboy;
+    let game = new Phaser.Game(config);
+    let spineboy;
 
-function preload () {
-    this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
-    this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
-}
+    function preload() {
+        this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
+        this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
+    }
 
-function create () {
-    spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas", new spine.SkinsAndAnimationBoundsProvider("run"));
-    spineboy.scale = 0.4
-    spineboy.setInteractive();
-    this.input.enableDebug(spineboy, 0xff00ff);
-    spineboy.on("pointerdown", () => spineboy.animationState.setAnimation(0, "run", true));
-}
+    function create() {
+        spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas", new spine.SkinsAndAnimationBoundsProvider("run"));
+        spineboy.scale = 0.4
+        spineboy.setInteractive();
+        this.input.enableDebug(spineboy, 0xff00ff);
+        spineboy.on("pointerdown", () => spineboy.animationState.setAnimation(0, "run", true));
+    }
 
-let time = 0;
-function update (t, delta) {
-    time += delta / 1000;
-    let scale = 0.4 + Math.cos(time) * 0.2;
-    spineboy.scale = scale;
-    spineboy.angle++;
-}
+    let time = 0;
+    function update(t, delta) {
+        time += delta / 1000;
+        let scale = 0.4 + Math.cos(time) * 0.2;
+        spineboy.scale = scale;
+        spineboy.angle++;
+    }
 </script>
+
 </html>

+ 5 - 6
spine-ts/spine-phaser/example/camera-pipeline-test.html

@@ -6,7 +6,6 @@
     <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/[email protected]/dist/phaser.js"></script>
-    <script src="../dist/iife/spine-phaser.js"></script>
     <title>Spine Phaser Example</title>
 </head>
 
@@ -22,11 +21,11 @@
             scene: {
                 preload: preload,
                 create: create,
-            },
-            plugins: {
-                scene: [
-                    { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-                ]
+                pack: {
+                    files: [
+                        { type: "scenePlugin", key: "spine.SpinePlugin", url: "../dist/iife/spine-phaser.js", sceneKey: "spine" }
+                    ]
+                }
             }
         };
 

+ 46 - 0
spine-ts/spine-phaser/example/canvas-test.html

@@ -0,0 +1,46 @@
+<!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/[email protected]/dist/phaser.js"></script>
+    <title>Spine Phaser Example</title>
+</head>
+
+<body>
+    <h1>Canvas test</h1>
+</body>
+<script>
+    var config = {
+        type: Phaser.AUTO,
+        width: 800,
+        height: 600,
+        type: Phaser.CANVAS,
+        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("spineboy-data", "assets/spineboy-pro.skel");
+        this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
+    }
+
+    function create() {
+        let spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
+        spineboy.scale = 0.5;
+        spineboy.animationState.setAnimation(0, "walk", true);
+    }
+</script>
+
+</html>

+ 49 - 48
spine-ts/spine-phaser/example/control-bones-test.html

@@ -1,71 +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/[email protected]/dist/phaser.js"></script>
-    <script src="../dist/iife/spine-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,
-    },
-    plugins: {
-        scene: [
-            { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-        ]
-    }
-};
+    <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);
+        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 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();
+        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 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);
+                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) {
+                control.setInteractive();
+                this.input.setDraggable(control);
+                this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
 
-            gameObject.x = dragX;
-            gameObject.y = dragY;
+                    gameObject.x = dragX;
+                    gameObject.y = dragY;
 
-            var bone = gameObject.getData('bone');
-            let point = { x: dragX, y: dragY };
-            stretchyman.phaserWorldCoordinatesToBone(point, bone);
+                    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();
+                    bone.x = point.x;
+                    bone.y = point.y;
+                    bone.update();
 
-        }, this);
-    }
-}
-</script>
+                }, this);
+            }
+        }
+    </script>
 </body>
+
 </html>

+ 50 - 0
spine-ts/spine-phaser/example/depth-test.html

@@ -0,0 +1,50 @@
+<!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/[email protected]/dist/phaser.js"></script>
+    <title>Spine Phaser Example</title>
+</head>
+
+<body>
+    <h1>Depth test</h1>
+</body>
+<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.image('logo', 'assets/phaser.png');
+        this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
+        this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
+    }
+
+    function create() {
+        this.add.image(400, 350, 'logo').setName('logo1').setDepth(2);
+        let spineboy = this.add.spine(400, 600, 'spineboy-data', "spineboy-atlas");
+        spineboy.animationState.setAnimation(0, "walk", true)
+        spineboy.setScale(0.5)
+        spineboy.setDepth(1);
+        this.add.text(400, 300, 'Set Depth Test', { font: '16px Courier', fill: '#00ff00' }).setName('text').setOrigin(0.5);
+    }
+</script>
+
+</html>

+ 103 - 0
spine-ts/spine-phaser/example/extended-class-test.html

@@ -0,0 +1,103 @@
+<!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/[email protected]/dist/phaser.js"></script>
+    <script src="../dist/iife/spine-phaser.js"></script>
+    <title>Spine Phaser Example</title>
+</head>
+
+<body>
+    <h1>Extended class</h1>
+</body>
+<script>
+
+
+    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, 300, 'spineboy-data', "spineboy-atlas");
+        spineboy.scale = 0.5;
+        spineboy.animationState.setAnimation(0, "walk", true);
+    }
+
+    class CustomSpineObject1 {
+        constructor(scene, x, y, data, atlas, animation, loop) {
+            this.scene = scene;
+            this.spine = scene.add.spine(x, y, data, atlas);
+            this.spine.animationState.setAnimation(0, animation, loop);
+        }
+    }
+
+    class CustomSpineObject2 {
+        constructor(scene, x, y, dataKey, atlasKey, animation, loop) {
+            this.scene = scene;
+            this.spine = scene.make.spine({ scene, x, y, dataKey, atlasKey });
+            this.spine.animationState.setAnimation(0, animation, loop);
+
+            scene.sys.displayList.add(this.spine);
+            scene.sys.updateList.add(this.spine);
+        }
+    }
+
+    class CustomSpineObject3 {
+        constructor(scene, x, y, dataKey, atlasKey, animation, loop) {
+            this.scene = scene;
+
+            this.parent = scene.add.container(0, 0);
+            this.spine = scene.make.spine({ scene, x, y, dataKey, atlasKey });
+            this.spine.animationState.setAnimation(0, animation, loop);
+            this.parent.add(this.spine);
+        }
+    }
+
+    class Example extends Phaser.Scene {
+        constructor() {
+            super();
+        }
+
+        preload() {
+            this.load.image('logo', 'assets/phaser.png');
+            this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
+            this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
+        }
+
+        create() {
+            this.add.image(0, 0, 'logo').setOrigin(0);
+
+            let custom1 = new CustomSpineObject1(this, 100, 550, 'spineboy-data', 'spineboy-atlas', 'idle', true);
+            custom1.spine.setScale(0.5);
+            let custom2 = new CustomSpineObject2(this, 350, 550, 'spineboy-data', 'spineboy-atlas', 'walk', true);
+            custom2.spine.setScale(0.5);
+            let custom3 = new CustomSpineObject3(this, 600, 550, 'spineboy-data', 'spineboy-atlas', 'run', true);
+            custom3.spine.setScale(0.5);
+
+            this.add.image(400, 0, 'logo').setOrigin(0);
+        }
+    }
+
+
+    const config = {
+        type: Phaser.WEBGL,
+        parent: 'phaser-example',
+        width: 800,
+        height: 600,
+        backgroundColor: '#2d2d2d',
+        scene: Example,
+        plugins: {
+            scene: [
+                { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
+            ]
+        }
+    };
+
+    const game = new Phaser.Game(config);
+</script>
+
+</html>

+ 7 - 0
spine-ts/spine-phaser/example/index.html

@@ -1,5 +1,6 @@
 <!DOCTYPE html>
 <html lang="en">
+
 <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -7,6 +8,7 @@
     <script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>
     <title>Spine Phaser Example</title>
 </head>
+
 <body>
     <h1>Spine Phaser</h1>
     <ul>
@@ -19,6 +21,11 @@
         <li><a href="./blend-test.html">Blend test</a></li>
         <li><a href="./camera-pipeline-test.html">Camera pipeline test</a></li>
         <li><a href="./control-bones-test.html">Control bones</a></li>
+        <li><a href="./extended-class-test.html">Extended class</a></li>
+        <li><a href="./canvas-test.html">Canvas test</a></li>
+        <li><a href="./depth-test.html">Depth test</a></li>
+        <li><a href="./render-to-texture-test.html">Render to texture test</a></li>
     </ul>
 </body>
+
 </html>

+ 44 - 41
spine-ts/spine-phaser/example/multi-scene-test.html

@@ -1,5 +1,6 @@
 <!DOCTYPE html>
 <html lang="en">
+
 <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -8,58 +9,60 @@
     <script src="../dist/iife/spine-phaser.js"></script>
     <title>Spine Phaser Example</title>
 </head>
+
 <body>
     <h1>Multi-scene test</h1>
 </body>
 <script>
-class Scene1 extends Phaser.Scene {
-    constructor () {
-        super({key: "Scene1"})
-    }
+    class Scene1 extends Phaser.Scene {
+        constructor() {
+            super({ key: "Scene1" })
+        }
 
-    preload() {
-        this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
-        this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
-    }
+        preload() {
+            this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
+            this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
+        }
 
-    create() {
-        let spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
-        spineboy.scale = 0.5;
-        spineboy.animationState.setAnimation(0, "walk", true);
-        this.input.once('pointerdown', () => this.scene.start('Scene2'));
+        create() {
+            let spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
+            spineboy.scale = 0.5;
+            spineboy.animationState.setAnimation(0, "walk", true);
+            this.input.once('pointerdown', () => this.scene.start('Scene2'));
+        }
     }
-}
 
-class Scene2 extends Phaser.Scene {
-    constructor () {
-        super({key: "Scene2"})
-    }
+    class Scene2 extends Phaser.Scene {
+        constructor() {
+            super({ key: "Scene2" })
+        }
 
-    preload() {
-        this.load.spineJson("raptor-data", "assets/raptor-pro.json");
-        this.load.spineAtlas("raptor-atlas", "assets/raptor-pma.atlas");
-    }
+        preload() {
+            this.load.spineJson("raptor-data", "assets/raptor-pro.json");
+            this.load.spineAtlas("raptor-atlas", "assets/raptor-pma.atlas");
+        }
 
-    create() {
-        let raptor = this.add.spine(300, 600, 'raptor-data', "raptor-atlas");
-        raptor.scale = 0.5;
-        raptor.animationState.setAnimation(0, "walk", true);
-        this.input.once('pointerdown', () => this.scene.start('Scene1'));
+        create() {
+            let raptor = this.add.spine(300, 600, 'raptor-data', "raptor-atlas");
+            raptor.scale = 0.5;
+            raptor.animationState.setAnimation(0, "walk", true);
+            this.input.once('pointerdown', () => this.scene.start('Scene1'));
+        }
     }
-}
 
-var config = {
-    type: Phaser.AUTO,
-    width: 800,
-    height: 600,
-    type: Phaser.WEBGL,
-    scene: [ Scene1, Scene2 ],
-    plugins: {
-        scene: [
-            { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-        ]
-    }
-};
-let game = new Phaser.Game(config);
+    var config = {
+        type: Phaser.AUTO,
+        width: 800,
+        height: 600,
+        type: Phaser.WEBGL,
+        scene: [Scene1, Scene2],
+        plugins: {
+            scene: [
+                { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
+            ]
+        }
+    };
+    let game = new Phaser.Game(config);
 </script>
+
 </html>

+ 57 - 0
spine-ts/spine-phaser/example/render-to-texture-test.html

@@ -0,0 +1,57 @@
+<!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/[email protected]/dist/phaser.js"></script>
+    <title>Spine Phaser Example</title>
+</head>
+
+<body>
+    <h1>Render to texture</h1>
+</body>
+<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("spineboy-data", "assets/spineboy-pro.skel");
+        this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
+    }
+
+    function create() {
+        let renderTexture = this.add.renderTexture(0, 0, 800, 600);
+        let spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
+        spineboy.scale = 0.5;
+        spineboy.animationState.setAnimation(0, "walk", true);
+        this.add.text(200, 8, 'Click to stamp SpineBoy');
+
+        this.input.on('pointermove', function (pointer) {
+            spineboy.setPosition(pointer.x, pointer.y);
+        }, this);
+
+        this.input.on('pointerdown', function (pointer) {
+            renderTexture.draw(spineboy);
+            spineboy.angle += 10;
+        }, this);
+    }
+</script>
+
+</html>

+ 32 - 29
spine-ts/spine-phaser/example/visibility-test.html

@@ -1,5 +1,6 @@
 <!DOCTYPE html>
 <html lang="en">
+
 <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -8,43 +9,45 @@
     <script src="../dist/iife/spine-phaser.js"></script>
     <title>Spine Phaser Example</title>
 </head>
+
 <body>
     <h1>Basic example</h1>
 </body>
 <script>
-var config = {
-    type: Phaser.AUTO,
-    width: 800,
-    height: 600,
-    type: Phaser.WEBGL,
-    scene: {
-        preload: preload,
-        create: create,
-    },
-    plugins: {
-        scene: [
-            { key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
-        ]
-    }
-};
+    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);
+    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 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(250, 500, 'spineboy-data', "spineboy-atlas");
-    spineboy.scale = 0.5;
-    spineboy.animationState.setAnimation(0, "walk", true);
+    function create() {
+        let spineboy = this.add.spine(250, 500, 'spineboy-data', "spineboy-atlas");
+        spineboy.scale = 0.5;
+        spineboy.animationState.setAnimation(0, "walk", true);
 
-    let spineboy2 = this.add.spine(550, 500, 'spineboy-data', "spineboy-atlas");
-    spineboy2.scale = 0.5;
-    spineboy2.animationState.setAnimation(0, "run", true);
+        let spineboy2 = this.add.spine(550, 500, 'spineboy-data', "spineboy-atlas");
+        spineboy2.scale = 0.5;
+        spineboy2.animationState.setAnimation(0, "run", true);
 
-    this.input.on('pointerdown', () => spineboy2.visible = !spineboy2.visible);
-}
+        this.input.on('pointerdown', () => spineboy2.visible = !spineboy2.visible);
+    }
 </script>
+
 </html>

+ 3 - 4
spine-ts/spine-phaser/src/SpineGameObject.ts

@@ -1,8 +1,7 @@
 import { SPINE_GAME_OBJECT_TYPE } from "./keys";
 import { SpinePlugin } from "./SpinePlugin";
-import { ComputedSizeMixin, DepthMixin, FlipMixin, ScrollFactorMixin, TransformMixin, VisibleMixin } from "./mixins";
+import { ComputedSizeMixin, DepthMixin, FlipMixin, ScrollFactorMixin, TransformMixin, VisibleMixin, AlphaMixin } from "./mixins";
 import { AnimationState, AnimationStateData, Bone, MathUtils, Skeleton, Skin, Vector2 } from "@esotericsoftware/spine-core";
-import { Vector3 } from "@esotericsoftware/spine-webgl";
 
 class BaseSpineGameObject extends Phaser.GameObjects.GameObject {
 	constructor (scene: Phaser.Scene, type: string) {
@@ -76,7 +75,7 @@ export class SkinsAndAnimationBoundsProvider implements SpineGameObjectBoundsPro
 	}
 }
 
-export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(ScrollFactorMixin(TransformMixin(VisibleMixin(BaseSpineGameObject)))))) {
+export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(ScrollFactorMixin(TransformMixin(VisibleMixin(AlphaMixin(BaseSpineGameObject))))))) {
 	blendMode = -1;
 	skeleton: Skeleton | null = null;
 	animationStateData: AnimationStateData | null = null;
@@ -89,7 +88,7 @@ export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(Scro
 
 	constructor (scene: Phaser.Scene, private plugin: SpinePlugin, x: number, y: number, dataKey: string, atlasKey: string, public boundsProvider: SpineGameObjectBoundsProvider = new SetupPoseBoundsProvider()) {
 		super(scene, SPINE_GAME_OBJECT_TYPE);
-		this.setPosition(x, y); x
+		this.setPosition(x, y);
 		this.setSkeleton(dataKey, atlasKey);
 	}
 

+ 6 - 2
spine-ts/spine-phaser/src/SpinePlugin.ts

@@ -106,13 +106,16 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
 		};
 
 		let makeSpineGameObject = function (this: Phaser.GameObjects.GameObjectFactory, config: any, addToScene: boolean) {
+			let x = config.x ? config.x : 0;
+			let y = config.y ? config.y : 0;
 			let dataKey = config.dataKey ? config.dataKey : null;
 			let atlasKey = config.atlasKey ? config.atlasKey : null;
-			let gameObject = new SpineGameObject(this.scene, self, 0, 0, dataKey, atlasKey);
+			let boundsProvider = config.boundsProvider ? config.boundsProvider : undefined;
+			let gameObject = new SpineGameObject(this.scene, self, x, y, dataKey, atlasKey, boundsProvider);
 			if (addToScene !== undefined) {
 				config.add = addToScene;
 			}
-			Phaser.GameObjects.BuildGameObject(this.scene, gameObject, config);
+			return Phaser.GameObjects.BuildGameObject(this.scene, gameObject, config);
 		}
 		pluginManager.registerGameObject(SPINE_GAME_OBJECT_TYPE, addSpineGameObject, makeSpineGameObject);
 	}
@@ -123,6 +126,7 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
 			if (!this.webGLRenderer) {
 				this.webGLRenderer = new SceneRenderer((this.phaserRenderer! as Phaser.Renderer.WebGL.WebGLRenderer).canvas, this.gl!, true);
 			}
+			this.onResize();
 			this.game.scale.on(Phaser.Scale.Events.RESIZE, this.onResize, this);
 		} else {
 			if (!this.canvasRenderer) {

+ 1 - 0
spine-ts/spine-phaser/src/index.ts

@@ -6,3 +6,4 @@ export * from "@esotericsoftware/spine-core";
 export * from "@esotericsoftware/spine-webgl";
 import { SpinePlugin } from "./SpinePlugin";
 (window as any).spine = { SpinePlugin: SpinePlugin };
+(window as any)["spine.SpinePlugin"] = SpinePlugin;

+ 3 - 0
spine-ts/spine-phaser/src/mixins.ts

@@ -31,6 +31,7 @@ export const Flip = components.Flip;
 export const ScrollFactor = components.ScrollFactor;
 export const Transform = components.Transform;
 export const Visible = components.Visible;
+export const Alpha = components.Alpha;
 
 export interface Type<
 	T,
@@ -75,3 +76,5 @@ export const TransformMixin: TransformMixin = createMixin<Phaser.GameObjects.Com
 type VisibleMixin = Mixin<Phaser.GameObjects.Components.Visible, Phaser.GameObjects.GameObject>;
 export const VisibleMixin: VisibleMixin = createMixin<Phaser.GameObjects.Components.Visible>(Visible);
 
+type AlphaMixin = Mixin<Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.GameObject>;
+export const AlphaMixin: AlphaMixin = createMixin<Phaser.GameObjects.Components.Alpha>(Alpha);

+ 1 - 1
spine-ts/spine-webgl/src/SkeletonRenderer.ts

@@ -176,7 +176,7 @@ export class SkeletonRenderer {
 					clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
 					let clippedVertices = new Float32Array(clipper.clippedVertices);
 					let clippedTriangles = clipper.clippedTriangles;
-					if (transformer) transformer(renderable.vertices, renderable.numFloats, vertexSize);
+					if (transformer) transformer(clippedVertices, clippedVertices.length, vertexSize);
 					batcher.draw(texture, clippedVertices, clippedTriangles);
 				} else {
 					let verts = renderable.vertices;

+ 37 - 43
spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs

@@ -848,7 +848,7 @@ namespace Spine.Unity.Editor {
 
 			keys.Add(new Keyframe(0, rotation, 0, 0));
 
-			int listIndex = 1;
+			int listIndex = 0;
 
 			float r = rotation;
 
@@ -865,7 +865,7 @@ namespace Spine.Unity.Editor {
 				animation.Apply(skeleton, 0, currentTime, true, null, 1f, MixBlend.Setup, MixDirection.In);
 				skeleton.UpdateWorldTransform();
 
-				int pIndex = listIndex - 1;
+				int pIndex = listIndex;
 
 				Keyframe pk = keys[pIndex];
 
@@ -919,16 +919,16 @@ namespace Spine.Unity.Editor {
 			xKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] + boneData.X, 0, 0));
 			yKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[2] + boneData.Y, 0, 0));
 
-			int listIndex = 1;
-			int frameIndex = 1;
+			int listIndex = 0;
+			int frameIndex = 0;
 			int f = TranslateTimeline.ENTRIES;
 			float[] frames = timeline.Frames;
 			skeleton.SetToSetupPose();
 			float lastTime = 0;
 			while (currentTime < endTime) {
-				int pIndex = listIndex - 1;
+				int pIndex = listIndex;
 
-				float curveType = timeline.GetCurveType(frameIndex - 1);
+				float curveType = timeline.GetCurveType(frameIndex);
 				if (curveType == 0) {
 					//linear
 					Keyframe px = xKeys[pIndex];
@@ -999,8 +999,8 @@ namespace Spine.Unity.Editor {
 
 						timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
 
-						px = xKeys[listIndex - 1];
-						py = yKeys[listIndex - 1];
+						px = xKeys[listIndex];
+						py = yKeys[listIndex];
 
 						float xOut = (bone.X - px.value) / (currentTime - px.time);
 						float yOut = (bone.Y - py.value) / (currentTime - py.time);
@@ -1011,8 +1011,8 @@ namespace Spine.Unity.Editor {
 						xKeys.Add(new Keyframe(currentTime, bone.X, xOut, 0));
 						yKeys.Add(new Keyframe(currentTime, bone.Y, yOut, 0));
 
-						xKeys[listIndex - 1] = px;
-						yKeys[listIndex - 1] = py;
+						xKeys[listIndex] = px;
+						yKeys[listIndex] = py;
 
 						listIndex++;
 						lastTime = currentTime;
@@ -1055,16 +1055,16 @@ namespace Spine.Unity.Editor {
 			List<Keyframe> keys = new List<Keyframe>();
 			keys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] + boneDataOffset, 0, 0));
 
-			int listIndex = 1;
-			int frameIndex = 1;
+			int listIndex = 0;
+			int frameIndex = 0;
 			int f = TranslateXTimeline.ENTRIES;
 			float[] frames = timeline.Frames;
 			skeleton.SetToSetupPose();
 			float lastTime = 0;
 			while (currentTime < endTime) {
-				int pIndex = listIndex - 1;
+				int pIndex = listIndex;
 
-				float curveType = timeline.GetCurveType(frameIndex - 1);
+				float curveType = timeline.GetCurveType(frameIndex);
 				if (curveType == 0) {
 					//linear
 					Keyframe p = keys[pIndex];
@@ -1112,13 +1112,13 @@ namespace Spine.Unity.Editor {
 
 						timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
 
-						p = keys[listIndex - 1];
+						p = keys[listIndex];
 						float boneOffset = isXTimeline ? bone.X : bone.Y;
 						float valueOut = (boneOffset - p.value) / (currentTime - p.time);
 						p.outTangent = valueOut;
 						keys.Add(new Keyframe(currentTime, boneOffset, valueOut, 0));
 
-						keys[listIndex - 1] = p;
+						keys[listIndex] = p;
 
 						listIndex++;
 						lastTime = currentTime;
@@ -1155,15 +1155,15 @@ namespace Spine.Unity.Editor {
 			xKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] * boneData.ScaleX, 0, 0));
 			yKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[2] * boneData.ScaleY, 0, 0));
 
-			int listIndex = 1;
-			int frameIndex = 1;
+			int listIndex = 0;
+			int frameIndex = 0;
 			int f = ScaleTimeline.ENTRIES;
 			float[] frames = timeline.Frames;
 			skeleton.SetToSetupPose();
 			float lastTime = 0;
 			while (currentTime < endTime) {
-				int pIndex = listIndex - 1;
-				float curveType = timeline.GetCurveType(frameIndex - 1);
+				int pIndex = listIndex;
+				float curveType = timeline.GetCurveType(frameIndex);
 				if (curveType == 0) {
 					//linear
 					Keyframe px = xKeys[pIndex];
@@ -1234,8 +1234,8 @@ namespace Spine.Unity.Editor {
 
 						timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
 
-						px = xKeys[listIndex - 1];
-						py = yKeys[listIndex - 1];
+						px = xKeys[listIndex];
+						py = yKeys[listIndex];
 
 						float xOut = (bone.ScaleX - px.value) / (currentTime - px.time);
 						float yOut = (bone.ScaleY - py.value) / (currentTime - py.time);
@@ -1246,8 +1246,8 @@ namespace Spine.Unity.Editor {
 						xKeys.Add(new Keyframe(currentTime, bone.ScaleX, xOut, 0));
 						yKeys.Add(new Keyframe(currentTime, bone.ScaleY, yOut, 0));
 
-						xKeys[listIndex - 1] = px;
-						yKeys[listIndex - 1] = py;
+						xKeys[listIndex] = px;
+						yKeys[listIndex] = py;
 
 						listIndex++;
 						lastTime = currentTime;
@@ -1286,15 +1286,15 @@ namespace Spine.Unity.Editor {
 			List<Keyframe> keys = new List<Keyframe>();
 			keys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] * boneDataOffset, 0, 0));
 
-			int listIndex = 1;
-			int frameIndex = 1;
+			int listIndex = 0;
+			int frameIndex = 0;
 			int f = ScaleXTimeline.ENTRIES;
 			float[] frames = timeline.Frames;
 			skeleton.SetToSetupPose();
 			float lastTime = 0;
 			while (currentTime < endTime) {
-				int pIndex = listIndex - 1;
-				float curveType = timeline.GetCurveType(frameIndex - 1);
+				int pIndex = listIndex;
+				float curveType = timeline.GetCurveType(frameIndex);
 				if (curveType == 0) {
 					//linear
 					Keyframe p = keys[pIndex];
@@ -1340,14 +1340,14 @@ namespace Spine.Unity.Editor {
 
 						timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
 
-						p = keys[listIndex - 1];
+						p = keys[listIndex];
 
 						float boneScale = isXTimeline ? bone.ScaleX : bone.ScaleY;
 						float valueOut = (boneScale - p.value) / (currentTime - p.time);
 						p.outTangent = valueOut;
 						keys.Add(new Keyframe(currentTime, boneScale, valueOut, 0));
 
-						keys[listIndex - 1] = p;
+						keys[listIndex] = p;
 
 						listIndex++;
 						lastTime = currentTime;
@@ -1382,16 +1382,16 @@ namespace Spine.Unity.Editor {
 
 			keys.Add(new Keyframe(timeline.Frames[0], rotation, 0, 0));
 
-			int listIndex = 1;
-			int frameIndex = 1;
+			int listIndex = 0;
+			int frameIndex = 0;
 			int f = 2;
 			float[] frames = timeline.Frames;
 			skeleton.SetToSetupPose();
 			float lastTime = 0;
 			float angle = rotation;
 			while (currentTime < endTime) {
-				int pIndex = listIndex - 1;
-				float curveType = timeline.GetCurveType(frameIndex - 1);
+				int pIndex = listIndex;
+				float curveType = timeline.GetCurveType(frameIndex);
 
 				if (curveType == 0) {
 					//linear
@@ -1464,7 +1464,7 @@ namespace Spine.Unity.Editor {
 
 						timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
 						skeleton.UpdateWorldTransform();
-						pk = keys[listIndex - 1];
+						pk = keys[listIndex];
 
 						rotation = bone.Rotation;
 						angle += Mathf.DeltaAngle(angle, rotation);
@@ -1476,7 +1476,7 @@ namespace Spine.Unity.Editor {
 
 						keys.Add(new Keyframe(currentTime, r, rOut, 0));
 
-						keys[listIndex - 1] = pk;
+						keys[listIndex] = pk;
 
 						listIndex++;
 						lastTime = currentTime;
@@ -1582,10 +1582,7 @@ namespace Spine.Unity.Editor {
 				}
 			}
 
-			float currentTime = timeline.Frames[0];
-			float endTime = frames[frames.Length - 1];
-			int f = 0;
-			while (currentTime < endTime) {
+			for (int f = 0, frameCount = frames.Length; f < frameCount; ++f) {
 				float time = frames[f];
 
 				int frameIndex = Search(frames, time);
@@ -1602,9 +1599,6 @@ namespace Spine.Unity.Editor {
 						}
 					}
 				}
-
-				currentTime = time;
-				f += 1;
 			}
 
 			foreach (KeyValuePair<string, AnimationCurve> pair in curveTable) {