How can I stop getting mouse position of UI Elements in Unity2D? - unity3d

I'm making a mobile game where there is a simple circle with a handle attached to it, it can be controlled and can be rotated with mouse position, I'm using below code for handle control.
public class Controller : MonoBehaviour
{
private float m_force = 0.04f;
// amount of force for the player (circle and handle both)
public GameObject firePoint; // It is the tip of the handle which will shoot bullets
public float senstivity = 1f;
// senstivity control
public void ControlSenstivity(float index)
{
senstivity = index;
}
void Update()
{
//Get the Screen positions of the object
Vector2 positionOnScreen = Camera.main.WorldToViewportPoint(transform.position) ;
//Get the Screen position of the mouse
Vector2 mouseOnScreen = Camera.main.ScreenToViewportPoint(Input.mousePosition) ;
//Get the angle between the two points
float angle = AngleBetweenTwoPoints(positionOnScreen, mouseOnScreen) ;
// it will control the rotation of player (circle and handle both)
transform.rotation = Quaternion.Euler(new Vector3(0f, 0f, angle) * senstivity);
}
float AngleBetweenTwoPoints(Vector3 a, Vector3 b)
{
return Mathf.Atan2(a.y - b.y, a.x - b.x) * Mathf.Rad2Deg ;
}
// Below function for adding force to the player (both the circle and the handle), this function I added for mobile input whenever the button is pressed
public void AddForce()
{
transform.Translate(-firePoint.transform.localPosition.x, 0, 0 * m_force);
}
}
In this mobile game the user can rotate the player by dragging on the screen and can move the player by exerting force in the opposite direction of fire point whenever the add force button is pressed but the problem is that whenever I press the button the player takes Input.mousePosition of that button position and get rotated towards the button, that's why it will always move in one direction that is opposite of button. I wanted to know what can I do to not get Input.mousePosition of button which is in the canvas and can originally get position only of camera space. Any response will be appreciated, Thanks in advance!

You can use EventSystem.IsPointerOverGameObject. This method will check if your pointer(mouse/joystick) is on any of the UI elements.
Add if condition before getting mouse position.
// This will ignore all UI game objects
if (!EventSystem.current.IsPointerOverGameObject())
{
//Get the Screen positions of the object
Vector2 positionOnScreen = Camera.main.WorldToViewportPoint(transform.position);
}

Related

How to use AddForce to make a gameobject jump. The following code is attached to a gameobject. Gameobject wont jump when mouse key pressed

