【问题标题】:Rotate Bar Based on Touch Drag基于触摸拖动旋转栏
【发布时间】:2021-08-05 02:39:06
【问题描述】:

我想根据与枢轴点相关的手指触摸绘制来旋转条。在测试结构实现之后,我创建了它用于测试目的。

目前,我可以编写这段代码:

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

public class TestRotateController : MonoBehaviour
{

 float rotateSpeed = 10f;
 Vector2 touchStartPos;
 Transform touchItem;
 //
 [SerializeField] LayerMask touchItemsMask;

 private void Update()
 {
     if (Input.GetMouseButtonDown(0))
     {
         Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
         Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);

         RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero, 0f, touchItemsMask);

         if (hit.collider != null && hit.transform.CompareTag(GameConstants.TAG_RELEASE_ANGLE_BAR))
         {
             touchItem = hit.transform;
             touchStartPos = mousePos2D;
         }
     }
     else if (Input.GetMouseButton(0))
     {
         if (touchItem != null && touchItem.CompareTag(GameConstants.TAG_RELEASE_ANGLE_BAR))
         {

             Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
             Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);

             RotateReleaseAngleBar(touchStartPos, mousePos2D);

         }
     }
     else if (Input.GetMouseButtonUp(0))
     {
         touchItem = null;
     }
 }


 // rotate pivot parent
 public void RotateReleaseAngleBar(Vector2 touchStartPosition, Vector2 touchPosition)
 {
     if (touchStartPosition.x > touchPosition.x)
     {
         transform.parent.Rotate(Vector3.forward, rotateSpeed * Time.deltaTime);
     }
     else if (touchStartPosition.x < touchPosition.x)
     {
         transform.parent.Rotate(Vector3.forward, -rotateSpeed * Time.deltaTime);
     }
 }
}

现在使用此代码,我无法在手指移动时旋转栏。 选定的方向将保持正确,因为我已使用 X 值来决定这一点,但是当我停止拖动手指时,旋转也会继续沿同一方向。

我想停止这个,我想根据手指拖动量旋转条。这是一种体验,我想要一个人用手指在旋转杆。

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    我认为您并不想每帧将条形旋转一定量,而是在每帧相对于手指更新其旋转。 您当前正在旋转条形图,而不考虑当前帧的确切 (x,y) mouse2D 位置,这正是您所需要的。

    这个脚本适用于我,假设您将它分配给枢轴的子节点(正如我假设您在屏幕截图中所做的那样)

    public class TestRotateController : MonoBehaviour
    {
        //member variables
        
        void Update() {
            //[...] take the input as you did...
            //else
            if (Input.GetMouseButton(0)) {
                //if(touchItem != null...) {
                    Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                    Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);
                    RotateFollowPoint(mousePos2D);
                //}
            }
            //[else...]
        }
        
        //sets the angle of the bar to point in the direction of targetPoint2D
        void RotateFollowPoint(Vector2 targetPoint2D) {
    
            Vector2 position2D = new Vector2(transform.parent.position.x, transform.parent.position.y);
            float angle = Vector2.Angle(Vector2.right, targetPoint2D - position2D);
    
            if (targetPoint2D.y < position2D.y)
                angle *= -1;
    
            transform.parent.eulerAngles = new Vector3(0, 0, angle);
        }
        
    }
    

    首先获取轴心点的 2D 位置,然后计算从轴心点到点击点的向量(targetPoint2D - position2D)与Vector2.right 向量(即 (1, 0),所以是一个指向右的向量),这意味着条形必须在其默认位置上向右定向(当枢轴的 Z 旋转 = 0 时)。

    那么由于Vector2.Angle给出了锐角,如果大于180°就设置为负数,最后相应地更新角度

    【讨论】:

    • 谢谢@Lockyard,我不希望有比这更好的解释:)
    猜你喜欢
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    相关资源
    最近更新 更多