Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections;
- using UnityEngine.Rendering;
- /// <summary>
- /// This is meant to be placed on a child GameObject with a collider.
- /// </summary>
- public class PianoKey : MonoBehaviour {
- static double RootThing = YRoot(12, 2);
- public static double Volume = .8f;
- public const double Frequency = 440;
- public const double SamplingFrequency = 48000;
- public KeySet keySet;
- public int keyNumber;
- public int KeyNumber {
- get { return keySet.GetKeyNumber(keyNumber); }
- }
- double keyFrequency;
- bool hit;
- bool onDown;
- bool onUp;
- float time = 1;
- float keyAnimationTime;
- double phase;
- AudioSource Audio { get; set; }
- void Awake() {
- Audio = GetComponent<AudioSource>();
- keySet = GetComponentInParent<KeySet>();
- keyFrequency = GetKeyFrequency(KeyNumber);
- }
- void Update() {
- if(onDown) {
- time = 1.05f;
- if(!Audio.isPlaying)
- Audio.Play();
- if(keyAnimationTime < 1)
- keyAnimationTime = Mathf.Min(keyAnimationTime + Time.deltaTime * 8, 1);
- }
- else {
- if(keyAnimationTime > 0)
- keyAnimationTime = Mathf.Max(keyAnimationTime - Time.deltaTime * 2, 0);
- }
- float animationTime = -Mathf.Clamp01(keyAnimationTime);
- Vector3 position = transform.parent.localPosition;
- position.y = animationTime * .3f;
- transform.parent.localPosition = position;
- Vector3 rotation = transform.parent.localEulerAngles;
- rotation.x = animationTime * 8;
- transform.parent.localEulerAngles = rotation;
- }
- void LateUpdate() {
- onDown = false;
- onUp = false;
- if(Audio.isPlaying) {
- if(time > 0) {
- time -= Time.deltaTime * Mathf.Max(time, time > .5f ? 2 : .25f);
- if(time < 0) {
- time = 0;
- phase = 0;
- Audio.Stop();
- }
- }
- }
- else if(time < 1) {
- time = Mathf.Min(time + Time.deltaTime * 4, 1);
- }
- }
- void OnAudioFilterRead(float[] data, int channels) {
- if(time > 0) {
- double increment = System.Math.Pow(2, KeyNumber / 12d) * Frequency * 2 * Mathf.PI / SamplingFrequency;
- for(int i = 0; i < data.Length; i += channels) {
- phase += increment;
- data[i] = (float)(System.Math.Sin(phase) * Volume * Mathf.Clamp01(time));
- if(channels == 2) data[i + 1] = data[i];
- if(phase > 2 * Mathf.PI) phase = 0;
- }
- }
- }
- static double GetKeyFrequency(int keyNumber) {
- return System.Math.Pow(2, keyNumber / 12d) * Frequency;
- }
- static double YRoot(double value, int power) {
- return System.Math.Pow(value, 1d / power);
- }
- /// <summary>
- /// Don't know if this gives the right result yet. Check the keyFrequency variable in the inspector (debug mode) after hitting play.
- /// </summary>
- /// <param name="keyFrequency"></param>
- /// <returns></returns>
- static double GetKey(double keyFrequency) {
- return (System.Math.Log(12, 2) * (keyFrequency / Frequency)) + 49;
- }
- void OnMouseDown() {
- //hit = true;
- //onDown = true;
- }
- void OnMouseOver() {
- if(Input.GetMouseButton(0)) {
- //if(onDown != true) {
- // keyAnimationTime = 0;
- //}
- onDown = true;
- }
- }
- void OnMouseUp() {
- //hit = false;
- //onUp = true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement