baobao
12/1/2016 - 3:10 PM

Inputmanager.cs

//
// InputManager
//
// Copyright (C) 2016 Shunsuke Ohba
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using UnityEngine;

namespace info.shibuya24
{
    /// <summary>
    /// Singleton class using Input.
    /// </summary>
    public sealed class InputManager : MonoBehaviour
    {
        #region Field
        
        [SerializeField]
        private InputConfig _config;
        private int _tapStartFrame;
        
        #endregion

        #region Property

        public static InputManager Instance { get; private set; }
        public bool IsTaped { get; private set; }
        public Vector3 TapStartPos {get;private set;}

        #endregion

        #region public event
        
        public event System.Action<Vector3> onDelta;
        public event System.Action onTapUp;
        
        #endregion
        
        
        #region Unity Method


        void Awake()
        {
            if (Instance == null)
            {
                Instance = this;
            }
            else
            {
                Destroy(gameObject);
                Debug.LogWarning("InputManager is already exists.");
            }
        }

        void Start ()
        {
            if (_config == null) {
                // Default Setting
                _config = ScriptableObject.CreateInstance<InputConfig>();
                _config.clamp = new Vector2(200f, 200f);
                _config.tapMaxFrame = 20;
            }
        }
        
        void Update ()
        {
            Vector3 delta = new Vector3();
            
            if (Input.GetMouseButtonUp(0))
            {
                // Called when tap up
                OnTapUp();
            }
            
            if (Input.GetMouseButtonDown(0))
            {
                // Called when tap down once
                OnTapDown();
            }
            
            if (Input.GetMouseButton(0) && IsTaped)
            {
                // Called when tap down every frame
                OnTapStay(x => delta = x);
            }
            
            delta.x = Mathf.Clamp(delta.x, -_config.clamp.x, _config.clamp.x) / _config.clamp.x;
            delta.y = Mathf.Clamp(delta.y, -_config.clamp.y, _config.clamp.y) / _config.clamp.y;
            
            if (onDelta != null)
            {
                // result -1f ~ 1f
                onDelta(delta);
            }
        }
        
        #endregion
        
        #region Private Method
        
        private void OnTapUp ()
        {
            IsTaped = false;
            if (_tapStartFrame < _config.tapMaxFrame && onTapUp != null) {
                onTapUp();
            }
            _tapStartFrame = 0;
        }
        
        private void OnTapDown ()
        {
            TapStartPos = Input.mousePosition;
            IsTaped = true;
        }
        
        private void OnTapStay(System.Action<Vector3> callback)
        {
            if (callback != null) {
                callback(Input.mousePosition - TapStartPos);
            }
            _tapStartFrame++;
        }
        
        #endregion
    }

    [CreateAssetMenu]
    public class InputConfig : ScriptableObject
    {
        public int tapMaxFrame = 20;
        public Vector2 clamp = new Vector2(200f, 200f);
    }
}