unity踩坑填坑集——OnMouseOver没反应

情景

         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呢?

 unity踩坑填坑集——OnMouseOver没反应_第1张图片

热心网友给出答案:(简要结论:不是!

unity踩坑填坑集——OnMouseOver没反应_第2张图片

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。

解决方案1

将下述代码直接挂到物体上,注意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");
    }
}

缺点是只能实现左中右键点击事件,不能设置鼠标移到物体上后的事件。

解决方案2

对物体添加新组件 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

你可能感兴趣的:(unity踩坑填坑集)