diff --git a/Assets/TEngine/Runtime/Extension.meta b/Assets/TEngine/Runtime/Extension.meta new file mode 100644 index 00000000..c2444ce5 --- /dev/null +++ b/Assets/TEngine/Runtime/Extension.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c8b5c360cd2cef74d970f541e100de8c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension.meta b/Assets/TEngine/Runtime/Extension/UGUIExtension.meta new file mode 100644 index 00000000..d95b32fc --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d6d53de31ee70e0478fb74c7bd4ac2d4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend.meta b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend.meta new file mode 100644 index 00000000..4a3a3b0b --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 132d75994d564f239bd5cec2c237c0ee +timeCreated: 1673948810 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/DragHandler.cs b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/DragHandler.cs new file mode 100644 index 00000000..8014b966 --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/DragHandler.cs @@ -0,0 +1,117 @@ +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +namespace TEngine +{ + public class DragHandler : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler + { + private OnDragEvent _onDrag; + private OnDragEvent _onBeginDrag; + private OnDragEvent _onEndDrag; + private bool _isOnDrag = false; + private RectTransform _rect; + + private void Start() + { + _rect = (transform.parent) ? transform.parent.GetComponent() : null; + } + + public OnDragEvent onDrag + { + get + { + if (_onDrag == null) + { + _onDrag = new OnDragEvent(); + } + return _onDrag; + } + } + + public OnDragEvent onBeginDrag + { + get + { + if (_onBeginDrag == null) + { + _onBeginDrag = new OnDragEvent(); + } + return _onBeginDrag; + } + } + + public OnDragEvent onEndDrag + { + get + { + if (_onEndDrag == null) + { + _onEndDrag = new OnDragEvent(); + } + return _onEndDrag; + } + } + + public static DragHandler Get(GameObject go) + { + DragHandler listener = go.GetComponent(); + if (listener == null) listener = go.AddComponent(); + return listener; + } + + public void OnDrag(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) return; + _isOnDrag = true; + if (onDrag != null) + { + Vector3 position = new Vector3(eventData.position.x, eventData.position.y, 0); + if (_rect) + { + RectTransformUtility.ScreenPointToWorldPointInRectangle(_rect, eventData.position, eventData.pressEventCamera, out position); + position.z = 0; + } + onDrag.Invoke(position, eventData); + } + } + + public void OnBeginDrag(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) return; + _isOnDrag = true; + if (onBeginDrag != null) + { + Vector3 position = new Vector3(eventData.position.x, eventData.position.y, 0); + if (_rect) + { + RectTransformUtility.ScreenPointToWorldPointInRectangle(_rect, eventData.position, eventData.pressEventCamera, out position); + //position.z = eventData.pressEventCamera.transform.position.z; + position.z = 0; + } + onBeginDrag.Invoke(position, eventData); + } + } + + public void OnEndDrag(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left || !_isOnDrag) return; + if (onEndDrag != null) + { + Vector3 position = new Vector3(eventData.position.x, eventData.position.y, 0); + if (_rect) + { + RectTransformUtility.ScreenPointToWorldPointInRectangle(_rect, eventData.position, eventData.pressEventCamera, out position); + position.z = 0; + } + onEndDrag.Invoke(position, eventData); + } + _isOnDrag = false; + } + } + + public class OnDragEvent : UnityEvent + { + + } +} diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/DragHandler.cs.meta b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/DragHandler.cs.meta new file mode 100644 index 00000000..5bea506c --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/DragHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 11e8b4fd60224df8b40c720667926c51 +timeCreated: 1673948810 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/EventTriggerListener.cs b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/EventTriggerListener.cs new file mode 100644 index 00000000..63268a80 --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/EventTriggerListener.cs @@ -0,0 +1,180 @@ +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; + +namespace TEngine +{ + public class EventTriggerListener : EventTrigger + { + public delegate void VoidDelegate(GameObject go); + public delegate void EventDelegate(GameObject go, PointerEventData ev); + [FormerlySerializedAs("onClick")] + public VoidDelegate OnClick; + [FormerlySerializedAs("onDown")] + public EventDelegate OnDown; + [FormerlySerializedAs("v")] + public EventDelegate OnExit; + [FormerlySerializedAs("onUp")] + public EventDelegate OnUp; + [FormerlySerializedAs("onSelect")] + public VoidDelegate OnSelectEvent; + [FormerlySerializedAs("onUpdateSelect")] + public VoidDelegate OnUpdateSelect; + [FormerlySerializedAs("onDragBegin")] + public EventDelegate OnDragBegin; + [FormerlySerializedAs("onDrag")] + public EventDelegate OnDragEvent; + [FormerlySerializedAs("onDragEnd")] + public EventDelegate OnDragEnd; + [FormerlySerializedAs("onEnter")] + public EventDelegate OnEnter; + [FormerlySerializedAs("onDrop")] + public EventDelegate OnDropEvent; + + public delegate void ClickEffectDelegate(); + public static EventTriggerListener Get(GameObject go, float time = -1, bool play_ani = true, float scale = 1) + { + if (!go) + { + Log.Warning("EventTriggerListener.Get, GameObject is null!!"); + } + EventTriggerListener listener = go.GetComponent(); + + if (listener == null) + listener = go.AddComponent(); + return listener; + } + + private bool _IsValidTrigger() + { + return true; + } + + public override void OnPointerClick(PointerEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + if (Input.touchCount > 1) + { + return; + } + OnClick?.Invoke(gameObject); + } + + public override void OnPointerDown(PointerEventData event_data) + { + if (!this._IsValidTrigger()) + { + return; + } + OnDown?.Invoke(gameObject, event_data); + } + + public override void OnPointerEnter(PointerEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + OnEnter?.Invoke(gameObject, event_data); + } + + public override void OnPointerExit(PointerEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + OnExit?.Invoke(gameObject, event_data); + } + + public override void OnPointerUp(PointerEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + OnUp?.Invoke(gameObject, event_data); + } + + public override void OnSelect(BaseEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + OnSelectEvent?.Invoke(gameObject); + } + + public override void OnUpdateSelected(BaseEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + OnUpdateSelect?.Invoke(gameObject); + } + + public override void OnBeginDrag(PointerEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + OnDragBegin?.Invoke(gameObject, event_data); + } + + public override void OnDrag(PointerEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + OnDragEvent?.Invoke(gameObject, event_data); + } + + public override void OnEndDrag(PointerEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + OnDragEnd?.Invoke(gameObject, event_data); + } + + public override void OnDrop(PointerEventData event_data) + { + if (!_IsValidTrigger()) + { + return; + } + + OnDropEvent?.Invoke(gameObject, event_data); + } + + private void OnDestroy() + { + OnClick = null; + OnDown = null; + OnExit = null; + OnUp = null; + OnSelectEvent = null; + OnDragBegin = null; + OnDragEvent = null; + OnDragEnd = null; + OnEnter = null; + OnDropEvent = null; + OnDragEnd = null; + } + } +} diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/EventTriggerListener.cs.meta b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/EventTriggerListener.cs.meta new file mode 100644 index 00000000..f026990a --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/EventTriggerListener.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 82dee44fc47d40eca1d6896ae8d8fa44 +timeCreated: 1673948810 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/PointerLongPress.cs b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/PointerLongPress.cs new file mode 100644 index 00000000..0130bd03 --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/PointerLongPress.cs @@ -0,0 +1,154 @@ +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +namespace TEngine +{ + public class PointerLongPress : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler, IPointerClickHandler + { + public float durationThreshold = 1.0f; //触发长按的时间阈值 + public float startSpeed = 3; //开始速度 + public float addSpeed = 2; //加速度 + public float maxValue = 25; //最大值 + public float callIntervalTime = 0.05f; //调用间隔时间,时间为0只触发一次长按点击回调 + + private bool _isPointerDown = false; + private bool _longPressTriggered = false; + private bool _isGreaterMaxValue = false; //是否已经大于最大值 + private float _curTime = 0; + private float _curCallTime = 0; + + private OnLongPressEvent _onLongPress; + private UnityEvent _onClick; + + public UnityEvent onClick + { + get + { + if (_onClick == null) + { + _onClick = new UnityEvent(); + } + return _onClick; + } + } + + public OnLongPressEvent onLongPress + { + get + { + if (_onLongPress == null) + { + _onLongPress = new OnLongPressEvent(); + } + return _onLongPress; + } + } + + public static PointerLongPress Get(GameObject go) + { + PointerLongPress listener = go.GetComponent(); + if (listener == null) listener = go.AddComponent(); + return listener; + } + + public void SetLongPressParam(float durationThreshold, float startSpeed, float maxValue, float addSpeed, float callIntervalTime) + { + this.durationThreshold = durationThreshold; + this.startSpeed = startSpeed; + this.maxValue = maxValue; + this.addSpeed = addSpeed; + this.callIntervalTime = callIntervalTime; + } + + private void Update() + { + if (_isPointerDown) + { + if (!_longPressTriggered) + { + _curTime += Time.deltaTime; + if (_curTime >= durationThreshold) + { + _longPressTriggered = true; + _isGreaterMaxValue = false; + _curTime = 0; + _curCallTime = 0; + if (callIntervalTime <= 0) + { + onLongPress?.Invoke(0); + } + } + } + else if (callIntervalTime > 0) + { + _curTime += Time.deltaTime; + _curCallTime += Time.deltaTime; + if (_curCallTime >= callIntervalTime) + { + float value = 0; + if (_isGreaterMaxValue) + { + value = maxValue; + } + else + { + float curSpeed = (startSpeed + startSpeed + addSpeed * _curTime) * 0.5f; + value = curSpeed * _curTime; + if (value >= maxValue) + { + _isGreaterMaxValue = true; + value = maxValue; + } + } + + //TLogger.LogInfo("value:" + value + ",长按持续时间:" + _curTime); + _curCallTime = 0; + onLongPress?.Invoke(Mathf.FloorToInt(value)); + } + } + } + } + + private void OnEnable() + { + _isPointerDown = false; + _longPressTriggered = false; + _curTime = 0; + } + + public void OnPointerDown(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) return; + _curTime = 0; + _isPointerDown = true; + _longPressTriggered = false; + } + + public void OnPointerUp(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) return; + _isPointerDown = false; + } + + public void OnPointerExit(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) return; + _isPointerDown = false; + } + + public void OnPointerClick(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) return; + if (!_longPressTriggered) + { + onClick.Invoke(); + } + } + } + + public class OnLongPressEvent : UnityEvent + { + + } +} diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/PointerLongPress.cs.meta b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/PointerLongPress.cs.meta new file mode 100644 index 00000000..268f45e7 --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/MonoExtend/PointerLongPress.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 65a01507196e4cd4b08fbebeb3228346 +timeCreated: 1673948810 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper.meta b/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper.meta new file mode 100644 index 00000000..0aea0984 --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5d5f14034f8f4763b481911841c287d8 +timeCreated: 1673928618 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper/UIButtonSuper.cs b/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper/UIButtonSuper.cs new file mode 100644 index 00000000..d8e7c33a --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper/UIButtonSuper.cs @@ -0,0 +1,291 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.EventSystems; +using System; +using UnityEngine.UI; + +#if UNITY_EDITOR +using UnityEditor; +using UnityEditor.UI; + +[CustomEditor(typeof(UIButtonSuper), true)] +[CanEditMultipleObjects] +public class UIButtonSuperEditor : ButtonEditor +{ + private SerializedProperty m_ButtonUISounds; + private SerializedProperty m_CanClick; + private SerializedProperty m_CanDoubleClick; + private SerializedProperty m_DoubleClickIntervalTime; + private SerializedProperty onDoubleClick; + + private SerializedProperty m_CanLongPress; + private SerializedProperty m_ResponseOnceByPress; + private SerializedProperty m_LongPressDurationTime; + private SerializedProperty onPress; + + protected override void OnEnable() + { + base.OnEnable(); + + m_ButtonUISounds = serializedObject.FindProperty("m_ButtonUISounds"); + m_CanClick = serializedObject.FindProperty("m_CanClick"); + m_CanDoubleClick = serializedObject.FindProperty("m_CanDoubleClick"); + m_DoubleClickIntervalTime = serializedObject.FindProperty("m_DoubleClickIntervalTime"); + onDoubleClick = serializedObject.FindProperty("onDoubleClick"); + + m_CanLongPress = serializedObject.FindProperty("m_CanLongPress"); + m_ResponseOnceByPress = serializedObject.FindProperty("m_ResponseOnceByPress"); + m_LongPressDurationTime = serializedObject.FindProperty("m_LongPressDurationTime"); + onPress = serializedObject.FindProperty("onPress"); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + serializedObject.Update(); + EditorGUILayout.PropertyField(m_ButtonUISounds); //显示我们创建的属性 + EditorGUILayout.PropertyField(m_CanClick); //显示我们创建的属性 + EditorGUILayout.Space(); //空行 + EditorGUILayout.PropertyField(m_CanDoubleClick); //显示我们创建的属性 + EditorGUILayout.PropertyField(m_DoubleClickIntervalTime); //显示我们创建的属性 + EditorGUILayout.PropertyField(onDoubleClick); //显示我们创建的属性 + EditorGUILayout.Space(); //空行 + EditorGUILayout.PropertyField(m_CanLongPress); //显示我们创建的属性 + EditorGUILayout.PropertyField(m_ResponseOnceByPress); //显示我们创建的属性 + EditorGUILayout.PropertyField(m_LongPressDurationTime); //显示我们创建的属性 + EditorGUILayout.PropertyField(onPress); //显示我们创建的属性 + serializedObject.ApplyModifiedProperties(); + } +} + +#endif + +public enum ButtonSoundType +{ + Down, + Up, + Click, + Enter, + Exit, + Drag +} + +[Serializable] +public class ButtonSoundCell +{ + public ButtonSoundType ButtonSoundType = ButtonSoundType.Click; + public string ButtonUISoundName = "ui_click_button"; +} + +public delegate void ButtonBeginDragCallback(PointerEventData eventData); + +public delegate void ButtonDragCallback(PointerEventData eventData); + +public delegate void ButtonEndDragCallback(PointerEventData eventData); + +public class UIButtonSuper : Button, IBeginDragHandler, IDragHandler, IEndDragHandler +{ + public List m_ButtonUISounds = new List() { new ButtonSoundCell() }; + [Tooltip("是否可以点击")] public bool m_CanClick = true; + [Tooltip("是否可以双击")] public bool m_CanDoubleClick = false; + [Tooltip("双击间隔时长")] public float m_DoubleClickIntervalTime = 0.1f; + [Tooltip("双击事件")] public ButtonClickedEvent onDoubleClick; + [Tooltip("是否可以长按")] public bool m_CanLongPress = false; + [Tooltip("长按是否只响应一次")] public bool m_ResponseOnceByPress = false; + [Tooltip("长按满足间隔")] public float m_LongPressDurationTime = 1; + + [Tooltip("长按事件")] public ButtonClickedEvent onPress; + + //public ButtonClickedEvent onClick; + public ButtonBeginDragCallback onBeginDrag; + public ButtonDragCallback onDrag; + public ButtonEndDragCallback onEndDrag; + + private bool isDown = false; + private bool isPress = false; + private bool isDownExit = false; + private float downTime = 0; + + private int fingerId = int.MinValue; + + public bool IsDraging + { + get { return fingerId != int.MinValue; } + } //摇杆拖拽状态 + + public int FingerId + { + get { return fingerId; } + } + + private float clickIntervalTime = 0; + private int clickTimes = 0; + + void Update() + { + if (isDown) + { + if (!m_CanLongPress) + { + return; + } + + if (m_ResponseOnceByPress && isPress) + { + return; + } + + downTime += Time.deltaTime; + if (downTime > m_LongPressDurationTime) + { + isPress = true; + onPress.Invoke(); + } + } + + if (clickTimes >= 1) + { + if (!m_CanLongPress && !m_CanDoubleClick && m_CanClick) + { + onClick.Invoke(); + clickTimes = 0; + } + else + { + clickIntervalTime += Time.deltaTime; + if (clickIntervalTime >= m_DoubleClickIntervalTime) + { + if (clickTimes >= 2) + { + if (m_CanDoubleClick) + { + onDoubleClick.Invoke(); + } + } + else + { + if (m_CanClick) + { + onClick.Invoke(); + } + } + + clickTimes = 0; + clickIntervalTime = 0; + } + } + } + } + + /// + /// 是否按钮按下 + /// + public bool IsDown + { + get { return isDown; } + } + + /// + /// 是否按钮长按 + /// + public bool IsPress + { + get { return isPress; } + } + + /// + /// 是否按钮按下后离开按钮位置 + /// + public bool IsDownExit + { + get { return isDownExit; } + } + + public ButtonSoundCell GetButtonSound(ButtonSoundType buttonSoundType) + { + foreach (var buttonSound in m_ButtonUISounds) + { + if (buttonSound.ButtonSoundType == buttonSoundType) + { + return buttonSound; + } + } + + return null; + } + + private void PlayButtonSound(ButtonSoundType buttonSoundType) + { + ButtonSoundCell buttonSound = GetButtonSound(buttonSoundType); + if (buttonSound == null) + { + return; + } + + GameModule.Audio.Play(TEngine.AudioType.Sound, buttonSound.ButtonUISoundName); + } + + public override void OnPointerEnter(PointerEventData eventData) + { + base.OnPointerEnter(eventData); + PlayButtonSound(ButtonSoundType.Enter); + } + + public override void OnPointerDown(PointerEventData eventData) + { + base.OnPointerDown(eventData); + if (eventData.pointerId < -1 || IsDraging) return; //适配 Touch:只响应一个Touch;适配鼠标:只响应左键 + fingerId = eventData.pointerId; + isDown = true; + isDownExit = false; + downTime = 0; + PlayButtonSound(ButtonSoundType.Down); + } + + public override void OnPointerUp(PointerEventData eventData) + { + base.OnPointerUp(eventData); + if (fingerId != eventData.pointerId) return; //正确的手指抬起时才会; + fingerId = int.MinValue; + isDown = false; + isDownExit = true; + PlayButtonSound(ButtonSoundType.Up); + } + + public override void OnPointerExit(PointerEventData eventData) + { + base.OnPointerExit(eventData); + if (fingerId != eventData.pointerId) return; //正确的手指抬起时才会; + isPress = false; + isDownExit = true; + PlayButtonSound(ButtonSoundType.Exit); + } + + public override void OnPointerClick(PointerEventData eventData) + { + if (!isPress) + { + clickTimes += 1; + } + else + isPress = false; + + PlayButtonSound(ButtonSoundType.Click); + } + + public void OnBeginDrag(PointerEventData eventData) + { + onBeginDrag?.Invoke(eventData); + } + + public void OnDrag(PointerEventData eventData) + { + PlayButtonSound(ButtonSoundType.Drag); + onDrag?.Invoke(eventData); + } + + public void OnEndDrag(PointerEventData eventData) + { + onEndDrag?.Invoke(eventData); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper/UIButtonSuper.cs.meta b/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper/UIButtonSuper.cs.meta new file mode 100644 index 00000000..e0896e44 --- /dev/null +++ b/Assets/TEngine/Runtime/Extension/UGUIExtension/UIButtonSuper/UIButtonSuper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fa4f44179d534f148b96822ead9e9b8f +timeCreated: 1673928618 \ No newline at end of file