Search Unity

Reflect Samples

Discussion in 'Unity Reflect' started by unity_aica01, Sep 13, 2021.

  1. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Hi! I´m still learning with the new reflect samples, everything it´s okay and the samples are pretty usefull, but in the first one "Basic Reflect Pipeline" I still can´t get where the pipeline gets the model to stream from. I mean, I have understood every node, I had implemented my own pipeline, and my custom nodes to replace materials, instances etc... But still can´t to stream the model i want, just getting the tiny house of the samples. How can I get what I want?

    Hope i express my self well and you can understand my problem. Kind Regards.
     
  2. chafik_unity

    chafik_unity

    Unity Technologies

    Joined:
    Jun 27, 2017
    Posts:
    56
    Hi!

    If you look at the last line of BasicPipelineSample.cs you'll see :

    Code (CSharp):
    1. reflectBehaviour.InitializeAndRefreshPipeline(new SampleSyncModelProvider());
    The SampleSyncModelProvider is the class responsible to return the model's data.
    For the Samples, the data is stored inside an invisible ".SampleData" folder.
     
    unity_aica01 likes this.
  3. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Hi! Thanks for your answer.
    So if instead of use the SampleSynModelProvider I use my own class to stream my custom models (My own class or the project fetching code of the main viewer) It will work?

    Also, yesrterday I tried out the gameObjectReplacerNode, and its work almost at 100% I mean that it really get the object you want in the scene, but it just pop up in the previous object as you can see in the image below.
    Any advice about this? the code of the AdvancedGameObjectReplacementNode.cs that manages this par is this:


    if (category.Value.Contains(entry.category) && family.Value.Contains(entry.family))
    {
    var gameObject = Object.Instantiate(entry.prefab);
    ImportersUtils.SetTransform(gameObject.transform, streamInstance.instance.Transform);
    return;
    }

    Thanks again for your help!
     

    Attached Files:

  4. chafik_unity

    chafik_unity

    Unity Technologies

    Joined:
    Jun 27, 2017
    Posts:
    56
    Hi! Glad to know you were able to make progress!

    That's the idea yes. Keep in mind however that a minimum knowledge of the Reflect data model is required.
    You can find more about it here https://docs.unity3d.com/reflect/1.1/api/Unity.Reflect.Model.html

    The reason two objects are created is because both the "AdvancedGameObjectReplacerNode" and the "InstanceConverterNode" are creating a GameObject. There are multiple ways to fix that but the easiest one is to take a look at sample 07 - Filtering And Replacement Sample which seems to do exactly what you want.

    Hope this helps.
     
    unity_aica01 likes this.
  5. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Thank you so much for the help! Pretty usefull and complete info!
     
  6. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Hi @chafik_unity I have one last question about nodes...
    If i want to apply a node into the main reflect Pipeline how am I supposed to do it?
    I have been reviewing all the pipelines-related scripts and the one which looked closest like the pipelines of the samples was the ViewerPipelineHelper script but when i added my node into it it makes nothing... Then the ReflectPipeline.cs does not have any nodes into the script, neither the ViewerReflectPipeline.cs nor RuntimeReflectBootstrapper.cs so I´m confused about how should we set up the nodes into the pipeline
     
  7. chafik_unity

    chafik_unity

    Unity Technologies

    Joined:
    Jun 27, 2017
    Posts:
    56
    Hi @unity_aica01,

    Reflect pipeline doesn't have a proper editor. So yes, modifying the code inside the ViewerPipelineHelper is the only way to go for now. Once you've changed the ViewerPipelineHelper, you need to create a new Pipeline asset by going into
    Assets > Reflect > Pipeline > Create Viewer Pipeline Asset. I would recommend to backup the original
    ViewerPipeline.asset first or changing the generated asset name in the ViewerPipelineHelper around line 63 to something like this :

    Code (CSharp):
    1. AssetDatabase.CreateAsset(pipelineAsset, "Assets/Pipelines/MyCustomViewerPipeline.asset");
    Once your new asset is generated, you need to assign it to the ReflectPipeline MonoBehaviour and reapply the required settings in the inspector.
     
  8. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Thats it´s what I have been doing the last week, the setting of my node appears on the unity inspector and I was excited because I believed I made it but nop... Once I hit the play button, i passed throught the login and project selection screen, once I have selected a project nothing happens, its like streaming the project but nothing will come up, and the toolbars will appear disabled so I will not be abl to move in the scene or do anything... Don´t know what I am missing to not get what I want.
    SO this generates in my mind another question and is the following: If adding my nodes into the ViewerPipelineHelper it´s the only way to customize the viewer, then why in the ReflectPipeline.cs are two public event Actions called beforeInitialize and afterInitialize and a comment taht says "Use this event to do any change on the pipeline, like adding node or change connections" "Any change done on the pipeline after this callback is not legal and can have unexpected effects"???? Im so confused....
     
  9. chafik_unity

    chafik_unity

    Unity Technologies

    Joined:
    Jun 27, 2017
    Posts:
    56
    Ok, I see.
    If you only need to do slight modifications on the default ViewerPipeline then you can indeed use the `onBeforeInitialize` callback. Your changes will only exist at runtime and will not affect any persistent data.

    For the error, I can't really say what's happening but I suspect the settings in the Inspector are not set properly. If you're switching assets then you need to set all the settings to what they were in the original asset.
     
  10. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Yeah that´s what I thought about beforeInitialize, but i cant make the Action work....
    My intention is just to set some materials to be replaced from the model before the streaming.
    I tried to declare my custom node in the same namespace, at the bottom of the ReflectPipeline code, and then attach it to the before initialize to try call the pipelineasset to invoke the CreateNode and CreateConnection but didn´t achieve nothing and there is no info about how to use those actions.
    Sorry if it is a dumb question but Im almost a begginer in c#
     
    Last edited: Nov 8, 2021
  11. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Little update:
    I finally accomplished to add my node from the ReflectPipeline script, then click on th eplay button and almost everything goes right, excepting the fact that the node is not working... When I hit my node settings in the editor to select the materials I want to replace, there is the message that cames up: "UnityException: GetName is not allowed to be called during serialization, call it from OnEnable instead. Called from ScriptableObject 'PipelineAsset'." but no idea about how to fix it (I tried to follow the instructions of the editor but I was getting in more errors.
     
  12. chafik_unity

    chafik_unity

    Unity Technologies

    Joined:
    Jun 27, 2017
    Posts:
    56
    If you're using the beforeInitialize callback then you need to avoid going back to the inspector and must do everything by script.
    The best way to assign the materials to your node is by using the afterInitialize callback. If possible, you can share your node and processor code here so I can more easily guide you.
     
  13. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Oh okay I didn´t know that.
    Here is my node script:

    Code (CSharp):
    1.  [Serializable]
    2.     public class AMaterialReplacerNodeSettings
    3.     {
    4.         public string A_keyword;
    5.         public Material A_material;
    6.     }
    7.     public class MyNode :  ReflectNode<AMaterialReplacer>
    8.     {
    9.          public GameObjectInput input = new GameObjectInput();
    10.         public AMaterialReplacerNodeSettings A_settings;
    11.  
    12.         protected override AMaterialReplacer Create(ReflectBootstrapper hook, ISyncModelProvider provider, IExposedPropertyTable resolver)
    13.         {
    14.             var node = new AMaterialReplacer(A_settings);
    15.             input.streamEvent = node.OnGameObjectEvent;
    16.             return node;
    17.         }
    18.     }
    19.     public class AMaterialReplacer : IReflectNodeProcessor
    20.     {
    21.         readonly AMaterialReplacerNodeSettings A_Settings;
    22.  
    23.         public AMaterialReplacer(AMaterialReplacerNodeSettings Asettings)
    24.         {
    25.             A_Settings = Asettings;
    26.         }
    27.  
    28.         public void OnGameObjectEvent(SyncedData<GameObject> stream, StreamEvent streamEvent)
    29.         {
    30.             if (streamEvent == StreamEvent.Added)
    31.             {
    32.                 if (!stream.data.TryGetComponent(out MeshRenderer meshRenderer))
    33.                     return;
    34.  
    35.                 var materials = meshRenderer.sharedMaterials;
    36.                 for (int i = 0; i < materials.Length; ++i)
    37.                 {
    38.                     if (materials[i].name.Contains(A_Settings.A_keyword))
    39.                     {
    40.                         materials[i] = A_Settings.A_material;
    41.                     }
    42.                 }
    43.  
    44.                 meshRenderer.sharedMaterials = materials;
    45.             }
    46.         }
    47.  
    48.         public void OnPipelineInitialized()
    49.         {
    50.             // not needed
    51.         }
    52.  
    53.         public void OnPipelineShutdown()
    54.         {
    55.             // not needed
    56.         }
    57.     }
    and here is the trying of callback with beforeInitialize (first time using events btw)

    Code (CSharp):
    1.  
    2. void Awake()
    3.         {
    4.             beforeInitialize = Testing_beforeInitialize;
    5.             Testing_beforeInitialize();
    6.             // Register to Logs coming from the Reflect core assembly
    7.             Unity.Reflect.Utils.Logger.AddReceiver(this);
    8.         }
    9.        
    10.         void Testing_beforeInitialize()
    11.         {
    12.             var myMaterialReplacerNode = pipelineAsset.CreateNode<MyNode>();
    13.             pipelineAsset.CreateConnection(instanceConverter.output, myMaterialReplacerNode.input);
    14.         }
    15.  
     
  14. unity_aica01

    unity_aica01

    Joined:
    May 19, 2020
    Posts:
    86
    Hi! Little update here:
    I created a new project cloning the github repo and give a try to modify the ViewerHelperPipeline. Everything went nice, I can run reflect, select a project, stream it and move around the scene. The only three things that are not working are:
    BIM data selection, measure tool and my own node (but it could be due to the script looking for the wrong keyword, im not sure yet).
    I am reviewing all the Reflect scene hierarchy and looks like there aren´t more fields to set up to match the new CustomReflectPipeline.asset but dont know yet.
    here is the Console log error:
    NullReferenceException: Object reference not set to an instance of an object
    Unity.Reflect.Viewer.UI.UIStateManager.OnDispatch (SharpFlux.Payload`1[TAction] payload) (at Assets/Scripts/UI/UIStateManagerActions.cs:407)
    Unity.Reflect.Viewer.UI.UIStateManager.InvokeOnDispatch (SharpFlux.Payload`1[TAction] payload) (at Assets/Scripts/UI/UIStateManagerActions.cs:257)
    SharpFlux.Dispatching.Dispatcher.InvokeCallback[TPayload] (System.String id) (at D:/Users/jquinquilla/COMUNES/NODESTESTUNITY/Packages/com.unity.reflect.viewer-core/Runtime/UI/SharpFlux/Dispatching/Dispatcher.cs:79)
    SharpFlux.Dispatching.Dispatcher.DispatchImplementation[TPayload] (TPayload payload) (at D:/Users/jquinquilla/COMUNES/NODESTESTUNITY/Packages/com.unity.reflect.viewer-core/Runtime/UI/SharpFlux/Dispatching/Dispatcher.cs:52)
    SharpFlux.Dispatching.Dispatcher.Dispatch[TPayload] (TPayload payload) (at D:/Users/jquinquilla/COMUNES/NODESTESTUNITY/Packages/com.unity.reflect.viewer-core/Runtime/UI/SharpFlux/Dispatching/Dispatcher.cs:137)
    Unity.Reflect.Viewer.UI.RightSideBarController.OnSelectButtonClicked () (at Assets/Scripts/UI/Controllers/RightSideBarController.cs:133)
    Unity.Reflect.Viewer.UI.ToolButton.OnButtonClicked () (at Assets/Scripts/UI/ToolButton.cs:67)
    UnityEngine.Events.InvokableCall.Invoke () (at <4d9f7249f1de41e384668fea10e9822f>:0)
    UnityEngine.Events.UnityEvent.Invoke () (at <4d9f7249f1de41e384668fea10e9822f>:0)
    UnityEngine.UI.Button.Press () (at C:/Program Files/Unity/Hub/Editor/2020.3.3f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/UI/Core/Button.cs:68)
    UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/Program Files/Unity/Hub/Editor/2020.3.3f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/UI/Core/Button.cs:110)
    UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/Program Files/Unity/Hub/Editor/2020.3.3f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/ExecuteEvents.cs:50)
    UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at C:/Program Files/Unity/Hub/Editor/2020.3.3f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/ExecuteEvents.cs:262)
    UnityEngine.EventSystems.EventSystem:Update() (at C:/Program Files/Unity/Hub/Editor/2020.3.3f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/EventSystem.cs:385)
    Any advice?
    Kind Regards.
     
    Last edited: Nov 10, 2021
  15. JordanBerman

    JordanBerman

    Joined:
    Oct 9, 2022
    Posts:
    2
    @unity_aica01 I was wondering if you made any progress on part of your project.

    I am working on something similar now where I want to edit the ViewerPipelineHelper to add MyCustomNode to build additional features ontop of the base pipeline (https://forum.unity.com/threads/unity-reflect-develop-custom-features-and-ui.1373682/)

    In the project, I downloaded from the github repo (https://github.com/Unity-Technologies/com.unity.reflect.viewer/tree/beta/3.1.0) I have a mono behavior called ViewerReflectPipeline.cs, but I do not see any object in the hierarchy to where this component is attached... and therefore, I do not know where to add the new MyCustomViewerPipeline.asset or adjust any additional fields in the inspector.

    Anything helps. Thanks!