[bug] camera_set_end_script and related funcs don't work with object functions

Answered

Comments

9 comments

  • YoYo QA Dept

    Hello,

    This error is correct, as you are passing in the variable that is storing the function and not the function itself. To rectify this you just need to use cam_upd()  the brackets denoting the function call.

    I did a very quick test in the create event of an object, and it was outputting "Hello" every frame

    cam_upd = function(){show_debug_message("Hello")}
    camera_set_end_script(view_camera[0], cam_upd());

    Hope this helps, thank you for the feedback. If you encounter any further issues please do get back in touch

    Regards,
    Scott

    0
    Comment actions Permalink
  • Michael McFarlane

    Hi Scott and Chymic,

    I hope you don't mind my addition, but the code didn't seem right, so I decided to test it:

    I have copied your code, pasted it into create and it only output "Hello" once, which makes sense to me, since in the code it looks like you are setting the camera end script to the result of cam_upd by using () brackets. I'm not really sure how your example could actually output "Hello" every frame - wouldn't it just set the update script to "undefined" since it doesn't return anything?

    I though maybe you needed to use method() instead, but that gives the same crash as originally posted, so I think there is genuinely a bug here. I repro'd the bit where it works if the function is defined in a script too. 

    1
    Comment actions Permalink
  • Chymic Koffman

    Yeah I'm pretty sure this is a bug. I just tested it with layer_script_begin (effectively the same setup) and got the same "Result is NaN" error.

    I'm guessing this is an oversight with all of the functions that previously took a script as an argument.

    1
    Comment actions Permalink
  • YoYo QA Dept

    Hello,
     I have a sample project that has some updated code to include layer_script and to show that it is not just the result of the function but the function itself that is run. https://www.dropbox.com/s/zx6xty6i38iq8yu/cameraTest.yyz?dl=0 

    It outputs every frame (apart from the layer_script begin see below)



    Please do get back in touch if there are issues with that link.

    As above, there does seem to be an issue with layer_script_ functions, or in my understanding of how this should be working. As such I have reported the issues detailed by you both and passed this forum post along.

    I hope this helps, and perhaps when the tech team look into this issue they can provide more insights

    Regards,
    Scott


    0
    Comment actions Permalink
  • Michael McFarlane

    Hi again, I've done a little more testing with your project, and there is definitely a bug. Well, maybe 2 bugs.

    You can prove this by commenting out "camera_set_end_script" - the scripts still gets executed, because layer_script_begin grabs the first method instead. Alternatively, define layerFunc before cam_upd and only the layerFunc will keep executing. The cam_upd function is executing 9 times per frame (that's 8 times per layer from all the draw stages, and 1 per camera - it should only be the one per camera) in your project, which also shows that something is wrong . (this can be seen by resetting global.a and global.b in the Begin Step event)

    You can also see we are using the result by adding another debug message to the end of create, and seeing that the scripts get executed before this call - layer and camera scripts do not execute on assignment

    Also try adding a non-number return value to either of the methods - it doesn't work! It crashes immediately because we are using the result of the function (because of the brackets), and it cannot be converted to a number - your code only executes because of a bug. I know camera/layer scripts shouldn't really return anything, but this is not an issue with regular scripts.

    So there are two bugs:

    1. Methods without return statements always return 0 instead of something like "undefined", and this 0 just happens to represent the first method by pure luck (well, more like compilation order, I guess). This didn't work for my test project because I already had other scripts defined, so the 0 was referring to some other method/script.
    2. Camera and layer script functions do not accept method types.

    I hope this helps somewhat, this testing has made me more confident there is a bug here.

    0
    Comment actions Permalink
  • YoYo QA Dept

    Hello Again.

    Yes, I would agree with everything you have posted. As I said I have logged an issue to our database but I will add your investigation results in too. 

    Hopefully, a member of the tech team will be able to look at it by tomorrow and provide some more (accurate) information.

    Thanks again
    Scott

    0
    Comment actions Permalink
  • Michael McFarlane

    Awesome, thank you for helping us work this out! It's greatly appreciated!

    0
    Comment actions Permalink
  • Jason McKenzie

    Found a workaround for camera and layer scripts not accepting method types via method_get_index if that helps anyone.

    For the 2.3 release I think the following functions should be renamed for maximum compatibility and automatically changed when upgrading projects:

    • camera_set_begin_script -> camera_set_begin_method
    • camera_set_end_script -> camera_set_end_method
    • camera_set_update_script -> camera_set_update_method
    • layer_script_begin -> layer_method_begin
    • layer_script_end -> layer_method_end
    • timeline_moment_add_script -> timeline_moment_add_method
    • script_execute -> method_execute

    And these functions would work similar to the below GML which do not accept non-method types.

    Hope this helps!

    Edit:

    A bug with the workaround. These functions don't result in the methods being invoked correctly.

    var o = {
    _method: function() {
    show_debug_message(self);
    }
    };

    o._method();
    // { _method : function gml_Script_anon____struct___4_355_gml_Object_Player_Create_0 }
    // Correct!

    script_execute(method_get_index(o._method));
    // { ___struct___4 : function gml_Script____struct___4_gml_Object_Player_Create_0, ___struct___3 : function gml_Script____struct___3_gml_Object_Player_Create_0 }
    // Nope

    var m = method(o, o._method);
    script_execute(method_get_index(m));
    // { ___struct___4 : function gml_Script____struct___4_gml_Object_Player_Create_0, ___struct___3 : function gml_Script____struct___3_gml_Object_Player_Create_0 }
    // Nope

    layer_script_begin("Sequences", method_get_index(o._method));
    // { }
    // Nope
    1
    Comment actions Permalink
  • Michael McFarlane

    Ok, yeah, I can confirm method_get_index seems to work just fine in my mini test! The indices of the methods seem to start at 100001+however many other scripts are defined for me, but it does work.

    What's curious about this - and the reason I hadn't already tried this - is that it does not line up with the documentation at all - it currently says that it returns the script index the method was defined in, and -1 if it was not defined in a script - I'm seeing almost the exact opposite:

    I defined two functions in a script -- one with the same name as the script and on with a different name, and called method_get_index on both and it returned undefined for both. However it does return some kind of useful ID for these instance methods. So that's something.

    Just read your edit: Ah, so even method_get_index is not dependable, depending on the case. Though I think that could be because "self" loses meaning in these other contexts as the methods aren't actually being executed by a struct or a real instance.

    1
    Comment actions Permalink

Please sign in to leave a comment.