Please see the below images.
In the first image you can see that there is box collider.
The second image is when I run the code on Android device
Here is the code which is attached to Play Game (its a 3D Text)
using UnityEngine;
using System.Collections;
public class PlayButton : MonoBehaviour {
public string levelToLoad;
public AudioClip soundhover ;
public AudioClip beep;
public bool QuitButton;
public Transform mButton;
BoxCollider boxCollider;
void Start () {
boxCollider = mButton.collider as BoxCollider;
}
void Update () {
foreach (Touch touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
if (boxCollider.bounds.Contains (touch.position)) {
Application.LoadLevel (levelToLoad);
}
}
}
}
}
I want to see if touch point is inside the collider or not. I want to do this because right now if I click any where on the scene
Application.LoadLevel(levelToLoad); is called.
I want it to be called if I click on PLAY GAME text only. Can any one help me with this piece of code or can give me another solution to my problem??
Recent Code by following Heisenbug's Logic
void Update () {
foreach( Touch touch in Input.touches ) {
if( touch.phase == TouchPhase.Began ) {
Ray ray = camera.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity, 10)) {
Application.LoadLevel(levelToLoad);
}
}
}
}
Touch's position is expressed in screen space coordinate system (a Vector2). You need to convert that position in the world space coordinate system before trying to compare it against other 3D locations of objects in the scene.
Unity3D provides facility to do that. Since you are using a BoundingBox surrounding your text, you can do the following:
Create a Ray which origin is in the touch point position and which direction is parallel to the camera forward axis (Camera.ScreenPointToRay).
Check if that ray intersect the BoundingBox of your GameObject (Physic.RayCast).
the code may look something like that:
Ray ray = camera.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerOfYourGameObject))
{
//enter here if the object has been hit. The first hit object belongin to the layer "layerOfYourGameObject" is returned.
}
It's convenient to add a specific layer to your "Play Game" GameObject, in order to make the ray colliding only with it.
EDIT
Code and explanation above is fine. If you don't get a proper collision maybe you have not used the right layer. I haven't a touch device at the moment. The following code will work with mouse (without using layers).
using UnityEngine;
using System.Collections;
public class TestRay : MonoBehaviour {
void Update () {
if (Input.GetMouseButton(0))
{
Vector3 pos = Input.mousePosition;
Debug.Log("Mouse pressed " + pos);
Ray ray = Camera.mainCamera.ScreenPointToRay(pos);
if(Physics.Raycast(ray))
{
Debug.Log("Something hit");
}
}
}
}
It's just an example to put you in the right direction. Try to figure out what's going wrong in your case or post an SSCCE.
Related
i'm working on Android touch button can shooting with no luck until now, my need to have button with name fire inside the canvase , can do the following:
1 - when pressed: shoot one bullet
2 - keep pressing: shoots bullets
3 - stop press: hold shooting
i need help to update the following code with above needs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerShoot : MonoBehaviour {
public GameObject Ammo; // the shot
GameObject FiredShot;
public AudioClip bcgMusic;
public List<GameObject> ShotsOnAir;
//public AudioClip sound1; // Use this for initialization
void Start (){
ShotsOnAir = new List<GameObject>();
}
//update is called once per frame
void Update (){
if (Input.GetKeyDown(KeyCode.Mouse0)){
//if (Input.GetButtonDown("Fire1")){
FiredShot = (GameObject)Instantiate(Ammo,transform.position,transform.rotation);
ShotsOnAir.Add(FiredShot);
AudioSource.PlayClipAtPoint (bcgMusic, transform.position);
}
if(ShotsOnAir != null){
int i=0;
foreach (GameObject GB in ShotsOnAir){
ShotsOnAir[i].transform.position += ShotsOnAir[i].transform.forward * 200 * Time.deltaTime;
i++;
}
}
}
}
its solved after use Input.Touch insted of Input.GetKeyDown after follow the comment by programmer
I implemented input for my mobile game like so:
I have some buttons and I have anywhere else on the screen.
Basically when the player touches the screen and not a button ingame, the character jumps. Now, It is implemented by using OnPointerDown and OnPointerUp that sets a bool:
public class JumpInput : MonoBehaviour
{
public static bool JUMP;
public void PointerDown()
{
JUMP = true;
}
public void PointerUp()
{
JUMP = false;
}
}
If the player is jumping, it is checked by a FixedUpdate method:
if (!movementDisabled && grounded && JumpInput.JUMP)
{
//then we can jump
currentImageIndex = 0;
animState = CharAnimStates.jumpStart;
//added again from here
//zeroing out the Y axis velocity if we had one
rb2d.velocity = new Vector2(rb2d.velocity.x, 0.0f);
//until here
jump = true;
}
As I get decent frame rates even when using post-processing, I have no clue why the input is so delayed. I require assistance to verify if my solution for "anywhere on the screen input" is viable performancewise and it not, how to improve it.
Hey guys so Im making my first app. I know this is a pretty loaded question but Im having a hard time following examples because the script code is different. I am making a 2D platform runner. To start, I created the platforms, environment as well as a majority if not all of the physics. The player at this point is just a circle (just a place holder). The circle can move from left to right and jump. I have now, created an actual player sprite and made animations for walking, jumping and idle. How do I apply the new sprite animations to the current circle placeholder as well as the script? My next step is to go into the animator and start making transitions i guess. Im just not sure how to add the animations to my current script. I knew this was going to be a challenge and if there is any other info you need, please let me know. Thanks so much guys.
This is my "Controls.cs" that is currently attached to my circle player/placeholder. My CheckGround is attached to him. Everything else should be in relation to the platforms he is jumping on and I dont think will change. Again, I have a sprite walking, jumping and idle that I would like to take place of the current circle/placeholder. I need the walking animation to take place when the left and right arrows are pressed, the pump animation to play when the jump button is pressed and idle animation to play when the player is just standing still otherwise. Again, thanks so much guys!
using UnityEngine;
using System.Collections;
public class Controls : MonoBehaviour
{
public Rigidbody2D rb;
public float movespeed;
public float jumpheight;
public bool moveright;
public bool moveleft;
public bool jump;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask whatIsGround;
private bool onGround;
// Use this for initialization
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.velocity = new Vector2(-movespeed, rb.velocity.y);
}
if (Input.GetKey(KeyCode.RightArrow))
{
rb.velocity = new Vector2(movespeed, rb.velocity.y);
}
if (Input.GetKey(KeyCode.Space))
{
if (onGround)
{
rb.velocity = new Vector2(rb.velocity.x, jumpheight);
}
}
if (jump)
{
if (onGround)
{
rb.velocity = new Vector2(rb.velocity.x, jumpheight);
}
jump = false;
}
if (moveright)
{
rb.velocity = new Vector2(movespeed, rb.velocity.y);
}
if (moveleft)
{
rb.velocity = new Vector2(-movespeed, rb.velocity.y);
}
}
}
Read about Animation Controller. After you create it you can grab Animator from your gameObject like transform.GetComponent<Animator>()
Later you can blend your animations or just play them. Unity give you even possibility to make input conditions to play your animations so to be honest you don't even have to type too much code.
Definitely use an Animation Controller.
Have a look at this video - I'm following this tutorial at the moment.
https://www.youtube.com/watch?v=I0IVZhHNarg
I am developing an Android game using Unity and in my game I am instantiating objects which move in x direction visible to camera and when they leave camera view they are destroyed, to stop slowing the processing and taking memory. It works fine, but when my player moves in vertical direction there are objects which are instantiated but they are out of camera view, and then they are not destroyed. Therefore, when my objects are out of camera view I want to stop invokeRepeating. Here is the code which works only when objects are in view.
public GameObject colorbar;
public Vector2 velocity = new Vector2(-3, 0);
void Start () {
GetComponent<Rigidbody2D>().velocity = velocity;
transform.position = new Vector3(transform.position.x, transform.position.y, 0);
InvokeRepeating("CreateObstacle", 1f, 1.8f);
}
// Update is called once per frame
void Update () {
}
public void OnBecameInvisible()
{
Destroy(colorbar);
Debug.Log ("Color bar is Destroyed");
}
void CreateObstacle()
{
Instantiate(colorbar);
Debug.Log ("Color bar instantiating");
}
}
You can check if the renderer is visible when you create the object:
http://docs.unity3d.com/ScriptReference/Renderer-isVisible.html
void Awake(){
if(GetComponent<Renderer>().isVisible == false){
Destroy(this.gameObject);
}
}
But best would be to avoid creation if not needed, so you could get the point where you object should be created, then convert to screen point:
http://docs.unity3d.com/ScriptReference/Camera.WorldToScreenPoint.html
if the value is within the boundaries of the screen, then you good. You could also linecast from position to camera and if there is nothing stopping the cast, you are double good to create.
Vector3 pos = ObjectPos;
Vector3 screenPos = Camera.main.WorldToScreenPoint(pos);
if(screenPos.x > 0 && screenPos.x < Camera.main.pixelWidth &&
screenPos.y > 0 && screenPos.y < Camera.main.pixelHeight && screenPos.z > 0)
{
if (Physics.Linecast(pos, Camera.main.transform.position) == false){
// Create object
}
}
Keep in mind this is using the position of the object. If your object is large, then the position may be outside while some edges would be inside. The best would be to check for each vertex of the mesh. But if you have a complex mesh, that might get expensive, if you deal with a cube then maybe.
I am making a game in which my player is a UFO, and when the player collides with other game objects, I need the game objects to be attached or floated in the air below the player (UFO), like original UFO. I tried to attach them as a child, but it didn't worked.
I made one script as below:
if (coll) {
distance = Vector2.Distance (this.transform.position, player.transform.position);
if (distance < 2) {
this.transform.parent = encaixe.transform;
this.transform.localPosition = new Vector2 (0f, 1.2f);
this.transform.localRotation = Quaternion.identity;
encaixe.rigidbody2D.gravityScale=0;
}
}
In using this script, the gameobject is attaching, but the player is not moving as like original. The game object is pulling down or up forcefully.
Please suggest to me how to do this.
I know that this Thread is rather old, but maybe someone might come across this question and is in need of an answer.
You can actively set the Object's Position and Rotation to the UFO's on Collision.
Something like the following (pseudocode):
private bool hasCollided = false;
void OnCollisionEnter()
{
hasCollided = true;
}
void LateUpdate()
{
if (hasCollided)
{
followPlayer();
}
}
void followPlayer()
{
//update position and rotation
}