GML中点符号使用疑问及tooltip脚本报错求助
GML Tooltip脚本报错:<unknown_object>.this未设置 解决方法
问题背景
本人有Python及少量C语言基础,刚接触GML,编写了tooltip脚本,调用时出现<unknown_object>.this未设置错误,以下是脚本代码及报错信息,想确认脚本写法是否正确并解决报错:
原Tooltip脚本代码
function tooltip() { var this = {}; this.__init__ = function() { this.box = []; this.cx = obj_cursor.x; this.cy = obj_cursor.y; } this.update = function() { this.cx = obj_cursor.x; this.cy = obj_cursor.y; } this.create_id = function() { used_ids = [] for (var i = 0; i < array_length(this.box); i++) { array_push(used_ids, (this.box[i])._id); } if (array_length(used_ids) == 0) return 0; array_sort(used_ids, true); for (var i = 0; i < array_last(used_ids); i++) { if (!array_contains(used_ids, i)) return i; } return array_length(this.box); } this.create_box = function(_x, _y, _w, _h, _title, _desc, _state = false, _pict = spr_office) { var _box = { pos_x : _x, pos_y : _y, width : _w, height : _h, title : _title, desc : _desc, state : _state, pict : _pict, _id : this.create_id() } array_insert(this.box, _box._id, _box); } this.delete_box = function(box_id) { for (var i = 0; i < array_length(this.box); i++) { if ((this.box[i])._id == box_id) { array_delete(this.box, i, 1) break; } } } this.print = function(box_id) { var _data = {}; for (var i = 0; i < array_length(this.box); i++) { if ((this.box[i])._id == box_id) { _data = this.box[i]; break; } } var _x = _data.pos_x; var _y = _data.pos_y; var _w = _data.width; var _h = _data.height; var _t = _data.title; var _d = _data.desc; var _p = _data.pict; var _col = _data.state ? c_white : c_gray; draw_rectangle_colour(_x - 2, _y - 2, _x + _w+ 2, _y + _h + 2, c_white, c_white, c_white, c_white, false); draw_sprite_stretched_ext(_p, -1, _x, _y, _w, _h, _col, 1); if ((_x <= this.cx && this.cx <= _x + _w) && (_y <= this.cy && this.cy <= _y + _h)) { draw_set_colour(c_black); draw_rectangle(this.cx, this.cy, this.cx + _w + 6, this.cy + _h + 6, false); draw_set_colour(c_white); draw_text_ext(this.cx + 3, this.cy + 3, _d, string_height("Ay"), 150); } } this.get_value = function(box_id, target) { var _data = {} for (var i = 0; i < array_length(this.box); i++) { if ((this.box[i])._id == box_id) { _data = this.box[i]; break; } } switch (target) { case "pos_x" : return _data.pos_x; case "pos_y" : return _data.pos_y; case "width" : return _data.width; case "height" : return _data.height; case "title" : return _data.title; case "desc" : return _data.desc; case "state" : return _data.state; case "pict" : return _data.pict; case "_id" : return _data._id; } } this.get_length = function() { return array_length(this.box); } this.get_ids = function() { _arr = [] for (var i = 0; i < array_length(this.box); i++) { array_push(_arr, (this.box[i])._id); } return _arr; } return this; }
报错信息
ERROR in action number 1 of Create Event for object obj_ach_manager: Variable <unknown_object>.this(100048, -2147483648) not set before reading it. at gml_Script_anon@95@tooltip@tooltip (line 9) - this.box = []; gml_Script_anon@95@tooltip@tooltip (line 9) gml_Object_obj_ach_manager_Create_0 (line 2) - t.__init__();
错误原因
GML中直接调用对象的方法(如t.__init__())时,方法内部的this不会自动绑定到该对象实例——这和Python的类方法绑定逻辑完全不同。你这里的__init__方法里的this没有指向创建的t实例,导致访问this.box时找不到有效对象,触发报错。
修复方案
方式1:临时修复——手动绑定this调用方法
修改obj_ach_manager的Create事件代码,用with语句或method函数强制绑定实例:
// 方式1-1:用with语句 t = tooltip(); with(t) { __init__(); } // 方式1-2:用method函数绑定 t = tooltip(); method(t, t.__init__)();
方式2:彻底重构——使用GML官方构造函数语法(推荐)
GML提供了专门的构造函数写法(带constructor关键字),更符合语言特性,能从根源避免this绑定问题,同时代码更简洁:
function tooltip() constructor { // 直接在这里初始化属性,替代原__init__方法 box = []; cx = obj_cursor.x; cy = obj_cursor.y; update = function() { cx = obj_cursor.x; cy = obj_cursor.y; } create_id = function() { var used_ids = []; // 新增var,避免全局变量污染 for (var i = 0; i < array_length(box); i++) { array_push(used_ids, box[i]._id); } if (array_length(used_ids) == 0) return 0; array_sort(used_ids, true); for (var i = 0; i < array_last(used_ids); i++) { if (!array_contains(used_ids, i)) return i; } return array_length(box); } create_box = function(_x, _y, _w, _h, _title, _desc, _state = false, _pict = spr_office) { var _box = { pos_x : _x, pos_y : _y, width : _w, height : _h, title : _title, desc : _desc, state : _state, pict : _pict, _id : create_id() } array_insert(box, _box._id, _box); } delete_box = function(box_id) { for (var i = 0; i < array_length(box); i++) { if (box[i]._id == box_id) { array_delete(box, i, 1); break; } } } print = function(box_id) { var _data = {}; for (var i = 0; i < array_length(box); i++) { if (box[i]._id == box_id) { _data = box[i]; break; } } var _x = _data.pos_x; var _y = _data.pos_y; var _w = _data.width; var _h = _data.height; var _t = _data.title; var _d = _data.desc; var _p = _data.pict; var _col = _data.state ? c_white : c_gray; draw_rectangle_colour(_x - 2, _y - 2, _x + _w + 2, _y + _h + 2, c_white, c_white, c_white, c_white, false); draw_sprite_stretched_ext(_p, -1, _x, _y, _w, _h, _col, 1); if ((_x <= cx && cx <= _x + _w) && (_y <= cy && cy <= _y + _h)) { draw_set_colour(c_black); draw_rectangle(cx, cy, cx + _w + 6, cy + _h + 6, false); draw_set_colour(c_white); draw_text_ext(cx + 3, cy + 3, _d, string_height("Ay"), 150); } } get_value = function(box_id, target) { var _data = {}; for (var i = 0; i < array_length(box); i++) { if (box[i]._id == box_id) { _data = box[i]; break; } } switch (target) { case "pos_x" : return _data.pos_x; case "pos_y" : return _data.pos_y; case "width" : return _data.width; case "height" : return _data.height; case "title" : return _data.title; case "desc" : return _data.desc; case "state" : return _data.state; case "pict" : return _data.pict; case "_id" : return _data._id; } } get_length = function() { return array_length(box); } get_ids = function() { var _arr = []; // 新增var,避免全局变量污染 for (var i = 0; i < array_length(box); i++) { array_push(_arr, box[i]._id); } return _arr; } }
调用时直接使用new关键字创建实例,无需手动调用初始化方法:
// 在obj_ach_manager的Create事件中 t = new tooltip();
额外注意事项
- 原脚本中部分变量未加
var声明(如used_ids、_arr),会自动成为全局变量,容易引发不可预见的问题,修复后的代码已补充var声明。 - GML的构造函数语法是官方推荐的面向对象实现方式,比手动模拟对象的写法更稳定、高效。
内容的提问来源于stack exchange,提问作者Ayeah755
相关产品推荐
相关产品推荐

