public static void CheckForRemoveOrEditFromCurveEditor(SubstanceMaterialParams substanceMaterialParams, SubstanceAnimationParams animationParams, SubstanceToolParams substanceToolParams, SubstanceFlickerParams flickerValues) { bool inEditKeysMode = false; int keyframesModifiedSoFar = 0; //number of keyframes deleted edited so far int curvePointsCountDifference = animationParams.substanceCurveBackup.keys.Count() - animationParams.substanceCurve.keys.Count(); // difference between number of points before the change compared to the number of points after the change List <float> BackupKeyframePointTimes = new List <float>(); // points on curve before change List <float> CurrentKeyframePointTimes = new List <float>(); // points on curve after change Keyframe firstEditedKeyframeBeforeEdit = new Keyframe(-1, -1); //the first keyframe in the list that has been edited ore deleted int firstEditedKeyframeIndexBeforeEdit = -1; // index of the first edited keyframe if (animationParams.substanceCurve.keys[0].time != 0) { animationParams.substanceCurve.keys[0].time = 0; } for (int i = 0; i <= animationParams.substanceCurveBackup.keys.Count() - 1; i++) { BackupKeyframePointTimes.Add(animationParams.substanceCurveBackup.keys[i].time); } for (int i = 0; i <= animationParams.substanceCurve.keys.Count() - 1; i++) { CurrentKeyframePointTimes.Add(animationParams.substanceCurve.keys[i].time); } for (int i = 0; i <= BackupKeyframePointTimes.Count() - 2; i++) { if (!CurrentKeyframePointTimes.Contains(BackupKeyframePointTimes[i])) { // find index of the first key that has ben edited using context menu firstEditedKeyframeBeforeEdit = animationParams.substanceCurveBackup.keys[i]; float tempKeyframeTime = firstEditedKeyframeBeforeEdit.time; firstEditedKeyframeIndexBeforeEdit = i; SubstanceTweenSetParameterUtility.SetProceduralMaterialBasedOnAnimationTime(ref tempKeyframeTime, substanceMaterialParams, animationParams, substanceToolParams, flickerValues); break; } } for (int i = 0; i <= CurrentKeyframePointTimes.Count() - 2; i++) { if (!BackupKeyframePointTimes.Contains(CurrentKeyframePointTimes[i])) {// if i use the context menu to edit multiple keyframes to a value that is not already on the graph i can find that new keyframe here. // I can tell when i have EDITED a keyframe to a new value because when deleting keyframes, every new point's time should also exist in the backup inEditKeysMode = true; float tempKeyframeTime = firstEditedKeyframeBeforeEdit.time; SubstanceTweenSetParameterUtility.SetProceduralMaterialBasedOnAnimationTime(ref tempKeyframeTime, substanceMaterialParams, animationParams, substanceToolParams, flickerValues); // find/set material based on first edited keyframe if (firstEditedKeyframeIndexBeforeEdit != -1) // if multiple keyframes has been edited using context menu { SubstanceTweenKeyframeUtility.OverWriteKeyframe(firstEditedKeyframeIndexBeforeEdit, substanceMaterialParams, animationParams, substanceToolParams); // overwrite new keyframe with material of the first edited keyframe } } } for (int i = BackupKeyframePointTimes.Count() - 1; i > 0; i--) // Go through every key in the backup list(Before the keys got deleted) { if (!CurrentKeyframePointTimes.Contains(BackupKeyframePointTimes[i])) // if the current list of curve points does not contain this value(it was deleted in the curve editor) { //Find the index of the value and delete any information that has not already been deleted in the curve editor // get the index of the deleted point and delete the Dictionary/List associated with that index keyframesModifiedSoFar++; animationParams.keyFrameTimes.RemoveAt(BackupKeyframePointTimes.IndexOf(BackupKeyframePointTimes[i])); substanceMaterialParams.MaterialVariableKeyframeList.RemoveAt(BackupKeyframePointTimes.IndexOf(BackupKeyframePointTimes[i])); substanceMaterialParams.MaterialVariableKeyframeDictionaryList.RemoveAt(BackupKeyframePointTimes.IndexOf(BackupKeyframePointTimes[i])); if (animationParams.keyFrames > 0) { animationParams.keyFrames--; } } if (inEditKeysMode && i == 1 && keyframesModifiedSoFar > 0) { // if i edited multiple keyframes at the same time using the context menu I insert a keyframe when i reach the end of the for loop SubstanceTweenKeyframeUtility.InsertKeyframe(i, substanceMaterialParams, animationParams, substanceToolParams); } } for (int i = 0; i <= animationParams.substanceCurve.keys.Count() - 2; i++) { // rebuild/refresh animation times animationParams.keyFrameTimes[i] = animationParams.substanceCurve.keys[i + 1].time - animationParams.substanceCurve.keys[i].time; // this keyframe time = (next keyframe time - This keyframe time) substanceMaterialParams.MaterialVariableKeyframeList[i].animationTime = animationParams.substanceCurve.keys[i + 1].time - animationParams.substanceCurve.keys[i].time; } if (curvePointsCountDifference != keyframesModifiedSoFar) { // Because curvePoint EditDifference != keyframes Edited/changed, I know that keyframes have been changed with 'Edit Keys..' and not 'Delete' // when editing multipule keyframes to a new singular time that is not already on the list, // there should always be more edited keyframes then the difference between current curve points and backup curve points. if (animationParams.substanceCurve.keys[animationParams.substanceCurve.keys.Count() - 1].time > animationParams.substanceCurveBackup.keys[animationParams.substanceCurveBackup.keys.Count() - 1].time) {// Edited multiple keyframes to a new time that is more than the length of the backup curve SubstanceTweenKeyframeUtility.CreateKeyframe(substanceMaterialParams, animationParams, substanceToolParams); } } animationParams.substanceCurveBackup.keys = animationParams.substanceCurve.keys; SubstanceTweenAnimationUtility.CalculateAnimationLength(substanceMaterialParams, animationParams); inEditKeysMode = false; }
public static void SetProceduralMaterialBasedOnAnimationTime(ref float desiredTime, SubstanceMaterialParams substanceMaterialVariables, SubstanceAnimationParams substanceAnimationParams, SubstanceToolParams substanceToolParams, SubstanceFlickerParams flickerValues) { for (int i = 0; i <= substanceAnimationParams.substanceCurveBackup.keys.Count() - 1; i++) { if (substanceAnimationParams.substanceCurveBackup.keys[i].time > desiredTime) // find first key time that is greater than the desiredAnimationTime { float newLerp = (desiredTime - substanceAnimationParams.substanceCurveBackup.keys[i - 1].time) / (substanceAnimationParams.substanceCurveBackup.keys[i].time - substanceAnimationParams.substanceCurveBackup.keys[i - 1].time); // Finds point between two keyrames - finds percentage of desiredtime between substanceCurveBackup.keys[i - 1].time and substanceCurveBackup.keys[i].time substanceAnimationParams.currentAnimationTime = Mathf.Lerp(0, substanceAnimationParams.keyFrameTimes[i - 1], newLerp); substanceAnimationParams.animationTimeRestartEnd = desiredTime; substanceAnimationParams.currentKeyframeIndex = i - 1; if (EditorWindow.focusedWindow && EditorWindow.focusedWindow.ToString() != " (UnityEditor.CurveEditorWindow)") { substanceAnimationParams.lerp = newLerp; } for (int j = 0; j < substanceMaterialVariables.animatedMaterialVariables.Count; j++)// search through dictionary for variable names and if they match animate them { ProceduralPropertyDescription animatedMaterialVariable = substanceMaterialVariables.animatedMaterialVariables[j]; ProceduralPropertyType propType = substanceMaterialVariables.animatedMaterialVariables[j].type; if (substanceMaterialVariables.materialVariableNames.Contains(animatedMaterialVariable.name)) { if (propType == ProceduralPropertyType.Float) { substanceMaterialVariables.substance.SetProceduralFloat(animatedMaterialVariable.name, Mathf.Lerp(substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].PropertyFloatDictionary[animatedMaterialVariable.name], substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i].PropertyFloatDictionary[animatedMaterialVariable.name], newLerp * flickerValues.flickerFloatCalc)); } else if (propType == ProceduralPropertyType.Color3) { substanceMaterialVariables.substance.SetProceduralColor(animatedMaterialVariable.name, Color.Lerp(substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].PropertyColorDictionary[animatedMaterialVariable.name], substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i].PropertyColorDictionary[animatedMaterialVariable.name], newLerp * flickerValues.flickerColor3Calc)); } else if (propType == ProceduralPropertyType.Color4) { substanceMaterialVariables.substance.SetProceduralColor(animatedMaterialVariable.name, Color.Lerp(substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].PropertyColorDictionary[animatedMaterialVariable.name], substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i].PropertyColorDictionary[animatedMaterialVariable.name], newLerp * flickerValues.flickerColor4Calc)); } else if (propType == ProceduralPropertyType.Vector2 || propType == ProceduralPropertyType.Vector3 || propType == ProceduralPropertyType.Vector4) { if (propType == ProceduralPropertyType.Vector4) { substanceMaterialVariables.substance.SetProceduralVector(animatedMaterialVariable.name, Vector4.Lerp(substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].PropertyVector4Dictionary[animatedMaterialVariable.name], substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i].PropertyVector4Dictionary[animatedMaterialVariable.name], newLerp * flickerValues.flickerVector4Calc)); } else if (propType == ProceduralPropertyType.Vector3) { substanceMaterialVariables.substance.SetProceduralVector(animatedMaterialVariable.name, Vector3.Lerp(substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].PropertyVector3Dictionary[animatedMaterialVariable.name], substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i].PropertyVector3Dictionary[animatedMaterialVariable.name], newLerp * flickerValues.flickerVector3Calc)); } else if (propType == ProceduralPropertyType.Vector2) { substanceMaterialVariables.substance.SetProceduralVector(animatedMaterialVariable.name, Vector2.Lerp(substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].PropertyVector2Dictionary[animatedMaterialVariable.name], substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i].PropertyVector2Dictionary[animatedMaterialVariable.name], newLerp * flickerValues.flickerVector2Calc)); } } else if (propType == ProceduralPropertyType.Enum) { substanceMaterialVariables.substance.SetProceduralEnum(animatedMaterialVariable.name, substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].PropertyEnumDictionary[animatedMaterialVariable.name]); } else if (propType == ProceduralPropertyType.Boolean) { substanceMaterialVariables.substance.SetProceduralBoolean(animatedMaterialVariable.name, substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].PropertyBoolDictionary[animatedMaterialVariable.name]); } } } if (substanceMaterialVariables.rend.sharedMaterial.HasProperty("_EmissionColor")) { substanceMaterialVariables.emissionInput = Color.Lerp(substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].emissionColor, substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i].emissionColor, newLerp * flickerValues.flickerCalc); substanceMaterialVariables.rend.sharedMaterial.SetColor("_EmissionColor", substanceMaterialVariables.emissionInput); substanceToolParams.selectedPrefabScript.emissionInput = substanceMaterialVariables.emissionInput; } if (substanceMaterialVariables.rend.sharedMaterial.HasProperty("_MainTex")) { substanceMaterialVariables.rend.sharedMaterial.SetTextureOffset("_MainTex", Vector2.Lerp(substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i - 1].MainTex, substanceMaterialVariables.MaterialVariableKeyframeDictionaryList[i].MainTex, newLerp * flickerValues.flickerCalc)); } substanceMaterialVariables.substance.RebuildTextures(); return; } } }
public static void CheckForAddKeyFromCurveEditor(SubstanceMaterialParams substanceMaterialParams, SubstanceAnimationParams animationParams, SubstanceToolParams substanceToolParams, SubstanceFlickerParams flickerValues) { for (int i = 0; i <= animationParams.substanceCurveBackup.keys.Count() - 1; i++) { if (i <= animationParams.substanceCurve.keys.Count() - 1 && animationParams.substanceCurve.keys[i].time != animationParams.substanceCurveBackup.keys[i].time) // find keyframe that has just been created or deleted in the curve editor { if (animationParams.substanceCurve.keys.Count() > animationParams.substanceCurveBackup.keys.Count()) { animationParams.substanceCurve.MoveKey(i, new Keyframe(animationParams.substanceCurve.keys[i].time, animationParams.substanceCurve.keys[i].time)); // lerp does not work correctly if the keyframe value is different than the time. i cant edit the key so i delete then add a new one float tempKeyframeTime = animationParams.substanceCurve.keys[i].time; SubstanceTweenSetParameterUtility.SetProceduralMaterialBasedOnAnimationTime(ref tempKeyframeTime, substanceMaterialParams, animationParams, substanceToolParams, flickerValues); SubstanceTweenKeyframeUtility.InsertKeyframe(i, substanceMaterialParams, animationParams, substanceToolParams); SubstanceTweenKeyframeUtility.SelectKeyframe(i, substanceMaterialParams, animationParams, substanceToolParams); animationParams.currentAnimationTime = 0; animationParams.substanceCurveBackup.keys = animationParams.substanceCurve.keys; SubstanceTweenAnimationUtility.CalculateAnimationLength(substanceMaterialParams, animationParams); return; } } } }
public static void SavePrefab(SubstanceMaterialParams substanceMaterialParams, SubstanceAnimationParams animationParams, SubstanceToolParams substanceToolParams, SubstancePerformanceParams substancePerformanceParams, SubstanceFlickerParams flickerValues) // Saves a Prefab to a specified folder { string prefabPath = EditorUtility.SaveFilePanelInProject("", "", "prefab", ""); if (prefabPath.Length != 0) { GameObject prefab = PrefabUtility.CreatePrefab(prefabPath, substanceToolParams.currentSelection.gameObject, ReplacePrefabOptions.Default); if (prefab.GetComponent <PrefabProperties>() != null) { UnityEngine.Object.DestroyImmediate(prefab.GetComponent <PrefabProperties>(), true); } prefab.AddComponent <PrefabProperties>(); // adds prefab script to prefab PrefabProperties prefabProperties = prefab.GetComponent <PrefabProperties>(); prefabProperties.substance = substanceMaterialParams.substance; Renderer prefabRend = prefab.GetComponent <Renderer>(); prefabRend.material = substanceMaterialParams.substance; if (animationParams.animationType == SubstanceAnimationParams.AnimationType.Loop) { prefabProperties.animationType = PrefabProperties.AnimationType.Loop; } if (animationParams.animationType == SubstanceAnimationParams.AnimationType.BackAndForth) { prefabProperties.animationType = PrefabProperties.AnimationType.BackAndForth; } substanceToolParams.DebugStrings.Add("Created prefab: " + prefab.name); if (prefabRend.sharedMaterial) { substanceToolParams.DebugStrings.Add("Prefab material: " + prefabRend.sharedMaterial.name); } if (substanceMaterialParams.MaterialVariableKeyframeList.Count >= 1) {//writes keyfame lists to prefab(Could not serialize dictionaries) for (int i = 0; i <= substanceMaterialParams.MaterialVariableKeyframeList.Count - 1; i++) { if (prefabProperties.keyFrameTimes.Count == 0) { prefabProperties.MaterialVariableKeyframeList.Add(new MaterialVariableListHolder()); prefabProperties.MaterialVariableKeyframeList[0] = substanceMaterialParams.MaterialVariableKeyframeList[0]; prefabProperties.MaterialVariableKeyframeList[0].PropertyMaterialName = substanceMaterialParams.substance.name; prefabProperties.MaterialVariableKeyframeList[0].emissionColor = substanceMaterialParams.MaterialVariableKeyframeList[0].emissionColor; prefabProperties.MaterialVariableKeyframeList[0].MainTex = substanceMaterialParams.MaterialVariableKeyframeList[prefabProperties.keyFrames].MainTex; prefabProperties.keyFrameTimes.Add(substanceMaterialParams.MaterialVariableKeyframeList[0].animationTime); prefabProperties.prefabAnimationCurve = new AnimationCurve(); prefabProperties.prefabAnimationCurve.AddKey(new Keyframe(animationParams.substanceCurve.keys[0].time, animationParams.substanceCurve.keys[0].value, animationParams.substanceCurve.keys[0].inTangent, animationParams.substanceCurve.keys[0].outTangent)); AnimationUtility.SetKeyBroken(prefabProperties.prefabAnimationCurve, 0, true); if (substanceMaterialParams.MaterialVariableKeyframeList[0].hasParametersWithoutRange) { prefabProperties.MaterialVariableKeyframeList[0].hasParametersWithoutRange = true; } else { prefabProperties.MaterialVariableKeyframeList[0].hasParametersWithoutRange = false; } prefabProperties.keyFrames++; } else // After one keyframe is created create the rest { prefabProperties.MaterialVariableKeyframeList.Add(new MaterialVariableListHolder()); prefabProperties.MaterialVariableKeyframeList[prefabProperties.keyFrames] = substanceMaterialParams.MaterialVariableKeyframeList[prefabProperties.keyFrames]; prefabProperties.MaterialVariableKeyframeList[prefabProperties.keyFrames].PropertyMaterialName = substanceMaterialParams.substance.name; prefabProperties.MaterialVariableKeyframeList[prefabProperties.keyFrames].emissionColor = substanceMaterialParams.MaterialVariableKeyframeList[prefabProperties.keyFrames].emissionColor; prefabProperties.MaterialVariableKeyframeList[prefabProperties.keyFrames].MainTex = substanceMaterialParams.MaterialVariableKeyframeList[prefabProperties.keyFrames].MainTex; prefabProperties.keyFrameTimes.Add(substanceMaterialParams.MaterialVariableKeyframeList[prefabProperties.keyFrames].animationTime); prefabProperties.prefabAnimationCurve.AddKey(new Keyframe(animationParams.substanceCurve.keys[prefabProperties.keyFrames].time, animationParams.substanceCurve.keys[prefabProperties.keyFrames].value, animationParams.substanceCurve.keys[prefabProperties.keyFrames].inTangent, animationParams.substanceCurve.keys[prefabProperties.keyFrames].outTangent)); if (substanceMaterialParams.saveOutputParameters) { prefabProperties.MaterialVariableKeyframeList[prefabProperties.keyFrames].hasParametersWithoutRange = true; } else { prefabProperties.MaterialVariableKeyframeList[prefabProperties.keyFrames].hasParametersWithoutRange = false; } prefabProperties.keyFrames++; } } prefabProperties.keyFrameTimesOriginal = animationParams.keyFrameTimes; prefabProperties.prefabAnimationCurveBackup = prefabProperties.prefabAnimationCurve; prefabProperties.MaterialVariableKeyframeDictionaryList = substanceMaterialParams.MaterialVariableKeyframeDictionaryList; SubstanceTweenAnimationUtility.DeleteNonAnimatingParametersOnPrefab(prefabProperties, substanceMaterialParams, animationParams); if (substanceMaterialParams.MaterialVariableKeyframeList.Count >= 2) { prefabProperties.animateOnStart = true; prefabProperties.animateBasedOnTime = true; } } if (animationParams.cacheSubstance) { prefabProperties.cacheAtStartup = true; } else { prefabProperties.cacheAtStartup = false; } if (animationParams.animateOutputParameters) { prefabProperties.animateOutputParameters = true; } else { prefabProperties.animateOutputParameters = false; } if (substancePerformanceParams.myProceduralCacheSize.ToString() == ProceduralCacheSize.Heavy.ToString()) { prefabProperties.myProceduralCacheSize = PrefabProperties.MyProceduralCacheSize.Heavy; } else if (substancePerformanceParams.myProceduralCacheSize.ToString() == ProceduralCacheSize.Medium.ToString()) { prefabProperties.myProceduralCacheSize = PrefabProperties.MyProceduralCacheSize.Medium; } else if (substancePerformanceParams.myProceduralCacheSize.ToString() == ProceduralCacheSize.NoLimit.ToString()) { prefabProperties.myProceduralCacheSize = PrefabProperties.MyProceduralCacheSize.NoLimit; } else if (substancePerformanceParams.myProceduralCacheSize.ToString() == ProceduralCacheSize.None.ToString()) { prefabProperties.myProceduralCacheSize = PrefabProperties.MyProceduralCacheSize.None; } else if (substancePerformanceParams.myProceduralCacheSize.ToString() == ProceduralCacheSize.Tiny.ToString()) { prefabProperties.myProceduralCacheSize = PrefabProperties.MyProceduralCacheSize.Tiny; } if (substancePerformanceParams.mySubstanceProcessorUsage.ToString() == ProceduralProcessorUsage.All.ToString()) { prefabProperties.mySubstanceProcessorUsage = PrefabProperties.MySubstanceProcessorUsage.All; } else if (substancePerformanceParams.mySubstanceProcessorUsage.ToString() == ProceduralProcessorUsage.Half.ToString()) { prefabProperties.mySubstanceProcessorUsage = PrefabProperties.MySubstanceProcessorUsage.Half; } else if (substancePerformanceParams.mySubstanceProcessorUsage.ToString() == ProceduralProcessorUsage.One.ToString()) { prefabProperties.mySubstanceProcessorUsage = PrefabProperties.MySubstanceProcessorUsage.One; } else if (substancePerformanceParams.mySubstanceProcessorUsage.ToString() == ProceduralProcessorUsage.Unsupported.ToString()) { prefabProperties.mySubstanceProcessorUsage = PrefabProperties.MySubstanceProcessorUsage.Unsupported; } if (flickerValues.flickerEnabled) { prefabProperties.flickerEnabled = true; if (flickerValues.flickerFloatToggle) { prefabProperties.flickerFloatToggle = true; } if (flickerValues.flickerColor3Toggle) { prefabProperties.flickerColor3Toggle = true; } if (flickerValues.flickerColor4Toggle) { prefabProperties.flickerColor4Toggle = true; } if (flickerValues.flickerVector2Toggle) { prefabProperties.flickerVector2Toggle = true; } if (flickerValues.flickerVector3Toggle) { prefabProperties.flickerVector3Toggle = true; } if (flickerValues.flickerVector4Toggle) { prefabProperties.flickerVector4Toggle = true; } if (flickerValues.flickerEmissionToggle) { prefabProperties.flickerEmissionToggle = true; } prefabProperties.flickerMin = flickerValues.flickerMin; prefabProperties.flickerMax = flickerValues.flickerMax; } #if UNITY_2017_1_OR_NEWER prefabRend.sharedMaterial.enableInstancing = true;// enables GPU instancing #endif prefabProperties.useSharedMaterial = true; prefabProperties.rend = prefabRend; substanceToolParams.DebugStrings.Add("Prefab Path: " + prefabPath); substanceToolParams.DebugStrings.Add(prefab.name + " has " + prefabProperties.MaterialVariableKeyframeList.Count + " keyframes"); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); substanceToolParams.lastAction = MethodBase.GetCurrentMethod().Name.ToString(); } else { Debug.LogWarning("No Path/FileName specified for Prefab"); } }