Unity2D中如何让实例化的游戏对象各自独立执行脚本逻辑?
问题根源与解决方法
核心问题分析
你的两个游戏对象会同时响应,本质是它们共享了同一个enemy的healthBar引用,并且其中一个对象修改了Hp.Died的全局状态,导致另一个对象的逻辑被错误触发。另外,Update中重复调用GameObject.FindGameObjectWithTag不仅效率低,也会持续覆盖target引用。
修复步骤
1. 移除全局状态共享,让每个对象独立判断逻辑
删掉Start和Update中对全局Hp的引用与修改,转而在触发攻击时通过碰撞体获取当前敌人的healthBar,每个对象只关注自身动画和目标状态:
private Transform target; public float speed = 2f; private Animator anim; public float H2Damage = 5f; void Start() { // 只在初始化时查找一次目标 target = GameObject.FindGameObjectWithTag("enemy")?.GetComponent<Transform>(); anim = gameObject.GetComponent<Animator>(); } void Update() { // 目标为空时重新查找,避免空引用报错 if (target == null) { target = GameObject.FindGameObjectWithTag("enemy")?.GetComponent<Transform>(); if (target == null) return; } // 直接检查当前目标的存活状态,不修改全局标记 var enemyHp = target.GetComponent<healthBar>(); if (enemyHp.Died) { anim.SetBool("Hero2Attack", false); anim.SetBool("Hero2Move", false); return; } // 攻击状态下不移动 if (anim.GetCurrentAnimatorStateInfo(0).IsName("Hero2ATTACK")) return; transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime); anim.SetBool("Hero2Move", true); } private void OnTriggerEnter2D(Collider2D col) { if (col.gameObject.CompareTag("enemy")) { healthBar hp = col.transform.GetComponent<healthBar>(); // 只有敌人存活时才触发攻击 if (!hp.Died) { anim.SetBool("Hero2Attack", true); hp.GiveDamage(H2Damage); } } }
2. 确保动画状态独立
每个游戏对象的Animator都是自身组件,只要不共享全局状态,动画逻辑会自然独立。若仍有异常,检查动画控制器参数,确认没有误设全局共享参数(Unity的Animator参数默认是实例独立的)。
3. 优化对象查找性能
避免每帧调用GameObject.FindGameObjectWithTag,只在初始化或目标丢失时重新查找,减少性能消耗。
额外建议
- 如果场景中有多个敌人,可以改成让每个英雄追踪最近的敌人,实现各自独立的攻击目标。
- 给敌人的死亡逻辑添加事件通知,当敌人死亡时,所有追踪它的英雄自动收到通知并停止动作,比每帧检查状态更高效。
内容的提问来源于stack exchange,提问作者Vasil Kirilov
相关产品推荐
相关产品推荐

