googlevr / tilt-brush-toolkit

Scripts and assets that help you use Tilt Brush data in your creative projects.
Apache License 2.0
744 stars 164 forks source link

Using code to dynamically load FBX exported by Tilt Brush in Unity #35

Closed mahe373662858 closed 5 years ago

mahe373662858 commented 5 years ago

Hello, there is a question I want to ask Tilt brush unity sdk, this plug-in imported into unit, dynamic loading of FBX exported by Tilt Brush into the project through code in unit, error occurred. Is there a feasible way?

1

andybak commented 5 years ago

(Drive-by comment)

Could you please include the error messages as text?

  1. It's much easier to read
  2. People searching for similar issues will get zero results from a screenshot
mahe373662858 commented 5 years ago

您好 我这边错报的原因: 1.Misconfigured singleton UnityEngine.Debug:Assert(Boolean, String) TiltBrushToolkit.BrushManifest:get_Instance() (at Assets/TiltBrush/Scripts/BrushManifest.cs:37) TiltBrushToolkit.ModelImportSettings:GetDescriptorForStroke(String) (at Assets/TiltBrush/Scripts/Editor/ModelImportSettings.cs:325) TiltBrushToolkit.ModelImportSettings:OnAssignMaterialModel(Material, Renderer) (at Assets/TiltBrush/Scripts/Editor/ModelImportSettings.cs:134)

2.NullReferenceException: Object reference not set to an instance of an object TiltBrushToolkit.ModelImportSettings.GetDescriptorForStroke (System.String oldMaterialName) (at Assets/TiltBrush/Scripts/Editor/ModelImportSettings.cs:325) TiltBrushToolkit.ModelImportSettings.OnAssignMaterialModel (UnityEngine.Material material, UnityEngine.Renderer renderer) (at Assets/TiltBrush/Scripts/Editor/ModelImportSettings.cs:134) System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at :0) Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation. System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at :0) System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at :0) UnityEditor.AttributeHelper.InvokeMemberIfAvailable (System.Object target, System.String methodName, System.Object[] args) (at C:/buildslave/unity/build/Editor/Mono/AttributeHelper.cs:162) UnityEditor.AssetPostprocessingInternal.ProcessMeshAssignMaterial (UnityEngine.Renderer renderer, UnityEngine.Material material) (at C:/buildslave/unity/build/Editor/Mono/AssetPostprocessor.cs:399) Hello, I misstate the reason here:

1 Misconfiguration singleton

UnityEngine. Debug: Assert (Boolean, String)

TiltBrush Toolkit.Brush Manifest: get_Instance() (at Assets/TiltBrush/Scripts/Brush Manifest.cs:37)

TiltBrush Toolkit. ModelImportSettings: GetDescriptor ForStroke (String) (at Assets/TiltBrush/Scripts/Editor/ModelImportSettings.cs:325)

TiltBrush Toolkit. Model Import Settings: On AssignMaterial Model (Material, Renderer) (at Assets/TiltBrush/Scripts/Editor/Model Import Settings.cs:134)

2NullReference Exception: Object reference not set to an instance of an object

TiltBrush Toolkit. ModelImportSettings. GetDescriptor ForStroke (System. String oldMaterial Name) (at Assets / TiltBrush / Scripts / Editor / ModelImportSettings. cs: 325)

TiltBrush Toolkit. ModelImportSettings. OnAssignMaterial Model (UnityEngine. Material, UnityEngine. Renderer renderer) (at Assets/TiltBrush/Scripts/Editor/ModelImportSettings.cs:134)

System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at :0)

Rethrow as Target Invocation Exception: Exception has been thrown by the target of an invocation.

System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at :0)

System. Reflection. MethodBase. Invoke (System. Object obj, System. Object [] parameters) (at :0)

Unity Editor. AttributeHelper. InvokeMemberIf Available (System. Object target, System. String methodName, System. Object [] args) (at C:/buildslave/unity/build/Editor/Mono/AttributeHelper.cs:162)

