/// <summary> /// Takes an impulse and plays it with the ImpulseDemo's parameters. /// This takes an impulse so you don't need to instantiate one every time. /// If you're doing the same impulse regularly, it saves traversal/breadth first searching /// </summary> /// <param name="imp">A constructed impulse of the emanation or traversal</param> private void ConfigureAndPlayImpulse(ImpulseGenerator.Impulse imp) { if (CurrentMode == ImpulseType.Emanating) { StartCoroutine(ColorSuitForEmanation()); } else { StartCoroutine(ColorSuitForTraversal()); } //To support CodeSequence Samples if (SelectedCodeSequence < 0) { //These are broken up by lines for readability imp.WithDuration(ImpulseDuration); imp.WithAttenuation(Attenuation); imp.WithEffect(effectOptions[currentEffect], EffectDuration, EffectStrength); imp.Play(); //You can do something like: //i.WithAttenuation(Attenuation).WithDuration(ImpulseDuration).WithEffect(effectOptions[CurrentEffect], EffectDuration, EffectStrength).Play(); //Chaining and Functional Programming! } else { //These are broken up by lines for readability imp.WithDuration(ImpulseDuration); imp.WithAttenuation(Attenuation); imp.WithEffect(GetCodeSequence()); imp.Play(); } }
/// <summary> /// Repeatedly calls impulse.Play after X delay Y times. /// This sample DOES work. It will get baked into the Impulse's functionality later. /// </summary> /// <param name="impulse">The impulse to repeat</param> /// <param name="delay">How long AFTER the previous one do you want to start the next one</param> /// <param name="count">How many times you want to play it. (Ideally you should call .Play before you call RepeatedEmanations, otherwise it won't start when you start this coroutine.)</param> /// <returns></returns> IEnumerator RepeatedEmanations(ImpulseGenerator.Impulse impulse, float delay, int count) { impulse.Play(); for (int i = 0; i < count - 1; i++) { yield return(new WaitForSeconds(delay)); impulse.Play(); } }
private void ClickedSuitInTraversalMode(SuitBodyCollider clicked, RaycastHit hit) { //None are currently selected if (ImpulseOrigin == null) { //Select first ImpulseOrigin = clicked; //Mark it as selected ColorSuit(clicked, OriginColor); } //First one is already selected else { //If we click back on the first node. if (ImpulseOrigin == clicked) { //Unselect First ColorSuit(clicked, unselectedColor); ImpulseOrigin = null; //If we had a destination if (ImpulseDestination != null) { //Clear it. ColorSuit(ImpulseDestination, unselectedColor); ImpulseDestination = null; } } else { //If we had a destination (from last play) if (ImpulseDestination != null) { //Clear it to avoid leaving unnecessary colored nodes ColorSuit(ImpulseDestination, unselectedColor); ImpulseDestination = null; } //Set our destination ImpulseDestination = clicked; ColorSuit(clicked, OriginColor); //Leftover log to see that we're playing from the start to end. //Debug.Log((int)TraversalOrigin.regionID + "\t " + (int)suit.regionID); //Play Impulse from the origin to our brand new destination. ImpulseGenerator.Impulse imp = ImpulseGenerator.BeginTraversingImpulse(ImpulseOrigin.regionID, clicked.regionID); //Then play it ConfigureAndPlayImpulse(imp); } } }
private void Start() { Effect whichEffect = Effect.Pulse; //What's more electrical than pulses. float totalImpulseDuration = .35f; //How long does the shock take to traverse to the heart. float effectDuration = 0.0f; //0.0 defaults to the natural duration of the pulse effect. float effectStrength = 1; //How strong is the pulse effect //Create the Impulse object (which can be told to play, which instantiates what it 'is') shockImpulse = ImpulseGenerator.BeginTraversingImpulse(AreaFlag.Forearm_Right, AreaFlag.Chest_Left); // This sets the duration to be .25 seconds shockImpulse.WithDuration(totalImpulseDuration); //This defines the base effect (which needs an effect name, a strength and a duration) shockImpulse.WithEffect(whichEffect, effectDuration, effectStrength); }
/// <summary> /// This is a simple handful of lines. This plays when Walter (the giant red scorpion of player murdering) lands on the ground. /// This sample DOES work. /// The intention is to give an effect that goes up the body. /// It has been slightly adapted to take different effect families (click, double-click, hum, etc) /// </summary> public static void GiantScorpionLanding(string effect = "buzz") { //TWo different Impulses are used here even though the same one could be re-assigned. Two variables are more readable at neglible CPU cost. ImpulseGenerator.Impulse leftUp = ImpulseGenerator.BeginTraversingImpulse(AreaFlag.Lower_Ab_Left, AreaFlag.Forearm_Left) .WithDuration(0.5f) .WithEffect(effect, 0.1f, 1.0f); ImpulseGenerator.Impulse rightUp = ImpulseGenerator.BeginTraversingImpulse(AreaFlag.Lower_Ab_Right, AreaFlag.Forearm_Right) .WithDuration(0.5f) .WithEffect(effect, 0.1f, 1.0f); //Don't forget to play the effects leftUp.Play(); rightUp.Play(); //We could HapticHandle[] if we wanted to stop these prematurely - however they're very short effects, so it's unlikely that will be needed. //HapticHandle's can be Stopped or restarted until they (Finish playing AND go out of scope), after that they're gone. }
public override void OnSuitClicked(SuitBodyCollider clicked, RaycastHit hit) { //Start with which mode this SuitDemo is in // Emanation - Start at a point and affect in waves the neighbor pads. if (CurrentMode == ImpulseType.Emanating) { //Debug.Log((int)suit.regionID + "\n"); ImpulseGenerator.Impulse imp = ImpulseGenerator.BeginEmanatingEffect(clicked.regionID, (int)Depth); if (imp != null) { ColorSuit(ImpulseOrigin, unselectedColor); //Select first ImpulseOrigin = clicked; ConfigureAndPlayImpulse(imp); } } // Traversing - Start at a point and move in stages to the destination through neighbor pads else if (CurrentMode == ImpulseType.Traversing) { ClickedSuitInTraversalMode(clicked, hit); } }
/// <summary> /// Takes an impulse and plays it with the ImpulseDemo's parameters. /// This takes an impulse so you don't need to instantiate one every time. /// If you're doing the same impulse regularly, it saves traversal/breadth first searching /// </summary> /// <param name="imp">A constructed impulse of the emanation or traversal</param> private void ConfigureAndPlayImpulse(ImpulseGenerator.Impulse imp) { if (CurrentMode == ImpulseType.Emanating) { StartCoroutine(ColorSuitForEmanation()); } else { StartCoroutine(ColorSuitForTraversal()); } //To support HapticSequence Samples if (UseEffectSelectorSlider) { //Prevent array index out of bounds errors. Effect whichEffect = effectOptions[Mathf.Clamp(currentEffect, 0, effectOptions.Length - 1)]; //These are broken up by lines for readability imp.WithDuration(ImpulseDuration); imp.WithAttenuation(Attenuation); imp.WithEffect(whichEffect, EffectDuration, EffectStrength); imp.Play(); //You can do something like: //i.WithAttenuation(Attenuation).WithDuration(ImpulseDuration).WithEffect(effectOptions[CurrentEffect], EffectDuration, EffectStrength).Play(); //Chaining and Functional Programming! } else { //These are broken up by lines for readability imp.WithDuration(ImpulseDuration); imp.WithAttenuation(Attenuation); imp.WithEffect(GetHapticSequence()); imp.Play(); } }
/// <summary> /// [Note: this does not work] /// /// </summary> /// <param name="playerBody"></param> /// <param name="info"></param> public void DynamiteExplosionSample(GameObject playerBody, ExplosionInfo info) { //Again, we checked what was the closest place to the explosion for starting an impulse. AreaFlag loc = FindNearest(playerBody, info.explosionCenter); if (loc != AreaFlag.None) { //This is a little gross but the idea is simple: Closer to the explosion, the longer the effect. //If you're close to dynamite the visuals take longer to dissipate and you'll spend longer thinking 'Oh man I screwed up' even though you're unharmed. //This is accomplished in a couple of ways: //The emanation will traverse farther across the user's body. int depth = 8; //The emanation will restart several times int repeats = 3; //The starting strength of the effect will be stronger. float strength = 1.0f; //The delay between the repetitions will be shorter. float delay = .15f; //We do a simple bit of checking based on the distance from the blast. if (info.dist > 0) { //We base the depth off of the distance from the explosion. //There is some magic-numbering going on here. You can tune it or standardize your distances. //The farther, the less depth of the emanation depth = (int)(8 / info.dist); //The farther, the less initial strength - NOTE: this is just Effect strength, not using the Attenuation which is still a bit incomplete. strength = 2 / info.dist; } //The closer the player is to the explosion, the more the explosion will 'reverberate' by repeating. repeats = Mathf.RoundToInt(Mathf.Clamp(7 / info.dist, 0, 7)); //If we're going to experience it a lot, we'll get a shorter delay between the repeats. if (repeats > 4) { delay = .1f; } //Start at the correct spot. ImpulseGenerator.Impulse impulse = ImpulseGenerator.BeginEmanatingEffect(loc, depth) //Give the total effect a short duration (which you could choose to modify) .WithDuration(.15f) //Start with a natural duration click for the initial hit. This is good because it gets the motors going earlier on .WithEffect("click", .00f, strength) //Finish with a buzz which will last longer than natural duration. This gives the explosion a residual impact feeling .WithEffect("buzz", .15f, strength); //Finally, we call the coroutine that will repeatedly create new handles of the impulse with Play(). //Remember, an Impulse is like a prefab or a building plan for haptics. You can 'instantiate' multiple haptic effects off the same Impulse. StartCoroutine(RepeatedEmanations(impulse, delay, repeats)); } else { Debug.LogWarning("Invalid Hit at " + info.explosionCenter + "\n"); } }