Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by C_Randy · Oct 26, 2016 at 06:26 AM · uieventsystempointer

Cursor.lockstate and OnPointerEnter not working together

Today we moved our project over from Unity 5.3.6 to 5.4.2, and so far we have only noticed one big issue. Locking the cursor used to center it and still trigger Pointer enters and exits on world space UI. But now according to the EventSystem in editor, the pointer position is set to -1,-1 and it does not trigger any enter or exit calls. I am currently thinking I will have to change how it is setup, even though it worked perfectly in 5.3.6. Has anyone else seen this?

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image hexagonius · Oct 26, 2016 at 08:00 AM 1
Share

It does sound more useful now since a locked cursor should probably not be able to do anything. But since you know you want to do something in the screen center can't you just implement center clicks yourself?
You can probably use EventSystem,current.RaycastAll with an EventData and the position set to screen center position. Then you can use ExecuteEvents.Execute to issue a click event on the GUI element you found.
Of course this might only work if you're talking about GUI elements. Otherwise a screen center Raycast and executing whatever you want might be it.

avatar image hekto · Dec 07, 2016 at 09:00 AM 0
Share

Try creating a custom Physics Raycaster and attach to the camera:

 public class CustomPhysicsRaycaster : PhysicsRaycaster
 {
     public override void Raycast (PointerEventData eventData, List<RaycastResult> resultAppendList)
     {
         if (Cursor.lockState != CursorLock$$anonymous$$ode.Locked) {
             base.Raycast (eventData, resultAppendList);
             return;
         }
  
         Ray ray = eventCamera.ViewportPointToRay (new Vector3 (0.5f, 0.5f, 0f));
  
         var hits = Physics.RaycastAll (ray, eventCamera.farClipPlane, event$$anonymous$$ask.value);
         for (int i = 0; i < hits.Length; i++) {
             var hit = hits [i];
             var result = new RaycastResult ();
             result.distance = hit.distance;
             result.gameObject = hit.collider.gameObject;
             result.index = i;
             resultAppendList.Add (result);
         }
     }
 }
 

2 Replies

· Add your reply
  • Sort: 
avatar image
5

Answer by RemiCarreira · Sep 20, 2018 at 11:46 AM

Hello, I have found a solution to avoid this problem (Still available in Unity 2018.2.6f).
Is not the best solution, but this can help.

Before calling the Process method of your Input Module, you can set the lock state of the cursor to None. To do this easily, you can create your custom input module like the code below.

 using UnityEngine;
 using UnityEngine.EventSystems;
 
 public class CustomInputModule : StandaloneInputModule
 {
     // Current cursor lock state (memory cache)
     private    CursorLockMode    _currentLockState    =    CursorLockMode.None;
 
     /// <summary>
     /// Process the current tick for the module.
     /// </summary>
     public override void    Process()
     {
         _currentLockState    =    Cursor.lockState;
 
         Cursor.lockState    =    CursorLockMode.None;
 
         base.Process();
 
         Cursor.lockState    =    _currentLockState;
     }
 }



Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Clonkex · Jan 05, 2019 at 01:10 PM 0
Share

Nice! This is such a clean and simple way of fixing it! Thanks!! :D

avatar image dan_cmj · Mar 28, 2019 at 02:42 PM 0
Share

This solved my problem perfectly. Thank you!

avatar image
1

Answer by Bezzy · Dec 12, 2016 at 03:56 PM

I tried doing something like this, but it seemed to break in 5.5.

It seems that, if Cursor.lockstate is on, then although the custom raycaster fires, the processing of the move is discarded.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image hekto · Dec 13, 2016 at 08:46 AM 2
Share

It seems like they changed this to ignore all pointer events while cursor is locked in 5.5.

I played around a bit with it and managed to get it to work. Use the Custom Physics Raycaster i posted before, in addition to replacing the default StandaloneInput$$anonymous$$odule on the EventSystem object with a custom one. See code below.

