the hit script run for 3d objects but not 2d - c#

this is the script for my game.but it just works for 3d object like cube and not for 2d images in the game.how to fix it?
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class touchinput : MonoBehaviour {
void Update () {
if (Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay( Input.GetTouch(0).position );
RaycastHit hit;
if ( Physics.Raycast(Ray, out hit))
{
Destroy(hit.collider.gameObject);
}
}
}
}
i try to change to this but i get lots of errors and don't know how to fix.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class touchinput : MonoBehaviour {
void Update () {
if (Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Began)
{
Ray2D ray = Camera.main.ScreenPointToRay( Input.GetTouch(0).position );
RaycastHit2D hit;
if ( Physics2D.Raycast(Ray2D, out hit))
{
Destroy(hit.collider.gameObject);
}
}
}
}

Raycast indeed doesn't work on 2D colliders.
I found this method the other day, you can try it:
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
Vector3 wp = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
Vector2 touchPos = new Vector2(wp.x, wp.y);
if (collider2D == Physics2D.OverlapPoint(touchPos))
{
//your code
}
}

Related

Draw line between two game objects using linerenderer and raycast

What I'm trying to do is draw line between two gameobjects I'm using ray distance and line renderer but the line is too long. Below is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DrawLineTest : MonoBehaviour
{
RaycastHit hit;
public LineRenderer lineRender;
private void Awake()
{
lineRender = GetComponent<LineRenderer>();
}
void Start()
{
Ray ray = new Ray(transform.position, Vector3.down);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
lineRender.enabled = true;
lineRender.SetPosition(0, transform.position);
lineRender.SetPosition(1, Vector3.down * hit.distance);
}
}
}
}
The second point is
lineRender.SetPosition(1, transform.position + Vector3.down * hit.distance);
or
lineRender.SetPosition(1, ray.GetPoint(hit.distance));
or more succinct
lineRender.SetPosition(1, hit.point);

Unity fix NavMeshAgent jerky movements?

Record of the problem
https://youtu.be/BpzHQkVQz5A
Explaining my problem
I'm programming a mobile game using Unity3D Engine. For my player movement, I'm using NavMeshAgent because it's for me the easiest and most efficient way to do it. But when I hit the play button and ask my player to move, the movements are jerky and it's not pleasant to see at all.
Do you have any idea to fix this problem ?!
Thank you in advance for your answers ! ^^
My code
This is my code :
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Player : MonoBehaviour
{
NavMeshAgent agent;
Touch touch;
RaycastHit hit;
Ray ray;
// START FUNCTION
private void Start()
{
agent = GetComponent<NavMeshAgent>();
}
// UPDATE FUNCTION
private void Update()
{
// TOUCH DETECTION
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
// A FINGER TOUCHED THE SCREEN
if (touch.phase == TouchPhase.Began)
{
// RETURN X, Y AND Z WORLD POS OF THE TOUCH SCREEN POS
ray = Camera.main.ScreenPointToRay(touch.position);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
// MOVING PLAYER TO THE HIT POS
Vector3 hitVec = new Vector3(hit.point.x, hit.point.y + (GetComponent<Collider>().bounds.size.y / 2), hit.point.z);
agent.SetDestination(hitVec);
}
}
}
}
// SAME CODE USING MOUSE BUTTON
#if UNITY_EDITOR
if (Input.GetMouseButton(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
Vector3 hitVec = new Vector3(hit.point.x, hit.point.y + (GetComponent<Collider>().bounds.size.y / 2), hit.point.z);
agent.SetDestination(hitVec);
}
}
}
#endif
}
}
CameraFollow.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// BRACKEYS CAMERA FOLLOW SCRIPT WITHOUT THE LOOKAT METHODE
public class CameraFollow : MonoBehaviour
{
public Transform target;
public float smoothSpeed = 0.2f;
public Vector3 offset;
void FixedUpdate()
{
Vector3 desiredPosition = target.position + offset;
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
transform.position = smoothedPosition;
}
}
The problem isn't the navmesh controller but the camera follow script.
One thing you could try is to move the camera position using only the desiredPosition or use Vector3.SmoothDamp:
private Vector3 velocity;
void LateUpdate(){
...
Vector3 desiredPosition = target.position + offset;
Vector3 smoothedPosition = Vector3.SmoothDamp(transform.position, desiredPosition, ref velocity, smoothSpeed);
transform.position = smoothedPosition;
}
Also this is explained in a pinned comment on the Brackeys video

