I am trying to build a mobile game with a feature where we can navigate the screen with Mouseposition.
I also have buttons in the canvas.
When I am pressing a button the screen rotates to the button position.
If there is any other ways to navigate with screen please help me.
Or if somebody knows how to implement this with touch system please help.
My code.
void Start(){
initialrot = transform.rotation;
}
void Update(){
float x =
Input.GetAxis("Mouse x");
float y =
Input.GetAxis("Mouse Y");
Vector3 mousePos = new Vector3(x,y,0);
transform.eulerangles = initialrot * mousePos;
}
Related
Hi StackOverflow community, I have one common issue and need your help.
I am a newbie in Unity but trying each day to improve my knowledge, sooo...
Recently, I completed one of the Udemy courses and now trying to add new features and run the game on a Mobile device. I added a Virtual joystick asset and already changed movement with that Joystick.
But for aim functionality, it is hard for me to change to Joystick.
What I changed already:
//moveInput.x = Input.GetAxisRaw("Horizontal"); // PC
//moveInput.y = Input.GetAxisRaw("Vertical"); // PC
moveInput.x = movingJoystick.Horizontal; // Mobile
moveInput.y = movingJoystick.Vertical; // Mobile
But now I need to change Vector3 mousePos = Input.mousePosition; to something similar to weapon.Joystic.Horizonral as I did with movement.
Please, advise some good implementations.
Here is a part of the code that handles character's and weapon rotation:
if (canMove && !LevelManager.instance.isPaused)
{
//moveInput.x = Input.GetAxisRaw("Horizontal"); // PC
//moveInput.y = Input.GetAxisRaw("Vertical"); // PC
moveInput.x = movingJoystick.Horizontal; // Mobile
moveInput.y = movingJoystick.Vertical; // Mobile
moveInput.Normalize();
//transform.position += new Vector3(moveInput.x * Time.deltaTime * moveSpeed, moveInput.y * Time.deltaTime * moveSpeed, 0f);
theRB.velocity = moveInput * activeMoveSpeed;
Vector3 mousePos = Input.mousePosition;
Vector3 screenPoint = CameraController.instance.mainCamera.WorldToScreenPoint(transform.localPosition);
if (mousePos.x < screenPoint.x)
{
transform.localScale = new Vector3(-1f, 1f, 1f);
gunArm.localScale = new Vector3(-1f, -1f, 1f);
}
else
{
transform.localScale = Vector3.one;
gunArm.localScale = Vector3.one;
}
//rotate gun arm
Vector2 offset = new Vector2(mousePos.x - screenPoint.x, mousePos.y - screenPoint.y);
float angle = Mathf.Atan2(offset.y, offset.x) * Mathf.Rad2Deg;
gunArm.rotation = Quaternion.Euler(0, 0, angle);
}
There are several ways to go about FPS controls in Unity but a common approach is to first lock the cursor (so it doesn't go everywhere), set it to invisible, and treat it as another axis.
The first parts will involve the following Cursor APIs. Also, make sure you disable and reenable these as the player enters and exists UI vs the FPS parts of your game!:
Cursor.lockState = CursosLockMode.Locked;
Cursos.visible = false;
The second part is simply another usage of Input.GetAxis. As the documentation for that API mentions, you can use "Mouse X" and "Mouse Y" as axis:
Input.GetAxis("Mouse X");
Input.GetAxis("Mouse Y");
That doc also mentions the following, in case those exact strings aren't working for you (but AFAIK, those two are the defaults when making a new unity project):
To set up your input or view the options for axisName, go to Edit >
Project Settings > Input Manager. This brings up the Input Manager.
Expand Axis to see the list of your current inputs. You can use one of
these as the axisName. To rename the input or change the positive
button etc., expand one of the options, and change the name in the
Name field or Positive Button field. Also, change the Type to Joystick
Axis. To add a new input, add 1 to the number in the Size field.
I have a virtual movement joystick that I'm using to control the movement of a player object which works fine, the code for this is below.
The problem I have is when I rotate the camera within game mode (or device) the direction is not adjusted according to the cameras rotation, exactly like is shown in this post here that I looked through to try and understand the problem.
I realise I need to rotate my movement around the forward direction the camera is facing which I tried to do with the bottom snippet of code however this yields really strange behavior when the player object moves incredibly fast and eventually unity becomes unresponsive, so something is being incorrectly multiplied I guess.
Could anybody point out where I'm going wrong please? ta !
Edit - Modified to potential answer
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using EasyJoystick;
public class NewJoystick : MonoBehaviour
{
[SerializeField] private float speed;
[SerializeField] private Joystick1 joystick;
[SerializeField] Camera MainCam;
private Rigidbody RB;
private Transform cameraTransform;
// Start is called before the first frame update
void Start()
{
cameraTransform = MainCam.transform;
}
void Awake()
{
RB = gameObject.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
float xMovement = joystick.Horizontal();
float zMovement = joystick.Vertical();
Vector3 inputDirection = new Vector3(xMovement, 0, zMovement);
//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;
RB.velocity = moveDirection * speed;
}
}
I tried this in the update loop -
var Direction = transform.position += new Vector3(xMovement, 0f,zMovement); //* speed * Time.deltaTime;
Vector3 newDir = MainCam.transform.TransformDirection(Direction);
transform.position += new Vector3(newDir.x, 0f,newDir.z) * speed * Time.deltaTime;
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;
}
I recently started developing my very first top down 2d game. My problem is not knowing exactly how to get the bullet to go where the mouse is facing at the time of the activation of the bullet. I have a face mouse function as seen here
void faceMouse()
{
Vector3 mousePosition = Input.mousePosition;
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
Vector2 direction = new Vector2(
mousePosition.x - transform.position.x,
mousePosition.y - transform.position.y);
transform.up = direction;
}
However, I am not sure how to incorporate that if at all to be able to shoot at the location of my mouse. Thanks in advance!
You could try Quaternion.LookRotation() which creates a rotation based on a forward and upward vector (Documentation). Then you need to assing that rotation to your object. I use it something like this:
cursorPos = mainCamera.ScreenToWorldPoint(Input.mousePosition);
var forwardDirection = transform.position - cursorPos;
//Vector3.forward because is the z axis which is up/down in 2D
Quaternion playerRotation = Quaternion.LookRotation(forwardDirection, Vector3.forward);
transform.rotation = playerRotation;
I have a script that can rotate an object by touch or mouse on it but I want to rotate the object when mouse goes over the corner of the object only. How can I do this?
The code I'm using is
private float baseAngle = 0.0f;
void OnMouseDown(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
baseAngle = Mathf.Atan2(pos.y, pos.x) * Mathf.Rad2Deg;
baseAngle -= Mathf.Atan2(transform.right.y, transform.right.x) *Mathf.Rad2Deg;
}
void OnMouseDrag(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
float ang = Mathf.Atan2(pos.y, pos.x) *Mathf.Rad2Deg - baseAngle;
transform.rotation = Quaternion.AngleAxis(ang, Vector3.forward);
}
Put invisible GameObjects or RectTransforms onto the corners of your object you want to rotate, and use them as the controls for the parent object.
One way of doing so would be to add colliders to the corners of your object.
Using OnCollisionStay(), you could then trigger the appropriate functions when the mouse button is pressed. I've done similar myself, and this way does work.
Another method to the madness:
You could raycast where you are clicking, if your raycast is within an appropriate distance to the corners (which you could calculate based on its dimensions) then permit the rotation on click.
So I am trying to create a kind of turrent like a tank. The upper section needs to look at my mouse. I have tried
GetComponent().ScreenToWorldPoint(Argument);
many times togheter with
Input.mousePosistion();
But I couldn't figure this out really. I am programing this in C# if any one could help or provide a simple script that works in a 3D setting that would be great!
My code so far:
using UnityEngine;
using System.Collections;
public class Laser : MonoBehaviour {
public float Speed;
public AudioClip LaserSFX;
private Transform Player;
public Vector3 mousePos;
public Camera Cam;
// Use this for initialization
void Start () {
GameObject player = GameObject.FindWithTag("Player");
Player = player.transform;
if(!GetComponent<AudioSource>().isPlaying)
GetComponent<AudioSource> ().PlayOneShot (LaserSFX);
}
// Update is called once per frame
void Update () {
//Code to look at mouse or rotate
//Code to move towards it
float dist = Vector3.Distance(Player.position, transform.position);
if (dist >= 500)
{
Destroy(gameObject);
}
}
}
With kind regards,
Misterk99
You have to convert the mouse position to the view position, this means the ScreenToWorldPoint should be provided to you by the camera you are using at that time, and since you already have the camera as cam:
Vector3 pos = Input.mousePosition;
pos = Cam.ScreenToWorldPoint(pos);
with that now you have to face the position, and since you are using topdown 3D i supose the camera is facing the -y position. if so, don't forget to set the y you want:
pos.y = (your value here, depending to the position you are giving to your objects);
Vectgor3 dir = this.position - pos;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.up);
I figured out a solution while trying to find one for myself. The answer #Spike gave led me on the right track. However, I used the mouse's viewpoint position and converted the objects position to the viewport position. Here is the code in Javascript (what I am using) which should be easy enough to convert to C#.
My camera is facing the -Y direction, FYI.
#pragma strict
var cam: Camera;
function Start () {
}
function Update () {
var mousePos: Vector3 = Input.mousePosition;
var playerPos: Vector3 = cam.WorldToScreenPoint(transform.position);
var dir: Vector3 = mousePos - playerPos;
var angle: float = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(-angle, Vector3.up);
}