If you want to look more at the UI code, the relevant part can be found here: UI / UnityEngine.UI / EventSystem / Input$$anonymous$$odules / PointerInput$$anonymous$$odule.cs

I'm not sure this is the best workaround or how future proof it would be, though.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.EventSystems;
 
 public class CustomInput$$anonymous$$odule : StandaloneInput$$anonymous$$odule
 {
     protected override void Process$$anonymous$$ove (PointerEventData pointerEvent)
     {
         var targetGO = pointerEvent.pointerCurrentRaycast.gameObject;
         HandlePointerExitAndEnter (pointerEvent, targetGO);
     }
 }


avatar image Bezzy hekto · Dec 13, 2016 at 01:05 PM 1
Share

Haha, This is so funny. I literally was just co$$anonymous$$g back to show my fix and you've got the exact same one.

I'm going to post $$anonymous$$e just for fun.

 //This is only necessary because in Unity 5.5, code was added to ignore mouse process when the cursor was locked.
 namespace UnityEngine.EventSystems
 {
     [AddComponent$$anonymous$$enu("Event/Custom Standalone Input $$anonymous$$odule")]
     public class InteractiveStandaloneInput$$anonymous$$odule : StandaloneInput$$anonymous$$odule
     {
         protected override void Process$$anonymous$$ove(PointerEventData pointerEvent)
         {
             GameObject newEnterTarget =  pointerEvent.pointerCurrentRaycast.gameObject;
             base.HandlePointerExitAndEnter(pointerEvent, newEnterTarget);
         }
     }
 }

avatar image Bezzy Bezzy · Dec 13, 2016 at 01:08 PM 2
Share

Oh and I previously made my own custom raycaster. I actually use a sphere cast because it can be slightly more forgiving in terms of user interface. Like, you don't have to be pixel perfect. It's as if every object has a forgiving radius to it. Slightly more expensive, but it's a singleton so, whatevs.

 using System;
 using UnityEngine;
 using System.Collections.Generic;
 using UnityEngine.EventSystems;
 
 //I used IL2 to copy out the Physicsraycaster code and fix where the ray e$$anonymous$$ates from (in this case, always the center of the screen)
 public class InteractionRaycaster : PhysicsRaycaster {
 
     [Range(0.0f, 0.5f)]
     public float RayRadius;
 
     private readonly Vector2 _viewPos = new Vector2(0.5f, 0.5f);
   
     public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList)
     {
         if (!(this.eventCamera == null))
         {
             Ray ray = this.eventCamera.ViewportPointToRay(_viewPos);//this used to be the event position, but when the cursor is locked, that becomes -1,-1 so i fixed it
             float distance = this.eventCamera.farClipPlane - this.eventCamera.nearClipPlane;
             RaycastHit[] array = Physics.SphereCastAll(ray, RayRadius, distance, this.finalEvent$$anonymous$$ask);
             if (array.Length > 1)
             {
                 Array.Sort<RaycastHit>(array, (RaycastHit r1, RaycastHit r2) => r1.distance.CompareTo(r2.distance));
             }
             if (array.Length != 0)
             {
                 int i = 0;
                 int num = array.Length;
                 while (i < num)
                 {
                     RaycastResult item = new RaycastResult
                     {
                         gameObject = array[i].collider.gameObject,
                         module = this,
                         distance = array[i].distance,
                         worldPosition = array[i].point,
                         worldNormal = array[i].normal,
                         screenPosition = _viewPos,
                         index = (float)resultAppendList.Count,//dunno why this is a float
                         sortingLayer = 0,
                         sortingOrder = 0
                     };
                         
                     resultAppendList.Add(item);
                     i++;
                 }
             }
         }
     }
 }

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

91 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

IPointerEnterHandler doesn't work when object switches parent 1 Answer

PointerEnter / PointerExit keeps triggering on UI Element 0 Answers

Fake pointer up on UI gameobject A and pointer down on UI gameobject B 1 Answer

Get Global PointerEventData 1 Answer

Catch pointer events by multiple gameObjects 6 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges