Unity3D icon indicating copy to clipboard operation
Unity3D copied to clipboard

Using Camera.WorldToScreenPoint with SyphonServerCustomResolution

Open kingdrippa opened this issue 10 years ago • 3 comments

Hi Brian, Wondering what the best way to accomplish passing mouse position while the custom resolution output script is implemented. With a regular Syphon server running, I am still able to use Camera.WorldToScreenPoint, but as soon as I activate the custom resolution script instead, I get a NullReferenceException. Is there a new camera that I can call?

Thanks!! -Mike

kingdrippa avatar Aug 04 '14 19:08 kingdrippa

I've recently had to deal with similar issues myself. the issue is, you need to be able to

  1. send the rendered high rez camera targetTexture to Syphon and
  2. at the same time, draw it to the Unity window, preferably aspect-fit correctly.

In SyphonServerTextureCustomResolution, if you take a look, I was using OnGUI to do this drawing to the screen, but really, you should probably use a second camera (or soon, the new gui system) to achieve this. I've tested doing this with the new (beta) gui system, and it works fine.

If i were you, i'd simplify SyphonServerTextureCustomResolution-

  1. remove any instances of cameraInstance.enabled = false;
  2. delete the entire OnGUI method
  3. use a different way to render the camera texture to the Unity window- for instance, make a secondary orthographic camera that only renders a GUI layer and culls everything else, (and make sure your main camera isn't rendering the GUI layer)
  4. render a quad mesh that has your Syphon texture on it, rendered by the GUI layer by that new camera- whether it's by usin a Backdrop script on that camera, or some other method

Once the new gui system is released, I'll probably switch over to that method for an official release, as it is a quick and easy way to achieve this.

brianchasalow avatar Aug 07 '14 04:08 brianchasalow

This is an old issue but I'd like to add my two cents. I had a similar issue as well (Camera.main.ScreenPointToRay) when using the SyphonServerCustomResolution script.

In a main script I store a reference to the main camera on the Awake() method. That way you'll have that reference after SyphonServerCustomResolution disables the component.

Camera mainCamera;
void Awake() {
    mainCamera = Camera.main;
}

Usually Camera.main.pixelWidth/pixelHeight will have the same dimensions as Screen.width/height but in the case of SyphonServerCustomResolution the factor between these will become variable. I kept this x/y factor stored in a Vector2 and recalculate Input.mousePosition by this factor.

Vector2 cameraToScreenFactor = new Vector2(
    mainCamera.pixelWidth / Screen.width,
    mainCamera.pixelHeight / Screen.height
);

Vector3 cameraToScreenPos = new Vector3(
    cameraToScreenPos.x = Input.mousePosition.x * cameraToScreenFactor.x,
    cameraToScreenPos.y = Input.mousePosition.y * cameraToScreenFactor.y,
    cameraToScreenPos.z = 0f
);

Now, when doing a Physics.Raycast, instead of

if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition))) {};

we do this

if (Physics.Raycast (mainCamera.ScreenPointToRay (cameraToScreenPos))) {};

This worked wonders for me. I don't know if this is a crude method but it may help others.

bombarie avatar Feb 02 '16 09:02 bombarie

@bombarie s way seems to be the way to go. I had some issues with the code as is. This is what I did differently

            Vector2 cameraToScreenFactor = new Vector2(
                (float)cam.pixelWidth / (float)Screen.width,
                (float)cam.pixelHeight / (float)Screen.height
            );

            Vector3 cameraToScreenPos = new Vector3(
                Input.mousePosition.x * cameraToScreenFactor.x,
                Input.mousePosition.y * cameraToScreenFactor.y,
                0f
            );

TiborUdvari avatar Aug 30 '16 11:08 TiborUdvari