Unity实现鼠标拖动交换两个物体位置,拖动移动及拖动复制

845 阅读3分钟

1.拖动交换两个物体位置

(1)首先在场景中新建一个Plane 两个Sphere,两个材质球和一个空对象。如图

image.png (2)然后新建脚本thing,编辑脚本如下,主要是定义鼠标对应三个状态的函数。


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

public class thing : MonoBehaviour
{

    //当鼠标按下时
    private void OnMouseDown()
    {
    }

    //当鼠标在按下的状态时
    private void OnMouseEnter()
    {
            
    }

    //当鼠标抬起时
    private void OnMouseUp()
    {
      
    }


}

3)然后新建脚本change,编辑脚本如下,主要作用是实现鼠标对应三个状态的相应的响应动作。


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

public class change : MonoBehaviour
{
    //单例模式
    static private change instance;
    //储存鼠标点击时触碰到的对象和鼠标按下状态时触碰到的对象
    public thing pressthing;
    public thing enterthing;
    public static change Instance { get => instance; set => instance = value; }
    private void Awake()
    {
        instance = this;
    }

    //当鼠标按下时,得到鼠标所对应的物体
    public void MouseDown(thing press)
    {
        pressthing = press;
    }


    //当鼠标在按下的状态时,得到此时鼠标所对应的物体
    public void MouseEnter(thing enter)
    {
        enterthing = enter;
    }

    //当鼠标释放时时,交换两者的位置
    public void MouseUp()
    {
        ChangeThing(pressthing, enterthing);
    }

    //交换方法
    public void ChangeThing(thing press, thing enter)
    {
        Vector3 temp;
        temp = pressthing.transform.position;
        pressthing.transform.position = enterthing.transform.position;
        enterthing.transform.position = temp;        
    }

}


然后更新thing脚本如下:



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

public class thing : MonoBehaviour
{

    //当鼠标按下时
    private void OnMouseDown()
    {
        change.Instance.MouseDown(this);
    }

    //当鼠标在按下的状态时
    private void OnMouseEnter()
    {
        change.Instance.MouseEnter(this);      
    }

    //当鼠标释放时时
    private void OnMouseUp()
    {
        change.Instance.MouseUp();
    }


}

最后把thing脚本添加到红蓝小球上,change脚本添加到两个物体上。运行游戏点击拖动鼠标就可实现交换两者的位置。

(5)如果想要实现交换的动画效果,可以使用协程控制移动。更改thing脚本和change脚本如下 thing脚本:




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

public class thing : MonoBehaviour
{

    //当鼠标按下时
    private void OnMouseDown()
    {
        change.Instance.MouseDown(this);
    }

    //当鼠标在按下的状态时
    private void OnMouseEnter()
    {
        change.Instance.MouseEnter(this);      
    }

    //当鼠标释放时时
    private void OnMouseUp()
    {
        change.Instance.MouseUp();
    }


   
    //移动动画
   public IEnumerator Move(thing positionThing, float movetime)
    {
        Vector3 startposition;
        Vector3 endposition;

        endposition = positionThing.transform.position;
        startposition = transform.position;
        for (float i = 0; i <= movetime; i += Time.deltaTime)
        {
            transform.position = Vector3.Lerp(startposition, endposition, i / movetime);          
            yield return 0;
        }
       
    }

}


change脚本:

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

public class change : MonoBehaviour
{
    //单例模式
    static private change instance;
    //储存鼠标点击时触碰到的对象和鼠标按下状态时触碰到的对象
    public thing pressthing;
    public thing enterthing;
    public static change Instance { get => instance; set => instance = value; }
    private void Awake()
    {
        instance = this;
    }

  
    //当鼠标按下时,得到鼠标所对应的物体
    public void MouseDown(thing press)
    {
        pressthing = press;
    }


    //当鼠标在按下的状态时,得到此时鼠标所对应的物体
    public void MouseEnter(thing enter)
    {
        enterthing = enter;
    }

    //当鼠标释放时时,交换两者的位置
    public void MouseUp()
    {
        
        StartCoroutine(pressthing.Move(enterthing,1));
        StartCoroutine(enterthing.Move(pressthing, 1));
    }
}

2.拖动移动

思路:在上面的基础上我们只需获取鼠标释放时,鼠标所在位置,然后写把需要移动物体的坐标替换成该坐标。这里就需要用到一些射线的知识,不懂得话可以先看一下这篇博客。Unity的Ray射线

更改change脚本添加Movething方法如下:


 public void Movething(Vector3 target)
 {
     
    pressthing.transform.position = target;
       
 }

更改thing脚本OnMouseUp方法如下:



private void OnMouseUp()
{
    // change.Instance.MouseUp();      
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//摄像机向鼠标所在位置生成一条射线
    RaycastHit hit;//储存碰撞信息
    Physics.Raycast(ray, out hit, 200f);
    change.Instance.Movething(hit.point);
}

3.拖动复制

思路:在上面的基础上我们只需获取鼠标释放时,鼠标所在位置,然后写把需要在该坐标位置上生成鼠标按下时所触碰到的小球。

更改change脚本如下:




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

public class change : MonoBehaviour
{
    //单例模式
    static private change instance;
    //储存鼠标点击时触碰到的对象和鼠标按下状态时触碰到的对象
    public thing pressthing;
    public thing enterthing;
    public static change Instance { get => instance; set => instance = value; }
    private void Awake()
    {
        instance = this;
    }

  
    //当鼠标按下时,得到鼠标所对应的物体
    public void MouseDown(thing press)
    {
        pressthing = press;
    }


    //当鼠标在按下的状态时,得到此时鼠标所对应的物体
    public void MouseEnter(thing enter)
    {
        enterthing = enter;
    }

    //当鼠标释放时时,交换两者的位置
    public void MouseUp(Vector3 target)
    {

        Copy(target, pressthing);
        //StartCoroutine(pressthing.Move(enterthing,1));
        //StartCoroutine(enterthing.Move(pressthing, 1));
    }

    //复制物体到目标位置
    public void Copy(Vector3 target, thing press)
    {

        Instantiate(press.transform.gameObject, target, Quaternion.identity);

    }

    //移动物体到目标位置
    public void Movething(Vector3 target)
    {
     
        pressthing.transform.position = target;
       
    }


}

更改thing脚本OnMouseUp方法如下:

 private void OnMouseUp()
    {         
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//摄像机向鼠标所在位置生成一条射线
        RaycastHit hit;//储存碰撞信息
        Physics.Raycast(ray, out hit, 200f);
        change.Instance.MouseUp(hit.point);
    }