Search code examples
c#unity-game-engineimage-rotation

Unity3D - Rotate image in XY axis when mouse over


I want to find out how to rotating image when it is hovered like this:

https://drive.google.com/open?id=14_fxL8snv71yTd3F80Z6CsPeLKUQoco0

https://i.sstatic.net/CJu9S.jpg

I tried a lot of different options, but it works wrong.

Coroutine lastRoutine = null;

    public void OnPointerEnter(PointerEventData data)
    {
        lastRoutine = StartCoroutine(Test());
    }

        IEnumerator Test()
    {
        while (true)
        {
            Vector3 mousePos = Input.mousePosition;
            mousePos.z = 0f;

            Vector3 objectPos = Camera.main.WorldToScreenPoint(transform.position);
            mousePos.x = objectPos.x - mousePos.x;
            mousePos.y = objectPos.y - mousePos.y;

            float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
            transform.rotation = Quaternion.Euler(new Vector3(angle, angle, 0));

        yield return null;
        }
    }

    public void OnPointerExit(PointerEventData data)
    {
        StopCoroutine(lastRoutine);
    }

Solution

  • So here is how I would approach what you are trying to do:

    public class MouseEffect : MonoBehaviour
    {
        public float zOffset = -2f;
        public Vector2 tolerance = Vector2.one;
        Quaternion originalRotation;
    
        private void OnMouseEnter()
        {
            // Storing the original rotation so we can reset to it when we aren't hovering anymore
            originalRotation= transform.rotation;
        }
    
        private void OnMouseOver()
        {
            Vector3 localOffset = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
    
            // Multiplying by a adjustable tolerance, this is just a matter of preference if you want more rotation on the xAxis/yAxis or not.
            localOffset.x *= tolerance.x;
            localOffset.y *= tolerance.y;
            Vector3 worldOffset = transform.position + localOffset;
    
            // Setting a zOffset it will be really weird to adjust the rotation to look at something on the same Z as it.
            worldOffset.z = transform.position.z + zOffset;
    
            // Transform.LookAt for simplicity sake.
            transform.LookAt(worldOffset);
        }
    
        private void OnMouseExit()
        {
            // This can cause a bit of a twitching effect if you are right on the edge of the collider.
            transform.rotation = originalRotation;
        }
    }