Forum rules - please read before posting.

2.5D Camera doesn't work for URP

environment:
unity: 2019.4.4f1
AC:V1.72.4
URP: 7.3.1

2.5D warf demo works fine if you start a new project with standard pipeline by following the tutorial. But if you do the same with URP, it doesn't work . I can manually fix it. Set background camera as "base" , Set waterfront camera as "overlay" and add water front camera to the overlay stack of the background camera.

URP camera system seems work different from that of standard pipeline. Does AC 2.5 game support URP out of box or we should add some code to fix it?

Thanks in advance!

Comments

  • Welcome to the community, @knooc.

    AC is mainly render pipeline-independent, but 2.5D cameras is one of the few areas where it does need to manipulate camera rendering to work.

    The change you've made sounds like the right approach, but it should be possible to automate via script.

    Since the overlay-stacking feature is unique to URP, though, such code would only compile if URP is present. Therefore, it may be best placed on the AC wiki as an optional add-on script, as opposed to incorporating it into the official codebase.

    Either way, I shall look into writing something that should handle this - thanks for the details.

  • OK, give this a try:

    using UnityEngine.Rendering.Universal;
    using UnityEngine;
    using AC;
    
    public class URP_25D : MonoBehaviour
    {
    
        private void OnEnable () { EventManager.OnSwitchCamera += OnSwitchCamera; }
        private void OnDisable () { EventManager.OnSwitchCamera -= OnSwitchCamera; }
    
    
        private void Start ()
        {
            GameCamera25D[] gameCamera25Ds = FindObjectsOfType<GameCamera25D> ();
            foreach (GameCamera25D gameCamera25D in gameCamera25Ds)
            {
                gameCamera25D.Camera.enabled = true;
    
                var cameraData = gameCamera25D.Camera.GetUniversalAdditionalCameraData ();
                cameraData.renderType = CameraRenderType.Overlay;
            }
    
            Camera backgroundCamera = BackgroundCamera.Instance.GetComponent <Camera>();
            var backgroundCameraData = backgroundCamera.GetUniversalAdditionalCameraData ();
            backgroundCameraData.renderType = CameraRenderType.Overlay;
    
            var mainCameraData = KickStarter.mainCamera.Camera.GetUniversalAdditionalCameraData ();
            if (!mainCameraData.cameraStack.Contains (backgroundCamera))
            {
                mainCameraData.cameraStack.Add (backgroundCamera);
            }
        }
    
    
        private void OnSwitchCamera (_Camera fromCamera, _Camera toCamera, float transitionTime)
        {
            var cameraData = KickStarter.mainCamera.Camera.GetUniversalAdditionalCameraData ();
            if (fromCamera && cameraData.cameraStack.Contains (fromCamera.Camera))
            {
                cameraData.cameraStack.Remove (fromCamera.Camera);
            }
            if (!cameraData.cameraStack.Contains (toCamera.Camera))
            {
                cameraData.cameraStack.Add (toCamera.Camera);
            }
        }
    
    }
    

    When the scene begins, it'll do the following:

    • Set both your BackgroundCamera, and the 2.5D Cameras (WaterfrontCam etc) to Overlay, and enable the 2.5D Camera components
    • Assign the BackgroundCamera to the MainCamera as an Overlay
    • When a new 2.5D Camera is made active, assign it to the MainCamera as an Overlay, and remove the previous one
  • Thanks a lot! I'll give the feedback .

  • It works.Thanks a lot! One more question if you are convenient.The system has both main camera and 2.d camera, both of which have exactly the same parameters.However, the overlaid view does not have the content of the main camera.Don't know how the program blocks the view of the main camera?A little curious about that. :)

  • The "GameCamera 2.5D" camera should only render the characters - not the background as well, which the MainCamera will display due to the overlay.

    Normally, AC GameCameras are only intended to be used as a reference for the MainCamera, which will adopt the same position / rotation / FOV etc as whichever GameCamera it's attached to. In Unity's standard pipeline, it's enough to just have the MainCamera and the BackgroundCamera do the rendering, as the former can be display atop the latter.

    With URP, however, it's a little more complex: the MainCamera should still be the one rendering, but it needs to overlay the GameCamera (which just does the camera) as well as the BackgroundCamera, together.

    Is your 2.5D GameCamera not rendering anything? Feel free to share a screenshot to show what's going on, but it should be that only the characters (i.e. the physical 3D objects in the scene) are visible through it.

  • Yes. 2.5 D cameras render normally. But there is one more issue. It doesn't work sometimes .

    The order of cameras in the main camera stack is very important:.<BackgroundCam,WaterFrontCam> works fine while <WaterFrontCam,BackgroundCam> doesn't(The background will renders after the WaterFrontCam).

    I guess there seems to be no guarantee that Start () will be executed before OnSwitchCamera(). I don't know why.

    I made some change :

    using UnityEngine.Rendering.Universal;
    using UnityEngine;
    using AC;
    
    public class URP_25D : MonoBehaviour
    {
    
        private void OnEnable () { 
                     PrepareURPCameras();
                     EventManager.OnSwitchCamera += OnSwitchCamera; }
        private void OnDisable () { EventManager.OnSwitchCamera -= OnSwitchCamera; }
    
    
        private void PrepareURPCameras ()
        {
            GameCamera25D[] gameCamera25Ds =FindObjectsOfType<GameCamera25D> ();
            foreach (GameCamera25D gameCamera25D in gameCamera25Ds)
            {
                gameCamera25D.Camera.enabled = true;
    
                var cameraData = gameCamera25D.Camera.GetUniversalAdditionalCameraData ();
                cameraData.renderType = CameraRenderType.Overlay;
            }
    
            Camera backgroundCamera = BackgroundCamera.Instance.GetComponent <Camera>();
            var backgroundCameraData = backgroundCamera.GetUniversalAdditionalCameraData ();
            backgroundCameraData.renderType = CameraRenderType.Overlay;
            Debug.Log("start preapre urp camera");
    
            var mainCameraData = KickStarter.mainCamera.Camera.GetUniversalAdditionalCameraData ();
            if (!mainCameraData.cameraStack.Contains (backgroundCamera))
            {
                Debug.Log("add background camera="+backgroundCamera.gameObject.name);
                mainCameraData.cameraStack.Add (backgroundCamera);
            }
        }
    
    
        private void OnSwitchCamera (_Camera fromCamera, _Camera toCamera, float transitionTime)
        {
            var cameraData = KickStarter.mainCamera.Camera.GetUniversalAdditionalCameraData ();
    
    
            if (fromCamera && cameraData.cameraStack.Contains (fromCamera.Camera))
            {
                Debug.Log("from camera="+fromCamera.gameObject.name);
    
                cameraData.cameraStack.Remove (fromCamera.Camera);
            }
            if (!cameraData.cameraStack.Contains (toCamera.Camera))
            {
                Debug.Log("to camera="+toCamera.gameObject.name);
                cameraData.cameraStack.Insert(  cameraData.cameraStack.Count,toCamera.Camera);
            }
        }
    
    }
    

    I add this component to the GameEngine gameobject.

    So far so good.But I'm not sure if there is some chance that the system will switch the Camera before enabling this component when loaded. In that case it will fail again.

  • The BackgroundCamera indeed needs to go first in the stack - but the use of Start is also necessary to override the GameCamera25D's built-in behaviour of disabling itself.

    Here's an alternative that should cover all bases - it'll add the BackgroundCamera in Awake, but also set any GameCamera2D to Overlay in OnCameraSwitch:

    using UnityEngine.Rendering.Universal;
    using UnityEngine;
    using AC;
    
    public class URP_25D : MonoBehaviour
    {
    
        private void OnEnable () { EventManager.OnSwitchCamera += OnSwitchCamera; }
        private void OnDisable () { EventManager.OnSwitchCamera -= OnSwitchCamera; }
    
    
        private void Awake ()
        {
            Camera backgroundCamera = BackgroundCamera.Instance.GetComponent<Camera> ();
            var backgroundCameraData = backgroundCamera.GetUniversalAdditionalCameraData ();
            backgroundCameraData.renderType = CameraRenderType.Overlay;
    
            var mainCameraData = KickStarter.mainCamera.Camera.GetUniversalAdditionalCameraData ();
            if (!mainCameraData.cameraStack.Contains (backgroundCamera))
            {
                mainCameraData.cameraStack.Add (backgroundCamera);
            }
        }
    
    
        private void Start ()
        {
            GameCamera25D[] gameCamera25Ds = FindObjectsOfType<GameCamera25D> ();
            foreach (GameCamera25D gameCamera25D in gameCamera25Ds)
            {
                gameCamera25D.Camera.enabled = true;
    
                var cameraData = gameCamera25D.Camera.GetUniversalAdditionalCameraData ();
                cameraData.renderType = CameraRenderType.Overlay;
            }
        }
    
    
        private void OnSwitchCamera (_Camera fromCamera, _Camera toCamera, float transitionTime)
        {
            var mainCameraData = KickStarter.mainCamera.Camera.GetUniversalAdditionalCameraData ();
            if (fromCamera && mainCameraData.cameraStack.Contains (fromCamera.Camera))
            {
                mainCameraData.cameraStack.Remove (fromCamera.Camera);
            }
            if (!mainCameraData.cameraStack.Contains (toCamera.Camera))
            {
                var gameCameraData = toCamera.Camera.GetUniversalAdditionalCameraData ();
                gameCameraData.renderType = CameraRenderType.Overlay;
    
                mainCameraData.cameraStack.Add (toCamera.Camera);
            }
        }
    
    }
    
  • It works! I'm a programmer before but have almost no experience on Unity3D script. Your help means a lot to me. Thanks again.

  • Hi,
    I had the same problem and i solved with this script, Thanks.

    Is ther a way to Remember the Active state of Cameras for saving game?

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.