예제 #1
0
        public void Run(BuildTarget target,
                        NodeData node,
                        ConnectionPointData inputPoint,
                        ConnectionData connectionToOutput,
                        Dictionary <string, List <Asset> > inputGroupAssets,
                        List <string> alreadyCached,
                        Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            var modifier = ModifierUtility.CreateModifier(node, target);

            UnityEngine.Assertions.Assert.IsNotNull(modifier);
            bool isAnyAssetModified = false;

            foreach (var asset in incomingAssets)
            {
                var loadedAsset = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(asset.importFrom);
                if (modifier.IsModified(loadedAsset))
                {
                    modifier.Modify(loadedAsset);
                    isAnyAssetModified = true;
                }
            }

            if (isAnyAssetModified)
            {
                // apply asset setting changes to AssetDatabase.
                AssetDatabase.Refresh();
            }

            // Modifier does not add, filter or change structure of group, so just pass given group of assets
            Output(connectionToOutput, inputGroupAssets, null);
        }
예제 #2
0
        public ConnectionPointData GetConnectionPoint(FilterEntry f)
        {
            ConnectionPointData p = m_outputPoints.Find(v => v.Id == f.ConnectionPointId);

            UnityEngine.Assertions.Assert.IsNotNull(p);
            return(p);
        }
        public void Run(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var builder = PrefabBuilderUtility.CreatePrefabBuilder(node, target);
            UnityEngine.Assertions.Assert.IsNotNull(builder);

            var prefabOutputDir = FileUtility.EnsurePrefabBuilderCacheDirExists(target, node);
            Dictionary<string, List<Asset>> output = new Dictionary<string, List<Asset>>();

            foreach(var key in inputGroupAssets.Keys) {
                var allAssets = LoadAllAssets(inputGroupAssets[key]);
                var prefabFileName = builder.CanCreatePrefab(key, allAssets);
                UnityEngine.GameObject obj = builder.CreatePrefab(key, allAssets);
                if(obj == null) {
                    throw new AssetBundleGraphException(string.Format("{0} :PrefabBuilder {1} returned null in CreatePrefab() [groupKey:{2}]",
                        node.Name, builder.GetType().FullName, key));
                }

                var prefabSavePath = FileUtility.PathCombine(prefabOutputDir, prefabFileName + ".prefab");
                PrefabUtility.CreatePrefab(prefabSavePath, obj, ReplacePrefabOptions.Default);

                output[key] = new List<Asset> () {
                    Asset.CreateAssetWithImportPath(prefabSavePath)
                };
                GameObject.DestroyImmediate(obj);
            }

            Output(connectionToOutput, output, null);
        }
예제 #4
0
 public FilterEntry(string keyword, string keytype, ConnectionPointData point)
 {
     m_filterKeyword = keyword;
     m_filterKeytype = keytype;
     m_point         = point;
     SetLabelName();
 }
예제 #5
0
        public ConnectionPointData GetConnectionPoint(Variant v)
        {
            ConnectionPointData p = m_inputPoints.Find(point => point.Id == v.ConnectionPointId);

            UnityEngine.Assertions.Assert.IsNotNull(p);
            return(p);
        }
        public void Run(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            var modifier = ModifierUtility.CreateModifier(node, target);
            UnityEngine.Assertions.Assert.IsNotNull(modifier);
            bool isAnyAssetModified = false;

            foreach(var asset in incomingAssets) {
                var loadedAsset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(asset.importFrom);
                if(modifier.IsModified(loadedAsset)) {
                    modifier.Modify(loadedAsset);
                    isAnyAssetModified = true;
                }
            }

            if(isAnyAssetModified) {
                // apply asset setting changes to AssetDatabase.
                AssetDatabase.Refresh();
            }

            // Modifier does not add, filter or change structure of group, so just pass given group of assets
            Output(connectionToOutput, inputGroupAssets, null);
        }
예제 #7
0
        public ConnectionPointData AddInputPoint(string label)
        {
            var p = new ConnectionPointData(label, this, true);

            m_inputPoints.Add(p);
            return(p);
        }
예제 #8
0
        public ConnectionPointData AddOutputPoint(string label)
        {
            var p = new ConnectionPointData(label, this, false);

            m_outputPoints.Add(p);
            return(p);
        }
예제 #9
0
 public NodeEvent(EventType type, NodeGUI node, Vector2 localMousePos, ConnectionPointData point)
 {
     this.eventType = type;
     this.eventSourceNode = node;
     this.point = point;
     this.globalMousePosition = new Vector2(localMousePos.x + node.GetX(), localMousePos.y + node.GetY());
 }
예제 #10
0
 public NodeEvent(EventType type, NodeGUI node, Vector2 localMousePos, ConnectionPointData point)
 {
     this.eventType           = type;
     this.eventSourceNode     = node;
     this.point               = point;
     this.globalMousePosition = new Vector2(localMousePos.x + node.GetX(), localMousePos.y + node.GetY());
 }
예제 #11
0
 public FilterEntry(string keyword, string keytype, ConnectionPointData point)
 {
     m_filterKeyword = keyword;
     m_filterKeytype = keytype;
     m_point         = null;
     m_pointId       = point.Id;
 }
