How can I move an UI Image to a touch position? - unity3d

I have an image on the scene. Now when I touch on my mobile device to a specific position, I want, that the image moves to this position.
How can I do it?
I wrote this:
transform.position = Input.mousePosition;
But this don't work. Ok, it's working, but the image is not anymore on the screen. It's somewhere on the right side.
I found this. But it's also not working:
gameObject.GetComponent<RectTransform>().localPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
Here is the problem, that when I touch on the screen bottom left (mobile) the object is in the center of the screen.

You can move the UI Image by putting the following in a script attached to it:
void Update() {
for (var i = 0; i < Input.touchCount; i++) {
if (Input.GetTouch(i).phase == TouchPhase.Began) {
// assign new position to where finger was pressed
transform.position = new Vector3 (Input.GetTouch(i).position.x Input.GetTouch(i).position.y, transform.position.z);
}
}
}

use
gameobject.transform.position = camera.ScreenToWorldPoint(Input.mousePosition);
for Desktop. for mobile you want to replace InputmousePostion with input.getTouch[i].position.

I know this is an old post but this took way longer than it should have so thought i'd share my solution in case it helps other trying to do the same thing.
var touchpoint = Instantiate(Resources.Load("prefabs/touchpoint"), new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
//set it parent to the main canvas
touchpoint.transform.parent = MainCanvas.transform;
//convert touch position to localposition reletive to canvas
Vector2 localPos;
RectTransformUtility.ScreenPointToLocalPointInRectangle(MainCanvasRect, new Vector3(t.position.x, t.position.y, 0), null, out localPos);
//set position on canvas
touchpoint.transform.localPosition = localPos;

Related

Jump functionality for a 2D Top Down Unity game?

I am struggling to find an efficient way to let my player jump in a 2D Top Down world. I can see a lot of tutorials about platformer views where the camera is oriented at the side of the player, but nothing really working for a top down view like startdew Valley.
I am not using physics, so I move the character on the tilemap using a Couroutine which moves the player to the next position on grid, here it is my Update and DoMove methods:
private void Update()
{
if (!isMoving)
{
input.x = Input.GetAxisRaw("Horizontal");
input.y = Input.GetAxisRaw("Vertical");
if (input.x != 0)
input.y = 0;
if (input != Vector2.zero)
{
animator.SetFloat("Horizontal", input.x);
animator.SetFloat("Vertical", input.y);
var targetPos = transform.position + new Vector3(input.x, input.y, 0f);
// obstacle detection
Vector3Int obstaclesMapTile = obstacles.WorldToCell(targetPos - new Vector3(0, .5f, 0));
if (obstacles.GetTile(obstaclesMapTile) == null)
{
StartCoroutine(DoMove(targetPos));
}
}
animator.SetFloat("Speed", input.sqrMagnitude);
}
}
private IEnumerator DoMove(Vector3 newPos)
{
isMoving = true;
while ((newPos - transform.position).sqrMagnitude > Mathf.Epsilon)
{
transform.position = Vector3.MoveTowards(transform.position, newPos, moveSpeed * Time.fixedDeltaTime);
yield return null;
}
transform.position = newPos;
isMoving = false;
}
Is there anybody which could give me an hint on how to add a jumping feature? ( ideally with animation support?) I am kind of running out of ideas.
Thanks in advance.
Just think of it as animation only. Since it is 2D top down, it's more about it looking like it jumps, and then if it has to go over something while in the jump animation, test for just that.
For example; if over hole and jump animation is playing, then allow movement over the whole, otherwise fall. So if the player presses the button for jump, the animation would play, and there should be some variable storing what animation the player is currently in.

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

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);
}

Move object with hinge joint, but keep it connected to hinge