Unity Editor. AssetPost Processing Internal. ProcessMeshAssignMaterial (UnityEngine. Renderer renderer, UnityEngine. Material material) (at C:/buildslave/unity/build/Editor/Mono/AssetPost processor.cs:399)

dubois commented 5 years ago

There must have been a problem when you imported the .unitypackage. The error is here:

BrushManifest.cs:34
        sm_Instance = dummy.m_DefaultManifest;

If the .unitypackage was correctly imported, m_DefaultManifest will be a reference to Assets/TiltBrush/Assets/Brushes/AllBrushes.asset.

To fix it, try deleting and re-importing the .unitypackage. Or you can fix it by hand by viewing BrushManifest.cs in the Unity inspector and filling in m_DefaultManifest.

mahe373662858 commented 5 years ago

@dubois

Hello, I can manually drag FBX into the project without error and automatically specify shader. But when the code downloads FBX from the server to the project, it reports an error, and I've seen what you said last time that the m_default list already exists.

2

mahe373662858 commented 5 years ago

@Dubois This is the code that I downloaded tiltbrush to export FBX.

Do you support downloading in this way? If not, please let me know which way to support downloading.

1using UnityEngine;

using System.Collections;

using System.IO;

using System.Net;

using System;

using UnityEditor;

public class WWWLoad : MonoBehaviour

{

//string urlPath = "http://www.....";

string urlPath = @"http://beijinghanrick.com/resc/test.fbx";//资源网络路径(自己写)

string file_SaveUrl = @"D:\Tiltttttttttttttttttttttttttttttttttttttttttttttttt\Tilt_unity\Assets\Resources\Untitled_30.FBX";//资源保路径

FileInfo file;

bool isLoadModel = false;

HttpDldFile httpDown_O;

//初始化

void Start()

{

    file = new FileInfo(file_SaveUrl);

    httpDown_O = new HttpDldFile();

    Debug.Log(file_SaveUrl);

    WWWmodelsa();

}

//启动下载

public void WWWmodelsa()

{

    bool run_f = httpDown_O.Download(urlPath, file_SaveUrl);

    AssetDatabase.Refresh();//unity刷新

    isLoadModel = true;

    Debug.Log(urlPath);
    LoadModelas();
}

//实例化模型

public void LoadModelas()

{

    if (isLoadModel)

    {

        //GameObject objPrefab = (GameObject)Instantiate(AssetDatabase.LoadAssetAtPath(filePath,typeof(GameObject)));  

        //GameObject objPrefab = (MonoBehaviour.Instantiate(mPrefab, Vector3.zero, Quaternion.identity) as GameObject);

        GameObject objPrefab = (GameObject)Resources.Load("Untitled_30");

        Instantiate(objPrefab);

        Debug.Log(objPrefab.GetType().ToString());

    }

}

}

class HttpDldFile

{

// Http方式下载文件

public bool Download(string url, string localfile)

{

    bool flag = false;

    long startPosition = 0; // 上次下载的文件起始位置

    FileStream writeStream; // 写入本地文件流对象

    // 判断要下载的文件夹是否存在

    if (File.Exists(localfile))

    {

        writeStream = File.OpenWrite(localfile);             // 存在则打开要下载的文件

        startPosition = writeStream.Length;                  // 获取已经下载的长度

        writeStream.Seek(startPosition, SeekOrigin.Current); // 本地文件写入位置定位

    }

    else

    {

        writeStream = new FileStream(localfile, FileMode.Create);// 文件不保存创建一个文件

        startPosition = 0;

    }

    try

    {

        HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(url);// 打开网络连接

        if (startPosition > 0)

        {

            myRequest.AddRange((int)startPosition);// 设置Range值,与上面的writeStream.Seek用意相同,是为了定义远程文件读取位置

        }

        Stream readStream = myRequest.GetResponse().GetResponseStream();// 向服务器请求,获得服务器的回应数据流

        byte[] btArray = new byte[512];// 定义一个字节数据,用来向readStream读取内容和向writeStream写入内容

        int contentSize = readStream.Read(btArray, 0, btArray.Length);// 向远程文件读第一次

        while (contentSize > 0)// 如果读取长度大于零则继续读

        {

            writeStream.Write(btArray, 0, contentSize);// 写入本地文件

            contentSize = readStream.Read(btArray, 0, btArray.Length);// 继续向远程文件读取

        }

        //关闭流

        writeStream.Close();

        readStream.Close();

        flag = true;        //返回true下载成功

    }

    catch (Exception e)

    {

        writeStream.Close();

        flag = false;       //返回false下载失败

    }

    return flag;

}

}

