【Unity开发】Unity实现对模型移动、缩放、旋转操作的功能

发布于:2025-07-05 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、效果展示

Unity实现模型移动、旋转和缩放功能

通过鼠标实现对模型的不同操作
鼠标中键点击,模型变为高亮状态,表示选中状态,再次点击其他地方,则取消高亮,表示未选中状态
鼠标中键上下滚动,实现模型的缩放
鼠标左键点击或长按,实现模型的移动
鼠标右键点击,左右滑动,实现模型的水平旋转;同时按下shift键,上下滑动,实现模型垂直旋转

二、实现完整代码

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

public class ModelControl : MonoBehaviour
{
    private Material originalMaterial;      //模型原始材质
    private Material highlightMaterial;     //模型选中时的高亮材质
    private Renderer myRenderer;            //模型渲染组件
    private bool isSelect = false;          //模型是否被旋转

    // Start is called before the first frame update
    void Start()
    {
        //确保模型在地面上方
        KeepOnGround();

        //新建一个高亮材质
        highlightMaterial = new Material(Shader.Find("Universal Render Pipeline/Lit"));
        highlightMaterial.color = Color.yellow;
        highlightMaterial.SetFloat("_Smoothness", 0.8f);
        highlightMaterial.SetColor("_EmissionColor", Color.yellow * 1.2f); // 开启自发光

        //获取原始材质
        myRenderer = GetComponent<Renderer>();
        if (myRenderer != null)
        {
            originalMaterial = myRenderer.material;
        }
        //判断是否包含碰撞体组件,不包含直接添加
        if (GetComponent<Collider>() == null)
        {
            gameObject.AddComponent<BoxCollider>();
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButton(0)&&isSelect)
        {
            //鼠标左键控制移动
            Drag();
        }
        if (Input.GetMouseButton(1)&&isSelect)
        {
            //鼠标右键控制旋转
            Rotate();
        }
        
        float scroll = Input.GetAxis("Mouse ScrollWheel");
        if (Mathf.Abs(scroll) > 0.01f&&isSelect)
        {
            // 鼠标中键滚轮:缩放模型
            Scale(scroll);

        }


        if (Input.GetMouseButton(2))
        {
            //鼠标中键点击,进行模型选中
            Select();
        }
        
    }

    /// <summary>
    /// 模型选中方法  选中显示高亮  否则选择原始材质
    /// </summary>
    public void Select()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out RaycastHit hit))
        {
            //鼠标点击到模型
            if (hit.collider.gameObject == this.gameObject)
            {
                myRenderer.material = highlightMaterial;
                isSelect = true;
            }
            else
            {
                //点击到别的模型
                myRenderer.material = originalMaterial;
                isSelect = false;
            }
        }
        else
        {
            //点击到空白处
            myRenderer.material = originalMaterial;
            isSelect = false;
        }
    }

    /// <summary>
    /// 模型移动方法
    /// </summary>
    void Drag()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {
            if (hit.transform.name == "Plane")
            {
                this.transform.position = hit.point;
                KeepOnGround();
            }
        }
    }

    /// <summary>
    /// 模型旋转方法 鼠标右键=左右旋转 shift+鼠标右键=上下旋转
    /// </summary>
    void Rotate()
    {       
        if (Input.GetKey(KeyCode.LeftShift))
        {
            float rotY = Input.GetAxis("Mouse Y") * 5f;
            this.transform.Rotate(Vector3.right, rotY, Space.World);
        }
        else
        {
            float rotX = Input.GetAxis("Mouse X") * 5f;
            this.transform.Rotate(Vector3.up, rotX, Space.World);
        }
    }

    /// <summary>
    /// 模型缩放方法
    /// </summary>
    /// <param name="scroll">缩放倍率</param>
    void Scale(float scroll)
    {
        float scaleFactor = 1 + scroll;
        this.transform.localScale *= scaleFactor;
        KeepOnGround();
    }

    /// <summary>
    /// 确保模型在地面上方,防止穿模
    /// </summary>
    void KeepOnGround()
    {
        // 计算当前模型的边界包围盒
        Renderer renderer = GetComponentInChildren<Renderer>();
        if (renderer != null)
        {
            Bounds bounds = renderer.bounds;
            float bottomY = bounds.min.y;
            float offsetY = transform.position.y - bottomY;
            float targetY = 0f; // 地面高度为0(可根据你的地面高度调整)
            Vector3 pos = transform.position;
            pos.y += targetY - bottomY;
            this.transform.position = pos;
        }
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到