Wow, thanks! I'll check this out when I get home.synthsin75 wrote:Here's code that gets both next and last keyframe (point motion here), whether the current frame is keyed or not:Code: Select all
local pos = 1 local neg = -1 local frame = moho.frame local ch = moho.layer:Channel(2, 1, moho.document) if (ch:GetKeyWhen(ch:GetClosestKeyID(frame)) ~= frame) then neg = 0 end local nextKeyframe = ch:GetKeyWhen(ch:GetClosestKeyID(frame)+pos) local lastKeyframe = ch:GetKeyWhen(ch:GetClosestKeyID(frame)+neg) print("nextKeyframe = "..nextKeyframe.."\n".."lastKeyframe = "..lastKeyframe)
Two scripts for you: "Maintain pose" and "Toggle visibility"
Moderators: Víctor Paredes, Belgarath, slowtiger
-
- Posts: 107
- Joined: Mon Jan 14, 2013 3:18 pm
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
-
- Posts: 107
- Joined: Mon Jan 14, 2013 3:18 pm
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
I can't get this to work. Despite what I give as pos/neg, it always returns the closest previous key, never the next. I can't control the direction... What could it be?
- hayasidist
- Posts: 3596
- Joined: Wed Feb 16, 2011 8:12 pm
- Location: Kent, England
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
How I'd go about this:
idOfKey = AnimChannel:GetClosestKeyID(when) -- the id of the key at or before "when"
later = idOfKey + 1 -- the id of the key later than "when"
frameOfKey = AnimChannel:GetKeyWhen(id)
use the above to get the key ids at the start and end of the frame range you want
e.g. between frames 15 and 25:
AnimChannel:GetClosestKeyID(15) will give you a key at or before 15 -- get its frame - if it's at 15 you have it; if not add one to keyId - make sure it's a valid keyId- get that id's frame, check it's not more than 25 - and that's the "earliest in timeline in range"
AnimChannel:GetClosestKeyID(25) will give you a key at or before 25 -- get its frame - if it's at 25 you have it; if not, check it's not less than 15 and that's the "latest in timeline in range"
there might not be a key in range; or earliest and latest may well be the same key of course!
for the whole timeline:
latest in range is the id of the key at AnimChannel:Duration() (should be AnimChannel:CountKeys()-1)
earliest in range is the id of the key at frame 0 (should be 0)
if there's only one key then it'll be at frame 0.
to go backwards between two key ids start at "latest in range" and subtract 1 from that until you get to "earliest in range"
to go forwards between two key ids start at "earliest in range" and add 1 to that until you get to until you get to "latest in range"
using AnimChannel:GetKeyWhen(keyId) as you go to find the key's frame
(and I'm sure I don't actually need to say this, but take care if you're moving keys as you go ... )
idOfKey = AnimChannel:GetClosestKeyID(when) -- the id of the key at or before "when"
later = idOfKey + 1 -- the id of the key later than "when"
frameOfKey = AnimChannel:GetKeyWhen(id)
use the above to get the key ids at the start and end of the frame range you want
e.g. between frames 15 and 25:
AnimChannel:GetClosestKeyID(15) will give you a key at or before 15 -- get its frame - if it's at 15 you have it; if not add one to keyId - make sure it's a valid keyId- get that id's frame, check it's not more than 25 - and that's the "earliest in timeline in range"
AnimChannel:GetClosestKeyID(25) will give you a key at or before 25 -- get its frame - if it's at 25 you have it; if not, check it's not less than 15 and that's the "latest in timeline in range"
there might not be a key in range; or earliest and latest may well be the same key of course!
for the whole timeline:
latest in range is the id of the key at AnimChannel:Duration() (should be AnimChannel:CountKeys()-1)
earliest in range is the id of the key at frame 0 (should be 0)
if there's only one key then it'll be at frame 0.
to go backwards between two key ids start at "latest in range" and subtract 1 from that until you get to "earliest in range"
to go forwards between two key ids start at "earliest in range" and add 1 to that until you get to until you get to "latest in range"
using AnimChannel:GetKeyWhen(keyId) as you go to find the key's frame
(and I'm sure I don't actually need to say this, but take care if you're moving keys as you go ... )
- synthsin75
- Posts: 10051
- Joined: Mon Jan 14, 2008 11:20 pm
- Location: Oklahoma
- Contact:
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
You shouldn't have to change the pos/neg values. Just use the one you need to get the direction you want.lehtiniemi wrote:I can't get this to work. Despite what I give as pos/neg, it always returns the closest previous key, never the next. I can't control the direction... What could it be?
Previous keyframe:
Code: Select all
local neg = -1
local frame = moho.frame
local ch = moho.layer:Channel(2, 1, moho.document)
if (ch:GetKeyWhen(ch:GetClosestKeyID(frame)) ~= frame) then
neg = 0
end
local lastKeyframe = ch:GetKeyWhen(ch:GetClosestKeyID(frame)+neg)
print("lastKeyframe = "..lastKeyframe)
Code: Select all
local pos = 1
local frame = moho.frame
local ch = moho.layer:Channel(2, 1, moho.document)
local nextKeyframe = ch:GetKeyWhen(ch:GetClosestKeyID(frame)+pos)
print("nextKeyframe = "..nextKeyframe)
The only thing you may need to change is the frame value, if you are evaluating it from somewhere other than the current frame.
- Wes
Donations: https://www.paypal.com/paypalme/synthsin75 (Thx, everyone.)
https://www.youtube.com/user/synthsin75
Scripting reference: https://mohoscripting.com/
Donations: https://www.paypal.com/paypalme/synthsin75 (Thx, everyone.)
https://www.youtube.com/user/synthsin75
Scripting reference: https://mohoscripting.com/
-
- Posts: 107
- Joined: Mon Jan 14, 2013 3:18 pm
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
Ah sorry I wrote unclearly. But to me it seems that GetClosestKeyID only looks for current frame and before it. It doesn't seem to look forwards in timeline, always backwards. At least I couldn't make it do so.synthsin75 wrote:You shouldn't have to change the pos/neg values. Just use the one you need to get the direction you want.lehtiniemi wrote:I can't get this to work. Despite what I give as pos/neg, it always returns the closest previous key, never the next. I can't control the direction... What could it be?
Previous keyframe:Next keyframe:Code: Select all
local neg = -1 local frame = moho.frame local ch = moho.layer:Channel(2, 1, moho.document) if (ch:GetKeyWhen(ch:GetClosestKeyID(frame)) ~= frame) then neg = 0 end local lastKeyframe = ch:GetKeyWhen(ch:GetClosestKeyID(frame)+neg) print("lastKeyframe = "..lastKeyframe)
Code: Select all
local pos = 1 local frame = moho.frame local ch = moho.layer:Channel(2, 1, moho.document) local nextKeyframe = ch:GetKeyWhen(ch:GetClosestKeyID(frame)+pos) print("nextKeyframe = "..nextKeyframe)
The only thing you may need to change is the frame value, if you are evaluating it from somewhere other than the current frame.
- synthsin75
- Posts: 10051
- Joined: Mon Jan 14, 2008 11:20 pm
- Location: Oklahoma
- Contact:
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
GetClosestKeyID does only get either the current frame, if keyed, or the last. But it returns an ID. Keyframe IDs are chronological, so if the current frame ID is 16, the next later keyframe ID is 17. My code uses the pos/neg to determine the direction we're looking by ID. Only after getting the next or last keyframe ID do we give that to GetKeyWhen to get the frame. Does it help to write it like this:lehtiniemi wrote:Ah sorry I wrote unclearly. But to me it seems that GetClosestKeyID only looks for current frame and before it. It doesn't seem to look forwards in timeline, always backwards. At least I couldn't make it do so.
Code: Select all
local pos = 1
local frame = moho.frame
local ch = moho.layer:Channel(2, 1, moho.document)
local nextKeyID = ch:GetClosestKeyID(frame)+pos
local nextKeyedFrame = ch:GetKeyWhen(nextKeyID)
print("nextKeyedFrame = "..nextKeyedFrame)
Last edited by synthsin75 on Wed Mar 23, 2016 11:17 pm, edited 1 time in total.
- Wes
Donations: https://www.paypal.com/paypalme/synthsin75 (Thx, everyone.)
https://www.youtube.com/user/synthsin75
Scripting reference: https://mohoscripting.com/
Donations: https://www.paypal.com/paypalme/synthsin75 (Thx, everyone.)
https://www.youtube.com/user/synthsin75
Scripting reference: https://mohoscripting.com/
-
- Posts: 107
- Joined: Mon Jan 14, 2013 3:18 pm
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
Oh, now I get it! Genious! Thank you! In addition, there probably has to be a check that the ID isn't bigger than the amount of keyframes?synthsin75 wrote:GetClosestKeyID does only get either the current frame, if keyed, or the last. But it returns an ID. Keyframe IDs are chronological, so if the current frame ID is 16, the next later keyframe ID is 17. My code uses the pos/neg to determine the direction we're looking by ID. Only after getting the next or last keyframe do we give that to GetKeyWhen to get the frame. Does it help to write it like this:lehtiniemi wrote:Ah sorry I wrote unclearly. But to me it seems that GetClosestKeyID only looks for current frame and before it. It doesn't seem to look forwards in timeline, always backwards. At least I couldn't make it do so.
Code: Select all
local pos = 1 local frame = moho.frame local ch = moho.layer:Channel(2, 1, moho.document) local nextKeyID = ch:GetClosestKeyID(frame)+pos local nextKeyedFrame = ch:GetKeyWhen(nextKeyID) print("nextKeyedFrame = "..nextKeyedFrame)
- synthsin75
- Posts: 10051
- Joined: Mon Jan 14, 2008 11:20 pm
- Location: Oklahoma
- Contact:
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
Yeah, off-hand, I'd assume a HasKey(when) check would work.lehtiniemi wrote:Oh, now I get it! Genious! Thank you! In addition, there probably has to be a check that the ID isn't bigger than the amount of keyframes?
if (ch:HasKey(frame+pos)) then
Last edited by synthsin75 on Wed Mar 23, 2016 11:20 pm, edited 1 time in total.
- Wes
Donations: https://www.paypal.com/paypalme/synthsin75 (Thx, everyone.)
https://www.youtube.com/user/synthsin75
Scripting reference: https://mohoscripting.com/
Donations: https://www.paypal.com/paypalme/synthsin75 (Thx, everyone.)
https://www.youtube.com/user/synthsin75
Scripting reference: https://mohoscripting.com/
-
- Posts: 107
- Joined: Mon Jan 14, 2013 3:18 pm
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
Thank you so much again. I know I ask alot, I'm really greatful for your help...!synthsin75 wrote:Yeah, off-hand, I'd assume a HasKey(when) check would work.lehtiniemi wrote:Oh, now I get it! Genious! Thank you! In addition, there probably has to be a check that the ID isn't bigger than the amount of keyframes?
-
- Posts: 19
- Joined: Mon Jan 18, 2016 9:32 am
Re: Two scripts for you: "Maintain pose" and "Toggle visibil
I'm that someone you helped. But Its not working with multiple layers, When selecting 2 or more layers, It applies only on first selected layer. Can you update this script to v1.1 ?lehtiniemi wrote: TOGGLE VISIBILITY
The script toggles the current visibility state for the layer: if it's visible, it becomes hidden and vice versa. "Automated layer effects" is automatically enabled for the selected layer. If the new visibility state is the same as in previous frame (=layer visibility state doesn't change), the keyframe is automatically removed.
Makes animating visibility a LOT faster than with the built-in functions (unless there's something I've missed), especially when the "Automated layer effects" isn't enabled and you animate visibility for the first time in the project.
Installation
Copy both .lua and .png files to the tool-folder.
The buttons appear in "Other"-group after restart.
Download both here:
http://www.juhanalehtiniemi.com/tmp/JL_ ... cripts.zip