private void SwitchClip(MorphAnimationClip clip) { _currentClip = clip; if (!_currentClip.Valid) { _updateAnimation = null; MorphDebug.LogError("动画剪辑 " + _currentClip.Name + " 是无效的!", gameObject); return; } if (!_currentClip.Eligible) { _updateAnimation = null; MorphDebug.LogError("动画剪辑 " + _currentClip.Name + " 无法播放,可能其并未拥有至少两个关键帧!", gameObject); return; } _playIndex = 0; _playLocation = 0; if (_currentClip.TransitionClip != -1 && Clips[_currentClip.TransitionClip].Valid && Clips[_currentClip.TransitionClip].Eligible) { _updateAnimation = UpdateAnimationTransition; } else { _updateAnimation = UpdateAnimationLoop; } EventCallBack(_currentClip.Keyframes[_playIndex]); }
private void ReviewClips() { for (int i = 0; i < _morphAnimator.Clips.Count; i++) { if (_morphAnimator.Clips[i].BoneNumber == _skinnedMeshRenderer.bones.Length) { _morphAnimator.Clips[i].Valid = true; } else { _morphAnimator.Clips[i].Valid = false; MorphDebug.LogError(_morphAnimator.Clips[i].Name + " 无效,骨骼数量不与网格匹配!"); } } }
/// <summary> /// 切换动画状态,Change animation state /// </summary> /// <param name="state">要切换到的动画剪辑的名称,Animation clip name</param> public void SwitchState(string state) { if (_skinnedMeshRenderer == null) { _updateAnimation = null; MorphDebug.LogError("物体丢失了 SkinnedMeshRenderer 组件!", gameObject); return; } MorphAnimationClip clip = Clips.Find((c) => { return(c.Name == state); }); if (clip != null) { SwitchClip(clip); } }
private void Start() { if (Clips.Count <= 0) { _updateAnimation = null; MorphDebug.LogError("当前不存在至少一个动画剪辑!", gameObject); return; } _skinnedMeshRenderer = GetComponent <SkinnedMeshRenderer>(); if (_skinnedMeshRenderer == null) { _updateAnimation = null; MorphDebug.LogError("物体丢失了 SkinnedMeshRenderer 组件!", gameObject); return; } SwitchClip(Clips[DefaultClipIndex]); }
private void ClipPropertyGUI() { if (_currentClip != null) { _clipPropertyViewWidth = (int)position.width - 204; Rect rect = new Rect(_clipPropertyViewWidth, 85, 200, _clipPropertyViewHeight); GUI.BeginGroup(rect, new GUIStyle("box")); _clipPropertyViewHeight = 4; if (_isRenameClip) { _newNameClip = GUI.TextField(new Rect(4, _clipPropertyViewHeight, 100, 16), _newNameClip); if (GUI.Button(new Rect(108, _clipPropertyViewHeight, 40, 16), "Sure", "MiniButtonLeft")) { if (MorphEditorTool.ClipNameIsAllow(_morphAnimator.Clips, _newNameClip)) { _currentClip.Name = _newNameClip; _newNameClip = ""; _isRenameClip = false; } else { MorphDebug.LogError("输入的剪辑名字不符合规定或者存在重名!", _skinnedMeshRenderer.gameObject); } } if (GUI.Button(new Rect(148, _clipPropertyViewHeight, 48, 16), "Cancel", "MiniButtonRight")) { _isRenameClip = false; } _clipPropertyViewHeight += 20; } GUI.Label(new Rect(4, _clipPropertyViewHeight, 192, 16), _currentClip.Name, "PreLabel"); _clipPropertyViewHeight += 20; if (GUI.Button(new Rect(4, _clipPropertyViewHeight, 192, 16), "Set Default Clip")) { int index = _morphAnimator.Clips.IndexOf(_currentClip); _morphAnimator.DefaultClipIndex = index; } _clipPropertyViewHeight += 20; GUI.Label(new Rect(4, _clipPropertyViewHeight, 192, 16), "Transition: " + (_currentClip.TransitionClip != -1 ? _morphAnimator.Clips[_currentClip.TransitionClip].Name : "<None>")); _clipPropertyViewHeight += 20; if (GUI.Button(new Rect(4, _clipPropertyViewHeight, 192, 16), "Make Transition")) { GenericMenu gm = new GenericMenu(); for (int i = 0; i < _morphAnimator.Clips.Count; i++) { if (_morphAnimator.Clips[i] != _currentClip) { int si = i; gm.AddItem(new GUIContent(_morphAnimator.Clips[si].Name), si == _currentClip.TransitionClip, () => { _currentClip.TransitionClip = si; }); } } gm.ShowAsContext(); } _clipPropertyViewHeight += 20; GUI.EndGroup(); } }
private void TitleGUI() { GUILayout.BeginHorizontal("Toolbar"); if (GUILayout.Button(_skinnedMeshRenderer.transform.name, "Toolbarbutton", GUILayout.Width(100))) { Selection.activeGameObject = _skinnedMeshRenderer.gameObject; } if (GUILayout.Button(MorphStyle.IconGUIContent("Animation.Record"), "Toolbarbutton")) { _isRecord = !_isRecord; } if (GUILayout.Button(MorphStyle.IconGUIContent("Animation.PrevKey"), "Toolbarbutton")) { if (_currentKeyframe != null) { int index = _currentClip.Keyframes.IndexOf(_currentKeyframe); index -= 1; if (index < 0) { index = _currentClip.Keyframes.Count - 1; } SelectKeyframe(_currentClip.Keyframes[index]); } } MorphEditorTool.SetGUIEnabled(true); if (GUILayout.Toggle(_isPreview, MorphStyle.IconGUIContent("Animation.Play"), "Toolbarbutton") != _isPreview) { _isPreview = !_isPreview; if (_isPreview) { _previewIndex = 0; _previewLocation = 0; if (_currentClip == null || !_currentClip.Eligible) { MorphDebug.LogError("无法预览动画!当前未选中动画剪辑或选中的剪辑关键帧数小于2!", _skinnedMeshRenderer.gameObject); _isPreview = false; } } } MorphEditorTool.SetGUIEnabled(!_isPreview); if (GUILayout.Button(MorphStyle.IconGUIContent("Animation.NextKey"), "Toolbarbutton")) { if (_currentKeyframe != null) { int index = _currentClip.Keyframes.IndexOf(_currentKeyframe); index += 1; if (index >= _currentClip.Keyframes.Count) { index = 0; } SelectKeyframe(_currentClip.Keyframes[index]); } } GUILayout.FlexibleSpace(); if (GUILayout.Button("Create Clip", "Toolbarbutton")) { CreateClip(new Vector2(position.width / 2, position.height / 2)); } if (_currentClip != null) { if (GUILayout.Button("Rename Clip", "Toolbarbutton")) { _isRenameClip = !_isRenameClip; if (_isRenameClip) { _newNameClip = _currentClip.Name; } } if (GUILayout.Button("Delete Clip", "Toolbarbutton")) { if (EditorUtility.DisplayDialog("Prompt", "Whether to delete clip '" + _currentClip.Name + "'?This is unrecoverable.", "Sure", "Cancel")) { DeleteClip(_currentClip); } } } GUILayout.EndHorizontal(); }
private void GenerateMorphController() { if (!_meshFilter.sharedMesh) { MorphDebug.LogError("MeshFilter组件丢失了Mesh数据!", _meshFilter.gameObject); return; } if (!_meshRenderer) { MorphDebug.LogError("GameObject丢失了组件MeshRenderer!", _meshFilter.gameObject); return; } string path = EditorUtility.SaveFilePanel("Save Morph Mesh", Application.dataPath, _meshFilter.sharedMesh.name + "(Morph)", "asset"); if (path.Length != 0) { Collider[] cols = _meshFilter.GetComponents <Collider>(); for (int i = 0; i < cols.Length; i++) { cols[i].enabled = false; } string subPath = path.Substring(0, path.IndexOf("Asset")); path = path.Replace(subPath, ""); Mesh mesh = Instantiate(_meshFilter.sharedMesh); AssetDatabase.CreateAsset(mesh, path); AssetDatabase.SaveAssets(); Mesh meshAsset = AssetDatabase.LoadAssetAtPath(path, typeof(Mesh)) as Mesh; //生成蒙皮网格组件,并创建根骨骼 if (!_skinnedMeshRenderer) { _skinnedMeshRenderer = _meshFilter.transform.gameObject.AddComponent <SkinnedMeshRenderer>(); } _skinnedMeshRenderer.sharedMesh = meshAsset; _skinnedMeshRenderer.rootBone = _meshFilter.transform; _skinnedMeshRenderer.sharedMaterials = _meshRenderer.sharedMaterials; _skinnedMeshRenderer.enabled = true; GameObject boneRoot = new GameObject("BoneRoot"); boneRoot.hideFlags = HideFlags.HideInHierarchy; MorphBone mb = boneRoot.AddComponent <MorphBone>(); mb.hideFlags = HideFlags.HideInInspector; Transform[] bones = new Transform[1]; Matrix4x4[] bindposes = new Matrix4x4[1]; bones[0] = boneRoot.transform; bones[0].SetParent(_skinnedMeshRenderer.rootBone); bones[0].localPosition = Vector3.zero; bones[0].localRotation = Quaternion.identity; bindposes[0] = bones[0].worldToLocalMatrix * _skinnedMeshRenderer.transform.localToWorldMatrix; _skinnedMeshRenderer.bones = bones; _skinnedMeshRenderer.sharedMesh.bindposes = bindposes; //生成网格碰撞器 if (!_meshCollider) { _meshCollider = _meshFilter.transform.gameObject.AddComponent <MeshCollider>(); } _meshCollider.sharedMesh = meshAsset; _meshCollider.enabled = true; //生成变形动画数据组件 if (!_morphAnimationData) { _morphAnimationData = _meshFilter.transform.gameObject.AddComponent <MorphAnimationData>(); } _morphAnimationData.Identity = true; _morphAnimationData.hideFlags = HideFlags.HideInInspector; _morphAnimationData.Vertexs.Clear(); _morphAnimationData.Triangles.Clear(); //处理顶点 List <int> repetitionVertices = new List <int>(); for (int i = 0; i < meshAsset.vertices.Length; i++) { EditorUtility.DisplayProgressBar("Please wait", "Dispose vertices(" + i + "/" + meshAsset.vertices.Length + ")......", 1.0f / meshAsset.vertices.Length * i); if (repetitionVertices.Contains(i)) { continue; } List <int> verticesGroup = new List <int>(); verticesGroup.Add(i); for (int j = i + 1; j < meshAsset.vertices.Length; j++) { if (meshAsset.vertices[i] == meshAsset.vertices[j]) { verticesGroup.Add(j); repetitionVertices.Add(j); } } _morphAnimationData.Vertexs.Add(new MorphVertex(_meshFilter.transform.localToWorldMatrix.MultiplyPoint3x4(meshAsset.vertices[i]), verticesGroup)); } //处理三角面 List <int> allTriangles = new List <int>(meshAsset.triangles); for (int i = 0; (i + 2) < allTriangles.Count; i += 3) { EditorUtility.DisplayProgressBar("Please wait", "Dispose triangles(" + i + "/" + allTriangles.Count + ")......", 1.0f / allTriangles.Count * i); int mv1 = _morphAnimationData.GetVertexIndexByIndex(allTriangles[i]); int mv2 = _morphAnimationData.GetVertexIndexByIndex(allTriangles[i + 1]); int mv3 = _morphAnimationData.GetVertexIndexByIndex(allTriangles[i + 2]); MorphTriangle mt = new MorphTriangle(mv1, mv2, mv3); _morphAnimationData.Triangles.Add(mt); } _morphAnimationData.BindposesPosition.Add(boneRoot.transform.localPosition); _morphAnimationData.BindposesRotation.Add(boneRoot.transform.localRotation); _morphAnimationData.BindposesScale.Add(boneRoot.transform.localScale); EditorUtility.ClearProgressBar(); DestroyImmediate(_meshFilter); DestroyImmediate(_meshRenderer); _skinnedMeshRenderer.transform.parent = null; } }