标签:鼠标 bool raycast 类型 class prot active 初始 private
??Selectable一共有Normal、Highlighted、Pressed、Disabled四个状态。
??新版本加入了Selected状态,老版本的Unity其实也对Selected状态进行了处理,当该Selectable是全局Selected对象时,将状态设置为Highlighted。
??老版本对Pressed状态的判定是要同时满足isPointerDown和isPointerInside时才时Pressed状态。当点击边缘时,如果有一个缩小的动画,会导致触发OnPointerExit,使isPointerInside为false,导致Pressed判定失败、Highlighted判定也失败、所以状态变为了Normal。这个时候按钮又变回了原来的大小,又会触发OnPointerEnter,使isPointerInside为true。Pressed判定成功。在这两个状态间不停循环,造成抽搐的表现。
protected bool IsPressed()
{
if (!IsActive())
return false;
return isPointerInside && isPointerDown
}
??移除了对Pressed状态的单独判定,整合在了currentSelectionState里,且移除了isPointerInside的限制。
protected SelectionState currentSelectionState
{
get
{
if (!IsInteractable())
return SelectionState.Disabled;
if (isPointerDown)
return SelectionState.Pressed;
if (hasSelection)
return SelectionState.Selected;
if (isPointerInside)
return SelectionState.Normal;
}
}
??没看具体是哪个版本修复的,就贴了两个我看到有改变的版本。
??最简单的方案。
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
//对状态切换的修复
//也可以加入一些长按逻辑、点击音效等功能,成为一个更完善的按钮类
public class BetterButton : Button
{
private bool isPointerDown = false;
public override void OnPointerDown(PointerEventData eventData)
{
isPointerDown = true;
base.OnPointerDown(eventData);
}
public override void OnPointerUp(PointerEventData eventData)
{
isPointerDown = false;
base.OnPointerUp(eventData);
GameObject currentOverGo = eventData.pointerCurrentRaycast.gameObject;
//如果pointerUp时所指向的press对象和按下时不一样,则需要主动调一下PointerExit去纠正isPointerInside
GameObject curPress = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
if (eventData.pointerPress != curPress)
{
OnPointerExit(eventData);
}
}
public override void OnPointerExit(PointerEventData eventData)
{
if (isPointerDown == false)
{
base.OnPointerExit(eventData);
}
}
}
??因为看过代码后我们可以确定在老版本中,OnPointerExit只负责isPointerInside和按钮状态的维护,没有其他逻辑。所以我们通过修改这部分代码区控制它的调用是一种比较安全的行为。
??我们强制让PointerExit在Selectable按下时不生效,在Selectable抬起时再尝试调用OnPointerExit纠正状态即可。
??如果升版本的话要及时把这些Trick代码删掉,因为我们在没有看新版的代码之前,不能确定是否会产生其他意料外的结果。
标签:鼠标 bool raycast 类型 class prot active 初始 private
原文地址:https://www.cnblogs.com/blueberryzzz/p/12682502.html