pixijs / spine

Pixi.js plugin that enables Spine support.
Other
564 stars 217 forks source link

Spine animation sometimes turn black #339

Open johanzhu opened 4 years ago

johanzhu commented 4 years ago

Spine animation sometimes turn black here is my code:

function initPixi() {
    let app
    try {
      app = new window.PIXI.Application({
        transparent: true,
        width: 750,
        height: 750 * (window.screen.height / window.screen.width),
      })
    } catch (err) {
      console.log('pixi init err', err)
    }
    if (app && app.renderer) {
      app.renderer.view.style.width = '100vw'
      app.renderer.view.style.height = '100vh'
      spineRef.current.appendChild(app.view)
      appRef.current = app
    }
  }

  function loadSpine() {
    const spineLoaderOptions = {
      metadata: {
        image: window.PIXI.BaseTexture.from(spineTexture),
        spineAtlasFile: spineAtlas,
      }
    }
    const loader = new window.PIXI.Loader()
    loader
      .add('green', spineJson, spineLoaderOptions)
    loader.load(onAssetsLoaded.bind(this))
  }

  function onAssetsLoaded(loader, resources) {
    initStage(resources)
  }

  function initStage(resources) {
    const spineData = resources.green.spineData
    const green = new window.PIXI.spine.Spine(spineData)
    green.state.setAnimation(0, 'shuye', true)
    green.position.y = 740
    appRef.current.stage.addChild(green)
  }

most time animation shows correctly but somtimes it turns black and this is the error image

black like this: image

and this is is the real animation: image

Surprisingly, animation can still play。。。

pixi version 5.2.0 pixi spine version 2.1.7

ivanpopelyshev commented 4 years ago

I added ```js to your post

Yes, interesting, its probably some unholy combination of Mesh and not-yet-loaded-texture. For debug you have to turn off the browser cache (there's a checkbox in devtools settings).

Workaround: wait for it to load before you start rendering, here's thread about how to do that: https://github.com/pixijs/pixi.js/issues/6583

Yes, its hacky. We dont have promises in BaseTexture.from() interface yet, though people are talking about that case in v6 proposal ( https://github.com/pixijs/pixi.js/issues/6595 )

Can you give me whole example in zip file?

johanzhu commented 4 years ago

Thank you for reply ^ - ^ In fact , it happens on many of my spine resource here is the spine resource on my pic 归档.zip

image And Im wondering if I set app autoStart attribute to false and call render in this initStage function ,will the problem be solved ?

ivanpopelyshev commented 4 years ago

autoStart:false, app.ticker.start() when you are ready. But it wont help if we dont wait for all BaseTexture.from() to load, Spine starts rendering only when you add it in stage anyway :)

Yes, I know its not good that you have to pass existing texture in metadata, and loader itself doesnt give existing textures before load, only BaseTexture.from() does. I will think how to make solution for it globally.

As for your example, i'll look in weekend. It will help me determine whats wrong with pixi meshes and not-entirely-loaded textures.

ivanpopelyshev commented 4 years ago

Alternatively: use two loaders. First to load all the textures you need instead of all the baseTexture.from's . In its callback initialize second loader that handles all spine json

I think its the easiest way.

ivanpopelyshev commented 4 years ago

Btw, just in case you dont know what is actually application: https://github.com/pixijs/pixi.js/wiki/v5-Custom-Application-GameLoop

johanzhu commented 4 years ago

Thank you so much ~ (๑•̀ㅂ•́)و✧.