PDA

View Full Version : How to create key??



RebelHill
04-15-2010, 06:43 AM
Ok, so next question... how can I create a key with Lscript.

Sure, I got the CreateKey command... but only CreateKey X Y Z, etc... namely with values entered.

But how can I create a key for an item at its current position, roation, etc, whatever that happens to be without telling LS what value to use..

Basically, how do I reference for current value??

Thanks.

RebelHill
04-15-2010, 06:50 AM
ahhh... wait...

is it...

CreateKey getPosition(time)

??

Seems to work, did I get it, did I actually manage to get something right from trawling the reference guide??

evenflcw
04-15-2010, 08:13 AM
It depends. If you are writing a generic script and just want to add a key to motion channels at the current time and current value then...

CreateKey(Scene().currenttime);

...should suffice. This is equivalent to user pressing Create Key button.



To get current position you first have to get a valid item identifier. Most commonly you're interested in some selected item. You can query selected items from the scene.

items = Scene().getSelect(); //gets an array of selected items in the current scene.
for(i=1;i<=items.count();i++) { //loops through the items
pos = items[i].getPosition(Scene().currenttime); //assigns each items position to pos (overwrite).
info(pos);
}

Tell more, and answers will perhaps be more exact aswell. Are you working on a generic script (ie something that shows up as a button in the menu)?

RebelHill
04-15-2010, 01:06 PM
yes... basically just after being able to create a set of buttons for quick keying of all controls on a character... both nulls and bones, since they cant be selected together.

So yes... Im happy enough to just do a list of...

SelectItem("someitem")
CreateKey getPosition(time)
CreateKey getRotation(time)


and so on..

But if theres a quick way that I can tell it to cycle a list of items and key them all, Im up for that too.

evenflcw
04-15-2010, 03:21 PM
Hmmm... how much help do you want? Do you want finished code?

I just looked up CreateKey(). It seems like it always keys all 9 motion channels. I guess thats not what you want to do.

As see it you have two option. The proper but somewhat tedious way is to create keys one channel at a time. The quick and easy way is to create keys one item or channel group at a time. You can do the latter by calling Position(), Rotation(), Scale(), with the current vales as argument (from getPosition() etc). These commands only work on one item at a time. So you select an item, position it, then select the next, position it etc. The two caveats is that autokey has to be on and that it alters selection. Both are surmountable. You can check and turn on and off autokey as needed, and you can restore the selection to what it was before your script started.

RebelHill
04-15-2010, 06:34 PM
Nope... tahts exactly waht I want to do... key all channels, for a whole bunch of items.

If I punch createKey getPosition(time) into LScommander... it works... But actually putting it in a script an running it it doesnt work.

All I want to do is select an item, and tell it to key at its current position, rotation, and scale... and then do it for a whole bunch of them... which is fine, I already got the lists, so its just copy paste... but cant seem to get it to work for one without just using createKey() whereby the keyframe requester pops up, which is no good.

evenflcw
04-16-2010, 03:25 AM
Ah ok. LSCommander doesn't run LScript. It runs command sequence scripts (CSScript). And what youre seeing is actually a false positive.

CreateKey getPosition(time)

is actually interpreted as

CreateKey gibberish

CreateKey expects a time value, a single number. For some odd reason LW creates keys at the current time anyway. getPostion() isn't a CS command (it's a LScript method; there are no parenthesis in CSScript), nor is time a valid value. In CSScript there is no way to fetch the current time. All you can do in CSScript is invoke commands, because thats all it is, a bunch of commands. LScript infact calls these commands in order to change Layouts state. CS is Layouts human-to-computer language, and it only goes one way.

But if your happy exploiting CS you could indeed select items by name, and call CreateKey with gibberish as argument, over and over. Relying on names however is seldom good. Nor is keying all channels arbitrarily I would think.


SelectByName someitemname
CreateKey gibberish
SelectByName someotheritemname
CreateKey gibberish
etc...

The LScript way would be to create a function to key an item. And then call that function for each item in a list of items. The list could be compiled in various ways, from file, from an interface, from selection. See below for a full example lscript. Copy paste into a *.ls file and install and it should work. This is option 2 from my previous post.


@script generic

generic {
//get a list of items, in this case, all selected items
items = Scene().getSelect();

//check autokey state, turn on if its off.
autokey = Scene().generalopts[7];
if(!autokey) AutoKey();

//keyframe all items in position and rotation using user defined function below.
foreach(item, items) { //foreach item in items.
keyframe(item, POSITION, item.getPosition(Scene().currenttime));
keyframe(item, ROTATION, item.getRotation(Scene().currenttime));
}

//restore selection using user defined function below.
selectitems(items);

//restore autokey state
if(!autokey) AutoKey();
}



//function to creates keyframes for specified channelgroup and item.
//item item identifier
//group channel group constant, POSITION=1, ROTATION=2, SCALE=3
//value vector
@define POSITION 1
@define ROTATION 2
@define SCALE 3
keyframe: item, group, value {
SelectItem(item.id);
switch(group) {
case POSITION:
Position(value);
break;

case ROTATION:
Rotation(value);
break;

case SCALE:
Scale(value);
break;
}
}



//function to selects multiple items
//items array of item identifiers
selectitems: items {
SelectItem(items[items.size()].id);
for(i=items.size()-(1); i>0; i--)
AddToSelection(items[i].id);
}

