You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何通过UI按钮实现物体放置并跟随鼠标移动?

Unity物体放置:解决UI按钮触发后无法持续跟随鼠标的问题
  • 问题根源:你当前的PlaceHouse函数仅在UI按钮点击时执行一次,里面的鼠标跟随和点击检测逻辑自然只会运行一次,没法实时更新物体位置。用while循环导致冻结是因为Unity主线程被循环完全占用,根本没时间处理渲染、输入等核心任务,直接陷入死锁。

  • 正确实现思路:把需要持续执行的逻辑放到Unity的Update()函数中——这个函数会在每帧自动调用,完美适配鼠标跟随这类需要实时更新的操作。UI按钮只负责切换放置状态,以及创建/销毁预览物体。

修改后的完整代码:

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

public class PlaceObjectsWithUI : MonoBehaviour
{
    [SerializeField]
    private GameObject placeableObjectPrefab;

    private GameObject currentPlaceableObject;
    // 标记是否处于放置状态
    private bool isPlacing = false;

    public void PlaceHouse()
    {
        isPlacing = !isPlacing;

        if (isPlacing)
        {
            // 开启放置模式,生成预览物体
            currentPlaceableObject = Instantiate(placeableObjectPrefab);
        }
        else
        {
            // 关闭放置模式,销毁未放置的预览物体
            if (currentPlaceableObject != null)
            {
                Destroy(currentPlaceableObject);
                currentPlaceableObject = null;
            }
        }
    }

    // 每帧执行的实时更新逻辑
    private void Update()
    {
        if (isPlacing && currentPlaceableObject != null)
        {
            MoveCurrentPlaceableObjectToMouse();
            ReleaseIfClicked();
        }
    }

    private void MoveCurrentPlaceableObjectToMouse()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;

        if (Physics.Raycast(ray, out hitInfo))
        {
            currentPlaceableObject.transform.position = hitInfo.point;
            currentPlaceableObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
        }
    }

    private void ReleaseIfClicked()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // 点击鼠标完成放置,退出放置模式
            isPlacing = false;
            currentPlaceableObject = null;
        }
    }
}

关键改动说明:

  • 新增isPlacing布尔变量,用来控制是否进入放置状态
  • UI按钮点击时仅切换isPlacing状态,同时处理预览物体的创建/销毁
  • Update()每帧检查放置状态,只要处于放置模式,就实时更新物体位置,并监听鼠标点击完成放置
  • 这种方式不会阻塞主线程,保证Unity正常处理帧更新,实现物体持续跟随鼠标的效果

内容的提问来源于stack exchange,提问作者unityfan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:35:21