private void SetAnimation(CharacterAnimation index, string animationName, string sceneName) { // Load the DAE using SCNSceneSource in order to be able to retrieve the animation by its identifier var sceneURL = NSUrl.FromFilename(NSBundle.MainBundle.PathForResource("Scenes.scnassets/boss/" + sceneName, "dae")); var sceneSource = SCNSceneSource.FromUrl(sceneURL, (NSDictionary)null); var bossAnimation = (CAAnimation)sceneSource.GetEntryWithIdentifier(animationName, new Class("CAAnimation")); Animations [(int)index] = bossAnimation; // Blend animations for smoother transitions bossAnimation.FadeInDuration = 0.3f; bossAnimation.FadeOutDuration = 0.3f; if (index == CharacterAnimation.Attack) { // Create an animation event and set it to the animation var attackSoundEvent = new SCNAnimationEventHandler((CAAnimation animation, NSObject animatedObject, bool playingBackward) => { InvokeOnMainThread(delegate { var soundUrl = NSUrl.FromFilename(NSBundle.MainBundle.PathForResource("Sounds/attack4", "wav")); new NSSound(soundUrl, false).Play(); }); }); bossAnimation.AnimationEvents = new SCNAnimationEvent[] { SCNAnimationEvent.Create(0.4f, attackSoundEvent) }; } }
private void ExtractAnimation(SCNSceneSource sceneSource) { // In this scene objects are animated separately using long animations // playing 3 successive animations. We will group these long animations // and then split the group in 3 different animation groups. // We could also have used three DAEs (one per animation). var animationIDs = sceneSource.GetIdentifiersOfEntries(new Class("CAAnimation")); var animationCount = animationIDs.Length; var longAnimations = new CAAnimation [animationCount]; var maxDuration = 0.0; for (var index = 0; index < animationCount; index++) { var animation = (CAAnimation)sceneSource.GetEntryWithIdentifier(animationIDs [index].ToString(), new Class("CAAnimation")); if (animation != null) { maxDuration = Math.Max(maxDuration, animation.Duration); longAnimations [index] = animation; } } var longAnimationsGroup = new CAAnimationGroup(); longAnimationsGroup.Animations = longAnimations; longAnimationsGroup.Duration = maxDuration; var idleAnimationGroup = (CAAnimationGroup)longAnimationsGroup.Copy(); idleAnimationGroup.TimeOffset = 6.45833333333333f; IdleAnimationGroup = CAAnimationGroup.CreateAnimation(); IdleAnimationGroup.Animations = new CAAnimation[] { idleAnimationGroup }; IdleAnimationGroup.Duration = 24.71f - 6.45833333333333f; IdleAnimationGroup.RepeatCount = float.MaxValue; IdleAnimationGroup.AutoReverses = true; var animationGroup1 = (CAAnimationGroup)longAnimationsGroup.Copy(); AnimationGroup1 = CAAnimationGroup.CreateAnimation(); AnimationGroup1.Animations = new CAAnimation[] { animationGroup1 }; AnimationGroup1.Duration = 1.4f; AnimationGroup1.FadeInDuration = 0.1f; AnimationGroup1.FadeOutDuration = 0.5f; var animationGroup2 = (CAAnimationGroup)longAnimationsGroup.Copy(); animationGroup2.TimeOffset = 3.666666666666667f; AnimationGroup2 = CAAnimationGroup.CreateAnimation(); AnimationGroup2.Animations = new CAAnimation[] { animationGroup2 }; AnimationGroup2.Duration = 6.416666666666667f - 3.666666666666667f; AnimationGroup2.FadeInDuration = 0.1f; AnimationGroup2.FadeOutDuration = 0.5f; }
public static CAAnimation LoadAnimationNamed (string animationName, string sceneName) { NSUrl url = NSBundle.MainBundle.GetUrlForResource (sceneName, "dae"); var options = new SCNSceneLoadingOptions () { ConvertToYUp = true }; var sceneSource = new SCNSceneSource (url, options); var animation = (CAAnimation)sceneSource.GetEntryWithIdentifier (animationName, new Class (typeof(CAAnimation))); return animation; }
public static CAAnimation LoadAnimationNamed(string animationName, string sceneName) { NSUrl url = NSBundle.MainBundle.GetUrlForResource(sceneName, "dae"); var options = new SCNSceneLoadingOptions() { ConvertToYUp = true }; var sceneSource = new SCNSceneSource(url, options); var animation = (CAAnimation)sceneSource.GetEntryWithIdentifier(animationName, new Class(typeof(CAAnimation))); return(animation); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Using a scene source allows us to retrieve the animations using their identifier var path = NSBundle.MainBundle.PathForResource("Scenes/skinning/skinning", "dae"); var sceneURL = NSUrl.FromFilename(path); var sceneSource = SCNSceneSource.FromUrl(sceneURL, (NSDictionary)null); // Place the character in the scene var error = new NSError(); var scene = sceneSource.SceneWithOption((SCNSceneLoadingOptions)null, out error); CharacterNode = scene.RootNode.FindChildNode("avatar_attach", true); CharacterNode.Scale = new SCNVector3(0.004f, 0.004f, 0.004f); CharacterNode.Position = new SCNVector3(5, 0, 12); CharacterNode.Rotation = new SCNVector4(0, 1, 0, -(float)(Math.PI / 8)); CharacterNode.Hidden = true; GroundNode.AddChildNode(CharacterNode); SkeletonNode = CharacterNode.FindChildNode("skeleton", true); // Prepare the other resources //TODO LoadGhostEffect (); ExtractAnimation(sceneSource); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Constraints"); TextManager.SetSubtitle("SCNIKConstraint"); TextManager.AddBulletAtLevel("Inverse Kinematics", 0); TextManager.AddBulletAtLevel("Node chain", 0); TextManager.AddBulletAtLevel("Target", 0); //load the hero Hero = Utils.SCAddChildNode(GroundNode, "heroGroup", "Scenes.scnassets/hero/hero", 12); Hero.Position = new SCNVector3(0, 0, 5); Hero.Rotation = new SCNVector4(1, 0, 0, -(nfloat)Math.PI / 2); //hide the sword var sword = Hero.FindChildNode("sword", true); sword.Hidden = true; //load attack animation var path = NSBundle.MainBundle.PathForResource("Scenes.scnassets/hero/attack", "dae"); var source = SCNSceneSource.FromUrl(NSUrl.FromFilename(path), (NSDictionary)null); Attack = (CAAnimation)source.GetEntryWithIdentifier("attackID", new Class("CAAnimation")); Attack.RepeatCount = 0; Attack.FadeInDuration = 0.1f; Attack.FadeOutDuration = 0.3f; Attack.Speed = 0.75f; Attack.AnimationEvents = new SCNAnimationEvent[] { SCNAnimationEvent.Create(0.55f, (CAAnimation animation, NSObject animatedObject, bool playingBackward) => { if (IkActive) { DestroyTarget(); } }) }; AnimationDuration = Attack.Duration; //setup IK var hand = Hero.FindChildNode("Bip01_R_Hand", true); var clavicle = Hero.FindChildNode("Bip01_R_Clavicle", true); var head = Hero.FindChildNode("Bip01_Head", true); Ik = SCNIKConstraint.Create(clavicle); hand.Constraints = new SCNConstraint[] { Ik }; Ik.InfluenceFactor = 0.0f; //add target Target = SCNNode.Create(); Target.Position = new SCNVector3(-4, 7, 10); Target.Opacity = 0; Target.Geometry = SCNPlane.Create(2, 2); Target.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Images/target", "png")); GroundNode.AddChildNode(Target); //look at LookAt = SCNLookAtConstraint.Create(Target); LookAt.InfluenceFactor = 0; head.Constraints = new SCNConstraint[] { LookAt }; ((SCNView)presentationViewController.View).WeakSceneRendererDelegate = this; }
private void SetAnimation(CharacterAnimation index, string animationName, string sceneName) { // Load the DAE using SCNSceneSource in order to be able to retrieve the animation by its identifier var path = NSBundle.MainBundle.PathForResource("Scenes/hero/" + sceneName, "dae"); var sceneURL = NSUrl.FromFilename(path); var sceneSource = SCNSceneSource.FromUrl(sceneURL, (NSDictionary)null); var animation = (CAAnimation)sceneSource.GetEntryWithIdentifier(animationName, new Class("CAAnimation")); Animations [(int)index] = animation; // Blend animations for smoother transitions animation.FadeInDuration = 0.3f; animation.FadeOutDuration = 0.3f; if (index == CharacterAnimation.Die) { // We want the "death" animation to remain at its final state at the end of the animation animation.RemovedOnCompletion = false; animation.FillMode = CAFillMode.Both; // Create animation events and set them to the animation var swipeSoundEventHandler = new SCNAnimationEventHandler((CAAnimation handlerAnimation, NSObject animatedObject, bool playingBackward) => { InvokeOnMainThread(delegate { var soundUrl = NSUrl.FromFilename(NSBundle.MainBundle.PathForResource("Sounds/swipe", "wav")); new NSSound(soundUrl, false).Play(); }); }); var deathSoundEventBlock = new SCNAnimationEventHandler((CAAnimation handlerAnimation, NSObject animatedObject, bool playingBackward) => { InvokeOnMainThread(delegate { var soundUrl = NSUrl.FromFilename(NSBundle.MainBundle.PathForResource("Sounds/death", "wav")); new NSSound(soundUrl, false).Play(); }); }); animation.AnimationEvents = new SCNAnimationEvent[] { SCNAnimationEvent.Create(0.0f, swipeSoundEventHandler), SCNAnimationEvent.Create(0.3f, deathSoundEventBlock) }; } if (index == CharacterAnimation.Attack) { // Create an animation event and set it to the animation var swordSoundEventHandler = new SCNAnimationEventHandler((CAAnimation handlerAnimation, NSObject animatedObject, bool playingBackward) => { InvokeOnMainThread(delegate { var soundUrl = NSUrl.FromFilename(NSBundle.MainBundle.PathForResource("Sounds/sword", "wav")); var attackSound = new NSSound(soundUrl, false); attackSound.Play(); }); }); animation.AnimationEvents = new SCNAnimationEvent[] { SCNAnimationEvent.Create(0.4f, swordSoundEventHandler) }; } if (index == CharacterAnimation.Walk) { // Repeat the walk animation 3 times animation.RepeatCount = 3; // Create an animation event and set it to the animation var stepSoundEventHandler = new SCNAnimationEventHandler((CAAnimation handlerAnimation, NSObject animatedObject, bool playingBackward) => { InvokeOnMainThread(delegate { var soundUrl = NSUrl.FromFilename(NSBundle.MainBundle.PathForResource("Sounds/walk", "wav")); new NSSound(soundUrl, false).Play(); }); }); animation.AnimationEvents = new SCNAnimationEvent[] { SCNAnimationEvent.Create(0.2f, stepSoundEventHandler), SCNAnimationEvent.Create(0.7f, stepSoundEventHandler) }; } }
private void ExtractAnimation (SCNSceneSource sceneSource) { // In this scene objects are animated separately using long animations // playing 3 successive animations. We will group these long animations // and then split the group in 3 different animation groups. // We could also have used three DAEs (one per animation). var animationIDs = sceneSource.GetIdentifiersOfEntries (new Class ("CAAnimation")); var animationCount = animationIDs.Length; var longAnimations = new CAAnimation [animationCount]; var maxDuration = 0.0; for (var index = 0; index < animationCount; index++) { var animation = (CAAnimation)sceneSource.GetEntryWithIdentifier (animationIDs [index].ToString (), new Class ("CAAnimation")); if (animation != null) { maxDuration = Math.Max (maxDuration, animation.Duration); longAnimations [index] = animation; } } var longAnimationsGroup = new CAAnimationGroup (); longAnimationsGroup.Animations = longAnimations; longAnimationsGroup.Duration = maxDuration; var idleAnimationGroup = (CAAnimationGroup)longAnimationsGroup.Copy (); idleAnimationGroup.TimeOffset = 6.45833333333333f; IdleAnimationGroup = CAAnimationGroup.CreateAnimation (); IdleAnimationGroup.Animations = new CAAnimation[] { idleAnimationGroup }; IdleAnimationGroup.Duration = 24.71f - 6.45833333333333f; IdleAnimationGroup.RepeatCount = float.MaxValue; IdleAnimationGroup.AutoReverses = true; var animationGroup1 = (CAAnimationGroup)longAnimationsGroup.Copy (); AnimationGroup1 = CAAnimationGroup.CreateAnimation (); AnimationGroup1.Animations = new CAAnimation[] { animationGroup1 }; AnimationGroup1.Duration = 1.4f; animationGroup1.FadeInDuration = 0.1f; animationGroup1.FadeOutDuration = 0.5f; var animationGroup2 = (CAAnimationGroup)longAnimationsGroup.Copy (); animationGroup2.TimeOffset = 3.666666666666667f; AnimationGroup2 = CAAnimationGroup.CreateAnimation (); AnimationGroup2.Animations = new CAAnimation[] { animationGroup2 }; AnimationGroup2.Duration = 6.416666666666667f - 3.666666666666667f; animationGroup2.FadeInDuration = 0.1f; animationGroup2.FadeOutDuration = 0.5f; }