dubois commented 5 years ago

Do you support downloading in this way? If not, please let me know which way to support downloading.

There are two things you could mean. I will try to answer both.

  1. It does not matter how the .fbx gets into your Assets/ folder. Unity Editor will process the fbx, and will call the code in ModelImportSettings.cs, and the materials will get assigned. Therefore yes, every asset processor, including the Tilt Brush Unity SDK, supports downloading assets into the Assets/ folder..

  2. From your screenshot in https://github.com/googlevr/tilt-brush-toolkit/issues/35#issue-459082976 I can see that you are in play mode when the error occurs. It is unusual to be importing assets in play mode, but I can't think of any reason why it wouldn't work. However, you should understand only the Unity Editor supports importing from Assets/. No asset processor, including the Tilt Brush Unity SDK, will support importing from Assets/ in a standalone build; there is not even an Assets/ folder to import from.

But when the code downloads FBX from the server to the project, it reports an error

The problem starts here:

      if (sm_Instance == null) {
        var dummy = CreateInstance<BrushManifest>();
        sm_Instance = dummy.m_DefaultManifest;   // [1] Is m_DefaultManifest null?
        DestroyImmediate(dummy);
      }
      Debug.Assert(sm_Instance != null, "Misconfigured singleton");  // [2] Why is it sm_Instance null?
      return sm_Instance;

I've seen what you said last time that the m_default list already exists.

I think you are saying "m_DefaultManifest is not null". Is that correct? Please make sure of this, and try to figure out how sm_Instance == null at [2].

If you are not comfortable debugging, then you can try this code:

  public static BrushManifest Instance {
    get {
      // How can we get a reference to the singleton AllBrushes.asset?
      // LoadAssetAtPath<>() is fragile, because it bakes in a file path.
      // Instead, (ab)use the ability for scripts to have default values
      // (which are stored in the .meta)
      if (sm_Instance == null) {
        var dummy = CreateInstance<BrushManifest>();
        Debug.Assert(dummy.m_DefaultManifest != null);
        sm_Instance = dummy.m_DefaultManifest;
        Debug.Assert(sm_Instance != null);
        DestroyImmediate(dummy);
        Debug.Assert(sm_Instance != null);
      }
      Debug.Assert(sm_Instance != null, "Misconfigured singleton");
#if UNITY_EDITOR
      if (sm_Instance == null) {
        string guid = AssetDatabase.FindAssets("t:BrushManifest")[0];
        sm_Instance = AssetDatabase.LoadAssetAtPath<BrushManifest>(
            AssetDatabase.GUIDToAssetPath(
                AssetDatabase.FindAssets("t:BrushManifest")[0]));
        Debug.Assert(sm_Instance == null);
      }
#endif
      return sm_Instance;
    }
  }
dubois commented 5 years ago

One other thing, regarding point #2 above:

No asset processor, including the Tilt Brush Unity SDK, will support importing from Assets/ in a standalone build

If you need to have dynamic content loaded from disk (or the network) in a standalone build, please take a look at Poly Toolkit, which supports Tilt Brush .gltf files.

https://github.com/googlearchive/poly-toolkit-unity

mahe373662858 commented 5 years ago

Hello, what you said did not solve my problem.

I want to solve the problem of rendering the FBX file exported by TiltBrush by loading in the unit scenario

dubois commented 5 years ago

My previous message was not supposed to solve your problem. It was meant to help you figure out what the problem is. Please give more details if you would like more help.

On Fri, Jun 28, 2019, 2:29 AM mahe373662858 notifications@github.com wrote:

