void MakeExplosion() { Vector3 position = transform.position; Collider[] colliders = Physics.OverlapSphere(position, radius); foreach (Collider collider in colliders) { Rigidbody rb = collider.GetComponent <Rigidbody>(); if (rb != null) { //add force to unity's physics stuff rb.AddExplosionForce(power, position, radius, 3.0f); } //add force to neofur NeoFurAsset nfa = collider.gameObject.GetComponent <NeoFurAsset>(); if (nfa) { RadialForce rf = new RadialForce(); rf.Origin = position; rf.Radius = radius; rf.Strength = power; nfa.AddRadialForce(rf); if (!string.IsNullOrEmpty(NameOfSoundToBePlayed)) { AudioManager.Instance.Play(NameOfSoundToBePlayed, this.transform.position); } } } }
private void SplineSection(NeoFurAsset nfa) { GUILayout.Space(10); Undo.RecordObject(target, "NeoFur Spline Data Assignment For " + nfa.gameObject.name); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Spline Data Asset: "); nfa.SplineGuideData = (NeoFur.Data.PreComputedGuideData)EditorGUILayout.ObjectField("", nfa.SplineGuideData, typeof(NeoFur.Data.PreComputedGuideData), false); GUILayout.EndHorizontal(); if (!nfa.SplineGuideData) { EditorGUILayout.HelpBox("Please specify a PrecomputedSplineData asset file to use by adding it to the object field or create a new one by clicking the button below!", MessageType.Info); } EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Create New PreComputedGuideData")) { NeoFur.Data.PreComputedGuideData splineData = NeoFur.Editor.PreComputedGuideDataEditor.CreateAssetWithPopup(nfa.mesh, true); if (splineData != null) { nfa.SplineGuideData = splineData; } } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); }
private void OnEnable() { nfa = (NeoFurAsset)target; projectIssueNotifications = new ProjectIssueNotifications(); projectIssueNotifications.onRepaint += Repaint; }
public static void AssignMatsInProjectToMatchingMatsInScene(List <Material> mats) { NeoFurAsset[] nfas = GetNeoFurAssetsInCurrentScene(); if (nfas.Length == 0) { Debug.LogWarning("No NeoFur Assets found in Scene"); return; } if (mats.Count == 0) { Debug.LogWarning("No mats found in current project folder"); EditorUtility.ClearProgressBar(); return; } else { Debug.Log("Found " + mats.Count + " materials"); } for (int i = 0; i < nfas.Length; ++i) { NeoFurAsset nfa = nfas[i]; EditorUtility.DisplayProgressBar("Assigning Materials to Scene", "Assigning " + i + "/" + nfas.Length + " to " + nfa.gameObject.name, (float)i / (float)nfas.Length); for (int m = 0; m < mats.Count; ++m) { Material mat = mats[m] as Material; if (mat == null) { Debug.LogWarning("Mat is null for some reason"); continue; } if (nfa.data.furryMat == null) { Debug.Log("NFA material ref is NULL"); continue; } if (mat.name.CompareTo(nfa.data.furryMat.name) == 0) { nfa.data.furryMat = mat; EditorUtility.SetDirty(nfa); } } } UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); EditorUtility.ClearProgressBar(); }
private static void MakeThings(string currentFolder) { // get NFA components GameObject go = GameObject.Find("MatBalls"); Dictionary <int, NeoFurAsset> nfaDict = new Dictionary <int, NeoFurAsset>(); for (int i = 0; i < go.transform.childCount; ++i) { Transform child = go.transform.GetChild(i); string numberStr = child.name; numberStr = numberStr.Substring(numberStr.LastIndexOf("_") + 1); int number = int.Parse(numberStr); if (!nfaDict.ContainsKey(number)) { Log("Found nfa go: " + child.name); nfaDict.Add(number, child.GetComponentInChildren <NeoFurAsset>()); } } //wrap in try catch just in case it crashes //so the display bar is closed and doesnt hang Unity try { List <Material> nfMats = new List <Material>(); // assign config data to NFA Components and Materials for (int i = 0; i < m_configs.Length; ++i) { NeoFurConfig config = m_configs[i]; NeoFurAsset nfa = nfaDict[i + 1]; bool cancel = EditorUtility.DisplayCancelableProgressBar("NeoFur Generation from Configs", "Building assets", (float)i / (float)(m_configs.Length)); if (cancel) { break; } Material m = CreateNFAPairFromConfig(currentFolder, config, nfa); if (m != null) { nfMats.Add(m); } } } catch (Exception e) { string err = "Config generator crashed: " + e.Message; LogError(err); Debug.LogError(err); } EditorUtility.ClearProgressBar(); }
private void OnDrawGizmosSelected() { Gizmos.color = new Color(0.65f, 1.0f, 0.35f, 1); Gizmos.DrawWireSphere(transform.position, radius); Gizmos.color = Color.white; Collider[] colliders = Physics.OverlapSphere(transform.position, radius); foreach (Collider collider in colliders) { NeoFurAsset nfa = collider.gameObject.GetComponent <NeoFurAsset>(); if (nfa) { Gizmos.DrawLine(transform.position, nfa.transform.position); } } }
void PreProcessSection(NeoFurAsset nfa) { bPreProcessFolded = NeoGUIHelper.HeaderWithFoldout(Styles.foldoutPreProcess.text, bPreProcessFolded); if (bPreProcessFolded) { EditorGUI.indentLevel++; EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth / 5; GUILayout.BeginHorizontal(); EditorGUILayout.LabelField(Styles.labelFurGuideGenMethod); string[] choices = new string[3]; choices[0] = "Splines"; choices[1] = "Morphs"; choices[2] = "Normals"; nfa.data.guideMethod = (NeoFurAssetData.GuideMethod)(GUILayout.SelectionGrid( (int)nfa.data.guideMethod, choices, 3, EditorStyles.radioButton)); mLastGuideMethod = nfa.data.guideMethod; GUILayout.EndHorizontal(); if (nfa.data.guideMethod == NeoFurAssetData.GuideMethod.Normals) { float oldWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth / 2; //desired length of guides generated from normals EditorGUILayout.PropertyField(guideLengthProp, Styles.labelGuideLength); EditorGUIUtility.labelWidth = oldWidth; } else if (nfa.data.guideMethod == NeoFurAssetData.GuideMethod.Morphs) { MorphSection(nfa); } else if (nfa.data.guideMethod == NeoFurAssetData.GuideMethod.Splines) { SplineSection(nfa); } EditorGUI.indentLevel--; } }
static void ApplyComponentProperties(Material mat, NeoFurConfig config, NeoFurAsset nfa) { if (nfa == null) { return; } Log("Assigning material: " + mat.name + " is assigned to " + nfa.gameObject.name); nfa.data.furryMat = mat; // set component values SetFieldValuesToProperties(config.Component, typeof(ComponentParameters), nfa, typeof(NeoFurAsset), true); // apply physics stuff SetFieldValuesToProperties(config.Component.FurPhysicsParameters, typeof(FurPhysicsParameters), nfa.physParams, typeof(PhysicsStuff)); // make sure the nfa is serialized and marked as needing to be serialized UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene()); }
/* * void SplineSection(NeoFurAsset nfa) * { * string fbxPathButtonText =""; * if(nfa.mPathToFBX == null || nfa.mPathToFBX == "") * { * fbxPathButtonText ="Pick Spline FBX File"; * } * else * { * fbxPathButtonText ="Change Spline FBX File"; * } * * GUILayout.BeginHorizontal(); * GUILayout.FlexibleSpace(); * * if(GUILayout.Button(fbxPathButtonText)) * { * string fullPath =EditorUtility.OpenFilePanel( * "FBX Spline Data File", "", "*.fbx;*.FBX"); * * nfa.mPathToFBX =FileUtil.GetProjectRelativePath(fullPath); * if(nfa.mPathToFBX == "") * { * nfa.mPathToFBX =fullPath; * } * } * * GUILayout.FlexibleSpace(); * GUILayout.EndHorizontal(); * * EditorGUIUtility.labelWidth =EditorGUIUtility.currentViewWidth / 3.5f; * * //path to spline data * EditorGUILayout.LabelField("Path to FBX:", nfa.mPathToFBX); * * //spline grab * if(BackGroundWorker.IsWorking()) * { * EditorGUILayout.HelpBox("Working... ", MessageType.Info); * } * else if(nfa.mPathToFBX != null && nfa.mPathToFBX != "") * { * GUILayout.BeginHorizontal(); * GUILayout.FlexibleSpace(); * if(nfa.bSplinesReady()) * { * if(GUILayout.Button("Reload Spline Data")) * { * object context; * ThreadStuff.ThreadFunc func; * * nfa.GrabSplineData(out context, out func); * * if(context != null && func != null) * { * BackGroundWorker.eComplete +=OnComplete; * mFunc =func; * BackGroundWorker.RunJob("Computing...", "Computing fur guides...", context, RunThread); * } * } * } * else * { * if(GUILayout.Button("Grab Spline Data")) * { * object context; * ThreadStuff.ThreadFunc func; * * nfa.GrabSplineData(out context, out func); * * if(context != null && func != null) * { * BackGroundWorker.eComplete +=OnComplete; * mFunc =func; * BackGroundWorker.RunJob("Computing...", "Computing fur guides...", context, RunThread); * } * } * } * GUILayout.FlexibleSpace(); * GUILayout.EndHorizontal(); * } * * if(!nfa.bSplinesReady()) * { * EditorGUILayout.HelpBox("No fur guides loaded, fixed length guides will be used.", MessageType.Warning); * } * else if(!nfa.bGuided() && nfa.bSplinesReady() && !BackGroundWorker.IsWorking()) * { * EditorGUILayout.HelpBox("Fur Guides processed. Recompute shell data to use them at runtime.", MessageType.Warning); * } * } */ void MorphSection(NeoFurAsset nfa) { Mesh gm = nfa.mesh; int morphCount = gm.blendShapeCount; if (morphCount <= 0) { EditorGUILayout.HelpBox("Growth mesh contains no morphs...", MessageType.Info); } else { if (nfa.morphWeights == null || nfa.morphWeights.Length != morphCount) { nfa.morphWeights = new float[morphCount]; } string[] choices = new string[morphCount]; EditorGUILayout.HelpBox("Set morphs to desired levels.", MessageType.Info); for (int i = 0; i < morphCount; i++) { choices[i] = gm.GetBlendShapeName(i); } float oldWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth / 2; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); mMorphChoice = EditorGUILayout.Popup(mMorphChoice, choices); EditorGUILayout.PropertyField(morphWeightsProp.GetArrayElementAtIndex(mMorphChoice), Styles.labelMorphTargetWeight); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); EditorGUIUtility.labelWidth = oldWidth; } }
static Material CreateNFAPairFromConfig(string currentFolder, NeoFurConfig config, NeoFurAsset nfa) { Material mat = null; string materialFolder = currentFolder + "/" + MaterialsFolderName; if (!AssetDatabase.IsValidFolder(materialFolder)) { materialFolder = AssetDatabase.CreateFolder(currentFolder, MaterialsFolderName); } // get material profile directory MaterialUtils.MaterialQuality qualityProfile = GetShaderTypeFromConfig(config); string materialProfileFolder = materialFolder + "/" + (m_targetFolderName); if (!AssetDatabase.IsValidFolder(materialProfileFolder)) { materialProfileFolder = AssetDatabase.CreateFolder(materialFolder, m_targetFolderName); } string materialSubName = config.Name.Substring(config.Name.LastIndexOf("_") + 1); string materialName = "MAT_NeoFur_" + materialSubName; Log("=======================================\nCreating mat + nfa: " + materialName); string path = materialProfileFolder + "/" + materialName /* + "_" + config.ShaderType*/ + ".mat"; // apply settings based on config file mat = MaterialUtils.CreateMaterialAsset(path, qualityProfile); ApplyMaterialProperties(mat, config); ApplyComponentProperties(mat, config, nfa); Log("======================================="); return(mat); }
bool TopSection(NeoFurAsset nfa) { EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth / 3; //camera EditorGUILayout.PropertyField(GetSerializedProperty("mData.mSceneCamera"), new GUIContent(Res.Label_SceneCamera, Res.Tooltip_SceneCamera)); if (Application.isPlaying) { return(true); } // try to use the gameobject tagged "main camera" as the default mSceneCamera if (nfa.data.sceneCamera == null && Camera.main != null) { nfa.data.sceneCamera = Camera.main; } if (nfa.renderer && !nfa.overrideRenderer) { EditorGUILayout.HelpBox("Using " + nfa.renderer.GetType().Name + " on this GameObject.", MessageType.Info); } EditorGUILayout.PropertyField(GetSerializedProperty("mOverrideRenderer"), Styles.labelOverrideRenderer, true); HashSet <Type> notSupportedRendererTypes = new HashSet <Type>(); foreach (var target in targets) { NeoFurAsset neoFur = target as NeoFurAsset; if (neoFur.overrideRenderer && !neoFur.RendererIsSupported(neoFur.overrideRenderer)) { notSupportedRendererTypes.Add(neoFur.overrideRenderer.GetType()); neoFur.overrideRenderer = null; } } if (notSupportedRendererTypes.Count > 0) { foreach (var type in notSupportedRendererTypes) { EditorUtility.DisplayDialog(type + " Not Supported", type + "s are not supported. Only MeshRenderer and SkinnedMeshRenderer are supported.", "Ok"); } } EditorGUILayout.PropertyField(GetSerializedProperty("mData.mOverrideGrowthMesh"), Styles.labelGrowthMesh); //early out if main stuff isn't set up if (!nfa.renderer) { EditorGUILayout.HelpBox("No supported renderer on this GameObject and no Override Renderer specified. Add a MeshRenderer and MeshFilter or a SkinnedMeshRenderer to this object, or drag a MeshRenderer or SkinnedMeshRenderer onto the Override Renderer field.", MessageType.Error); return(false); } else if (!nfa.mesh) { EditorGUILayout.HelpBox(nfa.renderer.GetType().Name + " on " + nfa.renderer.gameObject.name + " does not have a mesh. Give the render a mesh, specify an override renderer that does have a mesh, or provide an override growth mesh.", MessageType.Error); return(false); } return(true); }
public override void OnInspectorGUI() { // update serializedObject with NFA's values serializedObject.Update(); FindProperties(); GUILayout.Space(15); projectIssueNotifications.OnGUI(); if (!TopSection(nfa)) { //early out serializedObject.ApplyModifiedProperties(); return; } GUILayout.Space(25); //fur material, only allow changes editor time if (!Application.isPlaying) { EditorGUILayout.PropertyField(matProp, Styles.labelFurryMat); } //fur submesh index //don't allow changing this at game time if (!Application.isPlaying) { EditorGUILayout.PropertyField(subMeshIndexProp, Styles.labelFurSubMesh); } // shell count, fur length, shell fade EditorGUILayout.PropertyField(shellCountProp, Styles.labelShellCount); EditorGUILayout.PropertyField(shellDistanceProp, Styles.labelFurLength); EditorGUILayout.PropertyField(shellDistanceScaleProp, Styles.labelShellFade); EditorGUILayout.PropertyField(shellOffsetProp, Styles.labelShellOffset); GUILayout.Space(25); //Preprocessing foldout //skip if not in editor mode if (!Application.isPlaying) { PreProcessSection(nfa); } bShadowsFolded = NeoGUIHelper.HeaderWithFoldout(Styles.foldoutShadows.text, bShadowsFolded); if (bShadowsFolded) { EditorGUI.indentLevel++; //shadow settings EditorGUILayout.PropertyField(renderSettingsProp, Styles.labelUseRenderSettings); if (!nfa.useRendererSettings) { EditorGUILayout.PropertyField(castShadowProp, Styles.labelShadowCastingMode); EditorGUILayout.PropertyField(receiveShadowsProp, Styles.labelRecieveShadows); } EditorGUI.indentLevel--; } //LOD foldout //In the past here we'd check for an assigned scene camera, as LOD is kind of meaningless //without the ability to check the distance to the camera. But alot of users are setting //up cameras in code, so they need to be able to edit these numbers. { bLODFolded = NeoGUIHelper.HeaderWithFoldout(Styles.foldoutLOD.text, bLODFolded); if (bLODFolded) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(lodStartDistProp, Styles.labelLODStartDist); EditorGUILayout.PropertyField(lodEndDistProp, Styles.labelLODEndDist); EditorGUILayout.PropertyField(lodMinShellCountProp, Styles.labelLODMinShellCount); EditorGUILayout.PropertyField(maxCamDistProp, Styles.labelLODMaxCamDist); //near compression stuff EditorGUILayout.PropertyField(nearCompressionDistProp, Styles.labelNearCompressionDist); EditorGUILayout.PropertyField(nearCompressionMinProp, Styles.labelNearCompressionMin); EditorGUILayout.PropertyField(nearCompressionMaxProp, Styles.labelNearCompressionMax); EditorGUI.indentLevel--; } } // Physics foldout bPhysicsFolded = NeoGUIHelper.HeaderWithFoldout(Styles.foldoutPhysics.text, bPhysicsFolded); if (bPhysicsFolded) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(velocityInfluenceProp, Styles.labelVelocityInfluence); EditorGUILayout.PropertyField(springLenStiffProp, Styles.labelSpringLenStiff); EditorGUILayout.PropertyField(springAngleStiffProp, Styles.labelSpringAngleStiff); EditorGUILayout.PropertyField(springDampMultProp, Styles.labelSpringDampMult); EditorGUILayout.PropertyField(gravityInfluenceProp, Styles.labelGravityInfluence); EditorGUILayout.PropertyField(airResistMultProp, Styles.labelAirResistMult); EditorGUILayout.PropertyField(maxStretchDistMultProp, Styles.labelMaxStretchDistMult); EditorGUILayout.PropertyField(minStretchDistMultProp, Styles.labelMinStretchDistMult); EditorGUILayout.PropertyField(maxRotFromNormalProp, Styles.labelMaxRotFromNormal); EditorGUILayout.PropertyField(radialForceInfluenceProp, Styles.labelRadialForceInfluence); EditorGUILayout.PropertyField(windProp, Styles.labelWind); if (windProp.objectReferenceValue != null) { NeoGUIHelper.PushIndent(); EditorGUILayout.PropertyField(windInfluenceProp, Styles.labelWindInfluence); NeoGUIHelper.PopIndent(); } EditorGUILayout.PropertyField(bendExponentProp, Styles.labelBendExponent); // normal direction blend EditorGUILayout.PropertyField(normalDirectionBlendProp, Styles.labelNormalDirection); EditorGUI.indentLevel--; } // Debug Draw foldout bDebugDrawFolded = NeoGUIHelper.HeaderWithFoldout(Styles.foldoutDebugDraw.text, bDebugDrawFolded); if (bDebugDrawFolded) { NeoFurAsset neoFurAsset = ((NeoFurAsset)target); EditorGUI.indentLevel++; if (neoFurAsset.vertexProcessor != null) { GUILayout.Label($"Average compute time: {(neoFurAsset.vertexProcessor.averageProcessTime*1000).ToString("0.00")}ms"); GUILayout.Label($"Active shells: {(neoFurAsset.lodShellCount)}"); } // debug: draw control points? EditorGUILayout.PropertyField(drawControlPointsProp, Styles.labelDrawControlPoints); // debug: draw fur guides? EditorGUILayout.PropertyField(drawGuidesProp, Styles.labelDrawFurGuides); // if the application is playing, then show the section for debug textures if (Application.isPlaying) { bDebugDrawTexturesFolded = NeoGUIHelper.HeaderWithFoldout(Styles.foldoutDebugDrawTextures.text, bDebugDrawTexturesFolded); if (bDebugDrawTexturesFolded) { int originalIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; if (neoFurAsset.vertexProcessor != null) { repaintDebugTextures = EditorGUILayout.Toggle("Live Update", repaintDebugTextures); neoFurAsset.vertexProcessor.DebugDraw(); } if (repaintDebugTextures) { Repaint(); } EditorGUI.indentLevel = originalIndent; } } EditorGUI.indentLevel--; } // send values from property fields back to NFA serializedObject.ApplyModifiedProperties(); //if runtime, do material editor at the bottom if (Application.isPlaying) { ValidateMaterialEditor(); // only do stuff with the material editor if it was instantiated if (mMatEdit && mMatEdit.target) { GUI.changed = false; EditorGUIUtility.labelWidth = 0; mMatEdit.DrawHeader(); mMatEdit.OnInspectorGUI(); bool didUndo = Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed"; if (GUI.changed || didUndo) { nfa.CreateMaterialInstance(); } } } }
public VertexProcessor(NeoFurAsset neoFurAsset) { this.neoFurAsset = neoFurAsset; filters = new ReadOnlyCollection <VertexFilter>(filterList); }