예제 #12
0
        public void Setup(BuildTarget target,
                          NodeData node,
                          ConnectionPointData inputPoint,
                          ConnectionData connectionToOutput,
                          Dictionary <string, List <Asset> > inputGroupAssets,
                          List <string> alreadyCached,
                          Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            ValidateModifier(node, target, incomingAssets,
                             (Type expectedType, Type foundType, Asset foundAsset) => {
                throw new NodeException(string.Format("{3} :Modifier expect {0}, but different type of incoming asset is found({1} {2})",
                                                      expectedType.FullName, foundType.FullName, foundAsset.fileNameAndExtension, node.Name), node.Id);
            },
                             () => {
                throw new NodeException(node.Name + " :Modifier is not configured. Please configure from Inspector.", node.Id);
            },
                             () => {
                throw new NodeException(node.Name + " :Failed to create Modifier from settings. Please fix settings from Inspector.", node.Id);
            },
                             (Type expected, Type incoming) => {
                throw new NodeException(string.Format("{0} :Incoming asset type is does not match with this Modifier (Expected type:{1}, Incoming type:{2}).",
                                                      node.Name, (expected != null)?expected.FullName:"null", (incoming != null)?incoming.FullName:"null"), node.Id);
            }
                             );

            // Modifier does not add, filter or change structure of group, so just pass given group of assets
            Output(connectionToOutput, inputGroupAssets, null);
        }
예제 #13
0
 public static ConnectionGUI CreateConnection(string label, ConnectionPointData output, ConnectionPointData input)
 {
     return(new ConnectionGUI(
                new ConnectionData(label, output, input),
                output,
                input
                ));
 }
예제 #14
0
 public static ConnectionGUI LoadConnection(ConnectionData data, ConnectionPointData output, ConnectionPointData input)
 {
     return(new ConnectionGUI(
                data,
                output,
                input
                ));
 }
예제 #15
0
        public void UpdateVariant(Variant variant)
        {
            ConnectionPointData p = m_inputPoints.Find(v => v.Id == variant.ConnectionPointId);

            UnityEngine.Assertions.Assert.IsNotNull(p);

            p.Label = variant.Name;
        }
 public ConnectionPointData(V1.ConnectionPointData v1)
 {
     this.id         = v1.Id;
     this.label      = v1.Label;
     this.parentId   = v1.NodeId;
     this.isInput    = v1.IsInput;
     this.buttonRect = v1.Region;
 }
 public static ConnectionGUI LoadConnection(string label, string id, ConnectionPointData output, ConnectionPointData input)
 {
     return(new ConnectionGUI(
                label,
                id,
                output,
                input
                ));
 }
 public static ConnectionGUI CreateConnection(string label, ConnectionPointData output, ConnectionPointData input)
 {
     return(new ConnectionGUI(
                label,
                Guid.NewGuid().ToString(),
                output,
                input
                ));
 }
예제 #19
0
 public ConnectionData(string label, ConnectionPointData output, ConnectionPointData input)
 {
     m_id         = Guid.NewGuid().ToString();
     m_label      = label;
     m_fromNodeId = output.NodeId;
     m_fromNodeConnectionPointId = output.Id;
     m_toNodeId = input.NodeId;
     m_toNodeConnectionPoiontId = input.Id;
 }
        public void Setup(BuildTarget target,
                          NodeData node,
                          ConnectionPointData inputPoint,
                          ConnectionData connectionToOutput,
                          Dictionary <string, List <Asset> > inputGroupAssets,
                          List <string> alreadyCached,
                          Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output)
        {
            var outputDict = new Dictionary <string, List <Asset> >();

            outputDict[key] = new List <Asset>();

            var bundleNames = inputGroupAssets.Keys.ToList();

            var bundleVariants = new Dictionary <string, List <string> >();

            // get all variant name for bundles
            foreach (var name in bundleNames)
            {
                bundleVariants[name] = new List <string>();
                var assets = inputGroupAssets[name];
                foreach (var a in assets)
                {
                    var variantName = a.variantName;
                    if (!bundleVariants[name].Contains(variantName))
                    {
                        bundleVariants[name].Add(variantName);
                    }
                }
            }

            // add manifest file
            var manifestName = BuildTargetUtility.TargetToAssetBundlePlatformName(target);

            bundleNames.Add(manifestName);
            bundleVariants[manifestName] = new List <string>()
            {
                ""
            };

            var bundleOutputDir = FileUtility.EnsureAssetBundleCacheDirExists(target, node);

            foreach (var name in bundleNames)
            {
                foreach (var v in bundleVariants[name])
                {
                    string bundleName = (string.IsNullOrEmpty(v))? name : name + "." + v;
                    Asset  bundle     = Asset.CreateAssetWithImportPath(FileUtility.PathCombine(bundleOutputDir, bundleName));
                    Asset  manifest   = Asset.CreateAssetWithImportPath(FileUtility.PathCombine(bundleOutputDir, bundleName + AssetBundleGraphSettings.MANIFEST_FOOTER));
                    outputDict[key].Add(bundle);
                    outputDict[key].Add(manifest);
                }
            }

            Output(connectionToOutput, outputDict, new List <string>());
        }
 public void Run(BuildTarget target,
                 NodeData node,
                 ConnectionPointData inputPoint,
                 ConnectionData connectionToOutput,
                 Dictionary <string, List <Asset> > inputGroupAssets,
                 List <string> alreadyCached,
                 Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output)
 {
     Filter(node, inputGroupAssets, Output);
 }
