I want to move 2d object only horizontally by touch in Unity - c#

I implemented a touch drag.
But I can not move only horizontally.
I would expect to limit it to if, but I do not know what to do after that.
Here is my code.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
public class Draggable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public void OnBeginDrag (PointerEventData eventData)
{
Debug.Log ("OnBeginDrag");
}
public void OnDrag (PointerEventData eventData)
{
Debug.Log ("OnBeginDrag");
//this.transform.position = eventData.position;
GetComponent<Transform> ().position = eventData.position;
}
public void OnEndDrag (PointerEventData evnetData)
{
Debug.Log ("OnEndDrag");
}
}

You don't need to call GetComponent for transform.
If the code you were using works and you just want horizontal drag, something like this should work.
var currentPos = transform.position;
transform.position = new Vector3(eventData.position.x, currentPos.y, currentPos.z);

Related

Unity - How to Interact With Objects Between UI and World Space

I am new to unity and want to make a card - board game. I want to be able to place a card on a particular tile on the board. However, my draggable script that is attached to my card seems to not interact with the world space tile (it will interact with other UI). The world space tile has a droppable script, that currently doesn't have any real functionality, but should at least output a message to the console when a user hover overs it with their cursor. It doesn't even do that. (Again, droppable works with other UI elements) I thought that maybe because when the user is selecting their cards from their hand, and the canvas is in render mode - screen space camera - that had an effect, so I wrote a script that changes the render mode of the canvas to world space and it still seems to not interact. I will attach as much as I can for a clearer explanation, but at this point all I wish is for the board or tile to be able to recognize the user is hovering over it with the cursor.
Any help or information is appreciated, I am trying to absorb as much knowledge as I can, so even if you don't have a solution, advice is useful!
Dropzone.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Dropzone : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("OPEnt");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("OPExt");
}
public void OnDrop(PointerEventData eventData)
{
Debug.Log("on drop " + gameObject.name);
}
}
Draggable.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Draggable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
Transform originalParent = null;
private RectTransform RectTransform;
private void Awake()
{
RectTransform = GetComponent<RectTransform>();
}
public void OnBeginDrag(PointerEventData eventData)
{
originalParent = this.transform.parent;
this.transform.SetParent(this.transform.root);
GetComponent<CanvasGroup>().blocksRaycasts = false;
this.transform.parent.gameObject.GetComponent<CameraRender>().ChangeState();
}
public void OnDrag(PointerEventData eventData)
{
RectTransform.anchoredPosition += eventData.delta;
}
public void OnEndDrag(PointerEventData eventData)
{
this.transform.parent.gameObject.GetComponent<CameraRender>().ChangeState();
this.transform.SetParent(originalParent);
GetComponent<CanvasGroup>().blocksRaycasts = true;
}
}
CameraRender.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraRender : MonoBehaviour
{
enum RenderModeStates { camera, overlay, world };
RenderModeStates m_RenderModeStates;
Canvas m_Canvas;
// Use this for initialization
public void Start()
{
m_Canvas = GetComponent<Canvas>();
}
// Update is called once per frame
public void Update()
{
//Press the space key to switch between render mode states
if (Input.GetKeyDown(KeyCode.Space))
{
ChangeState();
}
}
public void ChangeState()
{
switch (m_RenderModeStates)
{
case RenderModeStates.camera:
m_Canvas.renderMode = RenderMode.WorldSpace;
m_RenderModeStates = RenderModeStates.world;
break;
case RenderModeStates.world:
m_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
m_RenderModeStates = RenderModeStates.camera;
break;
}
}
}
I have tried to add a script that transitions render modes from Screen Space to World Space, I have attached box colliders to the world space objects.
For non-UI 3D objects in order to receive the IPointerXYHandler etc messages you need
Collider on the according object(s)
a PhysicsRaycaster component attached to your Camera (and make sure the according Layers are selected as "Event Mask" in its Inspector)

ScreenToWorld point on 2d scale without affecting the Z position

I'm creating a draggable item but whenever I drag it's z position would become 47 and I wanted it to retain to 0.
using UnityEngine;
using UnityEngine.EventSystems;
public class draggableItem : MonoBehaviour, IBeginDragHandler, IDragHandler , IEndDragHandler
{
Transform setParentAferDrag;
public void OnBeginDrag(PointerEventData eventData)
{
setParentAferDrag = transform.parent;
transform.SetParent(transform.root);
transform.SetAsLastSibling();
}
public void OnDrag(PointerEventData eventData)
{
var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = mousePos;
}
public void OnEndDrag(PointerEventData eventData)
{
transform.SetParent(setParentAferDrag);
}
}

Touch event does not do any action on the Unity c # smartphone

