Trouble with Skins
by Jacob Dankovchik · in Torque 3D Professional · 09/19/2013 (9:10 pm) · 12 replies
I seem to be having nothing but trouble trying to get skins to work quite right. Maybe someone else here can shed some light on it?
So basically I'm trying to create a static shape and set a skin to it based on various inputs.
The trouble here is it will always set the skin to the first default one, which is called "block_base".
The datablock for the shape is:
And for material:
What's weird to me is when I set the skin manually via console after the block has been spawned, it sets just fine. But all at once with the code, it's no go. Doesn't matter if I set the skin to "R" at creation, or set it in the code after it's been created. Seems no matter what, unless I do it via the console, it always wants to create it as the first default skin.
So what am I missing here? How can I get it to set a specific skin when the block is first spawned?
So basically I'm trying to create a static shape and set a skin to it based on various inputs.
new StaticShape(%name) {
dataBlock = "baseTile";
skin = "R";
position = %pos;
rotation = "1 0 0 0";
scale = "1 1 1";
canSave = "1";
canSaveDynamicFields = "1";
};The trouble here is it will always set the skin to the first default one, which is called "block_base".
The datablock for the shape is:
datablock StaticShapeData(baseTile)
{
category = "Misc";
shapeFile = "art/block.dae";
availableSkins = "block_base R O Y G B V lR lO lY lG lB lV";
};And for material:
singleton Material(block_base)
{
mapTo = "block_base";
diffuseColor[0] = "1 1 1 1";
translucentBlendOp = "None";
diffuseMap[0] = "art/block.tga";
};
singleton Material(R : block_base)
{
mapTo = "R";
diffuseMap[0] = "art/blockRed.tga";
};All of the other color types have a material defined in a similar way.What's weird to me is when I set the skin manually via console after the block has been spawned, it sets just fine. But all at once with the code, it's no go. Doesn't matter if I set the skin to "R" at creation, or set it in the code after it's been created. Seems no matter what, unless I do it via the console, it always wants to create it as the first default skin.
So what am I missing here? How can I get it to set a specific skin when the block is first spawned?
#2
Just tried doing exactly as you have described too, no different.
Also just tested putting the skin change in another function. Ultimately the block behavior here is controlled by a tick object, so on the tick function I put in a line to set the block's skin if it exists. Works perfectly fine like that. Seems that if the skin change is called in the same line of functions, it doesn't want to work at all. But otherwise it's perfectly happy.
While I'm not opposed to this fix of my own, I still don't like it a lot because it leaves questions unanswered... Anyone have some insight?
09/19/2013 (9:35 pm)
Well it isn't that what I have doesn't work. It just doesn't work when called immediately from script. I do it from console, works perfectly fine.Just tried doing exactly as you have described too, no different.
Also just tested putting the skin change in another function. Ultimately the block behavior here is controlled by a tick object, so on the tick function I put in a line to set the block's skin if it exists. Works perfectly fine like that. Seems that if the skin change is called in the same line of functions, it doesn't want to work at all. But otherwise it's perfectly happy.
While I'm not opposed to this fix of my own, I still don't like it a lot because it leaves questions unanswered... Anyone have some insight?
#4
If I let the whole thing wait long enough, or if I just call it manually from console, everything seems to work ok. Although if done automatically in script too quickly, everything seems to just trip up and some skins won't change correctly.
I may just have to abandon the skin approach at this rate... Certainly a bit of a headache from this.
09/21/2013 (7:51 am)
No errors and with some more testing, it looks like I have it figured out more or less. It seems its actually about timing. I have a lot of these skin changes happening all together and the script seems to basically choke on it and timing gets out of sorts.If I let the whole thing wait long enough, or if I just call it manually from console, everything seems to work ok. Although if done automatically in script too quickly, everything seems to just trip up and some skins won't change correctly.
I may just have to abandon the skin approach at this rate... Certainly a bit of a headache from this.
#5
09/21/2013 (8:14 am)
You could try running a schedule on the block object to set the skin. Try like 100mS or something like that. You could also keep it invisible until the scheduled function runs so the player does not see any visual artifacts.
#6
If I manually enter the code, they all set correctly no matter how quickly I do it. If I call the function itself, they all set correctly no matter how quickly I do it.
If I try to set the skins when the blocks are created, none work at all. I do it as part of the tick function of the tick object that controls block creation and movement. But it's always the first one that has the most trouble for some reason. I can't quite understand it.
One theory I have is maybe it has to do with just setting the skins for the first time. Almost like caching a model, maybe if I set the skins to non-important objects off screen it will make the rest set much smoother.
I'd really like to get this to work right because if I don't, I would prolly have to resort to individual models. Which adds up to 66 different block models. They would all be small and no big deal, but I don't wanna have to manage that many tiny things.
09/21/2013 (8:27 am)
I've tried some similar stuff with little results. Kind of weird how it is behaving. If I try to apply all skins instantly on startup at once, everything but the first one applies. Wait 3 seconds, same thing. Wait 5, sometimes all go. Wait 7, they all set.If I manually enter the code, they all set correctly no matter how quickly I do it. If I call the function itself, they all set correctly no matter how quickly I do it.
If I try to set the skins when the blocks are created, none work at all. I do it as part of the tick function of the tick object that controls block creation and movement. But it's always the first one that has the most trouble for some reason. I can't quite understand it.
One theory I have is maybe it has to do with just setting the skins for the first time. Almost like caching a model, maybe if I set the skins to non-important objects off screen it will make the rest set much smoother.
I'd really like to get this to work right because if I don't, I would prolly have to resort to individual models. Which adds up to 66 different block models. They would all be small and no big deal, but I don't wanna have to manage that many tiny things.
#7
That is really messed up. It sounds like a material is not getting updated.
I don't remember having these kind of issues when I used skins in TGE. So this is just weird. Could this be a datablock issue? Like the datablock is not being transferred to the client?
What is messed up is that I had better luck getting things to function properly in script. I found that sometimes in the console that it would take a delayed amount of time for things to settle. It is like it is the opposite of what I experienced. I wonder if this is somehow related to that strange console delay? I am not even sure how I could recreate that though.
I see one thing:
diffuseMap[0] = "art/block.tga";
should be:
diffuseMap[0] = "art/block.base.tga";
And:
diffuseMap[0] = "art/blockRed.tga";
should be:
diffuseMap[0] = "art/block.Red.tga";
Of course when I did this before there were no materials involved. So that may be a monkey wrench. Maybe later today I can look at this closer.
09/21/2013 (8:44 am)
@Jacob,That is really messed up. It sounds like a material is not getting updated.
I don't remember having these kind of issues when I used skins in TGE. So this is just weird. Could this be a datablock issue? Like the datablock is not being transferred to the client?
What is messed up is that I had better luck getting things to function properly in script. I found that sometimes in the console that it would take a delayed amount of time for things to settle. It is like it is the opposite of what I experienced. I wonder if this is somehow related to that strange console delay? I am not even sure how I could recreate that though.
I see one thing:
diffuseMap[0] = "art/block.tga";
should be:
diffuseMap[0] = "art/block.base.tga";
And:
diffuseMap[0] = "art/blockRed.tga";
should be:
diffuseMap[0] = "art/block.Red.tga";
Of course when I did this before there were no materials involved. So that may be a monkey wrench. Maybe later today I can look at this closer.
#8
I think I narrowed it down a bit though for what causes it. I can't seem to change the skin until I first call setSkinName for "block_base", the initial default block color. It's only after I set that can I then set the color. And that's where it hangs up. Sometimes that doesn't actually set before the color skin gets set. So then the default color gets labeled as the red skin.
09/21/2013 (8:49 am)
Well I'm doing it without naming like that and everything still works perfectly fine, save for the timing issues. And I'm equally baffled by the whole thing. Console always seems to work without a hitch but when I call it via script, it goes a little nuts.I think I narrowed it down a bit though for what causes it. I can't seem to change the skin until I first call setSkinName for "block_base", the initial default block color. It's only after I set that can I then set the color. And that's where it hangs up. Sometimes that doesn't actually set before the color skin gets set. So then the default color gets labeled as the red skin.
#9
Right after that post, I thought about it that the code isn't getting skipped over or something, just not having time to execute properly. And for SOME reason, in my endless fatigue these last few days, I totally forgot to try holding off on calling the re-skins. So I set the default skin at spawn, then just a counter to count the number of ticks. Wait for about 20 ticks, then run the set of re-skin commands. Goes off without a hitch.
I just hate doing it like this because I can't stand creating a variable just to use for the first fraction of a second of the game, then never touch it again. Even though it's absolutely totally 100% negligible in its impact, always feels like such bad practice to me... Oh well!
09/21/2013 (9:14 am)
Looks like I finally got it working right. Weird how sometimes an idea just kinda "clicks" suddenly. While not a perfect fix and almost feels like a bit of a hack, it works. Since the skin changes are handled on the tick function of my script tick object, I delay it a bit.Right after that post, I thought about it that the code isn't getting skipped over or something, just not having time to execute properly. And for SOME reason, in my endless fatigue these last few days, I totally forgot to try holding off on calling the re-skins. So I set the default skin at spawn, then just a counter to count the number of ticks. Wait for about 20 ticks, then run the set of re-skin commands. Goes off without a hitch.
I just hate doing it like this because I can't stand creating a variable just to use for the first fraction of a second of the game, then never touch it again. Even though it's absolutely totally 100% negligible in its impact, always feels like such bad practice to me... Oh well!
#10
09/21/2013 (12:09 pm)
Why exactly does this need to be done on the script tick object? I thought this was happening during loading an object into a mission or something. I wonder if the script tick callback isn't the problem here.
#11
Then I tried making it so it only will change 1 skin per tick. That got it all working except the first one. To get that first one to change, I had to wait a really long time before scheduling the chain of commands. Although I was delaying on the load-in, not the skin changes. I recently tried that, making the skin changes wait, and all is well.
So long story short, it doesn't HAVE to be, but it makes the process much easier and more reliable. Also in the end I realized I have need for this tick counter as it is. Seems I can't find a reliable time metric for when the game actually begins. Sim::time starts from the main menu and never resets. I really need an exact measure of time, specifically ticks, so this actually works out perfectly in the end.
But the real take-away here is that the skin system seems to have some performance flaws when run quickly with a batch of others.
09/22/2013 (4:15 am)
That's what I tried to start with, changing skins on load in. It barely worked if at all, would get 1, maybe 2 to change skin. In the end I had a tick object created already for managing the creation and movement and stuff of the blocks, so I decided to toss it in there to get an easy delay instead of making a schedule. That helped, adding the 32ms gap.Then I tried making it so it only will change 1 skin per tick. That got it all working except the first one. To get that first one to change, I had to wait a really long time before scheduling the chain of commands. Although I was delaying on the load-in, not the skin changes. I recently tried that, making the skin changes wait, and all is well.
So long story short, it doesn't HAVE to be, but it makes the process much easier and more reliable. Also in the end I realized I have need for this tick counter as it is. Seems I can't find a reliable time metric for when the game actually begins. Sim::time starts from the main menu and never resets. I really need an exact measure of time, specifically ticks, so this actually works out perfectly in the end.
But the real take-away here is that the skin system seems to have some performance flaws when run quickly with a batch of others.
#12
09/24/2013 (12:31 pm)
This sounds like a bug in the C++ code, I might dig through the code and see if I can figure out whats wrong since I'm planning on using skins eventually.
Torque 3D Owner JeffH