RPG游戏中玩家打开背包,鼠标移动到道具(类型为UI->Image)上,显示物品摘要;右键道具,则使用掉该物品。
UI控件挂载包含OnMouseOver函数的脚本后,鼠标移动到该控件上但OnMouseOver未触发。
首先我们看官方文档中对于OnMouseOver使用条件的介绍:
Called every frame while the mouse is over the GUIElement or Collider.
A call to OnMouseEnter occurs on the first frame the mouse is over the object. OnMouseOver is then called each frame until the mouse moves away, at which point OnMouseExit is called.
This function is not called on objects that belong to Ignore Raycast layer.
This function is called on Colliders marked as Trigger if and only if Physics.queriesHitTriggers is true.
OnMouseOver can be a co-routine, simply use the yield statement in the function. This event is sent to all scripts attached to the Collider or GUIElement.
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseOver.html
划重点:挂载的物体必须 是“GUIElement”或 “Collider”
那么我们的Image控件(如下图)是不是 GUIElement呢?
热心网友给出答案:(简要结论:不是!)
https://answers.unity.com/questions/998848/onmouseenter-not-working-on-ui-elements.html
翻译:
“我不认为它(OnMouseOver)会在UI元素上。
它只会工作在碰撞体或“GUIElement”——这是GUI系统中使用过 OnGUI 的东西的名字。
新的UI系统使用Pointer方法,它要求你在脚本中实现回调(IPointerEnterHandler 等等)并且使用 Event System。”
我基本赞同,意思是不是在场景中新建一个UI->Image,就能把这个图片控件称为“GUIElement”的,因为“GUIElement”有严格的定义(如上),所以这个Image我们最多把它叫UI控件,因此不能触发OnMouseOver。
将下述代码直接挂到物体上,注意using
https://blog.csdn.net/beihuanlihe130/article/details/80179794
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class MyTest2: MonoBehaviour, IPointerClickHandler
{
public UnityEvent leftClick;
public UnityEvent middleClick;
public UnityEvent rightClick;
private void Start()
{
leftClick.AddListener(new UnityAction(ButtonLeftClick));
middleClick.AddListener(new UnityAction(ButtonMiddleClick));
rightClick.AddListener(new UnityAction(ButtonRightClick));
}
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
leftClick.Invoke();
else if (eventData.button == PointerEventData.InputButton.Middle)
middleClick.Invoke();
else if (eventData.button == PointerEventData.InputButton.Right)
rightClick.Invoke();
}
private void ButtonLeftClick()
{
Debug.Log("Button Left Click");
}
private void ButtonMiddleClick()
{
Debug.Log("Button Middle Click");
}
private void ButtonRightClick()
{
Debug.Log("Button Right Click");
}
}
缺点是只能实现左中右键点击事件,不能设置鼠标移到物体上后的事件。
对物体添加新组件 Event Trigger,添加两个 New Event Type,分别选PointerEnter和PointerExit
在脚本中这样写:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class TheGrid : MonoBehaviour{
bool isOver = false; //鼠标是否在物体上
public void MouseEnter() {
isOver = true;
}
public void MouseExit(){
isOver = false;
}
private void Update(){
if (isOver) {
//鼠标移动到物体上时的事件
if (Input.GetMouseButtonDown(1)){
//右键点击物体时的事件
}
}
}
}
把脚本挂在物体上,把物体移到Event Trigger的相应位置,再分别选中MouseEnter和MouseExit函数。
优点是可实现鼠标在物体上时的事件设置,缺点是看起来好像不够优雅。。。。
工程源码:https://github.com/734843327/OnMouseOver-
联系方式:微信 wangwenaowwa