private void PlayAnimation() { if (!string.IsNullOrEmpty(SplineDataOnPlay.Skin)) { SkeletoAnimation.skeleton.SetSkin(SplineDataOnPlay.Skin); } else { SkeletoAnimation.skeleton.SetSkin("default"); } SkeletoAnimation.Update(); SkeletoAnimation.state.SetAnimation(0, SplineDataOnPlay.AnimationName, SplineDataOnPlay.Loop); }
private void UpdateInternal() { var skeleton = SkeletonAnimation.skeleton; skeleton.SetSkin(_clonedSkin); skeleton.SetSlotsToSetupPose(); SkeletonAnimation.Update(0); }
public override void ProcessFrame(Playable playable, FrameData info, object playerData) { SkeletonAnimation spineComponent = playerData as SkeletonAnimation; if (spineComponent != null) { Skeleton skeleton = spineComponent.Skeleton; Spine.AnimationState animationState = spineComponent.AnimationState; if (!Application.isPlaying) { this.PreviewEditModePose(playable, spineComponent); } else { int inputCount = playable.GetInputCount <Playable>(); if ((this.lastInputWeights == null) || (this.lastInputWeights.Length < inputCount)) { this.lastInputWeights = new float[inputCount]; for (int j = 0; j < inputCount; j++) { this.lastInputWeights[j] = 0f; } } float[] lastInputWeights = this.lastInputWeights; for (int i = 0; i < inputCount; i++) { float num4 = lastInputWeights[i]; float inputWeight = playable.GetInputWeight <Playable>(i); bool flag = inputWeight > num4; lastInputWeights[i] = inputWeight; if (flag) { SpineAnimationStateBehaviour behaviour = ((ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput <Playable>(i)).GetBehaviour(); if (behaviour.animationReference == null) { float mixDuration = !behaviour.customDuration ? animationState.Data.DefaultMix : behaviour.mixDuration; animationState.SetEmptyAnimation(0, mixDuration); } else if (behaviour.animationReference.Animation != null) { TrackEntry entry = animationState.SetAnimation(0, behaviour.animationReference.Animation, behaviour.loop); entry.EventThreshold = behaviour.eventThreshold; entry.DrawOrderThreshold = behaviour.drawOrderThreshold; entry.AttachmentThreshold = behaviour.attachmentThreshold; if (behaviour.customDuration) { entry.MixDuration = behaviour.mixDuration; } } spineComponent.Update(0f); spineComponent.LateUpdate(); } } } } }
private void DoRenderPreview(bool drawHandles) { GameObject go = this.m_previewInstance; if (m_requireRefresh && go != null) { go.GetComponent <Renderer>().enabled = true; if (EditorApplication.isPlaying) { //do nothing } else { m_skeletonAnimation.Update((Time.realtimeSinceStartup - m_lastTime)); } m_lastTime = Time.realtimeSinceStartup; if (!EditorApplication.isPlaying) { m_skeletonAnimation.LateUpdate(); } if (drawHandles) { Handles.SetCamera(m_previewUtility.camera); Handles.color = m_originColor; Handles.DrawLine(new Vector3(-1000 * m_skeletonDataAsset.scale, 0, 0), new Vector3(1000 * m_skeletonDataAsset.scale, 0, 0)); Handles.DrawLine(new Vector3(0, 1000 * m_skeletonDataAsset.scale, 0), new Vector3(0, -1000 * m_skeletonDataAsset.scale, 0)); } this.m_previewUtility.camera.Render(); if (drawHandles) { Handles.SetCamera(m_previewUtility.camera); foreach (var slot in m_skeletonAnimation.skeleton.Slots) { var boundingBoxAttachment = slot.Attachment as BoundingBoxAttachment; if (boundingBoxAttachment != null) { DrawBoundingBox(slot.Bone, boundingBoxAttachment); } } } go.GetComponent <Renderer>().enabled = false; } }
public void ResetAnimation() { if (compAnimation.Skeleton == null) { compAnimation.Reset(); } compAnimation.state.SetAnimation(0, "combo", false).Time = 0; compAnimation.Update(0); compAnimation.state.SetAnimation(0, "combo", false).Time = 0; }
public void DoRenderPreview(bool drawHandles) { if (this.PreviewUtilityCamera.activeTexture == null || this.PreviewUtilityCamera.targetTexture == null) { return; } GameObject go = previewGameObject; if (requiresRefresh && go != null) { go.GetComponent <Renderer>().enabled = true; if (!EditorApplication.isPlaying) { skeletonAnimation.Update((Time.realtimeSinceStartup - animationLastTime)); } animationLastTime = Time.realtimeSinceStartup; if (!EditorApplication.isPlaying) { skeletonAnimation.LateUpdate(); } var thisPreviewUtilityCamera = this.PreviewUtilityCamera; if (drawHandles) { Handles.SetCamera(thisPreviewUtilityCamera); Handles.color = OriginColor; float scale = skeletonDataAsset.scale; Handles.DrawLine(new Vector3(-1000 * scale, 0, 0), new Vector3(1000 * scale, 0, 0)); Handles.DrawLine(new Vector3(0, 1000 * scale, 0), new Vector3(0, -1000 * scale, 0)); } thisPreviewUtilityCamera.Render(); if (drawHandles) { Handles.SetCamera(thisPreviewUtilityCamera); SpineHandles.DrawBoundingBoxes(skeletonAnimation.transform, skeletonAnimation.skeleton); if (SkeletonDataAssetInspector.showAttachments) { SpineHandles.DrawPaths(skeletonAnimation.transform, skeletonAnimation.skeleton); } } go.GetComponent <Renderer>().enabled = false; } }
void DoRenderPreview(bool drawHandles) { if (this.PreviewUtilityCamera.activeTexture == null || this.PreviewUtilityCamera.targetTexture == null) { return; } GameObject go = this.m_previewInstance; if (m_requireRefresh && go != null) { go.GetComponent <Renderer>().enabled = true; if (!EditorApplication.isPlaying) { m_skeletonAnimation.Update((Time.realtimeSinceStartup - m_lastTime)); } m_lastTime = Time.realtimeSinceStartup; if (!EditorApplication.isPlaying) { m_skeletonAnimation.LateUpdate(); } var c = this.PreviewUtilityCamera; if (drawHandles) { Handles.SetCamera(c); Handles.color = m_originColor; Handles.DrawLine(new Vector3(-1000 * m_skeletonDataAsset.scale, 0, 0), new Vector3(1000 * m_skeletonDataAsset.scale, 0, 0)); Handles.DrawLine(new Vector3(0, 1000 * m_skeletonDataAsset.scale, 0), new Vector3(0, -1000 * m_skeletonDataAsset.scale, 0)); } c.Render(); if (drawHandles) { Handles.SetCamera(c); SpineHandles.DrawBoundingBoxes(m_skeletonAnimation.transform, m_skeletonAnimation.skeleton); if (showAttachments) { SpineHandles.DrawPaths(m_skeletonAnimation.transform, m_skeletonAnimation.skeleton); } } go.GetComponent <Renderer>().enabled = false; } }
/// <summary> /// 反向播放spine动画 /// </summary> /// <returns>The play action.</returns> /// <param name="anim">Animation.</param> /// <param name="name">Name.</param> /// <param name="loop">If set to <c>true</c> loop.</param> /// <param name="sc">Sc.</param> public static TrackEntry RevertPlayAction(SkeletonAnimation anim, string name, bool loop = true, float sc = 1f) { if (anim != null && anim.state != null) { TrackEntry t = anim.state.SetAnimation(0, name, loop); float time = anim.Skeleton.Data.FindAnimation(name).Duration; anim.Update(time); if (anim.timeScale != sc) { anim.timeScale = sc; } return(t); } return(null); }
private void refreshAnimation() { if (_skeletonAnimation == null) { return; } if (!_skeletonAnimation.valid) { return; } if (!isInspectingPrefab) { if (_wasAnimationNameChanged) { if (_skeletonAnimation.state != null) { _skeletonAnimation.state.ClearTrack(0); } _skeletonAnimation.skeleton.SetToSetupPose(); Spine.Animation animationToUse = _skeletonAnimation.skeleton.Data.FindAnimation(animationName.stringValue); if (animationToUse != null) { Spine.SkeletonExtensions.PoseSkeleton(animationToUse, _skeletonAnimation.Skeleton, 0f); } _skeletonAnimation.Update(0); _skeletonAnimation.LateUpdate(); SceneView.RepaintAll(); _curFrameIndex = 0; _wasAnimationNameChanged = false; } } }
public static void ShowSpineAnim(this GameObject go, string animName, bool loop = false, float startTime = 0) { SkeletonAnimation anim = go.GetComponentInChildren <SkeletonAnimation> (); if (anim == null) { return; } anim.AnimationName = null; anim.loop = loop; anim.skeleton.SetToSetupPose(); anim.AnimationName = animName; anim.Update(startTime); anim.LateUpdate(); anim.LateUpdate(); }
public void OnEditorUpdateEvent(float time) { if (_animation == null || _animation.state == null) { return; } var track = _animation.state.GetCurrent(0); if (track == null) { return; } track.Time = time; _animation.Update(0); }
public void SetPerformerSkillAnimationOverriden(SkillArtInfo skillInfo, string mode, bool activate) { SkeletonAnimation skillAnimation = unitAnimator.Effects.Find(item => item.name == skillInfo.ArtId); if (skillAnimation != null) { skillAnimation.gameObject.layer = CurrentState.gameObject.layer; skillAnimation.gameObject.SetActive(activate); if (activate) { skillAnimation.Reset(); skillAnimation.state.SetAnimation(0, skillInfo.ArtId + "_" + mode, false).Time = 0; skillAnimation.Update(0); skillAnimation.AnimationName = skillInfo.ArtId + "_" + mode; } } unitAnimator.Animator.SetBool(skillInfo.AnimationId + "_" + mode, activate); }
public void ShowBattleAnnouncment() { battleAnnouncment.gameObject.SetActive(true); if (battleAnnouncment.state.GetCurrent(0) != null) { battleAnnouncment.Skeleton.SetToSetupPose(); battleAnnouncment.AnimationName = "start"; battleAnnouncment.state.GetCurrent(0).Time = 0; battleAnnouncment.state.SetAnimation(0, "start", false).Time = 0; battleAnnouncment.Update(0); } else { battleAnnouncment.Skeleton.SetToSetupPose(); battleAnnouncment.AnimationName = "start"; battleAnnouncment.state.SetAnimation(0, "start", false); } }
/// <summary> /// 换装备并且合并材质球 /// </summary> /// <param name="skeletonAnimation">spine 组件</param> /// <param name="atlasAsset"> 图片+atlas 生成的图集文件 </param> /// <param name="regionName"> 图集文件中的具体的一张图片 最好一个图片一个图集 </param> /// <param name="e"> 装备类型 </param> public void ExchangeEquipmentAndMerge(SkeletonAnimation skeletonAnimation, List <EquipmentItem> infos) { for (int i = 0; i < infos.Count; i++) { EquipmentItem info = infos[i]; string regionName = info.equipmentImageName; string defaultSkinName = info.defaultSkinName; string spineEquipmentType = info.spineEquipmentTypeName; AssetBundlePackage assetbundle = HFResourceManager.Instance.LoadAssetBundleFromFile(info.equipmentAssetbundleName); AtlasAsset atlasAsset = assetbundle.LoadAssetWithCache <AtlasAsset>(info.equipmentAtlasAssetName); float scale = skeletonAnimation.skeletonDataAsset.scale; Atlas atlas = atlasAsset.GetAtlas(); AtlasRegion region = atlas.FindRegion(regionName); Slot slot = skeletonAnimation.skeleton.FindSlot(info.slotName); Attachment originalAttachment = slot.Attachment; if (region == null) { slot.Attachment = null; } else if (originalAttachment != null) { slot.Attachment = originalAttachment.GetRemappedClone(region, true, true, 1); } else { var newRegionAttachment = region.ToRegionAttachment(region.name, scale); slot.Attachment = newRegionAttachment; } slot.Skeleton.Skin.SetAttachment(slot.Data.Index, info.slotPlaceholderName, slot.Attachment); } Skin repackedSkin = new Skin(RepackConst); repackedSkin.Append(skeletonAnimation.Skeleton.Data.DefaultSkin); // Include the "default" skin. (everything outside of skin placeholders) repackedSkin.Append(skeletonAnimation.Skeleton.Skin); // Include your new custom skin. Texture2D runtimeAtlas = null; Material runtimeMaterial = null; repackedSkin = repackedSkin.GetRepackedSkin(RepackConst, skeletonAnimation.SkeletonDataAsset.atlasAssets[0].materials[0], out runtimeMaterial, out runtimeAtlas); // Pack all the items in the skin. skeletonAnimation.Skeleton.SetSkin(repackedSkin); // Assign the repacked skin to your Skeleton. skeletonAnimation.skeleton.SetSlotsToSetupPose(); // Use the pose from setup pose. skeletonAnimation.Update(0); // Use the pose in the currently active animation. }
private void Apply() { SkeletonAnimation component = base.GetComponent <SkeletonAnimation>(); Skeleton skeleton = component.Skeleton; if (this.customSkin == null) { } this.customSkin = new Skin("custom skin"); Skin skin = skeleton.Data.FindSkin(this.templateAttachmentsSkin); int slotIndex = skeleton.FindSlotIndex(this.visorSlot); Attachment attachment = skin.GetAttachment(slotIndex, this.visorKey).GetRemappedClone(this.visorSprite, this.sourceMaterial, true, true, false); this.customSkin.SetAttachment(slotIndex, this.visorKey, attachment); int num2 = skeleton.FindSlotIndex(this.gunSlot); Attachment attachment4 = skin.GetAttachment(num2, this.gunKey).GetRemappedClone(this.gunSprite, this.sourceMaterial, true, true, false); if (attachment4 != null) { this.customSkin.SetAttachment(num2, this.gunKey, attachment4); } if (this.repack) { Skin destination = new Skin("repacked skin"); destination.Append(skeleton.Data.DefaultSkin); destination.Append(this.customSkin); destination = destination.GetRepackedSkin("repacked skin", this.sourceMaterial, out this.runtimeMaterial, out this.runtimeAtlas, 0x400, 2, TextureFormat.RGBA32, false, true); skeleton.SetSkin(destination); if (this.bbFollower != null) { this.bbFollower.Initialize(true); } } else { skeleton.SetSkin(this.customSkin); } skeleton.SetSlotsToSetupPose(); component.Update(0f); Resources.UnloadUnusedAssets(); }
private void DoRenderPreview(bool drawHandles) { GameObject go = this.m_previewInstance; if (m_requireRefresh) { go.renderer.enabled = true; if (EditorApplication.isPlaying) { //do nothing } else { m_skeletonAnimation.Update((Time.realtimeSinceStartup - m_lastTime)); } m_lastTime = Time.realtimeSinceStartup; if (!EditorApplication.isPlaying) { m_skeletonAnimation.LateUpdate(); } if (drawHandles) { Handles.SetCamera(m_previewUtility.m_Camera); Handles.color = m_originColor; Handles.DrawLine(new Vector3(-1000 * m_skeletonDataAsset.scale, 0, 0), new Vector3(1000 * m_skeletonDataAsset.scale, 0, 0)); Handles.DrawLine(new Vector3(0, 1000 * m_skeletonDataAsset.scale, 0), new Vector3(0, -1000 * m_skeletonDataAsset.scale, 0)); } this.m_previewUtility.m_Camera.Render(); go.renderer.enabled = false; } }
//进行绘制 private void RenderPreview() { if (this.previewUtilityCamera.activeTexture == null || this.previewUtilityCamera.targetTexture == null) { return; } if (_requireRefresh && _previewGameObject != null) { var renderer = _previewGameObject.GetComponent <Renderer>(); renderer.enabled = true; if (EditorApplication.isPlaying != true) { //在编辑器模式下代替Time.DeltaTime float current = currentTime; float deltaTime = current - _lastANimationTime; _skeletonAnimation.Update(deltaTime); _lastANimationTime = current; } previewUtilityCamera.Render(); //不关的话物体会显示在场景中 renderer.enabled = false; } }
void Apply() { SkeletonAnimation skeletonAnimation = GetComponent <SkeletonAnimation>(); Skeleton skeleton = skeletonAnimation.skeleton; SkeletonData skeletonData = skeleton.Data; // Get the template skin. Prepare the custom skin. Skin templateSkin = skeletonData.FindSkin(templateSkinName); Skin currentEquipsSkin = new Skin("my custom skin"); // BODY SETUP if (bodySprite) { int bodySlotIndex = skeleton.FindSlotIndex(bodySlot); Attachment templateBody = templateSkin.GetAttachment(bodySlotIndex, bodyKey); Attachment newBody = templateBody.GetRemappedClone(bodySprite, sourceMaterial); if (newBody != null) { currentEquipsSkin.SetAttachment(bodySlotIndex, bodyKey, newBody); } } // HAIR SETUP if (hairSprite) { int hairSlotIndex = skeleton.FindSlotIndex(hairSlot); Attachment templateHair = templateSkin.GetAttachment(hairSlotIndex, hairKey); Attachment newHair = templateHair.GetRemappedClone(hairSprite, sourceMaterial); if (newHair != null) { currentEquipsSkin.SetAttachment(hairSlotIndex, hairKey, newHair); } } // EYE SETUP if (eyeSprite) { int eyeSlotIndex = skeleton.FindSlotIndex(eyeSlot); Attachment templateEye = templateSkin.GetAttachment(eyeSlotIndex, eyeKey); Attachment newEye = templateEye.GetRemappedClone(eyeSprite, sourceMaterial); if (newEye != null) { currentEquipsSkin.SetAttachment(eyeSlotIndex, eyeKey, newEye); } } // MOUTH SETUP if (mouthSprite) { int mouthSlotsIndex = skeleton.FindSlotIndex(mouthSlot); Attachment templateMouth = templateSkin.GetAttachment(mouthSlotsIndex, mouthKey); Attachment newMouth = templateMouth.GetRemappedClone(mouthSprite, sourceMaterial); if (newMouth != null) { currentEquipsSkin.SetAttachment(mouthSlotsIndex, mouthKey, newMouth); } } // ACC SETUP if (accSprite) { int accSlotsIndex = skeleton.FindSlotIndex(accSlot); Attachment templateAcc = templateSkin.GetAttachment(accSlotsIndex, accKey); Attachment newAcc = templateAcc.GetRemappedClone(accSprite, sourceMaterial); if (newAcc != null) { currentEquipsSkin.SetAttachment(accSlotsIndex, accKey, newAcc); } } // SHIRT SETUP if (shirtSprite) { int shirtSlotsIndex = skeleton.FindSlotIndex(shirtSlot); Attachment templateShirt = templateSkin.GetAttachment(shirtSlotsIndex, shirtKey); Attachment newShirt = templateShirt.GetRemappedClone(shirtSprite, sourceMaterial); if (newShirt != null) { currentEquipsSkin.SetAttachment(shirtSlotsIndex, shirtKey, newShirt); } } // //PANTS SETUP if (pantsSprite) { int pantsSlotIndex = skeleton.FindSlotIndex(pantsSlot); Attachment templatePants = templateSkin.GetAttachment(pantsSlotIndex, pantsKey); Attachment newPants = templatePants.GetRemappedClone(pantsSprite, sourceMaterial); if (newPants != null) { currentEquipsSkin.SetAttachment(pantsSlotIndex, pantsKey, newPants); } } // SHOE SETUP if (shoeSprite) { int shoeSlotsIndex = skeleton.FindSlotIndex(shoeSlot); Attachment templateShoe = templateSkin.GetAttachment(shoeSlotsIndex, showKey); Attachment newShoe = templateShoe.GetRemappedClone(shoeSprite, sourceMaterial); if (newShoe != null) { currentEquipsSkin.SetAttachment(shoeSlotsIndex, showKey, newShoe); } } // Set and apply the Skin to the skeleton. skeleton.SetSkin(currentEquipsSkin); skeleton.SetSlotsToSetupPose(); skeletonAnimation.Update(0); Resources.UnloadUnusedAssets(); }
protected override void DrawInspectorGUI() { base.DrawInspectorGUI(); SkeletonAnimation component = (SkeletonAnimation)target; if (!component.valid) { return; } if (wasAnimationNameChanged) { if (!Application.isPlaying) { if (component.state != null) { component.state.ClearTrack(0); } component.skeleton.SetToSetupPose(); } Spine.Animation animationToUse = component.skeleton.Data.FindAnimation(animationName.stringValue); if (!Application.isPlaying) { if (animationToUse != null) { animationToUse.Apply(component.skeleton, 0f, 0f, false, null); } component.Update(); component.LateUpdate(); SceneView.RepaintAll(); } else { if (animationToUse != null) { component.state.SetAnimation(0, animationToUse, loop.boolValue); } else { component.state.ClearTrack(0); } } wasAnimationNameChanged = false; } // Reflect animationName serialized property in the inspector even if SetAnimation API was used. if (Application.isPlaying) { TrackEntry current = component.state.GetCurrent(0); if (current != null) { if (component.AnimationName != animationName.stringValue) { animationName.stringValue = current.Animation.Name; } } } EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(animationName); wasAnimationNameChanged |= EditorGUI.EndChangeCheck(); EditorGUILayout.PropertyField(loop); EditorGUILayout.PropertyField(timeScale); component.timeScale = Math.Max(component.timeScale, 0); EditorGUILayout.Space(); if (!m_isPrefab) { if (component.GetComponent <SkeletonUtility>() == null) { if (GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))) { component.gameObject.AddComponent <SkeletonUtility>(); } } } }
protected void TrySetAnimation(SkeletonAnimation skeletonAnimation) { if (skeletonAnimation == null) { return; } if (!skeletonAnimation.valid) { return; } TrackEntry current = skeletonAnimation.AnimationState.GetCurrent(0); if (!isInspectingPrefab) { string activeAnimation = (current != null) ? current.Animation.Name : null; bool wasAnimationNameChanged = activeAnimation != animationName.stringValue; if (wasAnimationNameChanged) { var skeleton = skeletonAnimation.Skeleton; var state = skeletonAnimation.AnimationState; if (!Application.isPlaying) { if (state != null) { state.ClearTrack(0); } skeleton.SetToSetupPose(); } Spine.Animation animationToUse = skeleton.Data.FindAnimation(animationName.stringValue); if (!Application.isPlaying) { if (animationToUse != null) { skeletonAnimation.AnimationState.SetAnimation(0, animationToUse, loop.boolValue); } skeletonAnimation.Update(0); skeletonAnimation.LateUpdate(); requireRepaint = true; } else { if (animationToUse != null) { state.SetAnimation(0, animationToUse, loop.boolValue); } else { state.ClearTrack(0); } } } // Reflect animationName serialized property in the inspector even if SetAnimation API was used. if (Application.isPlaying) { if (current != null) { if (skeletonAnimation.AnimationName != animationName.stringValue) { animationName.stringValue = current.Animation.Name; } } } } }
override public void OnInspectorGUI() { serializedObject.Update(); SkeletonAnimation component = (SkeletonAnimation)target; EditorGUILayout.PropertyField(skeletonDataAsset); if (component.skeleton != null) { // Initial skin name. String[] skins = new String[component.skeleton.Data.Skins.Count]; int skinIndex = 0; for (int i = 0; i < skins.Length; i++) { String name = component.skeleton.Data.Skins[i].Name; skins[i] = name; if (name == initialSkinName.stringValue) { skinIndex = i; } } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Initial Skin"); EditorGUIUtility.LookLikeControls(); skinIndex = EditorGUILayout.Popup(skinIndex, skins); EditorGUILayout.EndHorizontal(); initialSkinName.stringValue = skins[skinIndex]; // Animation name. String[] animations = new String[component.skeleton.Data.Animations.Count + 1]; animations[0] = "<None>"; int animationIndex = 0; for (int i = 0; i < animations.Length - 1; i++) { String name = component.skeleton.Data.Animations[i].Name; animations[i + 1] = name; if (name == animationName.stringValue) { animationIndex = i + 1; } } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Animation"); EditorGUIUtility.LookLikeControls(); animationIndex = EditorGUILayout.Popup(animationIndex, animations); EditorGUILayout.EndHorizontal(); if (animationIndex == 0) { component.animationName = null; } else { component.animationName = animations[animationIndex]; } } // Animation loop. EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Loop"); loop.boolValue = EditorGUILayout.Toggle(loop.boolValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.PropertyField(timeScale); EditorGUILayout.PropertyField(normals); EditorGUILayout.PropertyField(tangents); if (serializedObject.ApplyModifiedProperties() || (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed") ) { if (!Application.isPlaying) { component.Clear(); component.Update(); } } }