RebelHill
04-18-2010, 11:36 AM
hey, yeah... no...

Im not trying to create a script to key items Ive selected in the scene... Im trying to make a script that will key a predefined list of items... both nulls and bones, basically a "key all controls" button.

Ive already done a bunch of motion/state on off scripts to switch parts and functions of rigs on and off... all I need is a "create key" command that'll let me apply keyframes to these items with their current values.

Also... I tried the second script you posted, and it runs without errors, but no keys are actually created on any of the selected items.

evenflcw
04-18-2010, 02:43 PM
I think I've understood what your trying to do, I'd rather not give off the game, unless asked to do so explicitly. I don't know what your aim with this is. What I would do in your case is first write a script that keys all selected items, then add the part that can key a predefined list of items. Last I'd do an interface to create the list in a convenient manner. Ie, one step at a time, building and testing the functions you need, and then put the pieces back together in the way you need them.

But it seems your happy with the CS solution and you got what you need for that (SelectItemByName and CreateKey, or Selecttem and AddItemToSelection if you can compile a list of item ids). Or aren't you satisfied? Do you care if its an LScript solution or do you want it in CS? Do you want to write it yourself or could you care less if someone provides the code?

About the script not working. It seems to be the constants POSITION, etc. Initially I had the main function at the bottom but thought it more instructive to have it ontop (cause thats were the script starts). Unfortunately this means the constants are yet undefined. So script fails. So to make it work just move the @define to the top. I suppose it might be better to just write 3 functions or use strings ("position", etc).

RebelHill
04-18-2010, 03:18 PM
ahh... the @define bit makes sense...

I do think though, maybe I asked the question poorly to begin with.

Basically, Im just looking for the command to create a key on something, at the current time, and current position/rotation/scale...

Basically, Ive got characters who are a mix of nulls and bones (as is often the case)... and Im just trying to make a lil script to provide a button to key all of the controllers, rather than having to pick the null selection set, hit return twice, now pick the bone selection set, hit return twice...

For instance Ive got scripts already for quickly showing hiding all controls...

SelectItem("someitem")
ItemVisibity (1)

SelectByName("somebone")
ItemVisibility (1)

And so on... The same again, for tuning IK/SAI on off for things to selectively strip rig, create proxy modes, etc, etc...

So im jsut looking for the eqivalent for making a "Key Character" button... some way to command...

SelectItem("someitem")
Create key XYZHPBXscYscZsc(here and now)

Slectitem("somebone")
CreateKey XYZHPBXscYscZsc(here and now)

As for CSS, LS... Im not really that fussed... so long as it works. The code doesnt need to be complex, or clever... Ive got the command to select an item (or group) down... Im jsut lost for finding the command for keying them (rather than changing vis, motion control, etc)...

RebelHill
04-19-2010, 04:44 AM
Hey...

So I got something to work, largely based off butchering your script... but it does exactly what I was after...


@script generic

generic {

@define POSITION 1
@define ROTATION 2
@define SCALE 3



SelectByName("L_THUMB_OFFSET_JENNY");
AddToSelection("L_THUMB1_JENNY");
//add lots more bones



//get a list of items, in this case, all selected items
items = Scene().getSelect();

//check autokey state, turn on if its off.
autokey = Scene().generalopts[7];
if(!autokey) AutoKey();

//keyframe all items in position and rotation using user defined function below.
foreach(item, items) { //foreach item in items.
keyframe(item, POSITION, item.getPosition(Scene().currenttime));
keyframe(item, ROTATION, item.getRotation(Scene().currenttime));
}



//restore autokey state
if(!autokey) AutoKey();





SelectByName("Root_Jenny");
AddToSelection("Root_Offset_Jenny");
//add lots more items



//get a list of items, in this case, all selected items
items = Scene().getSelect();

//check autokey state, turn on if its off.
autokey = Scene().generalopts[7];
if(!autokey) AutoKey();

//keyframe all items in position and rotation using user defined function below.
foreach(item, items) { //foreach item in items.
keyframe(item, POSITION, item.getPosition(Scene().currenttime));
keyframe(item, ROTATION, item.getRotation(Scene().currenttime));
}



//restore autokey state
if(!autokey) AutoKey();
}


Im sure it could be done mroe elegantly somehow or other... but hey, its all good.

Thanks a lot.

RebelHill
04-19-2010, 05:19 AM
Actually... one more Q...

If I wanted to add to this an additional piece for keying a bunch of master channels at their current values and time... would that be pretty much the same, but instead of getting selected items, would have to get selected channels??

And would I need a new definition to "define value"... rather than defining position, rotation, scale?

evenflcw
04-19-2010, 06:09 AM
Definitions typically aren't necessary. They are just there because thats how I wrote the function keyframe(). Set things up differently or create those keys differently and they won't be needed.

Keying master channels is somewhat different because you'll have to find those exact channels. Lucky for you (or me?) master channels are at the top level and easily found in the tree made up of channelgroups and channels (see GE).


time = Scene().currenttime;
channelgroup = ChannelGroup("MC");
if(channelgroup) {
for(channel=channelgroup.firstChannel(); channel!=nil; channel=channelgroup.nextChannel()) {
value =channel.value(time);
channel.createKey(time, value);
}
}