예제 #22
0
        public void Run(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            Export(target, node, inputPoint, connectionToOutput, inputGroupAssets, Output, true);
        }
        private Type FindIncomingAssetType(ConnectionPointData inputPoint)
        {
            var assetGroups = AssetBundleGraphEditorWindow.GetIncomingAssetGroups(inputPoint);

            if (assetGroups == null)
            {
                return(null);
            }
            return(TypeUtility.FindIncomingAssetType(assetGroups.SelectMany(v => v.Value).ToList()));
        }
        public void Setup(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            ValidateBundleNameTemplate(
                node.BundleNameTemplate[target],
                () => {
                    throw new NodeException(node.Name + ":Bundle Name Template is empty.", node.Id);
                }
            );

            var variantNames = node.Variants.Select(v=>v.Name).ToList();
            foreach(var variant in node.Variants) {
                ValidateVariantName(variant.Name, variantNames,
                    () => {
                        throw new NodeException(node.Name + ":Variant name is empty.", node.Id);
                    },
                    () => {
                        throw new NodeException(node.Name + ":Variant name cannot contain whitespace \"" + variant.Name + "\".", node.Id);
                    },
                    () => {
                        throw new NodeException(node.Name + ":Variant name already exists \"" + variant.Name + "\".", node.Id);
                    });
            }

            /*
             * Check if incoming asset has valid import path
             */
            var invalids = new List<Asset>();
            foreach (var groupKey in inputGroupAssets.Keys) {
                inputGroupAssets[groupKey].ForEach( a => { if (string.IsNullOrEmpty(a.importFrom)) invalids.Add(a); } );
            }
            if (invalids.Any()) {
                throw new NodeException(node.Name +
                    ": Invalid files are found. Following files need to be imported to put into asset bundle: " +
                    string.Join(", ", invalids.Select(a =>a.absoluteAssetPath).ToArray()), node.Id );
            }

            var output = new Dictionary<string, List<Asset>>();

            var currentVariant = node.Variants.Find( v => v.ConnectionPoint == inputPoint );
            var variantName = (currentVariant == null) ? null : currentVariant.Name;

            // set configured assets in bundle name
            foreach (var groupKey in inputGroupAssets.Keys) {
                var bundleName = GetBundleName(target, node, groupKey, variantName);
                output[bundleName] = ConfigureAssetBundleSettings(variantName, inputGroupAssets[groupKey]);
            }

            Output(connectionToOutput, output, null);
        }
예제 #25
0
        public void Setup(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            node.ValidateOverlappingFilterCondition(true);
            Filter(node, inputGroupAssets, Output);
        }
 public void Setup(BuildTarget target,
                   NodeData node,
                   ConnectionPointData inputPoint,
                   ConnectionData connectionToOutput,
                   Dictionary <string, List <Asset> > inputGroupAssets,
                   List <string> alreadyCached,
                   Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output)
 {
     node.ValidateOverlappingFilterCondition(true);
     Filter(node, inputGroupAssets, Output);
 }
 public static bool ContainsConnection(this List <ConnectionGUI> connections, ConnectionPointData output, ConnectionPointData input)
 {
     foreach (var con in connections)
     {
         if (con.IsEqual(output, input))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #28
0
        private bool IsValidInputConnectionPoint(ConnectionPointData point)
        {
            if (m_data.Kind == NodeKind.BUNDLECONFIG_GUI && !m_data.BundleConfigUseGroupAsVariants)
            {
                if (m_data.Variants.Count > 0 && m_data.Variants.Find(v => v.ConnectionPoint.Id == point.Id) == null)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #29
0
        public void AddVariant(string name)
        {
            ValidateAccess(
                NodeKind.BUNDLECONFIG_GUI
                );

            var point = new ConnectionPointData(name, this, true);

            m_inputPoints.Add(point);
            var newEntry = new Variant(name, point);

            m_variants.Add(newEntry);
        }
예제 #30
0
        public void AddFilterCondition(string keyword, string keytype)
        {
            ValidateAccess(
                NodeKind.FILTER_GUI
                );

            var point = new ConnectionPointData(keyword, this, false);

            m_outputPoints.Add(point);
            var newEntry = new FilterEntry(keyword, keytype, point);

            m_filter.Add(newEntry);
        }
        private void GroupingOutput(BuildTarget target,
                                    NodeData node,
                                    ConnectionPointData inputPoint,
                                    ConnectionData connectionToOutput,
                                    Dictionary <string, List <Asset> > inputGroupAssets,
                                    Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output)
        {
            ValidateGroupingKeyword(
                node.GroupingKeywords[target],
                () => {
                throw new NodeException("Grouping Keyword can not be empty.", node.Id);
            },
                () => {
                throw new NodeException(String.Format("Grouping Keyword must contain {0} for numbering: currently {1}", AssetBundleGraphSettings.KEYWORD_WILDCARD, node.GroupingKeywords[target]), node.Id);
            }
                );

            var outputDict = new Dictionary <string, List <Asset> >();

            var mergedGroupedSources = new List <Asset>();

            foreach (var groupKey in inputGroupAssets.Keys)
            {
                mergedGroupedSources.AddRange(inputGroupAssets[groupKey]);
            }

            var groupingKeyword        = node.GroupingKeywords[target];
            var split                  = groupingKeyword.Split(AssetBundleGraphSettings.KEYWORD_WILDCARD);
            var groupingKeywordPrefix  = split[0];
            var groupingKeywordPostfix = split[1];

            foreach (var source in mergedGroupedSources)
            {
                var targetPath = source.GetAbsolutePathOrImportedPath();

                var regex = new Regex(groupingKeywordPrefix + "(.*?)" + groupingKeywordPostfix);
                var match = regex.Match(targetPath);

                if (match.Success)
                {
                    var newGroupingKey = match.Groups[1].Value;
                    if (!outputDict.ContainsKey(newGroupingKey))
                    {
                        outputDict[newGroupingKey] = new List <Asset>();
                    }
                    outputDict[newGroupingKey].Add(source);
                }
            }

            Output(connectionToOutput, outputDict, null);
        }
예제 #32
0
        public void Run(BuildTarget target,
                        NodeData node,
                        ConnectionPointData inputPoint,
                        ConnectionData connectionToOutput,
                        Dictionary <string, List <Asset> > inputGroupAssets,
                        List <string> alreadyCached,
                        Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            ApplyImportSetting(node, incomingAssets);

            Output(connectionToOutput, inputGroupAssets, null);
        }
예제 #33
0
        private ConnectionGUI(ConnectionData data, ConnectionPointData output, ConnectionPointData input)
        {
            UnityEngine.Assertions.Assert.IsTrue(output.IsOutput, "Given Output point is not output.");
            UnityEngine.Assertions.Assert.IsTrue(input.IsInput, "Given Input point is not input.");

            m_inspector           = ScriptableObject.CreateInstance <ConnectionGUIInspectorHelper>();
            m_inspector.hideFlags = HideFlags.DontSave;

            this.m_data        = data;
            this.m_outputPoint = output;
            this.m_inputPoint  = input;

            connectionButtonStyle = "sv_label_0";
        }
예제 #34
0
        public void Setup(BuildTarget target,
                          NodeData node,
                          ConnectionPointData inputPoint,
                          ConnectionData connectionToOutput,
                          Dictionary <string, List <Asset> > inputGroupAssets,
                          List <string> alreadyCached,
                          Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            Action <Type, Type, Asset> multipleAssetTypeFound = (Type expectedType, Type foundType, Asset foundAsset) => {
                throw new NodeException(string.Format("{3} :ImportSetting expect {0}, but different type of incoming asset is found({1} {2})",
                                                      expectedType.FullName, foundType.FullName, foundAsset.fileNameAndExtension, node.Name), node.Id);
            };

            Action <Type> unsupportedType = (Type unsupported) => {
                throw new NodeException(string.Format("{0} :Incoming asset type is not supported by ImportSetting (Incoming type:{1}). Perhaps you want to use Modifier instead?",
                                                      node.Name, (unsupported != null)?unsupported.FullName:"null"), node.Id);
            };

            Action <Type, Type> incomingTypeMismatch = (Type expected, Type incoming) => {
                throw new NodeException(string.Format("{0} :Incoming asset type is does not match with this ImportSetting (Expected type:{1}, Incoming type:{2}).",
                                                      node.Name, (expected != null)?expected.FullName:"null", (incoming != null)?incoming.FullName:"null"), node.Id);
            };

            Action <ConfigStatus> errorInConfig = (ConfigStatus _) => {
                // give a try first in sampling file
                if (incomingAssets.Any())
                {
                    SaveSampleFile(node, incomingAssets[0]);

                    ValidateInputSetting(node, target, incomingAssets, multipleAssetTypeFound, unsupportedType, incomingTypeMismatch, (ConfigStatus eType) => {
                        if (eType == ConfigStatus.NoSampleFound)
                        {
                            throw new NodeException(node.Name + " :ImportSetting has no sampling file. Please configure it from Inspector.", node.Id);
                        }
                        if (eType == ConfigStatus.TooManySamplesFound)
                        {
                            throw new NodeException(node.Name + " :ImportSetting has too many sampling file. Please fix it from Inspector.", node.Id);
                        }
                    });
                }
            };

            ValidateInputSetting(node, target, incomingAssets, multipleAssetTypeFound, unsupportedType, incomingTypeMismatch, errorInConfig);

            // ImportSettings does not add, filter or change structure of group, so just pass given group of assets
            Output(connectionToOutput, inputGroupAssets, null);
        }
        private ConnectionGUI(string label, string id, ConnectionPointData output, ConnectionPointData input)
        {
            UnityEngine.Assertions.Assert.IsTrue(output.IsOutput, "Given Output point is not output.");
            UnityEngine.Assertions.Assert.IsTrue(input.IsInput, "Given Input point is not input.");

            conInsp           = ScriptableObject.CreateInstance <ConnectionGUIInspectorHelper>();
            conInsp.hideFlags = HideFlags.DontSave;

            this.label = label;
            this.id    = id;

            this.outputPoint = output;
            this.inputPoint  = input;

            connectionButtonStyle = "sv_label_0";
        }
예제 #36
0
        public void UpdateFilterEntry(FilterEntry f)
        {
            ConnectionPointData p = m_outputPoints.Find(v => v.Id == f.ConnectionPointId);

            UnityEngine.Assertions.Assert.IsNotNull(p);

            if (f.FilterKeytype == SaveDataConstants.DEFAULT_FILTER_KEYTYPE)
            {
                p.Label = f.FilterKeyword;
            }
            else
            {
                var pointIndex  = f.FilterKeytype.LastIndexOf('.');
                var keytypeName = (pointIndex > 0)? f.FilterKeytype.Substring(pointIndex + 1):f.FilterKeytype;
                p.Label = $"{f.FilterKeyword}[{keytypeName}]";
            }
        }
예제 #37
0
        private void GroupingOutput(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            ValidateGroupingKeyword(
                node.GroupingKeywords[target],
                () => {
                    throw new NodeException("Grouping Keyword can not be empty.", node.Id);
                },
                () => {
                    throw new NodeException(String.Format("Grouping Keyword must contain {0} for numbering: currently {1}", AssetBundleGraphSettings.KEYWORD_WILDCARD, node.GroupingKeywords[target]), node.Id);
                }
            );

            var outputDict = new Dictionary<string, List<Asset>>();

            var mergedGroupedSources = new List<Asset>();

            foreach (var groupKey in inputGroupAssets.Keys) {
                mergedGroupedSources.AddRange(inputGroupAssets[groupKey]);
            }

            var groupingKeyword = node.GroupingKeywords[target];
            var split = groupingKeyword.Split(AssetBundleGraphSettings.KEYWORD_WILDCARD);
            var groupingKeywordPrefix  = split[0];
            var groupingKeywordPostfix = split[1];

            foreach (var source in mergedGroupedSources) {
                var targetPath = source.GetAbsolutePathOrImportedPath();

                var regex = new Regex(groupingKeywordPrefix + "(.*?)" + groupingKeywordPostfix);
                var match = regex.Match(targetPath);

                if (match.Success) {
                    var newGroupingKey = match.Groups[1].Value;
                    if (!outputDict.ContainsKey(newGroupingKey)) outputDict[newGroupingKey] = new List<Asset>();
                    outputDict[newGroupingKey].Add(source);
                }
            }

            Output(connectionToOutput, outputDict, null);
        }
        public void Run(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var output = new Dictionary<string, List<Asset>>();

            var currentVariant = node.Variants.Find( v => v.ConnectionPoint == inputPoint );
            var variantName = (currentVariant == null) ? null : currentVariant.Name;

            // set configured assets in bundle name
            foreach (var groupKey in inputGroupAssets.Keys) {
                var bundleName = GetBundleName(target, node, groupKey, variantName);
                output[bundleName] = ConfigureAssetBundleSettings(variantName, inputGroupAssets[groupKey]);
            }

            Output(connectionToOutput, output, null);
        }
예제 #39
0
        public void Setup(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            ValidateExportPath(
                node.ExporterExportPath[target],
                node.ExporterExportPath[target],
                () => {
                    throw new NodeException(node.Name + ":Export Path is empty.", node.Id);
                },
                () => {
                    throw new NodeException(node.Name + ":Directory set to Export Path does not exist. Path:" + node.ExporterExportPath[target], node.Id);
                }
            );

            Export(target, node, inputPoint, connectionToOutput, inputGroupAssets, Output, false);
        }
예제 #40
0
        public void Setup(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            ValidateLoadPath(
                node.LoaderLoadPath[target],
                node.GetLoaderFullLoadPath(target),
                () => {
                    //can be empty
                    //throw new NodeException(node.Name + ": Load Path is empty.", node.Id);
                },
                () => {
                    throw new NodeException(node.Name + ": Directory not found: " + node.GetLoaderFullLoadPath(target), node.Id);
                }
            );

            Load(target, node, connectionToOutput, inputGroupAssets, Output);
        }
예제 #41
0
        private void Export(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output,
			bool isRun)
        {
            var outputDict = new Dictionary<string, List<Asset>>();
            outputDict["0"] = new List<Asset>();

            var failedExports = new List<string>();

            foreach (var groupKey in inputGroupAssets.Keys) {
                var exportedAssets = new List<Asset>();
                var inputSources = inputGroupAssets[groupKey];

                foreach (var source in inputSources) {
                    if (isRun) {
                        if (!Directory.Exists(node.ExporterExportPath[target])) {
                            Directory.CreateDirectory(node.ExporterExportPath[target]);
                        }
                    }

                    var destinationSourcePath = source.importFrom;

                    // in bundleBulider, use platform-package folder for export destination.
                    if (destinationSourcePath.StartsWith(AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE)) {
                        var depth = AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE.Split(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR).Length + 1;

                        var splitted = destinationSourcePath.Split(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR);
                        var reducedArray = new string[splitted.Length - depth];

                        Array.Copy(splitted, depth, reducedArray, 0, reducedArray.Length);
                        var fromDepthToEnd = string.Join(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR.ToString(), reducedArray);

                        destinationSourcePath = fromDepthToEnd;
                    }

                    var destination = FileUtility.PathCombine(node.ExporterExportPath[target], destinationSourcePath);

                    var parentDir = Directory.GetParent(destination).ToString();

                    if (isRun) {
                        if (!Directory.Exists(parentDir)) {
                            Directory.CreateDirectory(parentDir);
                        }
                        if (File.Exists(destination)) {
                            File.Delete(destination);
                        }
                        if (string.IsNullOrEmpty(source.importFrom)) {
                            failedExports.Add(source.absoluteAssetPath);
                            continue;
                        }
                        try {
                            File.Copy(source.importFrom, destination);
                        } catch(Exception e) {
                            failedExports.Add(source.importFrom);
                            Debug.LogError(node.Name + ": Error occured: " + e.Message);
                        }
                    }

                    var exportedAsset = Asset.CreateAssetWithExportPath(destination);
                    exportedAssets.Add(exportedAsset);
                }
                outputDict["0"].AddRange(exportedAssets);
            }

            if (failedExports.Any()) {
                Debug.LogError(node.Name + ": Failed to export files. All files must be imported before exporting: " + string.Join(", ", failedExports.ToArray()));
            }

            Output(connectionToOutput, outputDict, null);
        }
        public static Dictionary<string, List<Asset>> GetIncomingAssetGroups(ConnectionPointData inputPoint)
        {
            UnityEngine.Assertions.Assert.IsNotNull(inputPoint);
            UnityEngine.Assertions.Assert.IsTrue (inputPoint.IsInput);

            if(s_assetStreamMap == null) {
                return null;
            }

            var keyEnum = s_assetStreamMap.Keys.Where(c => c.ToNodeConnectionPointId == inputPoint.Id);
            if (keyEnum.Any()) {
                return s_assetStreamMap[keyEnum.First()];
            }

            return null;
        }
예제 #43
0
        public void Setup(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            ValidateModifier(node, target, incomingAssets,
                (Type expectedType, Type foundType, Asset foundAsset) => {
                    throw new NodeException(string.Format("{3} :Modifier expect {0}, but different type of incoming asset is found({1} {2})",
                        expectedType.FullName, foundType.FullName, foundAsset.fileNameAndExtension, node.Name), node.Id);
                },
                () => {
                    throw new NodeException(node.Name + " :Modifier is not configured. Please configure from Inspector.", node.Id);
                },
                () => {
                    throw new NodeException(node.Name + " :Failed to create Modifier from settings. Please fix settings from Inspector.", node.Id);
                },
                (Type expected, Type incoming) => {
                    throw new NodeException(string.Format("{0} :Incoming asset type is does not match with this Modifier (Expected type:{1}, Incoming type:{2}).",
                        node.Name, (expected != null)?expected.FullName:"null", (incoming != null)?incoming.FullName:"null"), node.Id);
                }
            );

            // Modifier does not add, filter or change structure of group, so just pass given group of assets
            Output(connectionToOutput, inputGroupAssets, null);
        }
        /**
            Perform Run or Setup from parent of given terminal node recursively.
        */
        private static void DoNodeOperation(
			BuildTarget target,
			NodeData currentNodeData,
			ConnectionPointData currentInputPoint,
			ConnectionData connectionToOutput,
			SaveData saveData,
			Dictionary<ConnectionData, Dictionary<string, List<Asset>>> resultDict, 
			Dictionary<NodeData, List<string>> cachedDict,
			List<string> performedIds,
			bool isActualRun,
			Action<NodeException> errorHandler,
			Action<NodeData, float> updateHandler
		)
        {
            if (performedIds.Contains(currentNodeData.Id) || (currentInputPoint != null && performedIds.Contains(currentInputPoint.Id))) {
                return;
            }

            /*
             * Find connections coming into this node from parent node, and traverse recursively
            */
            var connectionsToParents = saveData.Connections.FindAll(con => con.ToNodeId == currentNodeData.Id);

            foreach (var c in connectionsToParents) {

                var parentNode = saveData.Nodes.Find(node => node.Id == c.FromNodeId);
                UnityEngine.Assertions.Assert.IsNotNull(parentNode);

                // check if nodes can connect together
                ConnectionData.ValidateConnection(parentNode, currentNodeData);
                if( parentNode.InputPoints.Count > 0 ) {
                    // if node has multiple input, node is operated per input
                    foreach(var parentInputPoint in parentNode.InputPoints) {
                        DoNodeOperation(target, parentNode, parentInputPoint, c, saveData, resultDict, cachedDict, performedIds, isActualRun, errorHandler, updateHandler);
                    }
                }
                // if parent does not have input point, call with inputPoint==null
                else {
                    DoNodeOperation(target, parentNode, null, c, saveData, resultDict, cachedDict, performedIds, isActualRun, errorHandler, updateHandler);
                }
            }

            // mark this point as performed
            if(currentInputPoint != null) {
                performedIds.Add(currentInputPoint.Id);
            }
            // Root node does not have input point, so we are storing node id instead.
            else {
                performedIds.Add(currentNodeData.Id);
            }

            /*
             * Perform node operation for this node
            */

            if (updateHandler != null) {
                updateHandler(currentNodeData, 0f);
            }

            /*
                has next node, run first time.
            */

            var alreadyCachedPaths = new List<string>();
            if (cachedDict.ContainsKey(currentNodeData)) {
                alreadyCachedPaths.AddRange(cachedDict[currentNodeData]);
            }
            // load already exist cache from node.
            alreadyCachedPaths.AddRange(GetCachedDataByNode(target, currentNodeData));

            // Grab incoming assets from result by refering connections to parents
            var inputGroupAssets = new Dictionary<string, List<Asset>>();
            if(currentInputPoint != null) {
                // aggregates all input assets coming from current inputPoint
                var connToParentsFromCurrentInput = saveData.Connections.FindAll(con => con.ToNodeConnectionPointId == currentInputPoint.Id);
                foreach (var rCon in connToParentsFromCurrentInput) {
                    if (!resultDict.ContainsKey(rCon)) {
                        continue;
                    }

                    var result = resultDict[rCon];
                    foreach (var groupKey in result.Keys) {
                        if (!inputGroupAssets.ContainsKey(groupKey)) {
                            inputGroupAssets[groupKey] = new List<Asset>();
                        }
                        inputGroupAssets[groupKey].AddRange(result[groupKey]);
                    }
                }
            }

            /*
                the Action passes to NodeOperaitons.
                It stores result to resultDict.
            */
            Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output =
                (ConnectionData destinationConnection, Dictionary<string, List<Asset>> outputGroupAsset, List<string> cachedItems) =>
            {
                if(destinationConnection != null ) {
                    if (!resultDict.ContainsKey(destinationConnection)) {
                        resultDict[destinationConnection] = new Dictionary<string, List<Asset>>();
                    }
                    /*
                    merge connection result by group key.
                    */
                    foreach (var groupKey in outputGroupAsset.Keys) {
                        if (!resultDict[destinationConnection].ContainsKey(groupKey)) {
                            resultDict[destinationConnection][groupKey] = new List<Asset>();
                        }
                        resultDict[destinationConnection][groupKey].AddRange(outputGroupAsset[groupKey]);
                    }
                }

                if (isActualRun) {
                    if (!cachedDict.ContainsKey(currentNodeData)) {
                        cachedDict[currentNodeData] = new List<string>();
                    }
                    if(cachedItems != null) {
                        cachedDict[currentNodeData].AddRange(cachedItems);
                    }
                }
            };

            try {
                INodeOperation executor = CreateOperation(saveData, currentNodeData, errorHandler);
                if(executor != null) {
                    if(isActualRun) {
                        executor.Run(target, currentNodeData, currentInputPoint, connectionToOutput, inputGroupAssets, alreadyCachedPaths, Output);
                    }
                    else {
                        executor.Setup(target, currentNodeData, currentInputPoint, connectionToOutput, inputGroupAssets, alreadyCachedPaths, Output);
                    }
                }

            } catch (NodeException e) {
                errorHandler(e);
                // since error occured, this node should stop running for other inputpoints. Adding node id to stop.
                if(!performedIds.Contains(currentNodeData.Id)) {
                    performedIds.Add(currentNodeData.Id);
                }
            }

            if (updateHandler != null) {
                updateHandler(currentNodeData, 1f);
            }
        }
예제 #45
0
 private Type FindIncomingAssetType(ConnectionPointData inputPoint)
 {
     var assetGroups = AssetBundleGraphEditorWindow.GetIncomingAssetGroups(inputPoint);
     if(assetGroups == null) {
         return null;
     }
     return TypeUtility.FindIncomingAssetType(assetGroups.SelectMany(v => v.Value).ToList());
 }
예제 #46
0
 public Variant(string name, ConnectionPointData point)
 {
     m_name = name;
     m_point = point;
 }
 private bool IsConnectablePointFromTo(ConnectionPointData sourcePoint, ConnectionPointData destPoint)
 {
     if( sourcePoint.IsInput ) {
         return destPoint.IsOutput;
     } else {
         return destPoint.IsInput;
     }
 }
        public void Setup(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            ValidatePrefabBuilder(node, target, inputGroupAssets,
                () => {
                    throw new NodeException(node.Name + " :PrefabBuilder is not configured. Please configure from Inspector.", node.Id);
                },
                () => {
                    throw new NodeException(node.Name + " :Failed to create PrefabBuilder from settings. Please fix settings from Inspector.", node.Id);
                },
                (string groupKey) => {
                    throw new NodeException(string.Format("{0} :Can not create prefab with incoming assets for group {1}.", node.Name, groupKey), node.Id);
                },
                (Asset badAsset) => {
                    throw new NodeException(string.Format("{0} :Can not import incoming asset {1}.", node.Name, badAsset.fileNameAndExtension), node.Id);
                }
            );

            var builder = PrefabBuilderUtility.CreatePrefabBuilder(node, target);
            UnityEngine.Assertions.Assert.IsNotNull(builder);

            var prefabOutputDir = FileUtility.EnsurePrefabBuilderCacheDirExists(target, node);
            Dictionary<string, List<Asset>> output = new Dictionary<string, List<Asset>>();

            foreach(var key in inputGroupAssets.Keys) {
                var prefabFileName = builder.CanCreatePrefab(key, LoadAllAssets(inputGroupAssets[key]));
                output[key] = new List<Asset> () {
                    Asset.CreateAssetWithImportPath(FileUtility.PathCombine(prefabOutputDir, prefabFileName + ".prefab"))
                };
            }

            Output(connectionToOutput, output, null);
        }
예제 #49
0
        public void AddVariant(string name)
        {
            ValidateAccess(
                NodeKind.BUNDLECONFIG_GUI
            );

            var point = new ConnectionPointData(name, this, true);
            m_inputPoints.Add(point);
            var newEntry = new Variant(name, point);
            m_variants.Add(newEntry);
        }
        public void Setup(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var outputDict = new Dictionary<string, List<Asset>>();
            outputDict[key] = new List<Asset>();

            var bundleNames = inputGroupAssets.Keys.ToList();

            var bundleVariants = new Dictionary<string, List<string>>();

            // get all variant name for bundles
            foreach (var name in bundleNames) {
                bundleVariants[name] = new List<string>();
                var assets = inputGroupAssets[name];
                foreach(var a in assets) {
                    var variantName = a.variantName;
                    if(!bundleVariants[name].Contains(variantName)) {
                        bundleVariants[name].Add(variantName);
                    }
                }
            }

            // add manifest file
            var manifestName = BuildTargetUtility.TargetToAssetBundlePlatformName(target);
            bundleNames.Add( manifestName );
            bundleVariants[manifestName] = new List<string>();

            var bundleOutputDir = FileUtility.EnsureAssetBundleCacheDirExists(target, node);

            foreach (var name in bundleNames) {
                foreach(var v in bundleVariants[name]) {
                    string bundleName = (string.IsNullOrEmpty(v))? name : name + "." + v;
                    Asset bundle = Asset.CreateAssetWithImportPath( FileUtility.PathCombine(bundleOutputDir, bundleName) );
                    Asset manifest = Asset.CreateAssetWithImportPath( FileUtility.PathCombine(bundleOutputDir, bundleName + AssetBundleGraphSettings.MANIFEST_FOOTER) );
                    outputDict[key].Add(bundle);
                    outputDict[key].Add(manifest);
                }
            }

            Output(connectionToOutput, outputDict, new List<string>());
        }
예제 #51
0
 public FilterEntry(string keyword, string keytype, ConnectionPointData point)
 {
     m_filterKeyword = keyword;
     m_filterKeytype = keytype;
     m_point = point;
 }
        public void Run(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var bundleOutputDir = FileUtility.EnsureAssetBundleCacheDirExists(target, node);

            var bundleNames = inputGroupAssets.Keys.ToList();
            var bundleVariants = new Dictionary<string, List<string>>();

            // get all variant name for bundles
            foreach (var name in bundleNames) {
                bundleVariants[name] = new List<string>();
                var assets = inputGroupAssets[name];
                foreach(var a in assets) {
                    var variantName = a.variantName;
                    if(!bundleVariants[name].Contains(variantName)) {
                        bundleVariants[name].Add(variantName);
                    }
                }
            }

            int validNames = 0;
            foreach (var name in bundleNames) {
                var assets = inputGroupAssets[name];
                // we do not build bundle without any asset
                if( assets.Count > 0 ) {
                    validNames += bundleVariants[name].Count;
                }
            }

            AssetBundleBuild[] bundleBuild = new AssetBundleBuild[validNames];

            int bbIndex = 0;
            foreach(var name in bundleNames) {
                foreach(var v in bundleVariants[name]) {
                    var bundleName = name;
                    var assets = inputGroupAssets[name];

                    if(assets.Count <= 0) {
                        continue;
                    }

                    bundleBuild[bbIndex].assetBundleName = bundleName;
                    bundleBuild[bbIndex].assetBundleVariant = v;
                    bundleBuild[bbIndex].assetNames = assets.Where(x => x.variantName == v).Select(x => x.importFrom).ToArray();
                    ++bbIndex;
                }
            }

            BuildPipeline.BuildAssetBundles(bundleOutputDir, bundleBuild, (BuildAssetBundleOptions)node.BundleBuilderBundleOptions[target], target);

            var output = new Dictionary<string, List<Asset>>();
            output[key] = new List<Asset>();

            var generatedFiles = FileUtility.GetAllFilePathsInFolder(bundleOutputDir);
            // add manifest file
            bundleNames.Add( BuildTargetUtility.TargetToAssetBundlePlatformName(target) );
            foreach (var path in generatedFiles) {
                var fileName = Path.GetFileName(path);
                if( IsFileIntendedItem(fileName, bundleNames) ) {
                    output[key].Add( Asset.CreateAssetWithImportPath(path) );
                } else {
                    Debug.LogWarning(node.Name + ":Irrelevant file found in assetbundle cache folder:" + fileName);
                }
            }

            Output(connectionToOutput, output, alreadyCached);
        }
        /**
            create new connection if same relationship is not exist yet.
        */
        private void AddConnection(string label, NodeGUI startNode, ConnectionPointData startPoint, NodeGUI endNode, ConnectionPointData endPoint)
        {
            Undo.RecordObject(this, "Add Connection");

            var connectionsFromThisNode = connections
                .Where(con => con.OutputNodeId == startNode.Id)
                .Where(con => con.OutputPoint == startPoint)
                .ToList();
            if (connectionsFromThisNode.Any()) {
                var alreadyExistConnection = connectionsFromThisNode[0];
                DeleteConnectionById(alreadyExistConnection.Id);
            }

            if (!connections.ContainsConnection(startPoint, endPoint)) {
                connections.Add(ConnectionGUI.CreateConnection(label, startPoint, endPoint));
            }
        }
예제 #54
0
 public ConnectionPointData AddOutputPoint(string label)
 {
     var p = new ConnectionPointData(label, this, false);
     m_outputPoints.Add(p);
     return p;
 }
예제 #55
0
        public void AddFilterCondition(string keyword, string keytype)
        {
            ValidateAccess(
                NodeKind.FILTER_GUI
            );

            var point = new ConnectionPointData(keyword, this, false);
            m_outputPoints.Add(point);
            var newEntry = new FilterEntry(keyword, keytype, point);
            m_filter.Add(newEntry);
        }
예제 #56
0
 public ConnectionPointData AddInputPoint(string label)
 {
     var p = new ConnectionPointData(label, this, true);
     m_inputPoints.Add(p);
     return p;
 }
        public void Run(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            ApplyImportSetting(node, incomingAssets);

            Output(connectionToOutput, inputGroupAssets, null);
        }
        public void Setup(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            Action<Type, Type, Asset> multipleAssetTypeFound = (Type expectedType, Type foundType, Asset foundAsset) => {
                throw new NodeException(string.Format("{3} :ImportSetting expect {0}, but different type of incoming asset is found({1} {2})",
                    expectedType.FullName, foundType.FullName, foundAsset.fileNameAndExtension, node.Name), node.Id);
            };

            Action<Type> unsupportedType = (Type unsupported) => {
                throw new NodeException(string.Format("{0} :Incoming asset type is not supported by ImportSetting (Incoming type:{1}). Perhaps you want to use Modifier instead?",
                    node.Name, (unsupported != null)?unsupported.FullName:"null"), node.Id);
            };

            Action<Type, Type> incomingTypeMismatch = (Type expected, Type incoming) => {
                throw new NodeException(string.Format("{0} :Incoming asset type is does not match with this ImportSetting (Expected type:{1}, Incoming type:{2}).",
                    node.Name, (expected != null)?expected.FullName:"null", (incoming != null)?incoming.FullName:"null"), node.Id);
            };

            Action<ConfigStatus> errorInConfig = (ConfigStatus _) => {
                // give a try first in sampling file
                if(incomingAssets.Any()) {
                    SaveSampleFile(node, incomingAssets[0]);

                    ValidateInputSetting(node, target, incomingAssets, multipleAssetTypeFound, unsupportedType, incomingTypeMismatch, (ConfigStatus eType) => {
                        if(eType == ConfigStatus.NoSampleFound) {
                            throw new NodeException(node.Name + " :ImportSetting has no sampling file. Please configure it from Inspector.", node.Id);
                        }
                        if(eType == ConfigStatus.TooManySamplesFound) {
                            throw new NodeException(node.Name + " :ImportSetting has too many sampling file. Please fix it from Inspector.", node.Id);
                        }
                    });
                }
            };

            ValidateInputSetting(node, target, incomingAssets, multipleAssetTypeFound, unsupportedType, incomingTypeMismatch, errorInConfig);

            // ImportSettings does not add, filter or change structure of group, so just pass given group of assets
            Output(connectionToOutput, inputGroupAssets, null);
        }