float translation = Input.GetAxis("Vertical") * playerspeed * Time.deltaTime;
float rotation = Input.GetAxis("Horizontal") * playerRotationSpeed * Time.deltaTime;
//check if mouse button prsessed for jumping
IsClicked = (Input.GetMouseButtonUp(0));
if ((IsClicked) && IsOnGround())
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
//move player
transform.Translate(0,0, translation);
transform.Rotate(0, rotation, 0);
}
//checks if berry is grounded
bool IsOnGround()
{
if (Physics.Raycast(transform.position, Vector3.down, distancetoground))
return true;
else
return false;
}
}
The above code is attached to a gameobject. Gameobject won't jump when mouse key pressed. I think the problem is I can move the gameobject using translate. but unable to add a jumping force as required when the left mouse button is pressed as I have set the y axis paraemter in the translate. Don't know how to get round this one. Any offers?
Try to use a rigid body instead it might not be more efficient but it works fine for me. You add a force upwards when the button is pressed (This won't work in games where you move your platform instead of a player)

Canvas rotating when I change it to worldSpace, Unity

I've got a canvas that changes from Overlay to worldSpace when an event occurs, but when it changes to Overlay from worldSpace, the rotation of the canvas is changed, which I don't want it to be.
Images:
As you can see in the order that the images are, it starts with no rotation in worldSpace, then the event occurs changes it to overlay and the rotation is now 140, after the event and I'm back in worldSpace, it is still 140 degrees.
I don't know what is wrong with this. Please help if you can
This happens because, internally, the Canvas is being transformed into camera space when set to Overlay. That's how it renders. Your solution would be to cache the transform before changing the Render Mode.
Something like this, given a component:
using UnityEngine;
[RequireComponent(typeof(Canvas))]
public class CanvasRenderModeSwitcher : MonoBehaviour
{
private Canvas canvas;
private Vector3 position;
private Vector3 scale;
private Quaternion rotation;
private void OnEnable()
{
canvas = GetComponent<Canvas>();
}
public void SetRenderMode(RenderMode renderMode)
{
if (renderMode == RenderMode.WorldSpace)
{
// Set the render mode before values are reset.
canvas.renderMode = renderMode;
// Restore the values.
transform.position = position;
transform.rotation = rotation;
transform.localScale = scale;
}
else
{
// Cache the values.
position = transform.position;
rotation = transform.rotation;
scale = transform.localScale;
// Set the render mode after values are cached.
canvas.renderMode = renderMode;
}
}
}

the GameObject rotates incorrectly on the z-axis

there is a circle, it needs to be rotated by pressing the button, with a certain speed along the z axis, and when it turns 90, the rotation will stop, but for some reason the rotation is not working properly
public GameObject Circle;
private bool RotationActive;
//rotation value at which the circle stops rotation
private float RotatePost;
private float RotationSpeed;
private float CircleRotateZ;
void Start()
{
RotationActive = false;
RotationSpeed = 0.5f;
RotatePost = 90;
}
//function is bound to a button
public void RotateActive(){
RotationActive = true;
}
void FixedUpdate()
{
if (RotationActive == true)
{
CircleRotateZ = Circle.transform.rotation.z;
//if the circle along the z axis is rotated more than Rotation Post...
if (CircleRotateZ >= RotatePost )
{
RotatePost = CircleRotateZ + 90;
RotationActive = false;
}
//assignment of a new coordinate
Circle.transform.Rotate(new Vector3(0,0,RotationSpeed + CircleRotateZ));
}
}
You are trying to grab the rotation from the Quaternion which is not the angle of the object. Instead you should use:
CircleRotateZ = Circle.transform.eulerAngles.z;
Also the way you are currently rotating will make it speed up over time. The Rotate functions rotates the object by the amount, not to the amount given, so if you only want to rotate by the rotation speed you should use:
Circle.transform.Rotate(new Vector3(0, 0, RotationSpeed));
What do you mean by not working properly. You mean it doesn't move at all? If it doesn't move at all, check if you dragged the circle game object to the game object field in the Inspector. One more thing, why didn't you call the 'RotateActive' function?

Unity3d Move 2D Sprite relative to mouse position

if I move my sprite with the mouse, the sprite is always exactly under the cursor.
At the moment my code looks like that:
public GameObject player;
private float distance = 1;
private void Update()
{
if (Input.GetMouseButton(0))
{
Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance);
Vector3 playerPos = Camera.main.ScreenToWorldPoint(mousePos);
player.transform.position = playerPos;
}
}
but i want to move the sprite, no matter where my mouse courser is on the background. so if i click and hold next to the sprite and move my mouse to the right, i want that my sprite move the same way in same direction.
Example Picture
In this case, you should use a relative movement, that is, the amount that the mouse moved from its current position when the mouse button was clicked, as if that was the origin.
So, you should take note of the current mouse position when the user pressed the mouse button.
Here is one solution that does what I describe:
// by Vander 'imerso' Nunes to StackOverflow answer
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseDrag : MonoBehaviour
{
public GameObject player;
bool dragging = false;
Vector3 mouseStartPos;
Vector3 playerStartPos;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
dragging = true;
mouseStartPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
playerStartPos = player.transform.position;
}
else if (Input.GetMouseButtonUp(0))
{
dragging = false;
}
if (dragging)
{
Vector3 mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
Vector3 move = mousePos - mouseStartPos;
player.transform.position = playerStartPos + move;
}
}
}
You will notice that both current player position and current mouse position are noted when the button is initially pressed. So, they act as if they were the origin. The player is only moved by the distance that the mouse moves from its initial position when its button was pressed.

Orbiting target with camera and changing height

I want to be able to use joystick (left-right) to make the camera orbit around target. I have this handled with the code below:
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class OrbitCamera : MonoBehaviour {
public Transform target;
public float turnSpeed;
public float height;
public float distance;
private Vector3 offsetX;
void Start()
{
offsetX = new Vector3 (0, height, distance);
}
void LateUpdate()
{
offsetX = Quaternion.AngleAxis (CrossPlatformInputManager.GetAxis ("hOrbit") * turnSpeed, Vector3.down) * offsetX;
transform.position = target.position + offsetX;
transform.LookAt (target.position);
}
}
I need to extend this script so that the player can move camera also up and down using the same joystick. So what I want is the camera to be able to move around player in a shape of sphere, always looking at the player. Thanks in advance.
Use a boom camera
A boom camera is wonderfully easy to setup and has a range of convenient cinematic controls:
To set it up, you simply create a new game object which we'll call the dolly. You then simply parent the camera to the dolly and tidy up the positions and rotations:
Camera
Transform: 0,0,-distance
Rotation: 0,0,0
Dolly
Transform: 0,height,0
Rotation: 0,0,0
Why a boom camera is great
Rotate the dolly on x and y and you'll get the camera moving in a sphere. (Note that dragging the rotation gizmo in scene view doesn't show the effect properly because of axis alignment; edit the x/y rotation values in the inspector only).
That -distance z value is the zoom. Change the local position of the camera to zoom in/out.
Local rotating the camera gives interesting tilt/pan effects.
Making it work in your case
You'd attach the script to the dolly gameobject, then use the joystick input to rotate it on x/y:
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class OrbitCamera : MonoBehaviour {
// Height and distance are now set in the scene (by positioning the dolly and changing that camera z value).
public float turnSpeed;
private float horizontal;
private float vertical;
void LateUpdate()
{
// Update horizontal/ vertical angles:
horizontal += CrossPlatformInputManager.GetAxis ("hOrbit") * turnSpeed;
vertical += CrossPlatformInputManager.GetAxis ("vOrbit") * turnSpeed;
// Update the rotation:
transform.rotation = Quaternion.Euler(horizontal, vertical, 0f);
}
}