Search Unity

Object Rotation Not Snapping In 2D

Discussion in 'Scripting' started by ErmergerdEnt, Oct 3, 2019.

  1. ErmergerdEnt

    ErmergerdEnt

    Joined:
    Apr 7, 2017
    Posts:
    54
    I've been trying to get my 2D Image To snap to certain points on the Z. Like if its close to 90, say at 85 degrees, lets snap it to 90, else if we are dragging again unsnap.. heres my code.

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4.  
    5. public class DragRotate : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler, IPointerDownHandler
    6. {
    7.  
    8.     public GameObject target;
    9.  
    10.     public event Action<Quaternion> OnAngleChanged;
    11.  
    12.     Quaternion dragStartRotation;
    13.     Quaternion dragStartInverseRotation;
    14.  
    15.  
    16.     private void Awake()
    17.     {
    18.      
    19.         OnAngleChanged += (rotation) => target.transform.localRotation = rotation;
    20.     }
    21.  
    22.  
    23.  
    24.     public void OnPointerDown(PointerEventData eventData)
    25.     {
    26.         dragStartRotation = target.transform.localRotation;
    27.         Vector3 worldPoint;
    28.         if (DragWorldPoint(eventData, out worldPoint))
    29.         {
    30.            
    31.             dragStartInverseRotation = Quaternion.Inverse(Quaternion.LookRotation(worldPoint - target.transform.position, Vector3.forward));
    32.         }
    33.         else
    34.         {
    35.             Debug.LogWarning("Couldn't get drag start world point");
    36.         }
    37.     }
    38.  
    39.     public void OnBeginDrag(PointerEventData eventData)
    40.     {
    41.        
    42.     }
    43.     public void OnEndDrag(PointerEventData eventData)
    44.     {
    45.      
    46.     }
    47.  
    48.     public void OnDrag(PointerEventData eventData)
    49.     {
    50.         Vector3 worldPoint;
    51.         if (DragWorldPoint(eventData, out worldPoint))
    52.         {
    53.             Quaternion currentDragAngle = Quaternion.LookRotation(worldPoint - target.transform.position, Vector3.forward);
    54.             if (OnAngleChanged != null)
    55.             {
    56.                 OnAngleChanged(currentDragAngle * dragStartInverseRotation * dragStartRotation);
    57.             }
    58.  
    59.             if (target.transform.rotation.z > 85)
    60.             {
    61.                 target.transform.rotation = Quaternion.Euler(0, 0, 90);
    62.             }
    63.         }
    64.     }
    65.  
    66.  
    67.  
    68.     private bool DragWorldPoint(PointerEventData eventData, out Vector3 worldPoint)
    69.     {
    70.         return RectTransformUtility.ScreenPointToWorldPointInRectangle(
    71.             GetComponent<RectTransform>(),
    72.             eventData.position,
    73.             eventData.pressEventCamera,
    74.             out worldPoint);
    75.     }
    76. }
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    I only took a very quick look at your code, so there may be more, but first and foremost:
    Rotations are stored and internally worked with as Quaternions, meaning target.transform.rotation.z > 85 does not do what you expect it to do.
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    A good way to get around that is to pick a direction vector (say, Vector3.right), and use Vector3.Angle between that vector and some target vector. For example:
    Code (csharp):
    1. if ( (Vector3.Angle(target.transform.rotation * Vector3.right, Vector3.up) < 5f) {
     
    ErmergerdEnt likes this.