Closed jt0dd closed 2 years ago
For point 3:
But wait, none of the code in here references anything the Readme's Usage section showed. new Layer() isn't called anywhere, there's not even an import of '@pixi/layers', so how is the plugin attached?
I see (search for keyword "layer" there) :
Example Code (plugins used: pixi-layers)
...
// This is demo of pixi-layers.js, https://github.com/pixijs/pixi-layers
// Drag the rabbits to understand what's going on
...
// Drag is the best layer, dragged element is above everything else
const dragGroup = new PIXI.display.Group(2, false);
...
// PixiJS v5 sorting - works on zIndex - and layer gets its zIndex from a group!
app.stage.sortableChildren = true;
// sorry, group cant exist without layer yet :(;
app.stage.addChild(new PIXI.display.Layer(greenGroup));
app.stage.addChild(new PIXI.display.Layer(blueGroup));
app.stage.addChild(new PIXI.display.Layer(dragGroup));
app.stage.addChild(new PIXI.display.Layer(shadowGroup));
so instead of new Layer()
there is: new PIXI.display.Layer(greenGroup)
etc
Also about: how is the plugin attached?
- see:
https://github.com/pixijs/examples/blob/main/examples/manifest.json#L519-L525 https://github.com/pixijs/examples/blob/main/src/js/pixi-examples.js#L66
so is a logic of this "Pixi examples" website which loads plugins required for specific examples.
Of course for your project you can do it differently and simpler. Here is some random working example i found - it has "import" usage etc. It was written for pixi v4 but i converted it to pixi v6: https://codesandbox.io/s/stupefied-marco-cwjji?file=/src/index.js
Some notes:
monicaGroupZIndex
or mainGroupZIndex
to change order of Groups / Layersnew PIXI.display.Stage
or PIXI.display.Layer
or PIXI.display.Group
in other examples then you will now know to use it like this instead:
import { Layer, Group, Stage } from "@pixi/layers";
...
app.stage = new Stage();
...
const monicaGroup = new Group(monicaGroupZIndex, true);
...
const monicaLayer = new Layer(monicaGroup);
Last thing: please read this useful article about layers by @ShukantPal : https://www.shukantpal.com/blog/pixijs/pixijs-layers-kit/
If you create a layer, and assign element.parentLayer = layer
- element will be rendered the same time as layer
. That's it, nothing more. Everything else is optional.
Group
is only needed if you have multiple stages and you want to make global variable, you dont need it.
Sorting is needed only if you dont sort characters yourself or through pixi mechanism.
useRenderTexture
is needed if you understand how layering, renderTextures and filters work.
If you create a layer, and assign
element.parentLayer = layer
- element will be rendered the same time aslayer
. That's it, nothing more. Everything else is optional.
Group
is only needed if you have multiple stages and you want to make global variable, you dont need it.Sorting is needed only if you dont sort characters yourself or through pixi mechanism.
useRenderTexture
is needed if you understand how layering, renderTextures and filters work.
I'm following but it doesn't seem to be working for me, what stupid mistake am I making?
https://i.gyazo.com/4a1357bdab6729f3d3062e2ff5ac421c.png
What should happen here is sprite1
should be sorted between sprite2
and sprite3
.
You'll notice I use require
rather than import
(it's an Electron.js application) but I logged the classes out so you could see they're imported correctly.
That screenshot should show the problem along side the code, but here's the code separately:
//import { Layer, Group, Stage } from "@pixi/layers";
const PIXI = require('pixi.js')
const Layer = require('@pixi/layers').Layer
const Group = require('@pixi/layers').Group
const Stage = require('@pixi/layers').Stage
console.log('Layer', Layer )
console.log('Group', Group )
console.log('Stage', Stage )
const app = new PIXI.Application();
document.body.appendChild(app.view);
app.stage = new Stage();
const layer = new Layer()
layer.group.enableSort = true;
const image = "https://wsop-poker-stage1.s3.amazonaws.com/web/game/layouts/tableResource/Regular/cards/cardBack.png"
PIXI.Loader.shared.add(image).load(() => {
const texture = PIXI.Loader.shared.resources[image].texture
const container = new PIXI.Container();
// my goal is to have sprite2 and sprite3 in a container and sprite1 outside of the container, but
// sort sprite1 to render between the two
const sprite1 = new PIXI.Sprite(texture);
const sprite2 = new PIXI.Sprite(texture);
const sprite3 = new PIXI.Sprite(texture);
sprite1.parentLayer = layer
sprite1.zOrder = 2
sprite2.parentLayer = layer
sprite2.zOrder = 1
sprite3.parentLayer = layer
sprite3.zOrder = 3
sprite1.position.set(10,10)
sprite3.position.set(20,20)
container.position.set(0,0)
app.stage.addChild(sprite1)
container.addChild(sprite2, sprite3)
app.stage.addChild(container)
app.stage.updateStage();
console.log(layer._sortedChildren);
})
you didnt add layer here. The whole point is "element is rendered like its a child of layer". If layer is not in stage, well, when do you want to render this thing?
you didnt add layer here. The whole point is "element is rendered like its a child of layer". If layer is not in stage, well, when do you want to render this thing?
I see my mistake. Now it works perfectly. I missed that in the examples because I thought PIXI.display.Layer
was a native PIXI construct rather than a construct of your plugin. I would still suggest that a minimal working example would be appropriate on the Usage section of the Readme. It might help others not have the same confusion. Perhaps everyone else understood it and I'm just slow.
Anyhow, thanks for your help. @domis86 Thank you too, it was your example that cleared up some things for me.
For the record, this barely impacts my performance at all, and after spending 12 hours straight trying to achieve the same outcome, resulting in terrible performance, I have incredible appreciation and respect for what you guys have done with this plugin.
OK, so now performance is ok?
OK, so now performance is ok?
Yes, however you guys did it, it seems to be efficient.
Pixi layers work the same way people usually do it. It has one linear visitor, so it can be slow at 10000 elements or so. If you dont sort stuff - its efficient :)
Also, if you have 100 characters , each has one shadow, one hpbar, one body, e.t.c. , all you have to do is enable pixi sort with zIndex
, and contents of characters will be distributed to layers according to that sort - only 100 elements instead of 300
Pixi layers work the same way people usually do it. It has one linear visitor, so it can be slow at 10000 elements or so. If you dont sort stuff - its efficient :)
I thought the main point of the project was to be able to sort things (with a container independent zIndex that PIXI wouldn't normally allow you to)?
Also, if you have 100 characters , each has one shadow, one hpbar, one body, e.t.c. , all you have to do is enable pixi sort with
zIndex
, and contents of characters will be distributed to layers according to that sort - only 100 elements instead of 300
Are you basically saying that when the contents of a container doesn't require global zIndexing, and could be handled with normal PIXI zIndex sorting, I can enable standard PIXI zIndexing for that container? Like if I set container.sortableChildren = true
on a container, this plugin can handle the container more efficiently?
structure: container-> char1 -> hpbar1, shadow1, body1 char2 -> hpbar2, shadow2, body2
you can enable sort on container with zIndex, for example char1 and char2 will switch places.
If you enable layers, layer Shadow will contain shadow2, shadow1 layer hpbar - hpbar2 , hpbar1 layer body - body2, body1 because container has order of children char2, char1, because pixi sorted it
structure: container-> char1 -> hpbar1, shadow1, body1 char2 -> hpbar2, shadow2, body2
you can enable sort on container with zIndex, for example char1 and char2 will switch places.
If you enable layers, layer Shadow will contain shadow2, shadow1 layer hpbar - hpbar2 , hpbar1 layer body - body2, body1 because container has order of children char2, char1, because pixi sorted it
I think I understand.
But if I'm close to publishing my game a year from now and have any performance issues how about I just hire you for a week or two to make PIXI layer optimizations lol.
Maybe it's just me but I don't find that the Usage section or documentation is very intuitive. Perhaps it needs clarification or I'm just dense. I'm using PIXIJS 6.2.1.
Here's the specific things I found confusing:
1) Readme: "Nothing will work if you dont create Stage and set it as root. Please do it or read full explanation."
My thought: Ok but doesn't the standard
app
(const app = new PIXI.Application();
) have aStage
attached asapp.stage
by default? So does this mean I need to create a new one, likeapp.stage = new PIXI.display.Stage()
or what? This doesn't even work, I get the error:Uncaught TypeError: Cannot read properties of undefined (reading 'Stage')
2) Readme:
A DisplayObject/Container can be rendered inside its layer instead of direct parent
My thought: Ok then all I have to do is create a single global
layer
and assign a reference to it on every sprite in my scene likesprite.parentLayer = layer
. Then, according to the readme I should setlayer.group.enableSort = true;
and then I can just do:So I tried that and nothing happened. My app didn't break, but
onWillSort
didn't get triggered (I added a console log inside to check).3) So at this point I'm looking through all the examples for references to a complete set of working code, so I open up https://pixijs.io/examples/#/plugin-layers/zorder.js
My thought: But wait, none of the code in here references anything the Readme's Usage section showed.
new Layer()
isn't called anywhere, there's not even an import of'@pixi/layers'
, so how is the plugin attached? Is there some external thing I have to do to initiate the plugin or what? This example left me confused.4) So I went back to the Readme to re-read and see if I missed something. I notice "{@link Layer} extends {@link PIXI.Container}:".
My thought: Oh so I use this just like a
Container
instance, so maybe I need to do something like:... and assign
globalLayer
(likesprite.parentLayer = globalLayer
) to any sprites that get added to any child of globalLayer or its children. And then anyContainer
instances I add as a child ofglobalLayer
will have support for layers. Nope. Now nothing is rendering, and no errors either.I don't know about everyone else, but I am seriously missing something here. I wish there was a single simple example that shows from start to finish how to use the plugin. Or maybe there is and I just don't get it or missed something.