如何避免在预制模式下调用validate方法



我在我的场景中有一个gameObject作为实例预制。我添加了一个具有单obehaviour的组件,该组件在validate方法中具有验证逻辑。但是我注意到当我处于预制模式时,也要调用validate方法。

因此,我希望仅在我的场景中存在编辑器模式中的场景中,因为它们的值取决于场景中的其他对象。

因此,我想知道如何避免在预制模式下被调用。是否嵌套。

所以我尝试写我的方法从这里进行参考:https://github.com/unity-technologies/unitycsreference/blob/master/master/editor/mono/mono/scenemanagement/stagemanager/prefabstage/prefabstage/prefabstageutility.cs,但它失败了预制片嵌套在另一个预制板中。

class Helper
{
    //It doesn't work. It failed when the prefab is nested in another prefab.
    public static bool PrefabModeIsActive(Gameobject object)
    {
        UnityEditor.Experimental.SceneManagement.PrefabStage prefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetPrefabStage (gameObject);
        if(prefabStage != null)
            return true;
        if(UnityEditor.EditorUtility.IsPersistent(gameObject))
        {
            return true;
        }
        return false;
    }
}

mymonobehaviour

class MyMonobehaviour : MonoBehaviour
{
    public MyScriptableObject entity;
# IF UNITY_EDITOR
    void OnValidate()
    {
        //So I expected that logic onvalidate is called only on instance prefab in my scene.
        if(!Helper.PrefabModeIsActive(gameObject) && entity == null)
        {
            entity = Resources.Load<MyScriptableObject>("MyAssetScene/" + SceneManager.GetActiveScene().name) as MyScriptableObject;
        }
    }
#endif
}

所以我希望我的场景中仅在实例前列出validate逻辑。

更新1

似乎有效的替代解决方案是在游戏对象中的场景中检查一些值:

bool PrefabModeIsActive(Gameobject gameobject)
{
    return String.IsNullOrEmpty(gameObject.scene.path)
    && !String.IsNullOrEmpty(gameObject.scene.name);
}

,但我不确定是否有一些案例研究,这可能不是真的

这是我在所有项目中使用的几行,以避免此烦人的功能。

#if UNITY_EDITOR
using UnityEditor.Experimental.SceneManagement;
using UnityEditor;
#endif
void OnValidate()
    {
#if UNITY_EDITOR
        PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
        bool isValidPrefabStage = prefabStage != null && prefabStage.stageHandle.IsValid();
        bool prefabConnected = PrefabUtility.GetPrefabInstanceStatus(this.gameObject) == PrefabInstanceStatus.Connected;
        if (!isValidPrefabStage && prefabConnected)
        {
            //Variables you only want checked when in a Scene
        }
#endif
        //variables you want checked all the time (even in prefab mode)
   }

这做了两件事。第一,它不会在预制模式下检查变量,并且在预制模式有效之前也不会检查变量。您不会看到的第二个好处,但是有时候,当您打开一个新项目或删除库文件夹,并且需要重新登录资产,您会在preab有效之前触发onvalidate((,甚至仅将" Isprefabconnected&quot(放置;

不起作用。

您可以尝试使用prefabstageutility的getCurrentPrefabstage方法。

ex。

    bool PrefabModeIsActive()
    {
        return UnityEditor.Experimental.SceneManagement.
            PrefabStageUtility.GetCurrentPrefabStage() != null;
    }

最新更新