如何从编辑器脚本更新预制属性,并让实例获取更新? [英] How to update a prefab property from editor script and have the instances get the updates?

查看:317
本文介绍了如何从编辑器脚本更新预制属性,并让实例获取更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是对假设我有一个简单的MonoBehaviour

Assume I have a simple MonoBehaviour

public class FooScript : MonoBehaviour {
  public int someValue = 0;
  public int otherValue = 0;
}

我把它放在一个空的GameObject上,然后将GameObject拖到Project中以创建一个预制件.

I put that on an empty GameObject then drag the GameObject to the Project to create a prefab.

如果我选择预制并编辑someValue,那么如果我转到仍在场景中的实例,我会看到someValue已更新.

If I select the prefab and edit someValue then if I go to the instance still in the scene I see someValue is updated.

如果我在实例上编辑someValue,则在预制上更新someValue someValue在实例上 NOT 未更新,但是如果我在预制上更新otherValue则它确实在更新实例.换句话说,每个实例属性都具有自己的标志,无论是否已从源预制件对其进行了修改.

If I edit someValue on the instance then update someValue on the prefab someValue is NOT updated on the instance but if I update otherValue on the prefab it does update on the instance. In other words each instance property has it's own flag on if it has been modified from the source prefab or not.

但是,如果我制作一个编辑器脚本并在预制件上查找FooScript并设置someValue,则该实例 NOT 不会更新,只有预制件.我希望它的行为就像我在编辑器中手动完成的一样.换句话说,如果实例属性已由用户编辑,则不会更新.如果尚未编辑实例属性,请进行更新.

But, if I make an editor script and lookup FooScript on the prefab and set someValue the instance is NOT updated, only the prefab. I want it to act exactly as if I had done it manually in the editor. In other words, if the instance property has been edited by the user don't update. If instance property has not been edited do update.

问题是这样做的正确方法是什么?查看 PrefabUtilily 似乎没有ApplyPropertiesFromSourcePrefabOnAllUnmodifiedInstancePropreties函数.

The question is what's the correct way to do that? Looking at PrefabUtilily there doesn't appear to be a ApplyPropertiesFromSourcePrefabOnAllUnmodifiedInstancePropreties function.

我能想到的唯一解决方案 EXTREMELY 令人费解.我必须

The only solution I can think of sounds EXTREMELY convoluted. I'd have to

  1. 查找所有实例(遍历整个层次结构,不确定卸载场景中会发生什么情况)
  2. 对于每个实例记录,都可以通过调用PrefabUtility.GetPropertyModifications并将结果存储在某些Dictionary<GameObject, PropertyModifications[]>中对其进行修改. (很多内存)
  3. 将我的更改应用于预制件.
  4. 然后,对于我要更新的每个实例,也要更新该实例上的那个属性.
  1. find all instances (walk the entire hierarchy, not sure what happens in unloaded scenes)
  2. for each instance record the modifications are on it by calling PrefabUtility.GetPropertyModifications and storing the results in some Dictionary<GameObject, PropertyModifications[]>. (lots of memory)
  3. Apply my change to the prefab.
  4. Then, for every instance that doesn't have a modification to the field I'm updating update the that property on instance as well.

真的是令人费解吗?还是有一些更简单的方法?

Is it really that convoluted or is there some easier way?

推荐答案

在文档浏览中,Unity希望您在修改预制件的属性之前在代码中使用Undo.RecordObject(Object objectToUndo, string name),这也将带来好处在Unity本身中创建一个撤消"步骤,以便您可以还原所有更改的方法.

From a Documentation browse, it looks like Unity expects you to use Undo.RecordObject(Object objectToUndo, string name) in code before you modify a property on the prefab, which will also have the benefit of creating an Undo step in Unity itself so that you can revert any changes.

您可以使用EditorUtility.SetDirty(Object),但前提是您不想创建撤消"步骤,而Unity文档特别建议不要这样做.

You can use EditorUtility.SetDirty(Object), but only if you don't want to create an Undo step, and the Unity docs specifically recommend against it.

这篇关于如何从编辑器脚本更新预制属性,并让实例获取更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