Advertisement
GibTreaty

PianoKey.cs

Mar 27th, 2015
1,267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.11 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.Rendering;
  4.  
  5. /// <summary>
  6. /// This is meant to be placed on a child GameObject with a collider.
  7. /// </summary>
  8. public class PianoKey : MonoBehaviour {
  9.  
  10.     static double RootThing = YRoot(12, 2);
  11.     public static double Volume = .8f;
  12.  
  13.     public const double Frequency = 440;
  14.     public const double SamplingFrequency = 48000;
  15.  
  16.     public KeySet keySet;
  17.  
  18.     public int keyNumber;
  19.     public int KeyNumber {
  20.         get { return keySet.GetKeyNumber(keyNumber); }
  21.     }
  22.  
  23.     double keyFrequency;
  24.  
  25.     bool hit;
  26.     bool onDown;
  27.     bool onUp;
  28.  
  29.     float time = 1;
  30.     float keyAnimationTime;
  31.  
  32.     double phase;
  33.  
  34.     AudioSource Audio { get; set; }
  35.  
  36.     void Awake() {
  37.         Audio = GetComponent<AudioSource>();
  38.         keySet = GetComponentInParent<KeySet>();
  39.  
  40.         keyFrequency = GetKeyFrequency(KeyNumber);
  41.     }
  42.  
  43.     void Update() {
  44.         if(onDown) {
  45.             time = 1.05f;
  46.  
  47.             if(!Audio.isPlaying)
  48.                 Audio.Play();
  49.  
  50.             if(keyAnimationTime < 1)
  51.                 keyAnimationTime = Mathf.Min(keyAnimationTime + Time.deltaTime * 8, 1);
  52.         }
  53.         else {
  54.             if(keyAnimationTime > 0)
  55.                 keyAnimationTime = Mathf.Max(keyAnimationTime - Time.deltaTime * 2, 0);
  56.         }
  57.  
  58.         float animationTime = -Mathf.Clamp01(keyAnimationTime);
  59.  
  60.         Vector3 position = transform.parent.localPosition;
  61.         position.y = animationTime * .3f;
  62.         transform.parent.localPosition = position;
  63.  
  64.         Vector3 rotation = transform.parent.localEulerAngles;
  65.         rotation.x = animationTime * 8;
  66.         transform.parent.localEulerAngles = rotation;
  67.     }
  68.  
  69.     void LateUpdate() {
  70.         onDown = false;
  71.         onUp = false;
  72.  
  73.         if(Audio.isPlaying) {
  74.             if(time > 0) {
  75.                 time -= Time.deltaTime * Mathf.Max(time, time > .5f ? 2 : .25f);
  76.  
  77.                 if(time < 0) {
  78.                     time = 0;
  79.                     phase = 0;
  80.  
  81.                     Audio.Stop();
  82.                 }
  83.             }
  84.         }
  85.         else if(time < 1) {
  86.             time = Mathf.Min(time + Time.deltaTime * 4, 1);
  87.         }
  88.     }
  89.  
  90.     void OnAudioFilterRead(float[] data, int channels) {
  91.         if(time > 0) {
  92.             double increment = System.Math.Pow(2, KeyNumber / 12d) * Frequency * 2 * Mathf.PI / SamplingFrequency;
  93.  
  94.             for(int i = 0; i < data.Length; i += channels) {
  95.                 phase += increment;
  96.                 data[i] = (float)(System.Math.Sin(phase) * Volume * Mathf.Clamp01(time));
  97.  
  98.                 if(channels == 2) data[i + 1] = data[i];
  99.                 if(phase > 2 * Mathf.PI) phase = 0;
  100.             }
  101.         }
  102.     }
  103.  
  104.     static double GetKeyFrequency(int keyNumber) {
  105.         return System.Math.Pow(2, keyNumber / 12d) * Frequency;
  106.     }
  107.  
  108.     static double YRoot(double value, int power) {
  109.         return System.Math.Pow(value, 1d / power);
  110.     }
  111.  
  112.     /// <summary>
  113.     /// Don't know if this gives the right result yet. Check the keyFrequency variable in the inspector (debug mode) after hitting play.
  114.     /// </summary>
  115.     /// <param name="keyFrequency"></param>
  116.     /// <returns></returns>
  117.     static double GetKey(double keyFrequency) {
  118.         return (System.Math.Log(12, 2) * (keyFrequency / Frequency)) + 49;
  119.     }
  120.  
  121.     void OnMouseDown() {
  122.         //hit = true;
  123.         //onDown = true;
  124.     }
  125.  
  126.     void OnMouseOver() {
  127.         if(Input.GetMouseButton(0)) {
  128.             //if(onDown != true) {
  129.             //  keyAnimationTime = 0;
  130.             //}
  131.  
  132.             onDown = true;
  133.         }
  134.     }
  135.  
  136.     void OnMouseUp() {
  137.         //hit = false;
  138.         //onUp = true;
  139.     }
  140.  
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement