Unity how to make a Visual JoyStick in Unity
You can implement your own Visual Joystick by using the Unity new event callback functions such as OnBeginDrag
OnDrag
and the OnEndDrag
function. There is a already made Visual Joystick package out there for Unity, so implementing your own is like reinventing the wheel.
All you have to do is to import the CrossPlatformInputManager
package from Unity's UnityStandardAssets then use CrossPlatformInputManager.GetAxis("Horizontal")
and CrossPlatformInputManager.GetAxisRaw("Horizontal")
to read the direction of the image/thumb.
To make one from scratch, you can flow this video tutorial.
Unity - Virtual Joystick - Camera rotation
Well, here is a simple idea for how to solve it. At least this is how I did it, and it seems to work ever since.
First, you need to get the joystick input, like you did. Both axis input value should be between -1 and 1. This actually determines the direction itself, since the horizontal axis gives you the X coordinate of a vector and the vertical gives you the Y coordinate of that vector. You can visualize it easily:
Mind, that I just put up some random values there, but you get the idea.
Now, your problem is, that this angle you get from your raw input is
static in direction, meaning that it doesn't rely on the camera's face
direction. You can solve this problem by "locking it to the camera",
or in other words, rotate the input direction based on the camera
rotation. Here's a quick example:
//Get the input direction
float inputX = joystick.Horizontal();
float inputY = joystick.Vertical();
Vector3 inputDirection = new Vector3(inputX, 0, inputY);
//Get the camera horizontal rotation
Vector3 faceDirection = new Vector3(cameraTransform.forward.x, 0, cameraTransform.forward.z);
//Get the angle between world forward and camera
float cameraAngle = Vector3.SignedAngle(Vector3.forward, faceDirection, Vector3.up);
//Finally rotate the input direction horizontally by the cameraAngle
Vector3 moveDirection = Quaternion.Euler(0, cameraAngle, 0) * inputDirection;
IMPORTANT: The code above should be called in the Update cycle, since that is where you get the input information.
After this, you can work with moveDirection
to move your player. (I suggest using physics for moving, instead of modifying its position)
Simple moving example:
public RigidBody rigidbody;
public Vector3 moveDirection;
public float moveSpeed = 5f;
void FixedUpdate()
{
rigidbody.velocity = moveDirection * moveSpeed;
}
Use Mobile Joystick with Unity 3d RigidBody
If someone would need it. Here it is. It is simple movement with mobile joystick. You might want to modify it to your needs if you have complex movements
using UnityEngine;
public class MovementOfPlayer : MonoBehaviour
{
Vector3 movementInput;
Rigidbody playerRigidbody;
void Start()
{
playerRigidbody = GetComponent<Rigidbody>();
playerRigidbody.freezeRotation = true;
}
void FixedUpdate()
{
movementInput = Input.GetAxisRaw("Horizontal") * Vector3.right +
Input.GetAxisRaw("Vertical") * Vector3.forward;
movementInput.Normalize();
float y = playerRigidbody.velocity.y;
if (movementInput != Vector3.zero)
{
if (transform.forward != movementInput)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(movementInput), Time.deltaTime * 180);
playerRigidbody.velocity = Vector3.MoveTowards(playerRigidbody.velocity, Vector3.zero, Time.deltaTime * 30);
}
else
{
playerRigidbody.velocity = Vector3.MoveTowards(playerRigidbody.velocity, movementInput * 10, Time.deltaTime * 30);
}
}
else
{
playerRigidbody.velocity = Vector3.MoveTowards(playerRigidbody.velocity, Vector3.zero, Time.deltaTime * 30);
}
Vector3 velocity = playerRigidbody.velocity;
velocity.y = y;
playerRigidbody.velocity = velocity;
}
}
Why do I get this error for a joystick in Unity?
Based on the video, you have to drag and drop the FixedJoystick object from the scene's hierarchy onto the PlayerMovement's joystick field in the Inspector (check out 11:24 from the video)
How to change joystick position by tap?
You can create a class for example JoystricManager, where you'll have an Update() method. In Update() you will check for Input.GetMouseButtonDown(0) - which will be true when user taps the screen. Add a collider to you joystick GameObject and after getting click check if this click is inside the collider. If click is inside - ignore it and just check in your joystick script Input.MousePosition to check movement of joystick itself and do your custom actions (move player, etc). If click will be outside the joystick collider - simply move your joystick
to the new position. Save the click position in your joystick to get the beginning coordinate of click. When user will move finger you'll get new mouse position, using this two points you can calculate where your joystick points.
unity how to control camera view using a single joystick?
- In the editor, create an empty game object called "Pivot"
- Make your camera a child of Pivot.
- Move the camera away from Pivot, whatever distance you need.
- Now attach a script to Pivot.
Something like this :
void Update(){
float speed = 3.0f;
float xRot = speed * Input.GetAxis("Vertical");
float yRot = speed * Input.GetAxis("Horizontal");
transform.Rotate(xRot, yRot, 0.0f);
}
- Assign your camera to the camera var in the script attached to Pivot
- Now you do the messing around of the rotation
Unity - Joystick Controller - Camera Problem
Replacing the move direction calculation with the following should work.
move = (cameraTransform.forward * transform.localPosition.x + cameraTransform.right * transform.localPosition.z).normalized;
To understand why this works remember your default forward direction is Vect3(1.0, 0.0, 0.0) and your right direction is Vect3(0.0, 0.0, 1.0) meaning as long as we don't turn we get your original calculation. Once we start turning we basically rotate the pad movement by the y angle we're rotated by.
If your player is not supposed to move on the y axis make sure to set the y component of the move vector to 0 before normalizing it.
Unity Joystick Bug, it goes to the same place on the firt touch
I notice in OnDrag()
you set pos.y
using bgImg.rectTransform.sizeDelta.x
instead of bgImg.rectTransform.sizeDelta.y
.
And in Vertical()
you are also checking inputVector.x
instead of inputVector.z
.
These most likely won't fix the bug but they are good fixes to make.
What will work is removing the offset in
inputVector = new Vector3(pos.x * 2 + 1, 0, pos.y * 2 - 1);
Change this to
inputVector = new Vector3(pos.x * 2, 0, pos.y * 2);
removing the +1 and -1, and that should fix it!
Related Topics
Find Recursive Group Membership (Active Directory) Using C#
Splitting a String/Number Every Nth Character/Number
Generate a PDF That Automatically Prints
Why Use Simple Properties Instead of Fields in C#
How to Resize Multidimensional (2D) Array in C#
Why Can't We Change Access Modifier While Overriding Methods in C#
Passing a Value from One Form to Another Form
When Is a Custom Attribute's Constructor Run
Cannot Step into .Net Framework Source Code
Not Ableto Serialize Dictionary with Complex Key Using JSON.Net
Wpf: How to Dynamically Add Controls in Dynamically Created Wpf Window
Is It Worthwhile to Initialize the Collection Size of a List<T> If It's Size Reasonably Known
How to Connect to an Mdf Database File