一、效果展示
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;
}
}
}