You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
307 lines
10 KiB
307 lines
10 KiB
3 years ago
|
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. ===========
|
||
|
|
||
|
using HTC.UnityPlugin.Utility;
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Events;
|
||
|
|
||
|
namespace HTC.UnityPlugin.Vive
|
||
|
{
|
||
|
// Use this helper component to combine multiple Vive inputs into one virtual button
|
||
|
public class ViveInputVirtualButton : MonoBehaviour
|
||
|
{
|
||
|
public enum InputsOperatorEnum
|
||
|
{
|
||
|
Or,
|
||
|
And,
|
||
|
}
|
||
|
|
||
|
[Serializable]
|
||
|
public class InputEntry
|
||
|
{
|
||
|
public ViveRoleProperty viveRole = ViveRoleProperty.New(HandRole.RightHand);
|
||
|
[CustomOrderedEnum]
|
||
|
public ControllerButton button = ControllerButton.Trigger;
|
||
|
}
|
||
|
|
||
|
[Serializable]
|
||
|
public struct OutputEventArgs
|
||
|
{
|
||
|
public ViveInputVirtualButton senderObj;
|
||
|
public ButtonEventType eventType;
|
||
|
}
|
||
|
|
||
|
[Serializable]
|
||
|
public class OutputEvent : UnityEvent<OutputEventArgs> { }
|
||
|
|
||
|
[SerializeField]
|
||
|
private InputsOperatorEnum m_combineInputsOperator = InputsOperatorEnum.Or;
|
||
|
[SerializeField]
|
||
|
private List<InputEntry> m_inputs = new List<InputEntry>();
|
||
|
[SerializeField]
|
||
|
private OutputEvent m_onVirtualPress = new OutputEvent();
|
||
|
[SerializeField]
|
||
|
private OutputEvent m_onVirtualClick = new OutputEvent();
|
||
|
[SerializeField]
|
||
|
private OutputEvent m_onVirtualPressDown = new OutputEvent();
|
||
|
[SerializeField]
|
||
|
private OutputEvent m_onVirtualPressUp = new OutputEvent();
|
||
|
[SerializeField]
|
||
|
private List<GameObject> m_toggleGameObjectOnVirtualClick = new List<GameObject>();
|
||
|
[SerializeField]
|
||
|
private List<Behaviour> m_toggleComponentOnVirtualClick = new List<Behaviour>();
|
||
|
|
||
|
private bool m_isUpdating;
|
||
|
private int m_updatedFrameCount;
|
||
|
private bool m_prevPressState = false;
|
||
|
private bool m_currPressState = false;
|
||
|
private float m_lastPressDownTime = 0f;
|
||
|
private int m_clickCount = 0;
|
||
|
|
||
|
[Obsolete("Use Behaviour.enable instead.")]
|
||
|
public bool active { get { return enabled; } set { enabled = value; } }
|
||
|
|
||
|
public InputsOperatorEnum combineInputsOperator { get { return m_combineInputsOperator; } }
|
||
|
public List<InputEntry> inputs { get { return m_inputs; } }
|
||
|
public List<GameObject> toggleGameObjectOnVirtualClick { get { return m_toggleGameObjectOnVirtualClick; } }
|
||
|
public List<Behaviour> toggleComponentOnVirtualClick { get { return m_toggleComponentOnVirtualClick; } }
|
||
|
|
||
|
public OutputEvent onPress { get { return m_onVirtualPress; } }
|
||
|
public OutputEvent onClick { get { return m_onVirtualClick; } }
|
||
|
public OutputEvent onPressDown { get { return m_onVirtualPressDown; } }
|
||
|
public OutputEvent onPressUp { get { return m_onVirtualPressUp; } }
|
||
|
|
||
|
private bool isPress { get { return m_currPressState; } }
|
||
|
private bool isDown { get { return !m_prevPressState && m_currPressState; } }
|
||
|
private bool isUp { get { return m_prevPressState && !m_currPressState; } }
|
||
|
|
||
|
#if UNITY_EDITOR
|
||
|
private void Reset()
|
||
|
{
|
||
|
m_inputs.Add(new InputEntry()
|
||
|
{
|
||
|
viveRole = ViveRoleProperty.New(HandRole.RightHand),
|
||
|
button = ControllerButton.Trigger,
|
||
|
});
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
private void UpdateState()
|
||
|
{
|
||
|
if (!ChangeProp.Set(ref m_updatedFrameCount, Time.frameCount)) { return; }
|
||
|
|
||
|
m_prevPressState = m_currPressState;
|
||
|
m_currPressState = false;
|
||
|
|
||
|
if (m_inputs.Count == 0) { return; }
|
||
|
|
||
|
switch (m_combineInputsOperator)
|
||
|
{
|
||
|
case InputsOperatorEnum.Or:
|
||
|
|
||
|
m_currPressState = false;
|
||
|
|
||
|
for (int i = 0, imax = m_inputs.Count; i < imax; ++i)
|
||
|
{
|
||
|
if (ViveInput.GetPress(m_inputs[i].viveRole, m_inputs[i].button))
|
||
|
{
|
||
|
m_currPressState = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
case InputsOperatorEnum.And:
|
||
|
|
||
|
m_currPressState = true;
|
||
|
|
||
|
for (int i = 0, imax = m_inputs.Count; i < imax; ++i)
|
||
|
{
|
||
|
if (!ViveInput.GetPress(m_inputs[i].viveRole, m_inputs[i].button))
|
||
|
{
|
||
|
m_currPressState = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void Update()
|
||
|
{
|
||
|
m_isUpdating = true;
|
||
|
|
||
|
UpdateState();
|
||
|
|
||
|
var timeNow = Time.unscaledTime;
|
||
|
// handle events
|
||
|
if (isPress)
|
||
|
{
|
||
|
if (isDown)
|
||
|
{
|
||
|
// record click count
|
||
|
if (timeNow - m_lastPressDownTime < ViveInput.clickInterval)
|
||
|
{
|
||
|
++m_clickCount;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_clickCount = 1;
|
||
|
}
|
||
|
|
||
|
// record press down time
|
||
|
m_lastPressDownTime = timeNow;
|
||
|
|
||
|
// PressDown event
|
||
|
if (m_onVirtualPressDown != null)
|
||
|
{
|
||
|
m_onVirtualPressDown.Invoke(new OutputEventArgs()
|
||
|
{
|
||
|
senderObj = this,
|
||
|
eventType = ButtonEventType.Down,
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Press event
|
||
|
if (m_onVirtualPress != null)
|
||
|
{
|
||
|
m_onVirtualPress.Invoke(new OutputEventArgs()
|
||
|
{
|
||
|
senderObj = this,
|
||
|
eventType = ButtonEventType.Press,
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
else if (isUp)
|
||
|
{
|
||
|
// PressUp event
|
||
|
if (m_onVirtualPressUp != null)
|
||
|
{
|
||
|
m_onVirtualPressUp.Invoke(new OutputEventArgs()
|
||
|
{
|
||
|
senderObj = this,
|
||
|
eventType = ButtonEventType.Up,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (timeNow - m_lastPressDownTime < ViveInput.clickInterval)
|
||
|
{
|
||
|
for (int i = m_toggleGameObjectOnVirtualClick.Count - 1; i >= 0; --i)
|
||
|
{
|
||
|
if (m_toggleGameObjectOnVirtualClick[i] != null) { m_toggleGameObjectOnVirtualClick[i].SetActive(!m_toggleGameObjectOnVirtualClick[i].activeSelf); }
|
||
|
}
|
||
|
|
||
|
for (int i = m_toggleComponentOnVirtualClick.Count - 1; i >= 0; --i)
|
||
|
{
|
||
|
if (m_toggleComponentOnVirtualClick[i] != null) { m_toggleComponentOnVirtualClick[i].enabled = !m_toggleComponentOnVirtualClick[i].enabled; }
|
||
|
}
|
||
|
|
||
|
// Click event
|
||
|
if (m_onVirtualClick != null)
|
||
|
{
|
||
|
m_onVirtualClick.Invoke(new OutputEventArgs()
|
||
|
{
|
||
|
senderObj = this,
|
||
|
eventType = ButtonEventType.Click,
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!isActiveAndEnabled)
|
||
|
{
|
||
|
InternalDisable();
|
||
|
}
|
||
|
|
||
|
m_isUpdating = false;
|
||
|
}
|
||
|
|
||
|
private void OnDisable()
|
||
|
{
|
||
|
if (!m_isUpdating)
|
||
|
{
|
||
|
InternalDisable();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void InternalDisable()
|
||
|
{
|
||
|
var timeNow = Time.unscaledTime;
|
||
|
|
||
|
// clean up
|
||
|
m_prevPressState = m_currPressState;
|
||
|
m_currPressState = false;
|
||
|
|
||
|
if (isUp)
|
||
|
{
|
||
|
// PressUp event
|
||
|
if (m_onVirtualPressUp != null)
|
||
|
{
|
||
|
m_onVirtualPressUp.Invoke(new OutputEventArgs()
|
||
|
{
|
||
|
senderObj = this,
|
||
|
eventType = ButtonEventType.Up,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (timeNow - m_lastPressDownTime < ViveInput.clickInterval)
|
||
|
{
|
||
|
for (int i = m_toggleGameObjectOnVirtualClick.Count - 1; i >= 0; --i)
|
||
|
{
|
||
|
if (m_toggleGameObjectOnVirtualClick[i] != null) { m_toggleGameObjectOnVirtualClick[i].SetActive(!m_toggleGameObjectOnVirtualClick[i].activeSelf); }
|
||
|
}
|
||
|
|
||
|
for (int i = m_toggleComponentOnVirtualClick.Count - 1; i >= 0; --i)
|
||
|
{
|
||
|
if (m_toggleComponentOnVirtualClick[i] != null) { m_toggleComponentOnVirtualClick[i].enabled = !m_toggleComponentOnVirtualClick[i].enabled; }
|
||
|
}
|
||
|
|
||
|
// Click event
|
||
|
if (m_onVirtualClick != null)
|
||
|
{
|
||
|
m_onVirtualClick.Invoke(new OutputEventArgs()
|
||
|
{
|
||
|
senderObj = this,
|
||
|
eventType = ButtonEventType.Click,
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_prevPressState = false;
|
||
|
}
|
||
|
|
||
|
public bool GetVirtualPress()
|
||
|
{
|
||
|
UpdateState();
|
||
|
return isPress;
|
||
|
}
|
||
|
|
||
|
public bool GetVirtualPressDown()
|
||
|
{
|
||
|
UpdateState();
|
||
|
return isDown;
|
||
|
}
|
||
|
|
||
|
public bool GetVirtualPressUp()
|
||
|
{
|
||
|
UpdateState();
|
||
|
return isUp;
|
||
|
}
|
||
|
|
||
|
public int GetVirtualClickCount()
|
||
|
{
|
||
|
UpdateState();
|
||
|
return m_clickCount;
|
||
|
}
|
||
|
|
||
|
public float GetLastVirtualPressDownTime()
|
||
|
{
|
||
|
UpdateState();
|
||
|
return m_lastPressDownTime;
|
||
|
}
|
||
|
}
|
||
|
}
|