Unity中实现实例化对象旋转及点击停止功能的技术问题
问题修复与实现方案
核心问题分析
- 旋转逻辑完全错误:你在
Update末尾每帧都实例化一个新对象(还存在未定义的Capsule变量),这个对象和方向键切换的tempMesh毫无关系,不仅会导致内存暴涨,真正需要旋转的tempMesh反而没有被执行旋转逻辑。 - 左箭头边界硬编码:当
selectedObject越界时硬编码设为5,数组长度变化时会直接报错,应该适配数组实际长度。
修复步骤与完整代码
以下是修正后的代码,同时实现了自动旋转+鼠标点击停止旋转的需求:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ObjectSelector : MonoBehaviour { // 存储预制体数组 public GameObject[] ObjectArray; // 当前选中的预制体索引 private int selectedObject = 0; // 实例化位置标记 public Transform locator; // 当前场景中实例化的对象 public GameObject tempMesh; // 旋转控制开关 private bool isRotating = true; void Start() { // 实例化初始预制体 tempMesh = Instantiate(ObjectArray[selectedObject], locator.position, locator.rotation); } void Update() { // 右箭头切换下一个预制体 if (Input.GetKeyDown(KeyCode.RightArrow)) { selectedObject++; if (selectedObject >= ObjectArray.Length) { selectedObject = 0; } SwitchSelectedObject(); } // 左箭头切换上一个预制体 if (Input.GetKeyDown(KeyCode.LeftArrow)) { selectedObject--; if (selectedObject < 0) { selectedObject = ObjectArray.Length - 1; } SwitchSelectedObject(); } // 如果处于旋转状态,执行旋转逻辑 if (isRotating && tempMesh != null) { // 绕自身X轴每秒旋转30度(可自行调整速度) tempMesh.transform.Rotate(Vector3.right * 30f * Time.deltaTime); } // 鼠标左键点击停止旋转 if (Input.GetMouseButtonDown(0)) { // Raycast检测点击的对象是否是当前实例化的对象 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { if (hit.collider.gameObject == tempMesh) { isRotating = false; } } } } // 封装切换预制体的逻辑,避免重复代码 private void SwitchSelectedObject() { Destroy(tempMesh); tempMesh = Instantiate(ObjectArray[selectedObject], locator.position, locator.rotation); // 切换后恢复旋转状态(可选,根据需求调整) isRotating = true; print(selectedObject); } }
关键说明
- 新增
isRotating布尔变量控制旋转状态,默认开启,鼠标点击当前对象后关闭。 - 用
SwitchSelectedObject方法封装重复的销毁/实例化逻辑,减少代码冗余。 - 修正左箭头的边界判断,改为动态适配数组长度。
- Raycast检测需要确保预制体带有Collider组件,否则无法被检测到。
内容的提问来源于stack exchange,提问作者J K
相关产品推荐
相关产品推荐

