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

Cocos Creator 3.8.2安卓场景切换旋转时精灵短暂拉伸问题求助

Cocos Creator 3.8.2安卓端场景切换屏幕旋转精灵拉伸问题解决方案

现有实现代码

Cocos Creator 端代码

director.loadScene(this.ReturnGameSceneName(), () => {
    if (sys.platform === sys.Platform.ANDROID) {
        native.reflection.callStaticMethod(
            "com.cocos.game.AppActivity",
            "ChangeOrientation",
            "(Z)V",
            isLandscape
        );
    }

    if (orientation === macro.ORIENTATION_LANDSCAPE) {
        view.setDesignResolutionSize(1024, 576, ResolutionPolicy.FIXED_HEIGHT);
    } else if (orientation === macro.ORIENTATION_PORTRAIT) {
        view.setDesignResolutionSize(576, 1024, ResolutionPolicy.FIXED_WIDTH);
    }
});

安卓端代码

Activity activity = GlobalObject.getActivity();
if (activity == null) {
    Log.e("setOrientation", "Activity is null!");
    return;
}
Log.d(TAG, "ChangeOrientation: " + setorientaion);

 activity.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        if (setorientaion) {
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } else {
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
    }
});

问题原因

当前实现中,场景加载完成回调里直接触发安卓端屏幕旋转,系统级的屏幕旋转操作完成速度快于Cocos场景内UI元素的布局适配,导致短时间内布局尺寸与屏幕尺寸不匹配,出现精灵拉伸的视觉问题。

解决方案与最佳实践

1. 延迟触发旋转,等待场景布局完成

调整代码执行顺序,先设置Cocos分辨率,再延迟触发安卓端旋转,给场景布局留足时间:

director.loadScene(this.ReturnGameSceneName(), () => {
    // 优先设置分辨率
    if (orientation === macro.ORIENTATION_LANDSCAPE) {
        view.setDesignResolutionSize(1024, 576, ResolutionPolicy.FIXED_HEIGHT);
    } else if (orientation === macro.ORIENTATION_PORTRAIT) {
        view.setDesignResolutionSize(576, 1024, ResolutionPolicy.FIXED_WIDTH);
    }

    // 延迟触发安卓端旋转(延迟时间根据场景复杂度调整,100-200ms为合理区间)
    if (sys.platform === sys.Platform.ANDROID) {
        setTimeout(() => {
            native.reflection.callStaticMethod(
                "com.cocos.game.AppActivity",
                "ChangeOrientation",
                "(Z)V",
                isLandscape
            );
        }, 150);
    }
});

2. 添加全屏遮罩屏蔽拉伸视觉效果

在场景根节点添加全屏纯色遮罩(如黑色),场景加载完成后显示遮罩,直到旋转和布局完全完成后再隐藏:

director.loadScene(this.ReturnGameSceneName(), () => {
    const maskNode = find("Canvas/ScreenMask"); // 替换为实际遮罩节点路径
    if (maskNode) maskNode.active = true;

    // 先设置分辨率
    if (orientation === macro.ORIENTATION_LANDSCAPE) {
        view.setDesignResolutionSize(1024, 576, ResolutionPolicy.FIXED_HEIGHT);
    } else if (orientation === macro.ORIENTATION_PORTRAIT) {
        view.setDesignResolutionSize(576, 1024, ResolutionPolicy.FIXED_WIDTH);
    }

    if (sys.platform === sys.Platform.ANDROID) {
        setTimeout(() => {
            native.reflection.callStaticMethod(
                "com.cocos.game.AppActivity",
                "ChangeOrientation",
                "(Z)V",
                isLandscape
            );
            // 旋转完成后再延迟隐藏遮罩,确保系统布局同步
            setTimeout(() => {
                if (maskNode) maskNode.active = false;
            }, 100);
        }, 150);
    } else {
        setTimeout(() => {
            if (maskNode) maskNode.active = false;
        }, 100);
    }
});

3. 安卓端监听旋转完成事件,同步Cocos布局

修改安卓端代码,监听屏幕旋转后的布局变化事件,完成后通知Cocos执行最终布局调整,实现完全同步:

安卓端修改代码

public static void ChangeOrientation(boolean setorientaion) {
    Activity activity = GlobalObject.getActivity();
    if (activity == null) {
        Log.e("setOrientation", "Activity is null!");
        return;
    }
    Log.d(TAG, "ChangeOrientation: " + setorientaion);

    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            activity.setRequestedOrientation(setorientaion ? 
                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : 
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            
            // 监听布局变化,确认旋转完成
            activity.getWindow().getDecorView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                    v.removeOnLayoutChangeListener(this); // 移除监听避免重复触发
                    // 通知Cocos端旋转完成
                    CocosJavascriptJavaBridge.evalString("window.onOrientationChanged()");
                }
            });
        }
    });
}

Cocos Creator端添加监听

// 在场景脚本的onLoad/start中注册全局监听
window.onOrientationChanged = () => {
    // 旋转完成后执行分辨率设置与遮罩隐藏
    if (orientation === macro.ORIENTATION_LANDSCAPE) {
        view.setDesignResolutionSize(1024, 576, ResolutionPolicy.FIXED_HEIGHT);
    } else if (orientation === macro.ORIENTATION_PORTRAIT) {
        view.setDesignResolutionSize(576, 1024, ResolutionPolicy.FIXED_WIDTH);
    }
    const maskNode = find("Canvas/ScreenMask");
    if (maskNode) maskNode.active = false;
};

director.loadScene(this.ReturnGameSceneName(), () => {
    const maskNode = find("Canvas/ScreenMask");
    if (maskNode) maskNode.active = true;

    if (sys.platform === sys.Platform.ANDROID) {
        native.reflection.callStaticMethod(
            "com.cocos.game.AppActivity",
            "ChangeOrientation",
            "(Z)V",
            isLandscape
        );
    } else {
        window.onOrientationChanged();
    }
});

4. 优化分辨率策略配置

确保分辨率策略与旋转方向严格匹配:

  • 横屏固定使用ResolutionPolicy.FIXED_HEIGHT,保证高度适配屏幕,宽度按比例缩放
  • 竖屏固定使用ResolutionPolicy.FIXED_WIDTH,保证宽度适配屏幕,高度按比例缩放
  • 可在项目设置中预配置默认分辨率参数,减少动态设置时的冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:37:34