Unity 2019.1.0f2
Input System 1.0.2
I create an empty 3D project, then import the Input System into it.
I add EventSystem to the scene.
Then I write a simple script and add it to scene:
using UnityEngine;
using UnityEngine.InputSystem;
public class TestScroll : MonoBehaviour
{
void Update()
{
Debug.Log(Mouse.current.scroll.ReadValue());
}
}
Then I run the scene and just move my mouse (don't spin the mouse wheel) and see this in the console:
Also in the documentation for the Input System I found this:
Because of this feature Scroll Rect starts to scroll simply because I move the mouse pointer over it.
How can this be avoided and why is this happening?
It turns out this is a Unity bug: topic
Related
I am making a simple VR Tour in Unity, and I want to move the camera to the next sphere (or at all at this point) when I click on a sprite that is hovering in the air. Right now, when I run this code, I get the "Sprite Clicked" message in the console, but the camera doesn't move at all. Any help is greatly appreciated!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DebugOnClick : MonoBehaviour {
// Use this for initialization
void Start () {
}
void OnMouseDown () {
Debug.Log("Sprite Clicked");
Camera.main.transform.position = new Vector3(5.0f, 5.0f, 5.0f);
}
}
It doesn't let me comment (not enough rep) so I must pop this in as an answer.
If you're using some given VR scripts already, it could be possible that they're syncing the camera position constantly to where they should be relative to the player's headset position.
Meaning that after this move via script, the camera will be moved back instantly.
If that is the case, you need to move the player avatar themselves to the correct position rather than the camera.
Ive been trying to use raycasting for the better part of a day now to remove 2D objects . I know how to use the OnMouseDown method to effectivelly do the same thing and ive been using it so far. But ive read that using raycastign is much more efficient then using the OnMOuseDown method since the OnMouseDOwn method was designed specifically for mouse clicks. Looking over tutorials aswell as reading the forums ive seen people using different raycasting techniques, classes and methods available in the Unity libraries but these are mostly used for 3D objects. Since I'm designing a 2D game I want to find out how to do it for 2D objects. Ive tried severl things in order to get it to work but nothign seems to work:
Ive tried using Raycasthit2D, Raycast2D and nothing seems to work
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TouchTest : MonoBehaviour
{
void Start()
{
}
//public Vector2 direction;
void Update()
{
//Cast a ray in the direction specified in the inspector.
RaycastHit2D hit =
Physics2D.Raycast(this.gameObject.transform.position,
Input.GetTouch(0).position);
//If something was hit.
if (hit.collider != null)
{
//Display the point in world space where the ray hit the collider's surface.
Debug.Log("We Hit something");
}
}
}
The result should be that it outputs "we hit something" on the console when I touch an object on Unity Remote but it doesn't do anything except saying that my index for Input.GetTouch(0).position is out of bounce. Despite the fact that it says this it often says this but for other code, it still manages to perform what I want, but for this code, it doesn't work and still says the index is out of bounce.
The error you are receiving is because when the function is being called, the mouse is not clicked.
You must do this in the OnMouseDown method or put it in an if statement that only allows it to run if the mouse is actually clicked.
A good tutorial on this can be found here.
The best way (if you are only using 2D) is to check if the mouse click is in the shape when it is cliked:
Check when the mouse is clicked and get its position.
Get the rectangle of the body and compare it to the mouse position.
If the body's rectangle contains the mouse position, the mouse has clicked the body.
I'm making an Android app with Unity3D and it works with click detection already, but not with touch. I need touch though for multitouch detection.
What I want: I have my player and 2 images of arrows. One arrow points right and one left. When I touch the left arrow the player should start moving left, when I touch the right arrow the player should start moving right.
But how do I detect which arrow is touched (and held)? All the code I found on Google is too old and not working anymore.
I'm working with C# scripts and it's a 2D game.
Klausar, what you're looking for is .........
A BUTTON (!!!)
it's that easy!
click "add Canvas". (You very likely want "scale to screen size" - select that option.)
click "add Button".
there is no "three" .. go drinking.
In your code, have a routine like this for the right-side button
public void UserClickedRight()
{
Debug.Log("click right whoo!");
}
and have a similar routine for the left-side button.
1. Go to your Button in the editor.
2. Simply drag the script to it and select UserClickedRight !!
You actually do not have to program buttons from scratch :)
This is a basic mechanism of Unity - drag a game object to a "slot" for it in the Editor.
(The game object you drag, has the script in question on it.)
You DO NOT need to go to the level of touch handling to achieve a button!
Now you ask, what about "when holding down on the button"?
It's very easy, you just need to know a couple of things about the Unity "event" system.
In Button, Unity have done all the work for "OnClick":
Since "click" is common, they put that one right in the Inspector panel for you for convenience.
The good news is that Button has many more events you can use.
http://docs.unity3d.com/ScriptReference/UI.Button.html
My guess is you want to use OnPointerDown and OnPointerUp in your case.
To use the other events (which Unity did not bother putting in the Inspector panel) is very simple, you just
1, make a script that references the events you want,
and,
2, you put that script ON the button in question ...
it's that easy.
Step by step explanation:
You're going to be using Unity's event system, so:
using UnityEngine.EventSystems;
Next. You know that a script normally starts like this...
public class FancyButton:MonoBehaviour
The "MonoBehaviour" part just means that it's a c# script which will be "driving a GameObject".
In this case we have to further alert the engine that you will be using those click events. So you add this.
,IPointerDownHandler,IPointerUpHandler
So far we have this
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class FancyButton:MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
Now the easy part.
You just type the two routines which Unity will run for you, when, those things happen.
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class FancyButton:MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
public void OnPointerDown(PointerEventData data)
{
Debug.Log("holy! someone put the pointer down!")
}
public void OnPointerUp(PointerEventData data)
{
Debug.Log("whoa! someone let go!")
}
}
Now all you have to do is drop that script on the Button. Done!
You can put that script on any button, where, you need that functionality.
Next, click on Obi-wan to see where we're at so far!
Finally, it sounds like you want to do something "when the button is being held down". That's just a general programming issue - you'd have a boolean which you turn on and off as the button goes up and down. Let's do it.
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class FancyButton:MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
[System.NonSerialized] public bool mouseIsDownRightNow;
public void OnPointerDown(PointerEventData data)
{
mouseIsDownRightNow = true;
}
public void OnPointerUp(PointerEventData data)
{
mouseIsDownRightNow = false;
}
}
You could access that variable from another script, or whatever you want.
Add the following if you want to run a routine while the button is down:
void Update()
{
if (buttonIsDownRightNow) WhileButtonIsDown();
}
private void WhileButtonIsDown()
{
Debug.Log("THE BUTTON IS DOWN! WHOA!");
}
Try that and watch the console as you hold the button down and up.
Here's an example of something like continually increasing a value while the button is down:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class FancyButton:MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
[System.NonSerialized] public bool buttonIsDownRightNow;
private int countSomething;
public void OnPointerDown(PointerEventData data)
{
buttonIsDownRightNow = true;
}
public void OnPointerUp(PointerEventData data)
{
buttonIsDownRightNow = false;
}
private void WhileButtonIsDown()
{
++countSomething;
}
void Update()
{
if (buttonIsDownRightNow) WhileButtonIsDown();
Debug.Log("value is now " +countSomething.ToString());
}
}
That's all there is to it. Once you really understand events in Unity, there is not much more to learn about Unity.
The only other important topics are Mecanim, shader writing, touch, coroutines, threading, PhysX, native plugins, sprites, networking, dynamic mesh, navigation, VR, AR, animation, inverse kinematics, particles, terrain, IAP, lighting, baking, shadows, MMP, character controllers, and audio. Enjoy!
You should firsty read this.
What you are trying to do is actually simple:
foreach (Touch touch in Input.touches) {
if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary)
if (guiTexture1.HitTest(touch.position)) {
// Maybe move left
}
if (guiTexture2.HitTest(touch.position)) {
// Maybe move right
}
}
}
Edit 1: this code now checks which image is being pressed
Edit 2: Added multitouch support
I'm having a hell of time getting a 2D polygon collider to register a mouse click. I've attached images and code to show where I'm at. I cannot get the click to work.
Ultimately, the thing I'm trying to achieve is to just set the area defined by the collider to be clickable rather than the entire image sprite.
What am I doing wrong here? Need help!
using UnityEngine;
using System.Collections;
public class MouseClick : MonoBehaviour
{
void OnMouseDown()
{
Debug.Log ("Clicked the Collider!");
}
}
I've defined the collider:
I've setup the components for my image:
Set your Canvas "Render mode" to "Screen Space Camera" and attach your camera,
Your using the new uGUI system, you dont even need colliders!
Make your script look like this and you should be able to do it with any object that has Image component. so you can get rid of the collider!
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class MouseClick : MonoBehaviour, IPointerClickHandler
{
void OnPointerClick(PointerEventData data)
{
Debug.Log ("Clicked the Collider!");
}
}
I want to suggest to you a different approach seeing as this uses UGUI.
Attach an EventTrigger script. Then add a new trigger of type PointerClick. Now you can drag an object into that and call any function on that object. This is a very easy and reusable way.
With this in place you can safely remove you rigidbody and collider unless those are needed for something other than mouse interaction.
I needed to create UIButton attached to a gameobject.
I'm using a board based game i.e., when ever clicking a button at that time place one object to that particular button.
I am using c# script in unity3d .
void UIBtn(GameObject BName)
{
//here to write Button click event.
}
I'm assuming you mean GUI.Button .
Reading your first sentence I understood that you wanted to create a button where a GameObject is, but reading your second sentence it seems that you want a GameObject to appear when clicking a button. Since I'm not sure, I'll answer both.
To make a GUI button appear at the place the mouse is use something like:
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
void OnGUI() {
Vector2 screenPos = Event.current.mousePosition;
GUI.Button ( new Rect(screenPos.x,screenPos.y,100,100),"Hello");
}
}
Attaching a button to a GameObject requires first identifying the GameObject via Physics.Raycast and then getting the GameObject from the HitCollider and then, on the game object's OnGUI loop. constantly translate its world coordinates to screen coordinates to be able to show a button, via GUI.Button.