Unity实例化对象交互异常求助:独立缩放与销毁逻辑故障
问题分析与修复方案
核心问题根源
- 全局脚本共享状态:用同一个全局脚本(如Spawner上的脚本)处理所有克隆体的协程,导致所有克隆体的缩放逻辑依赖全局的
targetID和morphSizeController变量,新实例化对象时会覆盖这些全局值,进而影响所有旧对象的缩放。 - 索引错误:
thisMorphClone = morphSpawnerScript.morphClones[this.targetID + 1];中targetID +1逻辑错误,targetID本身是从0开始的自增ID,直接用targetID作为数组索引即可,否则会取到错误对象。 - 按键监听与销毁不绑定:协程未绑定到具体克隆体对应的按键,导致释放任意按键都会触发所有对象的销毁逻辑。
修复步骤
1. 重构克隆体控制器,让每个对象独立管理自身逻辑
将大小插值、按键监听逻辑移到每个克隆体专属的MorphSizeController脚本中,确保每个对象的状态独立,互不干扰:
public class MorphSizeController : MonoBehaviour { public int ID; public KeyCode boundKey; // 绑定当前对象对应的按键 public float attackTime = 0.5f; public float decayTime = 0.3f; public float sustainValue = 0.8f; public float durationRelease = 0.4f; private Coroutine currentLerpCoroutine; // 启动当前对象的大小插值流程 public void StartLerpChain() { if(currentLerpCoroutine != null) { StopCoroutine(currentLerpCoroutine); } currentLerpCoroutine = StartCoroutine(PerformLerpChain()); } private IEnumerator PerformLerpChain() { bool keyReleased = false; // 攻击阶段插值 yield return StartCoroutine(LerpTransformWithKeyCheck(0, 1, attackTime, transform, boundKey, () => keyReleased = true)); if(!keyReleased) { // 衰减阶段插值 keyReleased = false; yield return StartCoroutine(LerpTransformWithKeyCheck(1, sustainValue, decayTime, transform, boundKey, () => keyReleased = true)); // 按住按键时保持当前大小 if (!keyReleased) { while (Input.GetKey(boundKey)) { yield return null; } } } // 释放阶段插值后隐藏对象 yield return StartCoroutine(LerpTransform(sustainValue, 0, durationRelease, transform)); gameObject.SetActive(false); // 如需直接销毁可替换为:Destroy(gameObject); } private IEnumerator LerpTransform(float start, float end, float duration, Transform lerpingObject) { float startTime = Time.time; float elapsedTime = 0f; while (elapsedTime < duration) { elapsedTime = Time.time - startTime; float t = elapsedTime / duration; lerpingObject.localScale = Vector3.Lerp(Vector3.one * start, Vector3.one * end, t); yield return null; } } private IEnumerator LerpTransformWithKeyCheck(float start, float end, float duration, Transform lerpingObject, KeyCode key, System.Action onKeyReleased) { float startTime = Time.time; float elapsedTime = 0f; bool sameKeyReleased = false; while (elapsedTime < duration && !sameKeyReleased) { elapsedTime = Time.time - startTime; float t = elapsedTime / duration; lerpingObject.localScale = Vector3.Lerp(Vector3.one * start * 100, Vector3.one * end * 100, t); if (Input.GetKeyUp(key)) { sameKeyReleased = true; onKeyReleased?.Invoke(); } yield return null; } } }
2. 修改实例化函数,绑定按键并启动独立逻辑
在Spawner的InstantiateMorph函数中,给每个克隆体绑定对应按键,并直接启动它的专属插值逻辑:
// 新增参数:传入当前按下的按键 public GameObject InstantiateMorph(Vector3 spawnPosition, KeyCode pressedKey) { GameObject morphClone = Instantiate(morphObject, spawnPosition, Quaternion.identity); morphClone.SetActive(true); morphClones.Add(morphClone); latestMorphCloneIndex = morphClones.Count - 1; latestMorphClone = morphClones[latestMorphCloneIndex]; // 获取或添加控制器组件 MorphSizeController morphSizeController = morphClone.GetComponent<MorphSizeController>(); if(morphSizeController == null) { morphSizeController = morphClone.AddComponent<MorphSizeController>(); } SizeController2 sizeController = morphClone.GetComponent<SizeController2>(); // 设置唯一ID int currentID = _idCounter++; sizeController.targetID = currentID; morphSizeController.ID = currentID; sizeController.tag = currentID.ToString(); // 绑定按键并启动逻辑 morphSizeController.boundKey = pressedKey; morphSizeController.StartLerpChain(); return morphClone; }
3. 修复按键检测逻辑,确保每个按键对应独立实例
在Spawner的Update函数中,按下不同按键时传入对应KeyCode调用实例化函数:
void Update() { // 示例:检测WASD按键,可根据需求扩展 if(Input.GetKeyDown(KeyCode.W)) { InstantiateMorph(new Vector3(0,1,0), KeyCode.W); } if(Input.GetKeyDown(KeyCode.A)) { InstantiateMorph(new Vector3(-1,0,0), KeyCode.A); } if(Input.GetKeyDown(KeyCode.S)) { InstantiateMorph(new Vector3(0,-1,0), KeyCode.S); } if(Input.GetKeyDown(KeyCode.D)) { InstantiateMorph(new Vector3(1,0,0), KeyCode.D); } }
关键修复点说明
- 每个克隆体的逻辑完全独立,不再依赖全局变量,新实例化对象不会影响旧对象的缩放。
- 每个对象只监听自己绑定的按键,释放对应按键才会触发自身的隐藏/销毁逻辑,不会干扰其他对象。
- 移除了全局脚本中错误的索引引用和共享状态判断,确保每个对象的插值只作用于自身。
内容的提问来源于stack exchange,提问作者Jakob Visic
相关产品推荐
相关产品推荐