I have multiple spheres in my mobile game that are attached to hinge joints. The spheres are able to swing and knock into each other, causing other spheres to swing. I am creating movement in the spheres by touching on a sphere and dragging it to a new location. Letting go is supposed to cause the sphere that I just moved to swing accordingly.
The issue is that I am able to move the spheres well outside of the space provided by the hinge. I never want the spheres to move anywhere that they wouldn't be able to swing using the hinge. I am able to move the spheres multiple units/meters away from their original position, when ideally I wouldn't be able to move them more than a few centimeters. The spheres should just stop moving if I hit a limit in the hinge.
Here's my code for the script that controls movement of the spheres:
GameObject selectedObject;
Vector3 screenPoint;
Vector3 offset;
void Update () {
if (Input.touchCount == 0)
{
return;
}
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began) // when screen is touched...
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenToWorldPoint(touch.position), Camera.main.transform.forward, out hit)) // ...cast a ray...
{
if (hit.collider.tag == "Sphere") //...and check if ray hits a sphere
{
selectedObject = hit.collider.gameObject;
screenPoint = Camera.main.WorldToScreenPoint(selectedObject.transform.position);
offset = selectedObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, screenPoint.z));
}
}
}
if (touch.phase == TouchPhase.Moved)
{
Vector3 touchPoint = new Vector3(touch.position.x, touch.position.y, screenPoint.z);
Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touchPoint) + offset;
selectedObject.transform.position = touchPosition;
}
}
Any help is greatly appreciated! Let me know if I need to explain more or show a video of the issue.
I know I am a little late but you can use AddForce() and AddTorque() methods on the object you want to move but that works only if you have RigidBody on the object.

Get touch location on screen for perspective Camera

As the title of the question goes, I am trying to get the touch location on screen for perspective Camera.
Pretty much when I click a button my character has the ability to "teleport" or change it's location/transform to the same area of my finger with the Z axis hard coded.
Now I stress "Perspective Camera" because when the camera is Orthographic the following works fine.
if (canTeleport == true) {
if (Input.GetMouseButtonDown (0)) {
//fingerPos = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
// fingerPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); //Desktop
// transform.position = fingerPos;
// Debug.Log (transform.position);
//Needed for Mouse
//fingerPos = Input.mousePosition;
//Needed for Finger
fingerPos = Input.GetTouch(0).position;
//Oth Camera
fingerPos.z = -36.1f;
fingerPos = Camera.main.ScreenToWorldPoint (fingerPos);
//Pers Camera
// Vector3 screenPosition= new Vector3(0,0,0);
//fingerPos = GetWorldPositionOnPlane(screenPosition, -36.1f);
fingerPos.z = -36.1f;
transform.position = fingerPos;
Debug.Log (transform.position);
canTeleport = false;
}
}
But when in perspective it does not, I understand 2D and 3D space is different but only thing that should matter is the Z axis and i'm hard codding the Z axis so im not sure why it does not work.
any help offered will be appreciated.
thank you.
Update
The circle area is where I touched and as you can see my sprite went to the location on the canvas not in the game world.

Make rectangle in Unity

I stuck on the basics of Unity. I want to make a scene for mobiles in which there are four different coloured rectangles that take 25% of the screen each.
I tried making an GameObject Image, "registering" it as a prefab in Inspector.
Below code is an example of how I tried to make a single red rectangle and position it on the (x,y,z) => (0,0,0) coordinates on my scene.
Several problems are present:
Rectangle did not appear
I don't know how to programatically specify width and height of the rectangle
This is how it looks:
public class SceneScript : MonoBehaviour {
public GameObject prefab;
void Start () {
Vector3 pos = new Vector3(0, 0, 0);
GameObject gameObject = Instantiate(prefab);
Image image = gameObject.GetComponent<Image>();
image.color = new Color(1.0F, 0.0F, 0.0F);
gameObject.transform.position = new Vector3(0, 0, 0);
}
// Update is called once per frame
void Update () {
}
}
Is there an easier solution, or is this the best practice + could you please provide me some hints what should I do?
You probably don't have a Canvas in your heirarchy. Here's how you can programmatically create your Canvas, your Image and their containing GameObjects:
Vector3 pos = new Vector3(0, 0, 0);
GameObject parentGameObject = new GameObject();
Canvas canvas = parentGameObject.AddComponent<Canvas>();
GameObject imageGameObject = new GameObject();
imageGameObject.transform.SetParent(canvas.transform);
Image image = imageGameObject.AddComponent<Image>();
image.color = new Color(1.0F, 0.0F, 0.0F);
imageGameObject.transform.position = pos;
This will create a full-screen, red rectangle. Play around with the RectTransform settings in the inspector after these are created and you should be able to figure out how to size them properly.