- Home /
Covered by the Included tutorial
Moving mobile joystick
I imported the Standard Assets (Mobile), and I found to my surprise that the joystick prefab did not seem to work at all. So I tried writing my own script, but I didn't really get anywhere with that either.
I want to be able to move the joysticks around to control a tank, but I'm not having much luck.
Also, I only want the joysticks to be able to move within a confined area, (the red squares in the image) like you see in most mobile games.
Anybody have any ideas on how I can either use the standard Joystick script correctly, or write my own?
I was thinking perhaps the Joystick script I imported wasn't working because maybe it relies on actual touch, and mouse clicks don't work? I noticed certain things such as Input.touchCount
and Input.GetTouch()
and I wonder if maybe that is the problem.
I'm not a noob, but I've never made a mobile game before, so if anybody can help me out here, thanks.
Great pic ; - ) I'm putting this to my blog if you don't $$anonymous$$d (this is not a spam, I'm only documenting my progress while learning Unity)
Answer by localhost · Jul 18, 2013 at 10:47 AM
Only works when your on the device, doesnt work in scene/game window on the pc, only when exported
Answer by ahc · Jun 18, 2013 at 11:14 AM
You could use joystick.js. It is a pre-written script by unity. You can import it in Assets|Standard Assets(Mobile) and then select Joystick.js from the window.
That's what I'm saying. I already tried that script and nothing happened.
Answer by trs9556 · Jun 19, 2013 at 03:48 AM
So this code is in C, and I got a converted version of Joystick.js to C# so maybe someone can help convert this code into js, but this is what I do.
So I have a game manager, and it has a public GameObject and I set to a prefab that has Joystick.js as a component (actually it's called MPJoystick.cs for me because it's converted). My game manager checks if a instance of joystick exists, if not it creates one.
Example:
public GameObject joyStickPrefab;
public static GameObject joyStickInstance;
if (GameObject.Find(joyStickPrefab.name.ToString()) != null || GameObject.Find(joyStickPrefab.name.ToString()+"(Clone)") != null){
joyStickInstance = GameObject.Find(joyStickPrefab.name.ToString()+"(Clone)");
}else{
Instantiate(joyStickPrefab);
joyStickInstance = GameObject.Find(joyStickPrefab.name.ToString()+"(Clone)");
}
So now that I have my joystick visible, I can have my other scripts find them. So in my case it's a tower that needs to find it, so I do it doing this:
private MPJoystick rotateJoyStick; //so declare my joystick var
rotateJoyStick = GameObject.Find("JoyStick(Clone)").GetComponent<MPJoystick>(); //find my joystick
Now that I have my joystick, I can actually get values from it.
float speed = 55.5f;
Vector2 camRotation = Vector2.zero;
camRotation = rotateJoyStick.position;
camRotation.x *= speed * Time.deltaTime;
// Rotate the character around world-y using x-axis of joystick
turretObject.Rotate(0, camRotation.x, 0, Space.World );
So obviously I have this for rotating my tower in just the y axis.
Basically the script returns a value depending on where the joystick currently is. You can apply this simple example to get full movement and rotation.
Like stated before this is in C#, I don't know how to convert this into js. If you want the c# version of the joystick script it can be found here http://pastebin.com/rL1vWR1E
Answer by citizen_rafiq · Sep 01, 2013 at 10:47 AM
//you need two round texture one for boundary are which is bigger then 2nd texture which will //be touch and drag for controlling
public class JoyStick : MonoBehaviour {
public Texture areaTexture;
public Texture touchTexture;
public Vector2 joystickPosition = new Vector2( 135f,135f);
public Vector2 speed = new Vector2(2,100);
public float zoneRadius=100f;
public float touchSize = 30;
public float deadZone=20;
public float touchSizeCoef=0;
protected Vector2 joystickAxis;
protected Vector2 joystickValue;
public Vector2 joyTouch;
private Vector2 _joystickCenter;
[SerializeField]
private Vector2 _smoothing = new Vector2(20f,20f);
public Vector2 Smoothing
{
get {
return this._smoothing;
}
set {
_smoothing = value;
if (_smoothing.x<0.1f){
_smoothing.x=0.1f;
}
if (_smoothing.y<0.1){
_smoothing.y=0.1f;
}
}
}
private int _joystickIndex=-1;
private bool _enaReset;
private bool _enaZoom;
void Start ()
{
_joystickCenter = joystickPosition;
_enaReset=false;
}
void Update ()
{
if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android)
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
{
if (_joystickIndex==touch.fingerId){
_joystickIndex=-1;
_enaReset=true;
}
}
if(_joystickIndex==touch.fingerId)
{
OnTouchDown(touch.position);
}
if (touch.phase == TouchPhase.Began)
{
if (((Vector2)touch.position - _joystickCenter).sqrMagnitude < Mathf.Pow((zoneRadius+touchSizeCoef/2),2))
{
_joystickIndex = touch.fingerId;
}
}
}
UpdateJoystick();
if(_enaReset)
{
ResetJoystick();
}
}
else
{
if (Input.GetButtonUp ("Fire1"))
{
_joystickIndex=-1;
_enaReset=true;
}
if(_joystickIndex==1)
{
OnTouchDown(Input.mousePosition);
}
if (Input.GetButtonDown ("Fire1") )
{
if (((Vector2)Input.mousePosition - _joystickCenter).sqrMagnitude <Mathf.Pow( (zoneRadius+touchSizeCoef/2),2))
{
_joystickIndex = 1;
}
}
if(_enaReset)
{
ResetJoystick();
}
UpdateJoystick();
}
}
private void UpdateJoystick()
{
if (joyTouch.sqrMagnitude>deadZone*deadZone)
{
joystickAxis = Vector2.zero;
if (Mathf.Abs(joyTouch.x)> deadZone)
{
joystickAxis = new Vector2( (joyTouch.x -(deadZone*Mathf.Sign(joyTouch.x)))/(zoneRadius-touchSizeCoef-deadZone),joystickAxis.y);
}
else
{
joystickAxis = new Vector2( joyTouch.x /(zoneRadius-touchSizeCoef),joystickAxis.y);
}
if (Mathf.Abs(joyTouch.y)> deadZone)
{
joystickAxis = new Vector2( joystickAxis.x,(joyTouch.y-(deadZone*Mathf.Sign(joyTouch.y)))/(zoneRadius-touchSizeCoef-deadZone));
}
else{
joystickAxis = new Vector2( joystickAxis.x,joyTouch.y/(zoneRadius-touchSizeCoef));
}
}
else{
joystickAxis = new Vector2(0,0);
}
Vector2 realvalue = new Vector2( speed.x*joystickAxis.x,speed.y*joystickAxis.y);
joystickValue=realvalue;
print(realvalue);
}
void OnTouchDown(Vector2 position)
{
joyTouch = new Vector2( position.x, position.y) - _joystickCenter;
if ((joyTouch/(zoneRadius-touchSizeCoef)).sqrMagnitude > 1)
{
joyTouch.Normalize();
joyTouch *= zoneRadius-touchSizeCoef;
}
//print(joyTouch);
}
private void ResetJoystick()
{
if (joyTouch.sqrMagnitude>0.1)
{
joyTouch = new Vector2( joyTouch.x - joyTouch.x*_smoothing.x*Time.deltaTime, joyTouch.y - joyTouch.y*_smoothing.y*Time.deltaTime);
}
else{
joyTouch = Vector2.zero;
_enaReset=false;
}
}
void OnGUI()
{
GUI.DrawTexture( new Rect(_joystickCenter.x -zoneRadius ,Screen.height- _joystickCenter.y-zoneRadius,zoneRadius*2,zoneRadius*2), areaTexture,ScaleMode.ScaleToFit,true);
GUI.DrawTexture( new Rect(_joystickCenter.x+(joyTouch.x -touchSize) ,Screen.height-_joystickCenter.y-(joyTouch.y+touchSize),touchSize*2,touchSize*2), touchTexture,ScaleMode.ScaleToFit,true);
}
}
Answer by musaranya · Jun 18, 2014 at 01:42 PM
This is the way I make it: drag the FPSController prefab (Mobile) to the scene and VERY IMPORTANT: don't move it, just let it wherever it is. Then create an empty object and rename it to PlayerSpawn(1), place this object where you want the player to be spawned and that's all, when you hit play you can move the player properly with unity remote. Hope it helps
(1) this is because, if you open the FirstPersonControl.js, you can see that in the Start() function it looks for an object called PlayerSpawn and moves the player to it
Do you drag it to the scene or to the hierarchy window? I seem to notice that often times with non-visual assets (sometimes others as well... not sure) dragging to the hierarchy window gives better results.
Follow this Question
Related Questions
GUI Joystick 1 Answer
Unity 5 mobile single stick control 6 Answers
The joystick isnt working in Unity remote 5 3 Answers
Swipe and Joystick Together on Mobile 0 Answers
Mobile Joystick Problem 2 Answers