To work around this issue I’m creating/adding the frame in an frame that is definitely not being used by anyone and then setting the time of the keyframe to the target frame and subframe. It’s weird because the “add_key()” doesn’t works but setting the time directly in the keyframe works. The following python script is enough to reproduce the issue if you have the setup I described above. Just make sure you put the correct level sequence path and binding name on the global VARs bellow.
import unreal
SEQUENCE_PATH = "/Game/Cinematics/LS_CreateKeyframeTest.LS_CreateKeyframeTest"
BINDING_NAME = "B_TestActor"
FRAME_NUMBER = 42
SUBFRAME = 0.42
TARGET_FRAME_TIME = FRAME_NUMBER + SUBFRAME
def find_binding(sequence, name):
for binding in sequence.get_bindings():
if binding.get_display_name() == name:
return binding
return None
def main():
sequence = unreal.load_asset(SEQUENCE_PATH)
if not sequence:
unreal.log_error(f"LevelSequence asset not found at path: {SEQUENCE_PATH}")
return
binding = find_binding(sequence, BINDING_NAME)
if not binding:
unreal.log_error(f"Binding '{BINDING_NAME}' not found in sequence.")
return
transform_track = None
for track in binding.get_tracks():
if isinstance(track, unreal.MovieScene3DTransformTrack):
transform_track = track
break
if not transform_track:
unreal.log_error(f"Transform track not found for binding '{BINDING_NAME}'.")
return
for section in transform_track.get_sections():
loc_z_channel = section.get_channel("Location.Z")
if loc_z_channel is None:
unreal.log_error(f" Location Z channel not found for binding '{BINDING_NAME}'.")
loc_z_key = loc_z_channel.add_key(time= unreal.FrameNumber(FRAME_NUMBER), new_value= 42.0, sub_frame= SUBFRAME, time_unit= unreal.MovieSceneTimeUnit.DISPLAY_RATE, interpolation= unreal.MovieSceneKeyInterpolation.AUTO)
current_loc_z_frametime = loc_z_key.get_time()
current_loc_z_frame_number = current_loc_z_frametime.frame_number.value
current_loc_z_sub_frame = current_loc_z_frametime.sub_frame
unreal.log(f"[DEBUG] - current_loc_z_frame_number: {current_loc_z_frame_number}")
unreal.log(f"[DEBUG] - current_loc_z_sub_frame: {current_loc_z_sub_frame}")
loc_z_key.set_time(new_frame_number= unreal.FrameNumber(FRAME_NUMBER), sub_frame= SUBFRAME, time_unit= unreal.MovieSceneTimeUnit.DISPLAY_RATE)
new_loc_z_frametime = loc_z_key.get_time()
new_loc_z_frame_number = new_loc_z_frametime.frame_number.value
new_loc_z_sub_frame = new_loc_z_frametime.sub_frame
unreal.log(f"[DEBUG] - new_loc_z_frame_number: {new_loc_z_frame_number}")
unreal.log(f"[DEBUG] - new_loc_z_sub_frame: {new_loc_z_sub_frame}")
if __name__ == "__main__":
main()