Unity_移动端实现(多个)物体拖拽、旋转和缩放

目录

  • 一、说明
  • 二、实现
  • 三、注意
  • 四、使用思路


重要是做一个记录,思路不是太好,也不一定符合其他应用场景,应用不建议参考。


一、说明

场景:
有多个物体(模型)

目的:
平移模型、旋转模型、缩放模型

要求:
可单独操作某一个模型,而且不影响其他模型的操作(平移单独平移,旋转单独旋转)
点击在物体上操作的是平移,点击在物体外操作的是旋转(前提是要确定点击物体


二、实现

平移代码

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

public class Position_Script : MonoBehaviour {
     
    
    //偏移值
    Vector3 m_Offset;
    //当前物体对应的屏幕坐标
    Vector3 m_TargetScreenVec;
    //记录上一个点击的物体名字
    public string objectName = "Cube";

    private void Start()
    {
     
        
    }

    private void Update()
    {
     
        //当鼠标点击左键或者手触摸屏幕
        if (Input.GetMouseButtonDown(0))  //这个接口可能会报一个警告,不影响使用
        {
                                      //也可以使用另一个接口,Input.GetTouch(0)
           //确定点击物体
           ClickObject();
        }
    }

    private IEnumerator OnMouseDown()   //这个函数是在鼠标按下的时候执行
    {
     
        //当前物体对应的屏幕坐标
        m_TargetScreenVec = Camera.main.WorldToScreenPoint(transform.position);
        //偏移值=物体的世界坐标,减去转化之后的鼠标世界坐标(z轴的值为物体屏幕坐标的z值)
        m_Offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3
        (Input.mousePosition.x, Input.mousePosition.y, m_TargetScreenVec.z));
        //当鼠标左键点击
        while (Input.GetMouseButton(0))
        {
     
            //当前坐标等于转化鼠标为世界坐标(z轴的值为物体屏幕坐标的z值)+ 偏移量
            transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
             Input.mousePosition.y, m_TargetScreenVec.z)) + m_Offset;
            //等待固定更新
            yield return new WaitForFixedUpdate();
        }
    }

    /*  确定点击物体  */
    private void ClickObject()
    {
     
        RaycastHit raycastHit;
        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out raycastHit))  //Physics.Raycast 射线投射
        {
                                        //射线投射,当光线投射与任何碰撞器交叉时为真,否则为假
            Debug.Log(raycastHit.transform.name);
            //raycastHit.point 为点击的物体的具体位置
            Debug.Log(raycastHit.point);
            //将上一个点击的物体旋转脚本置为false。或者禁用所有物体上的  Rotation_Scale  脚本
            GameObject.Find(objectName).GetComponent<xz>().enabled = false;
            //this.GetComponent().enabled = false;  //
            //将现在点击的物体旋转脚本置为true
            GameObject.Find(raycastHit.transform.name).GetComponent<xz>().enabled = true;
            //将现在点击的物体名字记录下来
            objectName = raycastHit.transform.name;
        } 
    }
}


旋转代码

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

public class Rotation_Scale : MonoBehaviour {
     

    float speed = 0.1f;

    private Vector2 oldPos01;
    private Vector2 oldPos02;

    // Use this for initialization
    void Start () {
     
		
	}

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

        if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
        {
     
            RaycastHit raycastHit;
            var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            //Physics.Raycast() 当光线投射与任何碰撞器交叉时为真,否则为假
            if (Physics.Raycast(ray, out raycastHit))
            {
     

            }
            else
            {
     
                //得到手指在这一帧的移动距离
                Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
                //在X 轴上旋转物体
                // GameObject.Find("zhuan/Kazuko").transform.Rotate(0, touchDeltaPosition.x, 0);
                //任意轴旋转物体
                transform.Rotate(-Vector3.up * touchDeltaPosition.x * speed, Space.World);
                transform.Rotate(-Vector3.left * touchDeltaPosition.y * speed, Space.World);
            }
        }

        if (Input.touchCount == 2)
        {
     
            //第一个手指 或者第二个手指
            if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
            {
     
                Vector2 temPos1 = Input.GetTouch(0).position;
                Vector2 temPos2 = Input.GetTouch(1).position;
                if (IsEnlarge(oldPos01, oldPos02, temPos1, temPos2))
                {
     
                    //放大
                    float oldScale = transform.localScale.x;
                    float newScale = oldScale * 1.025f;
                    transform.localScale = new Vector3(newScale, newScale, newScale);
                }
                else
                {
     
                    //缩小
                    float oldScale = transform.localScale.x;
                    float newScale = oldScale / 1.025f;
                    transform.localScale = new Vector3(newScale, newScale, newScale);
                }

                oldPos01 = temPos1;
                oldPos02 = temPos2;
            }
        }


        //if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
        //{
     
        //    //得到手指在这一帧的移动距离
        //    Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
        //    //在X 轴上旋转物体
        //    // GameObject.Find("zhuan/Kazuko").transform.Rotate(0, touchDeltaPosition.x, 0);
        //    transform.Rotate(-Vector3.up * touchDeltaPosition.x * speed, Space.World);
        //    transform.Rotate(-Vector3.left * touchDeltaPosition.y * speed, Space.World);
        //}
    }

    //判断手势
    bool IsEnlarge(Vector2 op1, Vector2 op2, Vector2 np1, Vector2 np2)
    {
     
        //Mathf.Sqrt返回的平方根
        float lenth01 = Mathf.Sqrt((op1.x - op2.x) * (op1.x - op2.x) + (op1.y - op2.y) * (op1.y - op2.y));
        float lenth02 = Mathf.Sqrt((np1.x - np2.x) * (np1.x - np2.x) + (np1.y - np2.y) * (np1.y - np2.y));
        if (lenth01 < lenth02)
        {
     
            return true;
        }
        else
        {
     
            return false;
        }
    }
}


重置场景代码

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


public class ResetScene : MonoBehaviour {
     

	// Use this for initialization
	void Start () {
     
		
	}
	
	// Update is called once per frame
	void Update () {
     
		
	}

    public void RS()
    {
     
        SceneManager.LoadScene("test");
    }
}


三、注意

可能会修改的部分
Unity_移动端实现(多个)物体拖拽、旋转和缩放_第1张图片
Unity_移动端实现(多个)物体拖拽、旋转和缩放_第2张图片
Unity_移动端实现(多个)物体拖拽、旋转和缩放_第3张图片


四、使用思路

将脚本Position和脚本Rotation_Scale挂接在要操作的物体上,所有脚本Rotation_Scale默认不开启,点中哪个物体,哪个物体的脚本Rotation_Scale激活(置为true),可以进行旋转,但旋转不能操作在物体身上,而是在空白地方操作。当点击下一个物体的时候,下一个物体的脚本Rotation_Scale激活,上一个物体的脚本Rotation_Scale失效(置为false)(或者全部失效)。这样就实现了每次只操作一个物体

重置场景可以恢复到最初的状态。


你可能感兴趣的:(Unity,unity3d,脚本语言,移动开发)