Player doesn't move after being spawned

I'm currently working on a tactical RPG and I have the following issue:
When the player is destroyed, he is spawned at a specific position in the grid. However, after being spawned he doesn't move.
I'm using this script to destroy the player and spawn him. It's attached to each player in the game:
using System.Collections.Generic;
using UnityEngine;
public class Jogador : MonoBehaviour
{
[SerializeField] private Mapa mapa;
public Vector2Int GridPosition;
public bool isPlayer = false;
public float Health = 50f;
public GameObject SpawnPoint;
private void Awake()
{
if (!mapa) mapa = FindObjectOfType<Mapa>();
}
// Start is called before the first frame update
void Start()
{
foreach (var tile in mapa.GridMatriz)
{
//tile.jogador = this;
}
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit) && hit.transform == this.transform)
{
mapa.GetComponent<Movimentação>().TurnEnd();
isPlayer = true;
mapa.GetComponent<Movimentação>().TurnStart();
Debug.Log("clicked");
}
}
CheckHealth();
}
public void CheckHealth()// Function to check the player's health
{
if (Health <= 0)
{
Destroy(gameObject);
Instantiate(this, Spawnador.transform.position, Quaternion.identity);
}
}
}
This is the movement script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Movimentação : MonoBehaviour
{
//player variables
public GameObject player;
public GameObject[] Personagens;
//moving variables
Vector3 targetPosition;
float posY = 1;
public float velocity = 0.2f;
public float movMax = 3;
public bool ismoving = false;
public bool moveEnabled;
public int aux;
//bullet variables
public GameObject projetil;
private GameObject SpawBala;
public float ProjetilVeloc = 500f;
private void Start()
{
//sets the first unit as the active unit at the start of the game
Personagens[0].GetComponent<Jogador>().isPlayer = true;
TurnStart();
}
// Update is called once per frame
void Update()
{
//left mouse button to start movement
if (Input.GetMouseButtonDown(0))
{
//raycast checks and returns an object, if it's a tile, the unit moves
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
ismoving = true;
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.tag == "Tile")
{
//checks if the tile is available based on the max movement of the unit
Tile tileAux = hit.transform.gameObject.GetComponent<Tile>();
Jogador scriptJog = player.GetComponent<Jogador>();
if ((tileAux.TilePostion.x - scriptJog.GridPosition.x) + (tileAux.TilePostion.y - scriptJog.GridPosition.y) >= -movMax && (tileAux.TilePostion.x - scriptJog.GridPosition.x) + (tileAux.TilePostion.y - scriptJog.GridPosition.y) <= movMax)
{
if ((tileAux.TilePostion.x - scriptJog.GridPosition.x) - (tileAux.TilePostion.y - scriptJog.GridPosition.y) >= -movMax && (tileAux.TilePostion.x - scriptJog.GridPosition.x) - (tileAux.TilePostion.y - scriptJog.GridPosition.y) <= movMax)
{
targetPosition = (hit.transform.position);
targetPosition.y = posY;
moveEnabled = true;
}
}
}
}
}
//right click to shoot
if (Input.GetMouseButtonDown(1))
{
//raycast checks and returns an object, if it's a tile, the unit shoots
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
//checks if the tile is available based on the line and column of the unit
Tile tileAux = hit.transform.gameObject.GetComponent<Tile>();
Jogador scriptJog = player.GetComponent<Jogador>();
if (tileAux.TilePostion.x == scriptJog.GridPosition.x || tileAux.TilePostion.y == scriptJog.GridPosition.y)
{
if (tileAux.TilePostion.x > scriptJog.GridPosition.x)
tileAux.TilePostion.x = 5;
else
tileAux.TilePostion.x = 0;
if (tileAux.TilePostion.y > scriptJog.GridPosition.y)
tileAux.TilePostion.y = 5;
else
tileAux.TilePostion.y = 0;
Debug.Log(tileAux.TilePostion.x);
Debug.Log(tileAux.TilePostion.y);
//instantiates the bullet
GameObject tiro = Instantiate(projetil, SpawBala.transform.position, SpawBala.transform.rotation);
Rigidbody BalaRigid = tiro.GetComponent<Rigidbody>();
if (SpawBala.tag == "Bala1")
{
BalaRigid.AddForce(Vector3.forward * ProjetilVeloc);
}
if (SpawBala.tag == "Bala2")
{
BalaRigid.AddForce(Vector3.back * ProjetilVeloc);
}
}
}
}
//player moves until reaches the position
if (player.transform.position != targetPosition)
{
player.transform.position = Vector3.MoveTowards(player.transform.position, targetPosition, velocity);
if (player.transform.position == targetPosition)
ismoving = false;
}
//if player reaches position, it's deselected
if (moveEnabled && !ismoving)
{
player.GetComponent<Jogador>().isPlayer = false;
moveEnabled = false;
}
}
public void TurnStart()
{
//makes the selected unit the active unit
for (int i = 0; i < Personagens.Length; i++)
{
if (Personagens[i].GetComponent<Jogador>().isPlayer == true)
{
player = Personagens[i];
posY = player.transform.position.y;
targetPosition = player.transform.position;
SpawBala = player.transform.GetChild(0).gameObject;
}
}
}
public void TurnEnd()
{
//desactivates all units
for (int i = 0; i < Personagens.Length; i++)
{
Personagens[i].GetComponent<Jogador>().isPlayer = false;
}
}
}
I really don't know what's going on guys.

