Skip to content

Instantly share code, notes, and snippets.

@littilewing
Last active August 2, 2016 06:07
Show Gist options
  • Save littilewing/8e0d76e6f110758f9d07 to your computer and use it in GitHub Desktop.
Save littilewing/8e0d76e6f110758f9d07 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[RequireComponent(typeof(AudioSource))] //AudioSourceは必須.
[DisallowMultipleComponent] //複数アタッチさせない.
public class DeviceSensors : MonoBehaviour {
public Vector3 acceleration; //Input.acceleration
public Vector3 gyroUnbiased;
public Quaternion gyroAttitude;
public Dictionary<int,string> touchRepeatDic;
private IEnumerator coroutine;
private Color red = Color.red;
private Color originColor;
public xInputType sensorType = xInputType.TOUCHPAD;
public GameObject touchArea;
public GameObject touchArea2;
public Vector2 touchPos= Vector2.zero;
public Vector2 touchPos2= Vector2.zero;
private GameObject gamepadObj;
private GameObject touchpadObj;
private GameObject fullPadObj;
private LineRenderer _renderer1;// = gameObject.GetComponent<LineRenderer>();
private LineRenderer _renderer2;// = gameObject.GetComponent<LineRenderer>();
//音量関連
public AudioSource audio;
public float sensitivity = 100; //感度.音量の最大値.
float loudness; //音量.
float lastLoudness; //前フレームの音量.
[Range(0,0.95f)] //最大1にできてしまうと全く変動しなくなる.
public float lastLoudnessInfluence; //前フレームの影響度合い.
//low pass fliler
static float AccelerometerUpdateInterval = 1.0f / 60.0f;
static float LowPassKernelWidthInSeconds= 1.0f;
private float LowPassFilterFactor =AccelerometerUpdateInterval / LowPassKernelWidthInSeconds; // tweakable
//private Vector3 lowPassValue = Vector3.zero;
// Use this for initialization
void Start () {
audioInit ();
//red = ColorUtils.ToRGB (0xC83FB3);
red = ColorUtils.ToRGB (0x1E9797);
originColor = GameObject.Find ("ButtonA").transform.GetComponents<Renderer> () [0].materials [0].color;
touchRepeatDic = new Dictionary<int,string>();
acceleration = Input.acceleration;
gyroUnbiased = Input.gyro.rotationRateUnbiased;
if (SystemInfo.supportsGyroscope) {
Input.gyro.enabled = true;
} else {
Debug.Log ("no support gyro.");
}
//Compass
Input.compass.enabled = true;
gamepadObj = GameObject.Find ("GamePad");
touchpadObj= GameObject.Find ("TouchPad");
fullPadObj= GameObject.Find ("FullPad");
changeSensorType (sensorType);
//_renderer= gameObject.GetComponent<LineRenderer>();
// 線の幅
//_renderer.SetWidth(0.1f, 0.1f);
// 頂点の数
}
// Update is called once per frame
void Update () {
if(sensorType == xInputType.OFF)
return;
// get acceleration
//acceleration = Input.acceleration;
acceleration = LowPassFilterAccelerometer ();
gyroUnbiased = Input.gyro.rotationRateUnbiased;
// Debug.Log ("acceleration" + dir);
// get gyro attitude
if (Input.gyro.enabled) {
gyroAttitude = Input.gyro.attitude;
/*
gyroAttitude.x *= -1;
gyroAttitude.y *= -1;
gyroAttitude.z *= 1;
*/
}
// get Conpass
transform.rotation = Quaternion.Euler(0, -Input.compass.trueHeading, 0);
#if ( UNITY_ANDROID || UNITY_IPHONE || UNITY_WP8 ) && !UNITY_EDITOR
/* Touch Controlls*/
Touch[] _touch = Input.touches;
if(_touch.Length == 0 ){
touchPos = Vector2.zero;
touchPos2 = Vector2.zero;
_renderer.enabled = false;
if( touchRepeatDic.Count > 0){
foreach(var d in touchRepeatDic){
touchRepeatDic.Remove(d.Key);
try{
coroutine = ChangeColorOfGameObject (GameObject.Find(d.Value).gameObject, originColor ,false);
StartCoroutine ( coroutine);
}catch(UnityException e){}
}
}
}
else{
for(int i = 0; i< _touch.Length;i++){
Ray ray = Camera.main.ScreenPointToRay (_touch[i].position);
RaycastHit hit = new RaycastHit ();
int _fid = _touch[i].fingerId;
switch( Input.GetTouch(i).phase ){
case TouchPhase.Began:
if (Physics.Raycast (ray, out hit)) {
GameObject obj = hit.collider.gameObject;
if(obj == touchArea || obj == touchArea2 ){
drawLine(Camera.main.ScreenToWorldPoint(_touch[i].position) ,ref obj);
}
SendMessage("OscSendTouchBegin", obj.name);
touchRepeatDic[_fid] = obj.name;
coroutine = ChangeColorOfGameObject (obj.gameObject, red ,false);
StartCoroutine ( coroutine);
}
break;
case TouchPhase.Moved:
case TouchPhase.Stationary:
if (Physics.Raycast (ray, out hit)) {
GameObject obj = hit.collider.gameObject;
if(obj == touchArea ){
drawLine(Camera.main.ScreenToWorldPoint(_touch[i].position), ref obj );
}
if(obj == touchArea2 ){
drawLine(Camera.main.ScreenToWorldPoint(_touch[i].position), ref obj );
}
if(touchRepeatDic.ContainsKey(_fid) == false){
// Debug.Log ("KEYSTART"+ obj.name);
SendMessage("OscSendTouchBegin", obj.name);
touchRepeatDic[_fid] = obj.name;
}
//slide another button
else if(touchRepeatDic[_fid] != obj.name ){
coroutine = ChangeColorOfGameObject (GameObject.Find(touchRepeatDic[_fid]).gameObject, originColor ,false);
StartCoroutine ( coroutine);
SendMessage("OscSendTouchEnd", touchRepeatDic[_touch[i].fingerId]);
//touchState[Input.GetTouch(i).fingerId] = "";
touchRepeatDic.Remove(_fid );
}
touchRepeatDic[_fid] = obj.name;
coroutine = ChangeColorOfGameObject (obj.gameObject, red ,false);
StartCoroutine ( coroutine);
}
break;
case TouchPhase.Ended :
case TouchPhase.Canceled:
if(touchRepeatDic[_fid] != null ){
if(touchRepeatDic[_fid] == touchArea.name ){
touchPos = Vector2.zero;
_renderer.enabled = false;
}
if(touchRepeatDic[_fid] == touchArea2.name ){
touchPos2 = Vector2.zero;
_renderer.enabled = false;
}
SendMessage("OscSendTouchEnd", touchRepeatDic[_fid]);
coroutine = ChangeColorOfGameObject (GameObject.Find(touchRepeatDic[_fid]).gameObject, originColor ,false);
StartCoroutine ( coroutine);
touchRepeatDic.Remove(_fid);
}
break;
}
}
}
#else
/* Keyboard Controlls*/
int c =0;
foreach (var k in xMultiInputs.xKeymap){
if(Input.GetKeyDown(k.Value)){ //keydown
try{
GameObject obj = GameObject.Find(k.Key).gameObject;
SendMessage("OscSendTouchBegin", obj.name);
coroutine = ChangeColorOfGameObject (obj.gameObject, red ,false);
StartCoroutine ( coroutine);
}catch(UnityException e){}
}
else if(Input.GetKeyUp(k.Value)){ //keyup
try{
GameObject obj = GameObject.Find(k.Key).gameObject;
coroutine = ChangeColorOfGameObject (obj.gameObject, originColor ,false);
StartCoroutine ( coroutine);
SendMessage("OscSendTouchEnd", obj.name);
}catch(UnityException e){}
}
else if(Input.GetKey (k.Value)){ //repeat
//Debug.Log (xMultiInputs.xKeymap[k]);
try{
GameObject obj = GameObject.Find(k.Key).gameObject;
touchRepeatDic[c] = obj.name;
coroutine = ChangeColorOfGameObject (obj.gameObject, red ,false);
StartCoroutine ( coroutine);
c++;
}catch(UnityException e){
}
}
}
//delete previous repeat dict.
for (int s = touchRepeatDic.Count - 1; s >= c; s--) {
touchRepeatDic.Remove(s);
}
if(xInputActiveSensors.sensor [xInputSensor.TOUCHPOS].enable){
if(Input.GetMouseButtonUp(0)){
touchPos = touchPos2 = Vector2.zero;
_renderer.enabled = false;
SendMessage("OscSendTouchEnd", touchArea.name);
}
else if(Input.GetMouseButtonDown(0)){
SendMessage("OscSendTouchBegin", touchArea.name);
}
else if(Input.GetMouseButton(0)){
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit = new RaycastHit ();
if (Physics.Raycast (ray, out hit)) {
if(hit.collider.gameObject == touchArea ){
Vector3 mpos = Camera.main.ScreenToWorldPoint (Input.mousePosition);
touchRepeatDic[c] = touchArea.name;
coroutine = ChangeColorOfGameObject (touchArea.gameObject, red ,false);
StartCoroutine ( coroutine);
drawLine(mpos,ref touchArea);
}
if(hit.collider.gameObject == touchArea2 ){
Vector3 mpos = Camera.main.ScreenToWorldPoint (Input.mousePosition);
touchRepeatDic[c] = touchArea2.name;
coroutine = ChangeColorOfGameObject (touchArea2.gameObject, red ,false);
StartCoroutine ( coroutine);
drawLine(mpos,ref touchArea2);
}
}else{
touchPos = touchPos2 = Vector2.zero;
_renderer.enabled = false;
}
//Debug.Log (touchPos);
}
else{
touchPos = touchPos2 = Vector2.zero;
_renderer.enabled = false;
coroutine = ChangeColorOfGameObject (touchArea.gameObject, originColor ,false);
StartCoroutine ( coroutine);
coroutine = ChangeColorOfGameObject (touchArea2.gameObject, originColor ,false);
StartCoroutine ( coroutine);
}
}
#endif
}
private Vector3 LowPassFilterAccelerometer() {
acceleration = Vector3.Lerp(acceleration, Input.gyro.userAcceleration, LowPassFilterFactor);
return acceleration;
}
private void drawLine(Vector3 mpos,ref GameObject _t){
//Debug.Log (_t.name);
Transform t = _t.gameObject.transform;
float zidx = -20f;
_renderer.enabled = true;
_renderer.SetVertexCount(14);
//_renderer?.SetColors (red, red);
// -0.5 < xpos(ypos) < 0.5
if(_t.name == "TouchArea"){
if (touchPos != Vector2.zero) {
zidx = -2f;
}
touchPos.x = (mpos.x - t.position.x) / t.lossyScale.x;
touchPos.y = (mpos.y - t.position.y) / t.lossyScale.y;
// 頂点を設定
_renderer.SetPosition(0, new Vector3(mpos.x, t.position.y+(t.localScale.y/2), zidx));
_renderer.SetPosition(1, new Vector3(mpos.x, t.position.y-(t.localScale.y/2), zidx));
// 頂点を設定
_renderer.SetPosition(4, new Vector3(t.position.x-(t.localScale.x/2), mpos.y, zidx));
_renderer.SetPosition(5, new Vector3(t.position.x+(t.localScale.x/2), mpos.y, zidx));
}else{
if (touchPos2 != Vector2.zero) {
zidx = -2f;
}
touchPos2.x = (mpos.x - t.position.x) / t.lossyScale.x;
touchPos2.y = (mpos.y - t.position.y) / t.lossyScale.y;
// 頂点を設定
_renderer.SetPosition(8, new Vector3(mpos.x, t.position.y+(t.localScale.y/2), zidx));
_renderer.SetPosition(9, new Vector3(mpos.x, t.position.y-(t.localScale.y/2), zidx));
_renderer.SetPosition(12, new Vector3(t.position.x-(t.localScale.x/2), mpos.y, zidx));
_renderer.SetPosition(13, new Vector3(t.position.x+(t.localScale.x/2), mpos.y, zidx));
//Debug.Log (touchPos2);
}
_renderer.SetPosition(2, new Vector3(mpos.x, t.position.y-(t.localScale.y/2), -20.0f));
_renderer.SetPosition(3, new Vector3(t.position.x-(t.localScale.x/2), mpos.y, -20.0f));
_renderer.SetPosition(6, new Vector3(t.position.x+(t.localScale.x/2), mpos.y, -20f));
_renderer.SetPosition(7, new Vector3(mpos.x, t.position.y+(t.localScale.y/2), -20f));
_renderer.SetPosition(10, new Vector3(mpos.x, t.position.y-(t.localScale.y/2), -20.0f));
_renderer.SetPosition(11, new Vector3(t.position.x-(t.localScale.x/2), mpos.y, -20.0f));
}
/// <summary>
/// 入力されたオブジェクト及びその子、全ての色を変える
/// </summary>
/// <param name="targetObject">色を変更したいオブジェクト</param>
/// <param name="color">設定したい色</param>
///
private IEnumerator ChangeColorOfGameObject(GameObject targetObject, Color color,bool one = true){
if (targetObject == null)
yield return 0;
//入力されたオブジェクトのRendererを全て取得し、さらにそのRendererに設定されている全Materialの色を変える
foreach(Renderer targetRenderer in targetObject.GetComponents<Renderer>()){
foreach(Material material in targetRenderer.materials){
//material.color = color;
material.EnableKeyword("_Metallic");
if (color == red) {
material.SetFloat ("_Metallic", 0.5f);
} else {
material.SetFloat ("_Metallic", 0.0f);
}
if(one){
yield return new WaitForSeconds (0.2f);
// Prints 5.0
//material.color = originColor;
material.SetFloat ("_Metallic", 0.0f);
}
}
}
/*
//入力されたオブジェクトの子にも同様の処理を行う
for(int i = 0; i < targetObject.transform.childCount; i++){
coroutine = ChangeColorOfGameObject (targetObject.transform.GetChild(i).gameObject, color);
StartCoroutine ( coroutine);
}
*/
}
public void changeSensorType(xInputType type){
this.sensorType = type;
if (type == xInputType.OFF) {
//xInputActiveSensors.clear ();
touchpadObj.SetActive (false);
gamepadObj.SetActive (false);
fullPadObj.SetActive (false);
Screen.orientation = ScreenOrientation.Portrait;
} else if (type == xInputType.TOUCHPAD) {
// xInputActiveSensors.clear ();
//xInputActiveSensors.touchPos.enable = true;
//xInputActiveSensors.sensor[xInputSensor.TOUCHPOS].enable = true;
xInputActiveSensors.SetActive (xInputSensor.TOUCHPOS, true);
touchpadObj.SetActive (true);
gamepadObj.SetActive (false);
fullPadObj.SetActive(false);
_renderer.enabled = true;
touchArea = GameObject.Find ("TouchArea")as GameObject;
coroutine = ChangeColorOfGameObject (touchArea.gameObject, originColor ,false);
StartCoroutine ( coroutine);
Screen.orientation = ScreenOrientation.Portrait;
} else if (type == xInputType.GAMEPAD) {
touchpadObj.SetActive(false);
fullPadObj.SetActive(false);
gamepadObj.SetActive(true);
_renderer.enabled = false;
Screen.orientation = ScreenOrientation.LandscapeLeft;
} else if (type == xInputType.FULLPAD) {
touchpadObj.SetActive(false);
gamepadObj.SetActive(false);
fullPadObj.SetActive(true);
_renderer.enabled = true;
touchArea = GameObject.Find ("TouchArea")as GameObject;
Screen.orientation = ScreenOrientation.LandscapeLeft;
}
else {
touchpadObj.SetActive (true);
gamepadObj.SetActive (false);
fullPadObj.SetActive(false);
_renderer.enabled = true;
coroutine = ChangeColorOfGameObject (touchArea.gameObject, originColor ,false);
StartCoroutine ( coroutine);
Screen.orientation = ScreenOrientation.Portrait;
xInputActiveSensors.clear ();
xInputActiveSensors.SetActive (xInputSensor.TOUCHPOS, true);
if (type == xInputType.GYROATTITUDE) {
xInputActiveSensors.SetActive (xInputSensor.GYRO_ATTITUDE, true);
} else if (type == xInputType.GYROPAD) {
xInputActiveSensors.SetActive (xInputSensor.GYRO_UNBAISED, true);
}
}
}
public void audioInit(){
audio = GetComponent<AudioSource> ();
audio.clip = Microphone.Start(null, true, 10, 44100); // マイクからのAudio-InをAudioSourceに流す
audio.loop = true; // ループ再生にしておく
//audio.mute = true; // マイクからの入力音なので音を流す必要がない
while (!(Microphone.GetPosition("") > 0)){} // マイクが取れるまで待つ。空文字でデフォルトのマイクを探してくれる
audio.Play();
}
private float GetAveragedVolume()
{
float[] data = new float[256];
float a = 0;
audio.GetOutputData(data,0);
foreach(float s in data)
{
a += Mathf.Abs(s);
}
return a/256.0f;
}
//現フレームの音量を計算します.
//マイクの感度が良すぎる場合は, lastLoudnessInfluence を上げたりして調節しましょう.
public float GetLoudness() {
lastLoudness = loudness;
loudness = GetAveragedVolume() * sensitivity * ( 1 - lastLoudnessInfluence ) + lastLoudness * lastLoudnessInfluence;
return loudness;
}
void OnGUI () {
// Make a background box
GUI.Box(new Rect(Screen.width-140,Screen.height-20,140,20), "TYPE:"+sensorType.ToString()) ;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment