我正在使用IronPython在Unity3d项目中进行(仅限编辑器)清理工作。除了一个令人恼火的问题之外,这种方法很有效。
我有一个Python包装器类隐藏了使用SerializedProperties的C#详细程度:
class PropertyProxy(object):
PROPTYPES = {
SerializedPropertyType.Integer:"intValue",
SerializedPropertyType.Boolean:"boolValue",
SerializedPropertyType.Float:"floatValue",
SerializedPropertyType.String:"stringValue",
SerializedPropertyType.Color:"colorValue",
SerializedPropertyType.ObjectReference:"objectReferenceValue",
SerializedPropertyType.LayerMask:"objectReferenceValue",
SerializedPropertyType.Enum:"enumValueIndex",
SerializedPropertyType.Vector2:"vector2Value",
SerializedPropertyType.Vector3:"vector3Value",
SerializedPropertyType.Vector4:"vector4DValue",
SerializedPropertyType.Rect:"rectValue",
SerializedPropertyType.ArraySize:"arraySize",
SerializedPropertyType.Character:"objectReferenceValue",
SerializedPropertyType.AnimationCurve:"animationCurveValue",
SerializedPropertyType.Bounds:"boundsValue",
SerializedPropertyType.Gradient:"objectReferenceValue",
SerializedPropertyType.Generic:"objectReferenceValue"
}
def __init__(self, owner):
self.owner = owner
self.prop_path = self.PROPTYPES[owner.propertyType]
def __repr__(self):
return self.owner.serializedObject.targetObject.name +"." + self.owner.propertyPath
@property
def value(self):
if self.owner.isArray:
return []
else:
return getattr(self.owner, self.prop_path)
@value.setter
def set_value(self, val):
setattr(self.owner, self.prop_path, val)
self.owner.serializedObject.ApplyModifiedProperties()
get
功能正常,并返回正确的值。但是,制定者抱怨道。如果您尝试设置PropertyProxy
的值,我会收到错误声明我正在尝试设置只读属性。这不是真的 - 我可以这样做:
myPropertyProxy.owner.floatValue = 2.0
没有问题,但是当设置者试图做
时 setattr (myPropertyProxy.owner, 'floatValue', 2.0)
我收到错误。
我认为这是某种问题,IronPython无法为Unity方面的属性获得正确的setter,但我只是在猜测。有没有人有关于这里真正发生的事情的更多信息?
更新
颁发
setattr(myProp.owner, 'floatValue', 2.0)
myProp.owner.serializedObject.ApplyModifiedProperties()
直接 - 即外面类 - 工作。哎呀。
更新2
如果您在没有属性装饰器的情况下调用它们,value
和set_value
函数将起作用:(
答案 0 :(得分:2)
我不确定完全理解你要做什么,无论如何谈论SerializedProperty。
如果要设置SerializedProperty
的值(通常是编写自定义检查员代码),您可以采用以下几种方法:
SerializedProperty
访问字段并反序列化SerializedObject(就像您的方法一样)现在,每种方法都取决于具体的用例,并最终有其缺点。要记住的主要事情是 [de]序列化过程由不同的线程处理,需要知道在反序列化之前已经修改了哪个SerializedProperty
。
因此,在您的情况下(如果我理解正确),您需要至少调用2个函数,以使其在任何情况下都能正常工作:
SerializedObject
州。SerializedProperty
(就像你正在做的那样)serializedObject.ApplyModifiedProperties
(与更新中一样)我认为这是IronPython无法解决的某种问题 在Unity方面获得一个属性的正确的setter,但我只是 猜测。有没有人知道这里真正发生了什么?
我对Python知之甚少,所以我没有明确的答案,但这可能与floatValue setter referes和外部函数(可能在引擎的C ++端)有关:
public extern float floatValue
{
[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
get;
[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
set;
}
答案 1 :(得分:0)
原来的问题原来是一种准红鲱鱼;如果您转换
,上面发布的代码可以使用@property
def value(self):
if self.owner.isArray:
return []
else:
return getattr(self.owner, self.prop_path)
@value.setter
def set_value(self, val):
setattr(self.owner, self.prop_path, val)
self.owner.serializedObject.ApplyModifiedProperties()
更老套:
def _value(self):
if self.owner.isArray:
return []
else:
return getattr(self.owner, self.prop_path)
def _set_value(self, val):
setattr(self.owner, self.prop_path, val)
self.owner.serializedObject.ApplyModifiedProperties()
value = property(fget = _value, fset = _set_value)
我认为这代表了CPython和IronPython在实现@property装饰器时的分歧,因为在普通的CPython中这两者是可以互换的。