I am trying to implement pinch zoom and panning on mobile phones, but cannot find any instructions whatsoever on how to do it when using AC.
I tried to follow this tutorial, but it does not work.
I assume some settings in AC are overriding it?
Can someone please help?
Comments
Welcome to the community, @Dev_Martas.
From the looks of it, the script involved works by controlling the scene's
Camera.main
, or Main Camera. In an AC scene, this is AC's MainCamera, which is typically controlled instead with GameCameras acting as reference.It's similar to Cinemachine, and its Brain / Virtual Camera system, if you're familiar with it.
If you have the Default Camera field assigned in the Scene Manager, or have set a camera with the Camera: Switch Action, temporarily unset this and try again - does the MainCamera then allow for manual control through script?
You may want to adapt the script to instead have it control the current AC GameCamera (which you can get with
AC.KickStarter.mainCamera.attachedCamera
, but you may need to do so in LateUpdate or rely on the Basic Camera component instead of a GameCamera. Try the above first, however, and we'll take things from there.If the MainCamera still can't be controlled, share the exact script you're using and I'll try to spot what's wrong.
Dear @ChrisIceBox,
I did unset the AC camera in the Scene Manager and added the script as a component to the Main Camera and it works!
However, now I'm afraid that not using the AC camera will cause problems. What would be the next step, please? :-)
If you want to rely entirely on your custom camera control, you should be fine as you are - you'll only need to make changes if you want to also make use of AC's camera system at the same time.
Assuming so, the next step will be to adapt your script to instead control your active GameCamera, instead of the AC MainCamera.
While the MainCamera is the one that performs runtime rendering, it'll use the position / rotation / FOV etc values of whichever GameCamera it's currently attached to - so its the GameCamera you'll want to affect through script.
You can do this by first adding a public Camera variable at the top of your script, which you can then set in its Inspector:
Then, replace each instance of
Camera.main
withgameCamera.Camera
.Technically, this will then cause the GameCamera's Camera to be affected - but you may need more work depending on what exactly it is you're controlling, because the GameCamera may also be trying to update its position, FOV etc values depending on its type and Inspector values.
After this step, check to see what's not working - and then share details, along with the script, and screenshots of the GameCamera Inspector it's referencing, and I can look into it further.
Should this modified script be attached to the Main Camera and in the newly created public gameCamera field, should I select the camera crated in AC Game Editor (NavCam)?
I did modify the script, but I am unable to drag to- or select any camera in the Inspector of the "public AC.GameCamera gameCamera;". There is nothing.
Attach this modified script to the Camera you want to affect, rather than the MainCamera, as the MainCamera isn't directly affected by it.
What kind of GameCamera are you using, exactly? If you replace
AC.GameCamera
withAC._Camera
, it will work for all types.Thank you. The Zoom is working fine now! However, the panning stopped working for some reason.
In AC, the movement of my camera is set to be constrained by the background image of the scene. The Player is set to be the Target of the camera movement. Can some of these settings interfere with the panning?
I would like to be able to pan within the limits of the background image when the camera is zoomed in. And I would like the camera to follow/focus on the player when it performs some action only. But when standing idle, I'd like to be able to zoom in and scroll around the scene to inspect details.
Is there any way to deal with all this?
If your camera is constrained by a background, and uses the Player as its Target, is that to say you're using a GameCamera 2D?
A camera with such settings will be under its own positional control - it'll be positioning itself automatically to show the Player on-screen.
If you don't need the camera to follow the player outside of certain actions, switch instead to a "GameCamera 2D Drag" camera type, available in the Scene Manager's "Scene prefabs" panel.
This camera automatically provides panning features, as well as background constraint options. Its orthographic size is not controlled, however, allowing it to be set through custom script without interference.
The Drag Camera works and it also seems to work nicely with the Zoom script, thank you! But it causes another issue - I started a separate thread as it is not related to this topic specifically https://www.adventurecreator.org/forum/discussion/14539/drag-camera-2d-positioning-issue#latest.
Would it also be possible to have the non-drag GameCamera 2D set and still use panning to a certain level? Meaning you could scroll around the scene with a mouse button/finger down but once you release it, the camera would bounce back to refocus on the player?
Through script, you can toggle the GameCamera 2D's "Lock" checkboxes, which will prevent AC from taking control over it - but this'll also mean it'll no longer be bound by the constraint settings.
Rather than having your script control the Transform, and compete with the GameCamera, what you could try is to instead have the script modify the camera's Offset values. This would allow the camera to remain bound by the constraints at all times, and you could lerp them back to their original values upon releasing input.
You can modify the camera's offset via its afterOffset variable.
The other approach would be to have two separate cameras - one that's a regular GameCamera2D that follows the player, another that's a GameCamera2DDrag with your attached script, and then switch between them when custom input is detected/lost. You can switch between GameCameras with the SetGameCamera function:
The other approach would be to have two separate cameras - one that's a regular GameCamera2D that follows the player, another that's a GameCamera2DDrag with your attached script, and then switch between them when custom input is detected/lost. You can switch between GameCameras with the SetGameCamera function:
I did some reading and tried to implement the two cameras switching - the default one being the GameCamera2D and GameCamera2DDrag that would be triggered by mouse/finger dragging over the scene. Default GameCamera2D would be triggered back again by a simple click/tap without any drag detected.
I tried to recycle the script you gave me at the beginning of this topic and modify it using AI to switch between the cameras. I then put the script into empty object on the scene. But it is not working. I tried to add some Log lines to see how far it works. It seemed to work all the way to the "drag", but it seems the "NOdrag" was never detected. Please help me tweak this. Here is the script:
It doesn't get called because the code block will only run if
Input.mousePosition != startPosition
is true, in which case the first sub-block will run.You can replace:
with:
but coupled with the input reading in the script you're modifying, it's likely best to avoid switching camera after all.
Either way, it's cleaner to use a separate script for the separate behaviour. Try this: it's a separate script that relies on a single camera - just moving its own position back to the Player when not being dragged.
I tried to fix the camera switching script, but it seemed to have caused more issues and the standard camera didn't follow the player anyway. Your suggestion of a separate script works and is more elegant :-)
Unfortunately, the way this script works, I cannot zoom in on a specific area - I always have to zoom in on the player and then move the camera around.
Would it be possible to be able to drag the camera first and then be able to zoom on that area? Or zoom on a corner of a scene with the zoom centering on that specific corner and not in the middle of the screen? (I tried to set that before, but failed as it seems to somehow fight with the constraint of movement by scene background). I would ideally love to be able to do both.
And for both cases, the camera would reset to follow to player automatically only after you click on the NavMesh or interactive hotspot.
The script snaps back to the Player, but you could feasibly have it snap to the nearest other camera. I'm not 100% clear on your meaning - is that what you're geting at?
Sounds best to tackle this afterwards.
The camera should by default follow the player. But at any time, you can drag it - then it will stop following the player and stay where you leave it. It will reset back to default and follow the player again only after you click/tap somewhere on the screen (either to send the player to position or interact with an object).
In other words, dragging across the screen would activate the drag camera, and tap/click would activate the basic camera that automatically focuses on the player.
This should do it, when combined with the first ClickUpToMove script:
It works on desktop with Mouse and Keyboard Input! :-)
On Android phone seems to work properly only when the Mouse and Keyboard are set. However, pinch zoom breaks the camera when used. When I build the game with Touch input, the player still follows any tap when panning or zooming. Maybe the best way would be to modify the pinch zoom script? But can that be even done if the input method is Mouse and Keyboard?
The PanZoom script reads Unity input directly - it'll have the same behaviour regardless of AC's "Input method".
To prevent the player from moving when zooming due to PanZoom, you'll need to create a dependency - whereby ClickUpToMove checks if PanZoom is currently zooming, and ignores input if so.
Try these:
These scripts work, thank you! I just have a few details regarding the Zoom I'd need help with:
ClickUpToMove is camera-independent. You'll only need one instance of it present the scene, and it'll work regardless of which camera is active.
You can use the GameCamera2DDrag's SetPosition function to re-centre the camera based on the input (either the mouse position, or the combined average of the two touch positions).
This is down to the order in which the game calls the Update functions. You'll want PanZoom to run before AC's main loop, which can be done with the DefaultExecutionOrder attribute.
Changes to 2) and 3) below.
Just to be sure: it has a public field where I need to put the camera in Editor. So it does not matter which one I put there, even though a different camera may be used during gameplay?
The zooming out (3) is not leaving the borders of the scene anymore, thank you!
Unfortunately, the zooming to a spot between the fingers (2) kind of works, but sometimes the camera just slides somewhere else on the scene, especially when you leave the zooming fingers on the screen for too long or move one of the fingers more than the other. It also sometimes triggers the character to move to that location (he does not move during panning). Could that be somehow tweaked?