Unity 实现从UI拖物体到场景中对应的层级上

我看到网上好像有挺多做这个的,我就稍微加个功能,物体只能摆放在对应的层级上面,直接上图:

左边是小车子,只能放到左边的Terrain层级上面,右边是类似公交车的车型,只能放到Plane层级上面。

层级设置:

 

整个功能的实现只需要一个脚本,我直接上代码:

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

public class SelectScript : MonoBehaviour
{
    private GameObject _Obj = null; 
    private GameObject _slectedObj;
    private string perfabePath = "Models/FBX/";  //我的perfab资源路径
    private string objName;
    private int count; 
    private float _YOffset; 
    public int rotateAngle = 3;
    private Dictionary<string, string> tagLayer; 
    GameObject fatherNode; 

    //下面这几个变量是移动物体的时候需要用到的,在这里声明是为了不会每帧都声明,节省性能
    Vector3 Gpoint;
    Vector3 screenPosition;
    Ray ray;
    RaycastHit hitInfo; 

    public void Selected()
    {
        CreatePrefab();
    }
    void Start()
    {
        tagLayer = new Dictionary<string, string>();  //物体的tag对应到放置的Layer层
        tagLayer.Add("TerrainObj", "Terrain");
        tagLayer.Add("PlaneObj", "Plane");
    }
    void Update()
    {
        if(_Obj != null)
        {
            MoveCurrentObj();
        }
    }
    /// <summary>
    /// 从UI界面创建对象
    /// </summary>
    void CreatePrefab()
    {
        _slectedObj = UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject;
        objName = _slectedObj.GetComponent<Image>().sprite.name;
        _Obj = Instantiate(Resources.Load(perfabePath + objName, typeof(GameObject))) as GameObject;
        _Obj.name = count + objName;
        _YOffset = _Obj.GetComponent<MeshFilter>().sharedMesh.bounds.size.y / 2f;  //根据物体的mesh边界确定偏移

        switch (tagLayer[_Obj.tag])
        {
            case "Terrain":
                fatherNode = GameObject.Find("TerrainNode");
                break;
            case "Plane":
                fatherNode = GameObject.Find("PlaneNode");
                break;
            default:
                break;
        }
        _Obj.transform.parent = fatherNode.transform;
        count++;
    }
    /// <summary>
    ///让当前对象跟随鼠标移动
    /// </summary>
    void MoveCurrentObj()
    {
        screenPosition = Input.mousePosition; //得到鼠标在屏幕的位置
        ray = Camera.main.ScreenPointToRay(screenPosition); //从鼠标位置发出射线
        
        if (_Obj)
        {
            if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, LayerMask.GetMask(tagLayer[_Obj.tag])))
            {
                Gpoint = hitInfo.point;

                _Obj.transform.position = Gpoint + new Vector3(0, _YOffset + 0.1f, 0); //在Y轴有个偏移,不会贴着layer表面,也可以不要这个偏移

                if (Input.GetKeyDown(KeyCode.Escape)) //在移动物体还没放下之前可以按键盘ESC键删除
                {
                    Destroy(_Obj);
                    _Obj = null;
                    Debug.Log("撤销!");
                }
                if (Input.mouseScrollDelta.y != 0)  //滑动滚轮旋转物体
                {
                    if (Input.mouseScrollDelta.y > 0)
                    {
                        _Obj.transform.Rotate(0, rotateAngle, 0);
                    }
                    else
                    {
                        _Obj.transform.Rotate(0, -rotateAngle, 0);
                    }
                }
                if (Input.GetMouseButtonDown(0))  //点击放置物体
                {
                    _Obj = null;
                }
            }
        }
    } 
}

         细心的朋友会发现,我给每个物体都起了一个名字,就是count+预制体的名字,然后再去场景中找一个对应的空物体当成父物体,这样是为了以后对功能做扩展,有个名字,就相当于该物体在场景中有了唯一的标识,后面会很方便。还有一个需要注意的是这个脚本需要挂在场景中一个对象上面的,然后点击的UI也需要做成按钮,点击这个图片的时候调用Selected()方法。

=================================================

附上下载地址:https://github.com/narutotosasuke/ItemSetting.git

PS:新建一个项目直接导入Unitypackage就行,但是对物体设置的Layer可能丢失,需要自己添加。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值