How to link long press to move script

I found this script: https://unity3d.college/2018/01/30/unity3d-ugui-hold-click-buttons/
I am using Vuforia btw.
I was wondering how to link it to my movement script.
using UnityEngine;
public class MyDragBehaviour : MonoBehaviour
{
void Update()
{
if (Input.touchCount == 1 && Input.GetTouch(0).phase ==
TouchPhase.Moved)
{
// create ray from the camera and passing through the touch
position:
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
// create a logical plane at this object's position
// and perpendicular to world Y:
Plane plane = new Plane(Vector3.up, transform.position);
float distance = 0; // this will return the distance from the camera
if (plane.Raycast(ray, out distance))
{ // if plane hit...
Vector3 pos = ray.GetPoint(distance); // get the point
transform.position = pos;
// pos has the position in the plane you've touched
}
}
}
}
The current movement script will move my object instantly to where the tap happened on screen. I would like to have it so that you have to long press the object before moving it to avoid having the object jump around on screen.
EDIT
using UnityEngine;
using UnityEngine.EventSystems;
public class MyDragBehaviour : MonoBehaviour
{
float pointerDownTimer = 0;
const float requiredHoldTime = 0.5f; //has to hold for 0.5 seconds
void Update()
{
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
pointerDownTimer += Time.deltaTime;
if (pointerDownTimer >= requiredHoldTime)
{
pointerDownTimer = 0;
if (!EventSystem.current.IsPointerOverGameObject())
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
// create ray from the camera and passing through the touch position:
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
// create a logical plane at this object's position
// and perpendicular to world Y:
Plane plane = new Plane(Vector3.up, transform.position);
float distance = 0; // this will return the distance from the camera
if (plane.Raycast(ray, out distance))
{ // if plane hit...
Vector3 pos = ray.GetPoint(distance); // get the point
transform.position = pos; // pos has the position in the plane you've touched
} //whatever happens when you click
}
}
else
{
pointerDownTimer = 0;
}
}
}
}
You just need to implement a simple timer, that increases when you press and resets when you release:
float pointerDownTimer = 0;
const float requiredHoldTime = 0.5f //has to hold for 0.5 seconds
void Update(){
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
pointerDownTimer += Time.deltaTime;
if (pointerDownTimer >= requiredHoldTime){
...... //whatever happens when you click
}
} else{
pointerDownTimer = 0;
}
}

Rotation with the limit in unity 3D?

I am building an application in unity.
when User click on an GameObject the model position is changed.
Now I need is on change of the position, Rotation is also changed with the limit axis/Co-ordination point.
Here is my code change of the position on input click of the gameObject.
using UnityEngine;
using System.Collections;
public class centertheroombox : MonoBehaviour
{
public GameObject box345;
public int speed = 1;
// Update is called once per frame
void Update ()
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Ended)
{
Ray ray = Camera.main.ScreenPointToRay(touch.position);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000.0f))
{
if (hit.collider.gameObject.name == "Box345")
{
Debug.Log("yupiee pressed");
box345.transform.position = new Vector3(3, 0, -9);
//box345.transform.Rotate(Vector3.right, Time.deltaTime);
//box345.transform.Rotate = new Vector3(353,0,0);
}
}
}
}
}
}

Categories