是否应在分配之前检查变量值?



我知道这听起来像是一个愚蠢的问题,但我很好奇我应该在分配之前检查我的变量值吗?

例如,如果我根据方向(Vector2)翻转skin(由精灵和光线投射组成的Node2D):

func _process(delta):
...
if(direction.x>0):
skin.scale.x=1
elif(direction.x<0):
skin.scale.x=-1

#OR

if(direction.x>0):
if(skin.scale.x!=1):
skin.scale.x=1
elif(direction.x<0):
if(skin.scale.x!=-1):
skin.scale.x=-1

皮肤规模是否会每_process改变一次,从而消耗更多的 CPU 使用率
OR
如果值相同,是否会被忽略?

首先,鉴于这是GDScript,所以行数将是一个性能因素。

我们将看看C++面...

<小时 />

但在此之前...请注意,GDScript 对属性做了一些欺骗。

当你说skin.scale戈多会在skin对象上调用get_scale,这将返回一个Vector2Vector2是一种值类型。该Vector2不是对象具有的比例,而是一个副本,是值的快照。因此,在几乎任何其他语言中,skin.scale.x=1都会修改Vector2,并且对对象的比例没有影响。这意味着您应该这样做:

skin.scale = Vector2(skin.scale.x + 1, skin.scale.y)

或者这个:

var skin_scale = skin.scale
skin_scale.x += 1
skin.scale = skin_scale

我敢打赌,使用 C# 的人会觉得很熟悉。

但是你不需要在GDScript中这样做。戈多会叫set_scale,这是大多数人所期望的。这是一个功能!


所以,你设置scale,戈多会打电话给set_scale

void Node2D::set_scale(const Size2 &p_scale) {
if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
}
_scale = p_scale;
// Avoid having 0 scale values, can lead to errors in physics and rendering.
if (Math::is_zero_approx(_scale.x)) {
_scale.x = CMP_EPSILON;
}
if (Math::is_zero_approx(_scale.y)) {
_scale.y = CMP_EPSILON;
}
_update_transform();
_change_notify("scale");
}

该方法_change_notify仅在编辑器中执行某些操作。它是用于撤消/重做 et.al 的Godot 3.x工具。

set_scale会打电话给_update_transform

void Node2D::_update_transform() {
_mat.set_rotation_and_scale(angle, _scale);
_mat.elements[2] = pos;
VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat);
if (!is_inside_tree()) {
return;
}
_notify_transform();
}

如您所见,这将更新Node2DTransform2D(_mat)。然后就去VisualServer了.

然后_notify_transform.这就是在场景树中传播更改的原因。如果您启用了它,这也是调用notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED)set_notify_transform.它看起来像这样(这是来自"canvas_item.h"):

_FORCE_INLINE_ void _notify_transform() {
if (!is_inside_tree()) {
return;
}
_notify_transform(this);
if (!block_transform_notify && notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
}
}

你可以看到它委托给另一个看起来像这样的_notify_transform(这是来自"canvas_item.cpp"):

void CanvasItem::_notify_transform(CanvasItem *p_node) {
/* This check exists to avoid re-propagating the transform
* notification down the tree on dirty nodes. It provides
* optimization by avoiding redundancy (nodes are dirty, will get the
* notification anyway).
*/
if (/*p_node->xform_change.in_list() &&*/ p_node->global_invalid) {
return; //nothing to do
}
p_node->global_invalid = true;
if (p_node->notify_transform && !p_node->xform_change.in_list()) {
if (!p_node->block_transform_notify) {
if (p_node->is_inside_tree()) {
get_tree()->xform_change_list.add(&p_node->xform_change);
}
}
}
for (CanvasItem *ci : p_node->children_items) {
if (ci->top_level) {
continue;
}
_notify_transform(ci);
}
}

所以,没有。如果值相同,则不会进行检查以忽略更改。

然而,值得注意的是,戈多使全局变换无效,而不是立即计算它(global_invalid)。这不会使同一帧中的转换的多次更新免费,但它使它们比其他方式更便宜。


我还提醒您,查看源代码不能替代使用探查器。

你应该检查吗?也许。。。如果有很多孩子需要更新,额外的线路可能足够便宜。如有疑问:使用探查器进行测量。

最新更新