2019년 3월 21일 목요일

360 각도 조절기 cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

[RequireComponent(typeof(RectTransform))]
public class RadialSlider : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerDownHandler
{
    public SprinklerController sprinklerController; // 스프링클러 컨트롤러
    public RectTransform centerPivot; // 회전시킬 피벗 (원점)
    public float slideArea = 10f; // 슬라이드 할 수 있는 영역의 거리 (원의 외곽선으로부터의 거리)
    [Range(0f, 360f)] public float minAngle = 0f; // 슬라이드 영역 최소 각도
    [Range(0f, 360f)] public float maxAngle = 360f; // 슬라이드 영역 최대 각도

    private float outerRadius; // 원의 외부 반지름
    private float innerRadius; // 원의 내부 반지름 (내부 반지름은 0보다 크고 외부 반지름보다 작아야 함!)
    private bool isSlideArea = false; // 슬라이드 영역 내부를 클릭했는지 여부

    // Use this for initialization
    void Start()
    {
        outerRadius = ((RectTransform)transform).rect.width / 2f; // 외부 반지름 설정
        innerRadius = outerRadius - slideArea; // 내부 반지름 설정
    }

    // Update is called once per frame
    void Update()
    {

    }

    /// <summary>
    /// 포인트의 각도를 변환하는 메서드
    /// </summary>
    /// <param name="point"></param>
    /// <returns></returns>
    private float GetAngle(Vector2 point)
    {
        float angle = Mathf.Atan2(point.x, point.y) * Mathf.Rad2Deg;

        angle = (angle + 360f) % 360f; // 양수만 나오게 360도를 더한 후 360도로 모듈러 연산 수행

        return angle;
    }
   
    public void OnBeginDrag(PointerEventData eventData)
    {
        Vector2 point;
        RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, eventData.position, eventData.pressEventCamera, out point); // RectTransform의 로컬 포인트로 변환

        // 드래그를 시작한 포인트가 원의 외부 반지름보다 큰 영역일 경우 실행 안함
        if (point.x * point.x + point.y * point.y > outerRadius * outerRadius)
            return;

        // 드래그를 시작한 포인트가 원의 내부 반지름보다 작은 영역일 경우 실행 안함
        if (point.x * point.x + point.y * point.y < innerRadius * innerRadius)
            return;

        float angle = GetAngle(point);

        if (angle < minAngle || angle > maxAngle)
            return;

        isSlideArea = true;
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (!isSlideArea)
            return;

        Vector2 point;
        RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, eventData.position, eventData.pressEventCamera, out point); // RectTransform의 로컬 포인트로 변환

        if (centerPivot)
        {
            float angle = GetAngle(point);
           
            if (angle >= minAngle && angle <= maxAngle)
            {
                centerPivot.localEulerAngles = new Vector3(centerPivot.localEulerAngles.x, centerPivot.localEulerAngles.y, -angle);
                sprinklerController.OnValueChangedSprinklerPan(angle); // 스프링클러 팬 회전
            }
        }

    }

    public void OnEndDrag(PointerEventData eventData)
    {
        if (!isSlideArea)
            return;

        Vector2 point;
        RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, eventData.position, eventData.pressEventCamera, out point); // RectTransform의 로컬 포인트로 변환

        if (centerPivot)
        {
            float angle = GetAngle(point); // 라디안 각도를 도로 변환
           
            // UI의 Z축 회전은 World와 반대이기 때문에 -를 해줌
            if (angle >= minAngle && angle <= maxAngle)
            {
                centerPivot.localEulerAngles = new Vector3(centerPivot.localEulerAngles.x, centerPivot.localEulerAngles.y, -angle);
                sprinklerController.OnValueChangedSprinklerPan(angle); // 스프링클러 팬 회전
            }
        }

        isSlideArea = false;
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        Vector2 point;
        RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, eventData.position, eventData.pressEventCamera, out point); // RectTransform의 로컬 포인트로 변환

        // 마우스 다운 한 포인트가 원의 외부 반지름보다 큰 영역일 경우 실행 안함
        if (point.x * point.x + point.y * point.y > outerRadius * outerRadius)
            return;

        // 마우스 다운 한 포인트가 원의 내부 반지름보다 작은 영역일 경우 실행 안함
        if (point.x * point.x + point.y * point.y < innerRadius * innerRadius)
            return;

        if (centerPivot)
        {
            float angle = GetAngle(point); // 라디안 각도를 도로 변환
           
            // UI의 Z축 회전은 World와 반대이기 때문에 -를 해줌
            if (angle >= minAngle && angle <= maxAngle)
            {
                centerPivot.localEulerAngles = new Vector3(centerPivot.localEulerAngles.x, centerPivot.localEulerAngles.y, -angle);
                sprinklerController.OnValueChangedSprinklerPan(angle); // 스프링클러 팬 회전
            }
        }
    }

    public void OnPointerClick(PointerEventData eventData)
    {

    }
}

댓글 없음:

댓글 쓰기

git rejected error(feat. cherry-pick)

 문제 아무 생각 없이 pull을 받지않고 로컬에서 작업! 커밋, 푸시 진행을 해버렷다. push에선 remote와 다르니 당연히 pull을 진행해라고 하지만 로컬에서 작업한 내용을 백업하지 않고 진행하기에는 부담스럽다(로컬작업 유실 가능성) 해결하려...