- Home /
Implementing a simple on-screen joystick for mouse
So I am trying to implement a simple on screen joystick with the mouse (and later move it to touch). I am aware that the standard assets mobile has the joysticks but I cannot test them with the mouse and they are in JS and i'm trying to do it in c#. Also for my own person reference in understanding how it all works better by doing it myself (for something simple like this.
I currently have the following setup:
plane with a capsule on it. The capsule represents the player. The main camera is stationary
a separate "GUI" area with a small plane, an alpha = 50 background plane, and a "gui" camera that only sees this stuff, even though it's off to the side.
What I have working:
When you use the little on screen "button", it moves the capsule. However when I comment out the code regarding rotation, it moves in the correct direction (so if I move the plane up, it moves the character forward.. and if I move it down, it moves the plane towards me, etc). When I try to introduce rotation (if this was a player, you probably don't want it side stepping all over the place instead of just turning to the left and going left), it seems to go all over the place because I assume my calculations are off.
The Theory
So the theory behind it I was going with was, you have the anchor point of the button, and the raycast hit point on the plane of where the mouse is. This would cause a direction from point A to point B and based on the length (magnitude) of the vector then it affects speed. The speed part seems to be working just fine it's the direction part i'm having trouble with. When it rotates the model it seems to no longer want to go in the direction vector, but instead wants to go in the direction relative to the rotation. I tried debugging with Debug. DrawLine and it pointed to the rotation and direction points being not where I would expect them to be but I can't seem to figure out why.
using UnityEngine;
using System.Collections;
public class MoveCapsule : MonoBehaviour {
public Transform theCapsule;
public Camera cam;
public float speed = 5.0f;
private Transform trans;
private Vector3 main;
void Start () {
trans = transform;
main = trans.position;
}
void Update () {
if(Input.GetMouseButton(0))
{
RaycastHit hit;
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit))
{
float mag = (main - hit.point).magnitude;
Vector3 direction = (hit.point - main).normalized;
Vector3 rotation = direction;
Debug.DrawLine(main, hit.point);
Debug.DrawLine (theCapsule.position, rotation);
if(mag < 0.35f)
trans.position = hit.point;
if(mag > 0.35f)
mag = 0.35f;
// used this code to project the Y axis to the Z so
// that it doesn't go up, and only left/right/forward/back.
// reverse X direction because camera is on the wrong
// side I think but otherwise controls are backwards
direction.z = direction.y;
direction.y = 0;
direction.x = -direction.x;
rotation.y = 0;
theCapsule.rotation = Quaternion.Slerp(theCapsule.rotation, Quaternion.LookRotation(rotation), 0.1f);
theCapsule.Translate(direction * mag * Time.deltaTime * speed);
}
}
// on mouse up, reset position
if(Input.GetMouseButtonUp(0))
{
trans.position = main;
}
}
}
Thanks to any input you guys have.