Read this manual in English

脚本属性

脚本属性提供了一个定义并暴露游戏对象自定义属性的手段. 游戏对象上的脚本属性可以在编辑器里直接编辑也可以在代码里使用. 许多情况下使用脚本属性非常方便:

  • 当你想在编辑器中修改对象属性, 从而提高脚本重用性的时候.
  • 当你想用初始值创建游戏对象的时候.
  • 当你想创建属性值动画的时候.
  • 当你想从脚本里存取另一个脚本里的状态值的时候. (注意如果对象之间需要频繁访问互相的属性, 最好把数据共享到一个地方.)

常用于设置敌人的血量或者速度, 物品的颜色, 或者按钮被按下时需要向谁发送什么消息.

定义脚本属性

脚本组件中属性由 go.property() 函数定义. 函数应位于顶级—不应在 init()update() 之类的函数内部调用. 默认值决定了值类型: number, boolean, hash, msg.url, vmath.vector3, vmath.vector4 还是 vmath.quaternion. (好像最新版已经提供了属性类型的设置功能)

-- can.script
-- 对 health 和 target 创建脚本属性
go.property("health", 100)
go.property("target", msg.url())

function init(self)
  -- 初始化 target 位置.
  -- self.target 是用 url 引用的另一个游戏对象.
  self.target_pos = go.get_position(self.target)
  ...
end

function on_message(self, message_id, message, sender)
  if message_id == hash("take_damage") then
    -- decrease the health property
    self.health = self.health - message.damage
    if self.health <= 0 then
      go.delete()
    end
  end
end

加入此脚本组件的任何对象都可以设置属性值了.

Component with properties

在编辑器里选择 Outline 视图, 可编辑的属性值会出现在 Properties 部分:

Properties

被修改过的属性值以蓝色显示. 点击属性名旁边的重置按钮可以重置回默认值 (脚本里定义属性时的初始值).

生成项目时会分析脚本属性. 不计算表达式的值. 这意味着诸如 go.property("hp", 3+6) 不行而 go.property("hp", 9) 才行.

访问脚本属性

被定义好的脚本属性存在于 self 之中, 由脚本实例保存:

-- my_script.script
go.property("my_property", 1)

function update(self, dt)
  -- Read and write the property
  if self.my_property == 1 then
      self.my_property = 3
  end
end

自定义脚本属性也可使用 get, set 和动画函数进行访问, 与其他属性一样:

-- another.script

-- 对 "myobject#script" 里的 "my_property" 实施增 1
local val = go.get("myobject#my_script", "my_property")
go.set("myobject#my_script", "my_property", val + 1)

-- 对 "myobject#my_script" 里的 "my_property" 实施动画
go.animate("myobject#my_script", "my_property", go.PLAYBACK_LOOP_PINGPONG, 100, go.EASING_LINEAR, 2.0)

Factory 创建的对象

如果使用工厂创建对象, 可以在创建时赋初值:

local props = { health = 50, target = msg.url("player") }
local id = factory.create("#can_factory", nil, nil, props)

-- 访问工厂创建对象的脚本属性
local url = msg.url(nil, id, "can")
local can_health = go.get(url, "health")

当使用 collectionfactory.create() 创建对象时需要匹配id与对应的属性. 保存在一个表里传入 create() 函数:

local props = {}
props[hash("/can1")] = { health = 150 }
props[hash("/can2")] = { health = 250, target = msg.url("player") }
props[hash("/can3")] = { health = 200 }

local ids = collectionfactory.create("#cangang_factory", nil, nil, props)

使用 factory.create()collectionfactory.create() 创建的对象属性值会覆盖原型文件和脚本定义的初始值.

如果一个游戏对象上附加了多个脚本组件定义了同名的属性, 每一个属性都会用提供给 factory.create()collectionfactory.create() 的值来初始化.

资源属性

资源属性类似于脚本属性, 是为基础数据类型定义的:

go.property("my_atlas", resource.atlas("/atlas.atlas"))
go.property("my_font", resource.font("/font.font"))
go.property("my_material", resource.material("/material.material"))
go.property("my_texture", resource.texture("/texture.png"))
go.property("my_tile_source", resource.tile_source("/tilesource.tilesource"))

资源属性定义后像其他脚本属性一样会在 Properties 面板里展示出来, 但是是作为文件/资源浏览器项目:

Resource Properties

你可以用 go.get() 或者通过 self 脚本实例引用并使用 go.set() 访问和存取资源属性:

function init(self)
  go.set("#sprite", "image", self.my_atlas)
  go.set("#label", "font", self.my_font)
  go.set("#sprite", "material", self.my_material)
  go.set("#model", "texture0", self.my_texture)
  go.set("#tilemap", "tile_source", self.my_tile_source)
end