You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity技术问询:不切换场景实现类Rogue Legacy式房间敌人重置及Cinemachine锁定

实现无场景切换的房间式敌人状态管理 + Cinemachine房间锁定方案

嘿,我之前做过类似的类《Rogue Legacy》项目,完全明白你不想用场景切换来避免内存问题的需求,下面给你拆解两个核心需求的实现思路:

一、房间敌人状态重置与隔离的实现

核心思路是给每个房间做边界标记,通过玩家的房间进出事件来控制敌人的状态,全程不需要切换场景:

  1. 房间边界触发器设置

    • 给每个房间的根节点添加一个BoxCollider2D(或PolygonCollider2D),勾选Is Trigger,调整大小覆盖整个房间范围
    • 给这个触发器挂载RoomManager脚本,用来标记房间ID,同时存储房间内所有敌人的引用
  2. 敌人状态控制逻辑

    • 给每个敌人添加EnemyController脚本,包含EnterActiveState()(激活巡逻/攻击行为)和EnterIdleResetState()(回到 idle 并重置位置、血量等状态)方法
    • 在RoomManager中,通过OnTriggerEnter2D和OnTriggerExit2D检测玩家的进出:
      • 玩家进入房间:遍历房间内所有敌人,调用EnterActiveState(),激活敌人的AI和动画
      • 玩家离开房间:遍历房间内所有敌人,调用EnterIdleResetState(),让敌人回到初始位置,切换到 idle 状态,同时重置血量、仇恨等状态
  3. 代码示例片段

    // RoomManager.cs
    public class RoomManager : MonoBehaviour
    {
        [SerializeField] private List<EnemyController> roomEnemies;
        private PlayerController currentPlayer;
        private CinemachineConfiner cameraConfiner;
    
        private void Awake()
        {
            cameraConfiner = FindObjectOfType<CinemachineConfiner>();
        }
    
        private void OnTriggerEnter2D(Collider2D other)
        {
            if (other.TryGetComponent(out PlayerController player))
            {
                currentPlayer = player;
                ActivateRoomEnemies();
                // 同步切换相机边界(后面会讲)
                UpdateCameraBounds();
            }
        }
    
        private void OnTriggerExit2D(Collider2D other)
        {
            if (other.TryGetComponent(out PlayerController player) && player == currentPlayer)
            {
                DeactivateAndResetEnemies();
                currentPlayer = null;
            }
        }
    
        private void ActivateRoomEnemies()
        {
            foreach (var enemy in roomEnemies)
            {
                enemy.EnterActiveState();
            }
        }
    
        private void DeactivateAndResetEnemies()
        {
            foreach (var enemy in roomEnemies)
            {
                enemy.EnterIdleResetState();
            }
        }
    }
    
    // EnemyController.cs
    public class EnemyController : MonoBehaviour
    {
        private Vector3 initialPosition;
        private Animator anim;
        private EnemyAI enemyAI;
        private HealthSystem healthSystem;
    
        private void Awake()
        {
            initialPosition = transform.position;
            anim = GetComponent<Animator>();
            enemyAI = GetComponent<EnemyAI>();
            healthSystem = GetComponent<HealthSystem>();
        }
    
        public void EnterActiveState()
        {
            enemyAI.enabled = true;
            anim.SetBool("IsActive", true);
            // 启用敌人碰撞体(如果之前禁用了)
            GetComponent<Collider2D>().enabled = true;
        }
    
        public void EnterIdleResetState()
        {
            enemyAI.enabled = false;
            transform.position = initialPosition;
            anim.SetBool("IsActive", false);
            // 重置血量、清除仇恨
            healthSystem.ResetHealth();
            enemyAI.ClearAggro();
            // 可选:禁用非必要碰撞体节省性能
            GetComponent<Collider2D>().enabled = false;
        }
    }
    

二、Cinemachine锁定当前房间的方法

要让相机只在当前房间内移动,核心是动态切换Cinemachine的边界限制:

  1. 给每个房间添加相机边界碰撞体

    • 给每个房间创建一个PolygonCollider2D(或BoxCollider2D),调整形状贴合房间的可移动区域(避开墙壁、障碍物),不要勾选Is Trigger
    • 把这个碰撞体作为房间的相机边界,放在RoomManager的子物体下
  2. 动态切换Cinemachine Confiner的边界

    • 给你的Cinemachine Virtual Camera添加CinemachineConfiner组件
    • 在RoomManager的UpdateCameraBounds()方法中,当玩家进入房间时,把Confiner的m_BoundingShape2D设置为当前房间的边界碰撞体,同时强制刷新缓存
  3. 补充代码片段(在RoomManager.cs中)

    [SerializeField] private PolygonCollider2D roomCameraBounds;
    
    private void UpdateCameraBounds()
    {
        if (roomCameraBounds != null && cameraConfiner != null)
        {
            cameraConfiner.m_BoundingShape2D = roomCameraBounds;
            // 强制刷新边界缓存,避免相机卡顿
            cameraConfiner.InvalidatePathCache();
        }
    }
    

额外优化建议

  • 如果是程序化生成房间,记得在生成房间时自动创建边界触发器和相机边界碰撞体,并把生成的敌人自动添加到roomEnemies列表中
  • 可以给离开房间的敌人添加“休眠”逻辑,比如禁用刚体、动画组件(除了idle动画),进一步降低内存和性能消耗

内容的提问来源于stack exchange,提问作者TheYargonaut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:52:12