Hey forum, Lately, I have been trying to make a 3D RealTimeStrategy type camera for a project I am working on, I am trying to make this on the android platform as this is something I have never done before. Every time I look up how do something like this it always comes up with "Clash of clans like the camera". But as most of you probably know clash of clans is not 3D but isometric (2.5D ish...). And so I was wondering if any of you could help me but a basic script like clash of clans, but for 3D. This is just because I do not fully understand android and iPhone yet. Thanks in advance, Aliquidhacker
I didn't find anything Clash of clans when I searched for "unity3d rts camera" The first hit gave me this post. Hope that helps.
@Chris Trueman Thanks for the reply but as I mentioned in the post, I am not looking at how to make an rts camera but how to make one for android, Again thanks for the reply, AliquidHacker
Its only a mater of changes in the input of a system like for it to work on Android. Instead of the arrow keys on the keyboard to move the camera around, you could use buttons on the screen. How the input works is really up to you and how you want the game to function.
@Chris Trueman Sorry I have been away for a while, Thanks for the reply but I was looking like a dragging to move, Here is the small part of my camera code (C#) I feels its organised but that might just be me, Code (CSharp): using UnityEngine; using System.Collections; public class CameraController : MonoBehaviour { public float MovementSpeed = 5; void Update () { if ( Input.GetKey("w")) { transform.Translate( Vector3.forward * Time.deltaTime * MovementSpeed); } else if ( Input.GetKey("s")) { transform.Translate( Vector3.forward * Time.deltaTime * -MovementSpeed); } if ( Input.GetKey("d")) { transform.Translate( Vector3.right * Time.deltaTime * MovementSpeed); } else if ( Input.GetKey("a")) { transform.Translate( Vector3.right * Time.deltaTime * -MovementSpeed); } } } How exactly would I make it sense the dragging on the screen, Thanks in advance, Aliquidhacker
What I do is make 2 raycasts as soon as the level is loaded a 0,0 (screen) and at (width, height) Then you know how many game meters per screen pixel are there, so when you do the drag you multiply the X,Y drag per your pixel meter vector.
@Aldo Any chance for a script example, Sorry im not too good with android scripting, Anyone else is welcome too share as well Aliquidhacker
This is a very basic script, but it gets the job done with no raycasting. If you want elasticity you need to figure that out. Not tested on Android, but I don't see why it wouldn't work. Update. Needed to make some changes for it to work on Android properly. Code (CSharp): using UnityEngine; using System.Collections; [RequireComponent(typeof(Camera))] public class TouchCamera : MonoBehaviour { private Camera _cam; private Vector3 _lastPosition = Vector3.zero; private float _cameraToWorldRatio = 0.0f; void Awake() { _cam = GetComponent<Camera>();//Get the camera component. } void Start() { //Calculate the current camera to world ratio to convert the camera's movements into word units. Vector3 left = _cam.ScreenToWorldPoint(Vector3.zero); Vector3 right = _cam.ScreenToWorldPoint(new Vector3(Screen.width, 0, 0)); float width = Vector3.Distance(left, right); _cameraToWorldRatio = width / Screen.width; } void Update() { if (Input.touchCount > 0) { //Get touch info Touch touch = Input.GetTouch(0);//Get the touch info of the first finger. Vector3 touchPos = new Vector3(touch.position.x, touch.position.y, 0f); if (touch.phase == TouchPhase.Moved) { Vector3 moveDelta = (_lastPosition - touchPos) * _cameraToWorldRatio; transform.Translate(moveDelta); } _lastPosition = touchPos; } else if (Input.mousePresent)//Might as well add mouse support. { if (Input.GetMouseButton(0)) { Vector3 moveDelta = (_lastPosition - Input.mousePosition) * _cameraToWorldRatio; transform.Translate(moveDelta); } _lastPosition = Input.mousePosition; } } }
@Chris Trueman Thanks a lot, I made some changes for the things that weren't very necessary, I will post my whole script for anyone that needs it as soon as I am done, Thanks again, AliquidHacker
@Chris Trueman ScreenToWorldPoint() is what I was calling as raycast, I would only change it to be bottom right instead of right by adding the height since the script might need Y movement too. And that script is basically the same that I would had given.
ScreenToWorldPoint is some matrix math with no raycasting envolved. You don't need the Y component as you only need the ratio from screen to world. If you change it to use height instead of width you get the same number, so the script works in all directions.
@Chris Trueman Nice little debate going on here Anyway here is the script I modified, I also added a zoom function, but I do not think it is the most effective one, Anyone have an idea on how I could improve it? Unless it is perfect already (Doubt it Code (CSharp): using UnityEngine; using System.Collections; public class CameraController : MonoBehaviour { private float _MovementSpeed = 0.005f; private Vector3 _lastPosMove = Vector3.zero; void Update() { if (Input.touchCount == 1) { Touch touch = Input.GetTouch(0); Vector3 touchPos = new Vector3(touch.position.x, touch.position.y, 0f); if (touch.phase == TouchPhase.Moved) { Vector3 moveDelta = (_lastPosMove - touchPos) * _MovementSpeed; transform.Translate(moveDelta); } _lastPosMove = touchPos; } if(Input.touchCount == 2) { Touch zoomOne = Input.GetTouch(0); Touch zoomTwo = Input.GetTouch(1); Vector2 ZoomOnePrev = zoomOne.position - zoomOne.deltaPosition; Vector2 ZoomTwoPrev = zoomTwo.position - zoomTwo.deltaPosition; float prevTouchDeltaMag = (ZoomOnePrev - ZoomTwoPrev).magnitude; float touchDeltaMag = (zoomOne.position - zoomTwo.position).magnitude; float deltaMagnitudeDiff = (prevTouchDeltaMag - touchDeltaMag) *-1; transform.Translate(0, 0, deltaMagnitudeDiff); } } } PS: Anyone have an idea on how I can add a camera rotation? You know when you move two fingers clockwise or anticlockwise. Thanks again Aliquidhacker
@Chris Trueman any idea if there is a Input.mousePosition equivalent for touch input? Thanks AliquidHacker
touch.position is its equivalent. Its a Vector2 where as Input.mousePosition is a Vector3 thus the reason I converted it in the code I posted.
Ah, so no specific unity made line, I was not talking about your code, I was talking about in general, Thanks anyway. AliquidHacker
I used Input.touches which is Unity specific to get a Touch that has the position, you can also use Input.GetTouch(0); to get it as well. I would suggest you review the video tutorial Unity has on MultiTouch Input.