Hello, what you said did not solve my problem.

I want to solve the problem of rendering the FBX file exported by TiltBrush by loading in the unit scenario

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/googlevr/tilt-brush-toolkit/issues/35?email_source=notifications&email_token=AABDKMHYXRNLZOD44RAKKPLP4XKZBA5CNFSM4H2O3Y4KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYZSULI#issuecomment-506669613, or mute the thread https://github.com/notifications/unsubscribe-auth/AABDKMERHGMAMHSNCWIOBETP4XKZBANCNFSM4H2O3Y4A .

mahe373662858 commented 5 years ago

@dubois https://github.com/googlevr/tilt-brush-toolkit/issues/35#issuecomment-506400541 Hello, I have used the code you gave me to debug. The results are as follows. 7 1

mahe373662858 commented 5 years ago

35 (comment)

It does not matter how the .fbx gets into your Assets/ folder. Unity Editor will process the fbx, and will call the code in ModelImportSettings.cs, and the materials will get assigned. Therefore yes, every asset processor, including the Tilt Brush Unity SDK, supports downloading assets into the Assets/ folder.. @dubois What you said is that it can support downloading FBX to the project folder. Do you have a specific download description?

Thank you very much for your patient answer.

dubois commented 5 years ago

The results are as follows. Your screenshot shows that you have hit an assertion on line 56. You have modified the code, so please tell me what is on line 56.

What you said is that it can support downloading FBX to the project folder. Do you have a specific download description? I don't know what you mean by "download description", can you rephrase?

mahe373662858 commented 5 years ago

image

Including his 58 lines, 60 lines and 70 lines, all of them are assertions of failure.


image

image

dubois commented 5 years ago

Hi. Your first screenshot can be fixed with the instructions from my first comment https://github.com/googlevr/tilt-brush-toolkit/issues/35#issuecomment-505091093

I know, you said you have already checked this

I've seen what you said last time that the m_default list already exists.

but please check one more time. Inspect BrushManifest.cs and send a screenshot of the inspector. If the inspector shows that DefaultManifest is not null, but you still hit the assert, please try again with the following code:

  Debug.Assert(! ReferenceEquals(dummy.m_DefaultManifest, null));
  Debug.Assert(dummy.m_DefaultManifest != null);
mahe373662858 commented 5 years ago

image

Do you think this is correct?


FBX is downloaded to the project, 338 lines of code in the ModelImportSettings. CS script: NullReferenceException: Object reference not set to an instance of an object

image

QQ图片20190704100145

dubois commented 5 years ago

Hi. I think your issue is that you don't understand https://github.com/googlevr/tilt-brush-toolkit/issues/35#issuecomment-505091093 , specifically this part:

View BrushManifest.cs in the Unity inspector and fill in m_DefaultManifest.

And from my previous comment:

Inspect BrushManifest.cs and send a screenshot of the inspector

It should look like this:

image

mahe373662858 commented 5 years ago

Hello, I have tried to re-import, but the problem still exists.

Can you load tiltbrush. FBX over there and display it successfully?

If you can, please send me a copy of the packing project as a reference. Thank you.

My mailbox is 373662858@qq.com

mahe373662858 commented 5 years ago

image

dubois commented 5 years ago

OK, probably the issue is that you are in Play mode. In fact, in that screenshot I see a warning "Default references will only be applied in edit mode." Please check the warnings I mentioned in https://github.com/googlevr/tilt-brush-toolkit/issues/35#issuecomment-506400541 about trying to use the toolkit in play mode. If you still want to continue down this path, I suggest writing your own implementation of

  public static BrushManifest Instance {
    get {
      return (BrushManifest)UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/TiltBrush/Assets/Brushes/AllBrushes.asset");
dubois commented 5 years ago

If your problem is play mode, it should be fixed in 68cb85897b579a40b1f2c102e8fc415891f0dd3b. Thanks for your patience.

mahe373662858 commented 5 years ago

@dubois Thank you for your patience. My problem has been solved. thank you very much indeed