I have this code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
public class start : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public GameObject musica;
public bool pulsado;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void OnPointerDown(PointerEventData eventData)
{
pulsado = true;
audio();
SceneManager.LoadScene("pajaro");
}
public void OnPointerUp(PointerEventData eventData)
{
pulsado = false;
}
void audio()
{
musica.SetActive(true);
}
}
When I export it to Android, touch does not work, but if it works in unity
You're using OnPointerDown, this is specific to the mouse, this event does not fire for Touch input (touch input does not have a concept of "up" and "down").
In order to have touch input, you have to use Input.touches during the Update() loop.

Game Object does not retain its original position when left in space on drag n drop in unity

There is a game Object "Heat" in Unity 2D. I am trying to drag and drop game object on another game object Sun using UI(works for unity version greater than 4.6). Drag works right but when I drop the object in space other than Sun, heat object does not retain its original position. I tried to make it work using colliders and raycasting but it does not seem to work. Here is the code:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class Drag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
public static GameObject itemBeingDragged;
public static Vector2 startPos;
void Start () {
}
#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
itemBeingDragged = gameObject;
startPos = transform.position;
}
#endregion
#region IDragHandler implementation
public void OnDrag (PointerEventData eventData)
{
transform.position = eventData.position;
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
//if itemBeingDragged is in Space then move it to its original position and then assign null
//itemBeingDragged = null;
RaycastHit2D hit = Physics2D.Raycast (Camera.main.ScreenToWorldPoint (Input.mousePosition), Vector2.zero);
if (hit.collider != null)
{
print ("Inside hit.collider" + hit.collider.name);
//Itembeing Dragged ... set it to startPos if released in space
if (hit.collider.gameObject.name == "Heat")
{
LeanTween.move (hit.collider.gameObject,PublicVariables.startPosHeat, 1.5f);
}
}
}
#endregion
}
Any help is much appreciated. Thanks.

Buttons in Unity, without using UI?

Is there a way in Unity to create a simple 2D button without using the UI layer. I have a game with a lot of buttons and I don't want to make the whole app in the UI. Some more controls are welcome too: switches, sliders etc.
PS. I saw NGUI and I don't like it so far. Anything else?
Is there a way in Unity to create a simple 2D button without using the
UI layer
You can use Sprite/Sprite Render as a Button.First Create a GameObject and attach EventSystem and StandaloneInputModule to it. Attach Physics2DRaycaster to the Camera, implement IPointerClickHandler and override OnPointerClick function. Create a 2D Sprite by going to GameObject->2D Object->Sprite then attach your script to the Sprite. Here is a complete code to do that:
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
public class SPRITEBUTTON: MonoBehaviour, IPointerClickHandler,
IPointerDownHandler, IPointerEnterHandler,
IPointerUpHandler, IPointerExitHandler
{
void Start()
{
//Attach Physics2DRaycaster to the Camera
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
addEventSystem();
}
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Mouse Clicked!");
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Mouse Down!");
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("Mouse Enter!");
}
public void OnPointerUp(PointerEventData eventData)
{
Debug.Log("Mouse Up!");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("Mouse Exit!");
}
//Add Event System to the Camera
void addEventSystem()
{
GameObject eventSystem = null;
GameObject tempObj = GameObject.Find("EventSystem");
if (tempObj == null)
{
eventSystem = new GameObject("EventSystem");
eventSystem.AddComponent<EventSystem>();
eventSystem.AddComponent<StandaloneInputModule>();
}
else
{
if ((tempObj.GetComponent<EventSystem>()) == null)
{
tempObj.AddComponent<EventSystem>();
}
if ((tempObj.GetComponent<StandaloneInputModule>()) == null)
{
tempObj.AddComponent<StandaloneInputModule>();
}
}
}
}
EDIT:
If this is a 3D GameObject/Mesh, then you need to add a simple collider to it. If it is just Sprite then you must add a 2D collider to the sprite.
Another approach that is even simpler, is to just add a BoxCollider2D component, then add the following methods to the a new componenent, say UIButton, where you will to perform the button actions :
void OnMouseOver()
void OnMouseDown()
void OnMouseUp()
This avoids the use of an EventSystem, StandaloneInputModule and Physics2DRaycaster.
Example :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class UIButton : MonoBehaviour {
public Sprite regular;
public Sprite mouseOver;
public Sprite mouseClicked;
public TextMeshPro buttonText;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
private void OnMouseDown()
{
}
private void OnMouseEnter()
{
}
private void OnMouseExit()
{
}
private void OnMouseUpAsButton()
{
}
}
Tested in unity 2018.1. One difference I initially noticed to this and the above approach is that the right mouse button click is not detected in this model, but is detected in the EventSystemModel.

Categories