buttons only react to clicks/touches when clicking/touching to the right of them - unity3d

I'm making a 2D game in Unity3D for android. Right now I'm making buttons. And this buttons does not react clicks/touched properly. I've got same issue with mouse clicks and touches both. Every button has trigger boxcollider with a same size as an object. BUT buttons react only when I click on area, that is right from a button. I don't understand why is it so. What should I do? Here is my code:
if (Input.GetMouseButtonDown(0)) {
Vector3 i = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 1));
RaycastHit2D hit = Physics2D.Raycast (i, i);
if (hit.transform != null) {
if (hit.transform.tag == "button") {
hit.transform.gameObject.SetActive(false);
}
}
}
Also, I've instantiated an object on mouse click on "i" position to check does it convert screen position to world correctly, and it works fine.

the first parameter in Physics2D.Raycast is the origin and the second one is direction so you should make the raycast from your ray.origin in the direction of ray.direction
void Update () {
if (Input.GetMouseButtonDown(0)) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast (ray.origin, ray.direction, Mathf.Infinity);
if (hit) {
if(hit.collider.gameObject.tag=="button"){
//do something
}
}
}
}

Try to handle it by this way:
if (Input.GetMouseButtonDown(0)) {
Vector3 pos = Camera.main.ScreenToWorldPoint (Input.mousePosition);
Vector2 touchPos = new Vector2(pos.x, pos.y);
Collider2D hit = Physics2D.OverlapPoint(touchPos);
if (hit) {
Debug.Log(hit.transform.gameObject.name);
if (hit.transform.tag == "button") {
hit.transform.gameObject.SetActive(false);
}
}
}

Related

Unity 2D. Why raycasting does not work properly?

With this code I am changing color of gun object if raycast can hit player. Color changes as soon as Player walks into raycast radius. However color won't switch back from red to green as soon as player either goes away (more than Range distance) or hide behind walls. It will eventually switch back to green but not right away. Can you please help me figure out what seems to be the problem?
void Update()
{
Vector2 targetPos = Target.position;
Direction = targetPos - (Vector2)transform.position;
RaycastHit2D rayInfo = Physics2D.Raycast(transform.position, Direction, Range, layerMask);
if (rayInfo)
{
if (rayInfo.collider.gameObject.tag == "Player")
{
if (Detected == false)
{
Detected = true;
Gun.GetComponent<SpriteRenderer>().color = Color.red;
}
}
else
{
if (Detected == true)
{
Detected = false;
Gun.GetComponent<SpriteRenderer>().color = Color.green;
}
}
}
}
When your raycasthit doesn't hit anything with specified LayerMask you don't change your gun's color maybe this is the issue. if your reset your gun color it can solve. Here is the example
//define gunColor variable it is default color of your gun
Color gunColor=Color.green;
void Update()
{
Vector2 targetPos = Target.position;
Direction = targetPos - (Vector2)transform.position;
RaycastHit2D rayInfo = Physics2D.Raycast(transform.position, Direction, Range, layerMask);
if (rayInfo)
{
gunColor=rayInfo.collider.gameObject.CompareTag("Player")?Color.red:Color.green,
}else{
//when raycasthit doesnt hit any thing set gun color to green;
gunColor=Color.green;
}
//update gun color
Gun.GetComponent<SpriteRenderer>().color = gunColor;
}

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.

Raycast how to deal with more than one object same layer

I am using raycast to detect that the player is grounded after a jump, my problem is that some times the raycast is not detecting that the player is grounded and it is.
This is my code for the raycasting:
void IsGrounded()
{
RaycastHit hit;
int mask = 1 << LayerMask.NameToLayer("Floor");
if (Physics.Raycast(transform.position, Vector3.down, out hit, 0.1f, mask))
{
isGrounded = true;
checkGround = false;
Debug.Log("is grounded");
if (!myAudioSource.isPlaying)
{
myAudioSource.Play();
}
}
Debug.DrawLine(transform.position, hit.point, Color.red);
}
Here is my problem:
The character is in the ground but the ray is still not detecting it.
Sometimes this same location will detect and others it won't.

Using RayCastAll instead of RayCast

I have two gameobjects roller and marker. When I use physics raycast it works, but with raycastall it doesn't. I need to use raycastall, because i need to iterate through colliders. When marker is on roller normal raycast doesn't work and I need to use raycastall.
This code works:
if (Input.touchCount > 0)
{
// get mouse position in screen space
// (if touch, gets average of all touches)
Vector3 screenPos = Input.mousePosition;
// set a distance from the camera
screenPos.z = 10.0f;
// convert mouse position to world space
Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
Physics.Raycast(cameraRay, out hit);
if (hit.collider.tag == "Floor")
{
transform.position = hit.point;
}
/*
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
// get current position of this GameObject
Vector3 newPos = transform.position;
// set x position to mouse world-space x position
newPos.x = worldPos.x;
newPos.z = worldPos.z-3f;
// apply new position
transform.position = newPos;
*/
if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
Destroy(gameObject);
touchhandler = GameObject.Find("Roller").GetComponent<TouchHandler>();
touchhandler.markerexists = false;
}
}
And this doesn't:
if (Input.touchCount > 0)
{
// get mouse position in screen space
// (if touch, gets average of all touches)
Vector3 screenPos = Input.mousePosition;
// set a distance from the camera
screenPos.z = 10.0f;
// convert mouse position to world space
Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hits;
hits = Physics.RaycastAll(Camera.main.ScreenPointToRay(Input.mousePosition), 100.0F);
while (i < hits.Length)
{
RaycastHit hit = hits[i];
if (hit.collider.tag == "Floor")
{
transform.position = hit.point;
}
i++;
}
if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
Destroy(gameObject);
touchhandler = GameObject.Find("Roller").GetComponent<TouchHandler>();
touchhandler.markerexists = false;
}
}

movement on object click

On pressing down the object I want it to move continuously.I am a beginner in Unity 3D.
Please help.
function OnMouseDown()
{
Debug.Log("its a hit");
function Update()
{
transform.Translate(Vector3(0,0,3)*Time.deltaTime);
}
}
Check out this Unity Answer for several approaches on how to drag an object with the mouse:
http://answers.unity3d.com/questions/12322/drag-gameobject-with-mouse.html
Just click the mouse
function Update()
{
if(Input.GetMouseButtonDown(0)) //Left click
{
Debug.Log("Left Mouse Button Click");
transform.Translate(Vector3(0,0,3)*Time.deltaTime);
}
}
Or with select object
function Update()
{
if(Input.GetMouseButtonDown(0)) //Left click
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, hit))
{
hit.collider.gameObject.Translate(Vector3(0,0,3)*Time.deltaTime);
}
}
}