Please keep in mind that I'm new to unity. I created an 2D android game app.
I created a start button( from an image) and attacted a Box colider, and a C# script to it.
When I click the "button" I want the program to move to the next "Level", that Works except that I want it to only Work if i click the object and not everywhere on the game.
This is the C#:
using UnityEngine;
using System.Collections;
public class StartGame : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown(0)) {
Application.LoadLevel("Game");
}
}
}
I searched alot about this and maybe people say that to solve this you have to use, Ray and RaycastHit But I cant get that to Work either.
Here is what I tried to with Ray & RaycastHit
// Update is called once per frame
void Update () {
if ((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) || (Input.GetMouseButtonDown(0)))
{
RaycastHit hit;
Ray ray;
#if UNITY_EDITOR
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
#elif (UNITY_ANDROID || UNITY_IPHONE || UNITY_WP8)
ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
#endif
if(Physics.Raycast(ray, out hit))
{
Application.LoadLevel("Game");
}
}
}
Any help would be so appriciated.
Probably the easiest way is to add box collider and script component including function below to the gameobject.
void OnMouseOver()
{
if (Input.GetMouseButtonDown(0))
{
Application.LoadLevel("Game");
}
}
Edit:
I'm guessing that the original code is not working on your scene, because you are using box collider 2d. Physics.Raycast is testing against 3D colliders. When I run it with the 3D version box collider it works fine.
Related
I am new in Unity and trying to create an Android mobile game.
First, I decided to create a script called "SelectObject" that will move the objects, provided that the object has a collider.
I add this script to the "MainCamera" components, since we need to determine if the camera ray touched the object.
Here is the script "SelectObject":
using UnityEngine;
using System.Collections;
public class SelectObject : MonoBehaviour
{
void Start() {
}
public void Update()
{
if ((Input.touchCount > 0) && (Input.touches[0].phase == TouchPhase.Began)) {
Ray ray = Camera.main.ScreenPointToRay(Input.touches[0].position);
RaycastHit hit; //Declaring the variable hit, in order to further determine if the camera's ray touhed the object
if (Physics.Raycast(ray, out hit)) {
if (hit.collider != null) { //If the ray of camera touches the collider
hit.collider.GetComponent<Move>().Movement(); //Calling the "Movement" method from script "Move" to move the object
}
}
}
}
}
The Move class is a component of the "Cylinder" object that should move when you click on it.
Here is the "Move" class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour {
public float speedModifier; //Determine the speed of movement
public Touch touch; //Using this variable, we will determine if there was at least some touch on the screen
void Start() {
speedModifier = 2.01f;
}
public void Update() {
}
public void Movement() { //Creating a "Movement" method to call it in the "SelectObject" script
touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Moved) {
transform.position = new Vector3(transform.position.x + touch.deltaPosition.x * speedModifier, transform.position.y, transform.position.z + touch.deltaPosition.y * speedModifier);
}
}
}
But when I start the game, the cylinder still doesn't move.
What am I doing wrong?
Not 100% clear on what you're trying to do but have you tried passing your location into the Movement() method? Something like this.
public void Movement(Vector3 targetLocation) {
transform.position = targetLocation;
}
Then you'd call it like this.
Movement(Input.touches[0].position);
Just a note since I noticed your speed modifier. The way your code is currently set up is going to instanly move the object to the touch location. If you would like to have it smoothly move to it at a specified speed you'll need to look up Lerping or store the previous position, current, and target position.
I'm trying to have various interactions take place when looking at a game object, but it doesn't seem to work when I'm too close. I'm using Unity's first person controller and the script it attached to the camera.
void Update () {
RaycastHit hit;
Vector3 forward = transform.TransformDirection(Vector3.forward) * 10;
if(Physics.Raycast(transform.position,(forward), out hit) ){
GameObject lookingAt = hit.collider.gameObject;
if (lookingAt.layer == 9)
{
Debug.Log("This doesn't always show up.");
}
}
}
I put
public LayerMask interactionLayers = ~0;
And selected the elements that should be detected in the inspector. That seemed to fix the issue.
Thanks.
The camera that the script is attached to is above high the terrain look on the terrain from the top. And now when i click the mouse i'm getting List points. But now i want to make that when i click the mouse it will give me the position on the terrain including terrain high places like hills.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GetMousePosition : MonoBehaviour
{
private bool isMousePressed;
private List<Vector3> pointsList;
private Vector3 mousePos;
// Use this for initialization
void Start()
{
isMousePressed = false;
pointsList = new List<Vector3>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
isMousePressed = true;
pointsList.RemoveRange(0, pointsList.Count);
}
else if (Input.GetMouseButtonUp(0))
{
isMousePressed = false;
}
if (isMousePressed)
{
mousePos = GetComponent<Camera>().ScreenToWorldPoint(Input.mousePosition);
mousePos.z = 0;
if (!pointsList.Contains(mousePos))
{
pointsList.Add(mousePos);
}
}
}
}
You would do this with a Raycast, you can cast a ray from the camera position to the terrain and then get all of the details you desire using the data that you get back.
So in your case if you wanted to add the hit point to the list you would do something like this
float distance = 100f;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
isMousePressed = true;
pointsList.RemoveRange(0, pointsList.Count);
}
else if (Input.GetMouseButtonUp(0))
{
isMousePressed = false;
}
if (isMousePressed)
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast (ray, out hit, distance))
{
if(!pointsList.Contains(hit.point)
{
pointsList.Add(hit.point);
}
}
}
}
It should be noted in the above example that Physics.Raycast has many overloads which allow you to customise how the ray fires. You can also use the hit and ray variables to get much more information such as the specific collider it hit as well as the world position at which the ray originated from, more information on how to do just that can be found in the Unity API documentation page for the Physics Raycast.
If you'd like to learn more about Raycasting I'd recommend watching the official Unity video on the topic which goes into further detail, you'll be using it a lot in game development so it's worth learning as much as you can about it before moving forward.
This question already has answers here:
How to detect click/touch events on UI and GameObjects
(4 answers)
Closed 4 years ago.
i'm currently making a soccer game.
In this mini-game, when the player touch the ball, it adds force, and the goal is to make the higher score.
So i wrote:
void Update()
{
if(Input.touchCount == 1 && Input.GetTouch(0).phase== TouchPhase.Began)
{
AddForce, and playsound ect...
}
}
With this, when i touch anywhere on the screen, it adds force, but i just want to add force when i touch my gameobject (the ball).
How can i do that?
Thanks! :)
With this, when i touch anywhere on the screen, it adds force, but i
just want to add force when i touch my gameobject (the ball).
To detect tap on a particular GameObject, you have to use Raycast to detect click on that soccer ball. Just make sure that a collider(eg Sphere Collider) is attached to it.
void Update()
{
if ((Input.touchCount > 0) && (Input.GetTouch(0).phase == TouchPhase.Began))
{
Ray raycast = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
RaycastHit raycastHit;
if (Physics.Raycast(raycast, out raycastHit))
{
Debug.Log("Something Hit");
if (raycastHit.collider.name == "Soccer")
{
Debug.Log("Soccer Ball clicked");
}
//OR with Tag
if (raycastHit.collider.CompareTag("SoccerTag"))
{
Debug.Log("Soccer Ball clicked");
}
}
}
}
Use OnMouseDown() in your script. Here is an example:
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
void OnMouseDown() {
Application.LoadLevel("SomeLevel");
}
}
P.S : remove that previous code from Update() method.
EDIT : Alternative code for mobile devices
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class OnTouchDown : MonoBehaviour
{
void Update () {
// Code for OnMouseDown in the iPhone. Unquote to test.
RaycastHit hit = new RaycastHit();
for (int i = 0; i < Input.touchCount; ++i) {
if (Input.GetTouch(i).phase.Equals(TouchPhase.Began)) {
// Construct a ray from the current touch coordinates
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
if (Physics.Raycast(ray, out hit)) {
hit.transform.gameObject.SendMessage("OnMouseDown");
}
}
}
}
}
Attach the above script to any active gameObject in the scene and OnMouseDown() will work for mobile devices as well.
You need to do several items here
you need to raycast the touch to determine if the ball is touched
you need to increment the power on the duration of the touch
you need to fire the ball and reset the power on release of the touch
The code example here shows how to handle the rayCast
the code example here should help you with part 2
3 is nice and simple you just need to trigger your launch code an reset on Ended
put them together and you will get something like this
public class ExampleClass : MonoBehaviour {
void FixedUpdate() {
for (int i = 0; i < Input.touchCount; ++i) {
Ray camRay = Camera.main.ScreenPointToRay (Input.GetTouch(i).Position);
RaycastHit ballHit;
if(Physics.Raycast (camRay, out ballHit, camRayLength, ballMask))
{
if (Input.GetTouch(i).phase == TouchPhase.Stationary) {
power += speed + Time.deltaTime;
}
else if (Input.GetTouch(i).phase == TouchPhase.Ended) {
LauchBall(power);
power = 0;
}
}
}
}
}
NOTE:code is for example only it has not been tested and is not complete
this uses the physics update as the trigger you can instead link directly to an objects triggers as suggested by some of the other answers
Take Touch Event using Co-Rouitne will be good for you. If you will not use
coroutine, then it constant check for touch event in OnUpdate. Its better to take
touch event in co-routine.
This is my link in which you can check how to use it.
http://unitycodestuff.blogspot.in/2017/11/how-to-use-co-routine-for-taking-touch.html
I created a script that uses RayCasting for detecting two Prefabs - One prefab has a tag called "target" and the second prefab has a tag called "unTarget". On click on prefab 1 with "Target" tag its supposed to increment count and when clicking on prefab 2 with "unTarget" tag its supposed to decrement the count. This seems to work when only one Prefab is in the scene. It will increment/decrement when only one is added and clicked. When both prefabs are in the Scene both prefabs will increment. I am not sure why this is happening. Any Help or Ideas? Sorry if my code is a bit messy.
using UnityEngine;
using System.Collections;
public class clicks : MonoBehaviour
{
public int score;
void Start()
{
score = 0;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown (0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit,200))
{
if (GameObject.FindGameObjectWithTag ("target"))
{
score++;
}
else
{
score--;
}
}
}
}
The GameObject.FindGameObjectWithTag method is going to look at your entire scene for an object with target as the tag. Since you have one in the scene that will always return true, if you hit something.
You need to look at the properties on the RaycastHit and pull the tag from there.
if (hit.collider.tag == "target")
{
score++;
}
else
{
score--;
}