protected virtual void DrawWavingOptions(FTail_Animator tail) { EditorGUI.indentLevel++; EditorGUILayout.BeginVertical(FEditor_Styles.LBlueBackground); GUILayout.BeginHorizontal(FEditor_Styles.LBlueBackground); drawWavingParams = EditorGUILayout.Foldout(drawWavingParams, "Waving Options", true); GUILayout.FlexibleSpace(); EditorGUIUtility.labelWidth = 90; if (!tail.RootToParent) { EditorGUILayout.PropertyField(sp_useWav); } GUILayout.EndHorizontal(); if (!tail.RootToParent) { if (drawWavingParams) { EditorGUIUtility.labelWidth = 165; GUILayout.Space(5f); EditorGUILayout.PropertyField(sp_cosAd); GUILayout.Space(5f); EditorGUILayout.PropertyField(sp_wavSp); EditorGUILayout.PropertyField(sp_wavRa); GUILayout.Space(5f); EditorGUILayout.PropertyField(sp_wavAx); EditorGUILayout.PropertyField(sp_tailRotOff); } } EditorGUI.indentLevel--; EditorGUILayout.EndVertical(); EditorGUIUtility.labelWidth = 0; }
protected override void DrawSpeedSliders(FTail_AnimatorBase tail) { GUILayout.BeginVertical(FEditor_Styles.LNavy); EditorGUILayout.HelpBox("Elasticity Behaviour Parameters", MessageType.None); EditorGUILayout.Slider(sp_posSpeeds, 0f, 60f); EditorGUILayout.Slider(sp_rotSpeeds, 0f, 60f); GUILayout.EndVertical(); // V1.2 FTail_Animator tailSimple = tail as FTail_Animator; FTail_AnimatorBlending tailBlending = tail as FTail_AnimatorBlending; if (!tailBlending) { if (tailSimple != null) { EditorGUILayout.BeginVertical(FEditor_Styles.GrayBackground); GUILayout.BeginHorizontal(FEditor_Styles.LBlueBackground); EditorGUILayout.HelpBox("Use late update order for animated objects", MessageType.Info); GUILayout.EndHorizontal(); EditorGUILayout.PropertyField(sp_upClock, new GUIContent("Update Order")); EditorGUIUtility.labelWidth = 147; EditorGUILayout.PropertyField(sp_discTransf); EditorGUILayout.PropertyField(sp_queue); EditorGUIUtility.labelWidth = 0; EditorGUILayout.EndVertical(); } } GUILayout.Space(1f); EditorGUIUtility.labelWidth = 0; }
/// <summary> /// Skinning mesh to new skinned mesh renderer with choosed weight markers settings /// </summary> public void SkinMesh(bool addTailAnimator = false) { CalculateVertexDatas(); Vector3 prePos = transform.position; Quaternion preRot = transform.rotation; transform.position = Vector3.zero; transform.rotation = Quaternion.identity; GameObject newSkinObject = new GameObject(name + " [FSKINNED]"); newSkinObject.transform.localScale = transform.localScale; SkinnedMeshRenderer newSkinnedMesh = newSkinObject.AddComponent <SkinnedMeshRenderer>(); Mesh newMesh = Instantiate(GetBaseMesh()); newMesh.name = baseMesh.name + " [FSKINNED]"; newMesh.RecalculateNormals(); newMesh.RecalculateBounds(); newMesh.RecalculateTangents(); MeshRenderer meshRend = GetComponent <MeshRenderer>(); if (meshRend) { newSkinnedMesh.materials = meshRend.sharedMaterials; newSkinnedMesh.sharedMaterials = meshRend.sharedMaterials; } Transform[] bones = new Transform[ghostBones.Length]; Matrix4x4[] bindPoses = new Matrix4x4[ghostBones.Length]; string nameString = ""; if (baseMesh.name.Length < 6) { nameString = baseMesh.name; } else { nameString = baseMesh.name.Substring(0, 5); } for (int i = 0; i < ghostBones.Length; i++) { bones[i] = new GameObject("BoneF-" + nameString + "[" + i + "]").transform; if (i == 0) { bones[i].SetParent(newSkinObject.transform, true); } else { bones[i].SetParent(bones[i - 1], true); } bones[i].transform.position = ghostBones[i].position; bones[i].transform.rotation = ghostBones[i].rotation; bindPoses[i] = bones[i].worldToLocalMatrix * transform.localToWorldMatrix; } BoneWeight[] weights = new BoneWeight[newMesh.vertexCount]; for (int v = 0; v < weights.Length; v++) { weights[v] = new BoneWeight(); } // Calculating and applying weights for verices for (int i = 0; i < vertexDatas.Length; i++) { for (int w = 0; w < vertexDatas[i].weights.Length; w++) { weights[i] = SetWeightIndex(weights[i], w, vertexDatas[i].bonesIndexes[w]); weights[i] = SetWeightToBone(weights[i], w, vertexDatas[i].weights[w]); } } newMesh.bindposes = bindPoses; newMesh.boneWeights = weights; newSkinnedMesh.sharedMesh = newMesh;// (Mesh)AssetDatabase.LoadAssetAtPath(newMeshPath, typeof(Mesh)); newSkinnedMesh.rootBone = bones[0]; newSkinnedMesh.bones = bones; transform.position = prePos; transform.rotation = preRot; newSkinObject.transform.SetParent(transform.parent, true); newSkinObject.transform.position = prePos + Vector3.right; newSkinObject.transform.rotation = preRot; if (addTailAnimator) { FTail_Animator t = bones[0].gameObject.AddComponent <FTail_Animator>(); t.LookUpMethod = FTail_AnimatorBase.FELookUpMethod.Parental; } // Create asset for new model so it not disappear when we create prefab from this gameObject string newMeshPath = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(baseMesh)); AssetDatabase.CreateAsset(newMesh, newMeshPath + "/" + newMesh.name + ".mesh"); AssetDatabase.SaveAssets(); Debug.Log("New skinned mesh '" + newMesh.name + ".mesh" + "' saved under path: '" + newMeshPath + "'"); }
protected virtual void DrawWavingOptions(FTail_Animator tail) { EditorGUI.indentLevel++; EditorGUILayout.BeginVertical(FEditor_Styles.Style(new Color(0.5f, 0.2f, 0.9f, 0.1f))); GUILayout.BeginHorizontal(FEditor_Styles.LBlueBackground); drawWavingParams = EditorGUILayout.Foldout(drawWavingParams, "Waving Options", true); GUILayout.FlexibleSpace(); EditorGUIUtility.labelWidth = 90; if (!tail.RootToParent) { EditorGUILayout.PropertyField(sp_useWav); } GUILayout.EndHorizontal(); if (!tail.RootToParent) { if (drawWavingParams) { EditorGUIUtility.labelWidth = 165; EditorGUILayout.PropertyField(sp_wavType); if (tail.WavingType == FTail_Animator.FEWavingType.Simple) { GUILayout.Space(5f); EditorGUILayout.PropertyField(sp_cosAd); GUILayout.Space(5f); } else { GUILayout.Space(5f); EditorGUILayout.PropertyField(sp_altWave); GUILayout.Space(5f); } EditorGUILayout.PropertyField(sp_wavSp); EditorGUILayout.PropertyField(sp_wavRa); GUILayout.Space(5f); Color preCol = GUI.color; if (tail.WavingType == FTail_Animator.FEWavingType.Advanced) { if (tail.WavingAxis.x == 0f || tail.WavingAxis.y == 0f || tail.WavingAxis.z == 0f) { EditorGUILayout.HelpBox("With advanced waving, try use all axes", MessageType.None); GUI.color = new Color(1f, 1f, 0.8f, 0.95f); } } EditorGUILayout.PropertyField(sp_wavAx); GUI.color = preCol; EditorGUILayout.PropertyField(sp_tailRotOff); } } EditorGUI.indentLevel--; EditorGUILayout.EndVertical(); EditorGUIUtility.labelWidth = 0; }
protected override void DrawSpeedSliders(FTail_AnimatorBase tail) { GUILayout.BeginVertical(FEditor_Styles.LNavy); //EditorGUILayout.HelpBox("Elasticity Behaviour Parameters", MessageType.None); string preStr = "►"; if (drawAnimOptions) { preStr = "▼"; } GUILayout.BeginHorizontal(FEditor_Styles.Style(new Color32(255, 225, 255, 35))); //GUILayout.BeginHorizontal(FEditor_Styles.Style(new Color(0.8f,0.8f,0.8f, 0.45f) )); if (GUILayout.Button(preStr + " Animation & Elasticity Parameters", EditorStyles.miniLabel)) { drawAnimOptions = !drawAnimOptions; } GUILayout.EndHorizontal(); if (drawAnimOptions) { Color preCol = GUI.color; GUIStyle smallStyle = new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic }; GUI.color = new Color(1f, 1f, 1f, 0.7f); EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); GUILayout.Label(" Smooth", smallStyle); GUILayout.FlexibleSpace(); GUILayout.Label("Rapid ", smallStyle); EditorGUILayout.EndHorizontal(); GUILayout.Space(-8f); EditorGUIUtility.labelWidth = 115; GUI.color = preCol; //GUI.color = new Color(0.93f, 1f, 0.93f, 0.9f); EditorGUILayout.PropertyField(sp_posSpeeds); EditorGUILayout.PropertyField(sp_rotSpeeds); GUILayout.Space(2f); EditorGUILayout.EndVertical(); FEditor_Styles.DrawUILine(new Color(0.5f, 0.5f, 0.5f, 0.25f)); //GUILayout.Space(6f); //if ( tail.UseCollision ) if ( tail.LookUpMethod == FTail_AnimatorBase.FELookUpMethod.Parental ) if (tail.Springiness > 0.1f) GUI.color = new Color(0.95f, 0.85f, 0.8f, 0.9f); GUI.color = new Color(1f, 1f, 1f, 0.7f); EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); GUILayout.Label(" Calm", smallStyle); GUILayout.FlexibleSpace(); GUILayout.Label("Bouncy ", smallStyle); EditorGUILayout.EndHorizontal(); GUILayout.Space(-8f); GUI.color = preCol; EditorGUILayout.PropertyField(sp_Springiness); GUI.color = new Color(1f, 1f, 1f, 0.7f); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); GUILayout.Label(" Stiff", smallStyle); GUILayout.FlexibleSpace(); GUILayout.Label("Wavy ", smallStyle); EditorGUILayout.EndHorizontal(); GUI.color = preCol; GUILayout.Space(-8f); EditorGUILayout.EndVertical(); if (tail.UseCollision) { if (tail.LookUpMethod == FTail_AnimatorBase.FELookUpMethod.Parental) { if (tail.Sensitivity < 0.485f || tail.Sensitivity > 0.75f) { GUI.color = new Color(0.95f, 0.85f, 0.8f, 0.9f); } } } EditorGUILayout.PropertyField(sp_Sensitivity); GUI.color = preCol; FEditor_Styles.DrawUILine(new Color(0.5f, 0.5f, 0.5f, 0.25f)); if ((tail.Springiness > 0.5f && tail.MaxStretching > 0.3f)) { GUI.color = new Color(0.8f, 1f, 0.8f, 0.9f); } else if ((tail.AngleLimit < 90 && tail.MaxStretching > 0.2f)) { GUI.color = new Color(1f, 0.8f, 0.8f, 0.9f); } EditorGUILayout.PropertyField(sp_maxDist); GUI.color = preCol; //if (tail.AngleLimit >= 180) GUI.color = preCol * new Color(1f, 1f, 1f, 0.6f); EditorGUILayout.PropertyField(sp_AngleLimit); if (tail.AngleLimit < 90) { //EditorGUI.indentLevel++; if (tail.AngleLimitAxis == Vector3.zero) { GUI.color = preCol * new Color(1f, 1f, 1f, 0.6f); } EditorGUILayout.PropertyField(sp_AngleLimitAxis); GUI.color = preCol; if (tail.AngleLimitAxis != Vector3.zero) { if (tail.LimitAxisRange.x == tail.LimitAxisRange.y) { GUI.color = preCol * new Color(1f, 1f, 1f, 0.6f); } EditorGUILayout.MinMaxSlider(new GUIContent("Range", "If you want limit axes symmetrically leave this parameter unchanged, if you want limit one direction of axis more than reversed, tweak this parameter"), ref tail.LimitAxisRange.x, ref tail.LimitAxisRange.y, -90f, 90f); //EditorGUILayout.PropertyField(sp_AngleLimitAxisTo); GUI.color = preCol; } EditorGUILayout.PropertyField(sp_LimitSmoothing); //EditorGUI.indentLevel--; } GUI.color = preCol; EditorGUILayout.PropertyField(sp_MotionInfluence); EditorGUIUtility.labelWidth = 0; GUILayout.Space(5f); // V1.2 FTail_Animator tailSimple = tail as FTail_Animator; FTail_AnimatorBlending tailBlending = tail as FTail_AnimatorBlending; if (!tailBlending) { if (tailSimple != null) { EditorGUILayout.BeginVertical(FEditor_Styles.GrayBackground); //GUILayout.BeginHorizontal(FEditor_Styles.LBlueBackground); //if (!Application.isPlaying) // EditorGUILayout.HelpBox("Use late update order for animated objects", MessageType.Info); //else //EditorGUILayout.HelpBox(" Use late update order for animated objects", MessageType.None); //GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(FEditor_Styles.LBlueBackground); EditorGUIUtility.labelWidth = 97; EditorGUILayout.PropertyField(sp_upClock, new GUIContent("Update Order")); EditorGUIUtility.labelWidth = 0; if (!Application.isPlaying) { if (tail.UpdateClock != EFUpdateClock.LateUpdate) { GUILayout.FlexibleSpace(); GUI.color = new Color(1f, 1f, 1f, 0.7f); float width = (float)typeof(EditorGUIUtility).GetProperty("contextWidth", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).GetValue(null, null); if (width > 375) { GUILayout.Label(new GUIContent("Use LateUpdate for animated objects", "Use LateUpdate order for animated objects (animated by unity Animator or Animation components) or use FTail_AnimatorBlending component instead of FTail_Animator"), smallStyle); } else if (width > 310) { GUILayout.Label(new GUIContent("Use LateUpdate for...", "Use LateUpdate order for animated objects (animated by unity Animator or Animation components) or use FTail_AnimatorBlending component instead of FTail_Animator"), smallStyle); } else { GUILayout.Label(new GUIContent("Put Cursor Here", "(Tooltip) Use LateUpdate order for animated objects (animated by unity Animator or Animation components) or use FTail_AnimatorBlending component instead of FTail_Animator"), smallStyle); } GUI.color = preCol; } } GUILayout.EndHorizontal(); if (!Application.isPlaying) { EditorGUIUtility.labelWidth = 147; EditorGUILayout.PropertyField(sp_queue); } EditorGUIUtility.labelWidth = 0; EditorGUILayout.EndVertical(); } } GUILayout.Space(1f); EditorGUIUtility.labelWidth = 0; } GUILayout.EndVertical(); }
protected void DrawTailList(FTail_AnimatorBase tail) { GUILayout.BeginHorizontal(FEditor_Styles.BlueBackground); // Long text as tooltip to save space in inspectors EditorGUILayout.LabelField(new GUIContent("ENTER HERE FOR INFO TOOLTIP (no in playmode)", "Put under 'Tail Bones' first bone of tail - component will use children transform to get rest tail bones, or left empty, then tail structure will be created starting from this transform, also you can put here for example 3 bones so only this transforms will be animated")); GUILayout.EndHorizontal(); // Extra info for Tail bones array viewer string extraInfo = ""; bool red = false; if (tail.TailTransforms == null) { tail.TailTransforms = new System.Collections.Generic.List <Transform>(); } if (tail.TailTransforms.Count > 0) { if (tail.TailTransforms[0] == null) { extraInfo = " - NULL BONE!"; red = true; } else if (tail.TailTransforms.Count == 1) { if (tail.AutoGetWithOne) { if (drawTailBones) { extraInfo = " (1 - Auto Get)"; } else { extraInfo = " (1 - Auto Child Transforms)"; } } else { extraInfo = " (Only one bone)"; } } else { bool nullDetected = false; for (int i = 1; i < tail.TailTransforms.Count; i++) { if (tail.TailTransforms[i] == null) { nullDetected = true; break; } } if (nullDetected) { extraInfo = " (SOME NULLS!)"; red = true; } } } else { if (drawTailBones) { extraInfo = " (No Bone - Auto Get)"; } else { extraInfo = " (No Bone - Auto Get)"; } } if (extraInfo == "") { extraInfo = " (" + tail.TailTransforms.Count + ")"; } if (red) { GUILayout.BeginVertical(FEditor_Styles.RedBackground); } else { GUILayout.BeginVertical(FEditor_Styles.GrayBackground); } GUILayout.BeginHorizontal(); EditorGUI.indentLevel++; drawTailBones = EditorGUILayout.Foldout(drawTailBones, "Tail Bones" + extraInfo, true); if (tail.TailTransforms.Count == 1) { EditorGUILayout.PropertyField(sp_autoone, new GUIContent("", "When you want to use auto get when you assigning one bone inside inspector window (Not working with waving - then you have to rotate parent transform in your own way to get same effect)"), new GUILayoutOption[2] { GUILayout.MaxWidth(28), GUILayout.MaxHeight(18) }); } if (drawTailBones) { DrawAddTailButtons(tail); GUILayout.EndHorizontal(); EditorGUI.indentLevel++; for (int i = 0; i < tail.TailTransforms.Count; i++) { tail.TailTransforms[i] = (Transform)EditorGUILayout.ObjectField("Tail Bone [" + i + "]", tail.TailTransforms[i], typeof(Transform), true); } EditorUtility.SetDirty(target); EditorGUI.indentLevel--; } else { if (tail.TailTransforms.Count == 0) { DrawAddTailButtons(tail); } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUILayout.BeginVertical(FEditor_Styles.GrayBackground); EditorGUIUtility.labelWidth = 155; EditorGUILayout.PropertyField(sp_rootp); EditorGUIUtility.labelWidth = 0; GUILayout.EndVertical(); if (tail.RootToParent != wasRoot) { if (tail.RootToParent) { tail.LookUpMethod = FTail_AnimatorBase.FELookUpMethod.Parental; foreach (var s in Selection.gameObjects) { if (s == tail.gameObject) { continue; } FTail_Animator b = s.GetComponent <FTail_Animator>(); if (b) { bool enabledIs = false; if (b.RootToParent) { if (b.LookUpMethod == FTail_AnimatorBase.FELookUpMethod.Default) { enabledIs = true; } } if (enabledIs) { b.LookUpMethod = FTail_AnimatorBase.FELookUpMethod.Parental; } } } } } wasRoot = tail.RootToParent; GUILayout.Space(1f); EditorGUI.indentLevel--; EditorGUIUtility.labelWidth = 0; }