So im using this code to move around an object, but i dont know how to make it collide with the walls. No matter what I do the gameobject just goes through the walls or if it hits them they bounce. Sorry if its too simple I am new.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class controller : MonoBehaviour {
private float dist;
private bool dragging = false;
private Vector3 offset;
private Transform toDrag;
public Text score;
public int counterofbeers;
public Touch touch;
public bool lampa=false;
void Awake(){
counterofbeers = 0;
}
void Update() {
score.text= counterofbeers.ToString ();
Vector3 v3;
if (Input.touchCount != 1) {
dragging = false;
return;
}
touch = Input.touches[0];
Vector3 pos = touch.position;
if(touch.phase == TouchPhase.Began) {
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(pos);
if(Physics.Raycast(ray, out hit) && (hit.collider.tag == "Draggable"))
{
Debug.Log ("Here");
toDrag = hit.transform;
dist = hit.transform.position.z - Camera.main.transform.position.z;
v3 = new Vector3(pos.x,dist);
v3 = Camera.main.ScreenToWorldPoint(v3);
offset = toDrag.position - v3;
dragging = true;
}
}
if (dragging && touch.phase == TouchPhase.Moved) {
v3 = new Vector3(Input.mousePosition.x,dist);
v3 = Camera.main.ScreenToWorldPoint(v3);
toDrag.position = v3 + offset;
}
if (dragging && (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)) {
dragging = false;
}
}
void OnTriggerEnter(Collider other) {
if (other.gameObject.CompareTag ("pickup")) {
Destroy (other.gameObject); counterofbeers++;
}
if(other.gameObject.CompareTag("wall")){
lampa=true;
}
}
}
Related
I have an Android game where user moves player by touching left and right side of the screen. I tried the game on Android and all worked OK. But one day it stopped working: buttons work but I can't control the Player by touching screen sides. I tried to reinstall Unity, delete Library folder and even tried other OS. It didn't help. How can I fix my project?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MovingPlayer : MonoBehaviour
{
public float playerSpeed;
public float maxPos = 2.7f;
Vector3 position;
public uiManager ui;
public AudioManager am;
public Text coinCount;
int coin;
bool currntPlatformAndroid = false;
Rigidbody2D rb;
public GameObject particleSystemPrefab;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
#if UNITY_ANDROID
currntPlatformAndroid = true;
#else
currentPlatformAndroid = false;
#endif
am.playerSound.Play();
}
// Use this for initialization
void Start()
{
coin = 0;
position = transform.position;
}
// Update is called once per frame
void Update()
{
if (currntPlatformAndroid == true)
{
TouchMove();
//AccelerometerMove();
}
else
{
position.x += Input.GetAxis("Horizontal") * playerSpeed * Time.deltaTime;
position.x = Mathf.Clamp(position.x, -2.7f, 2.7f);
transform.position = position;
}
position = transform.position;
position.x = Mathf.Clamp(position.x, -2.7f, 2.7f);
transform.position = position;
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "CubeObstacle")
{
//Destroy (gameObject);
foreach (ContactPoint2D contact in col.contacts)
{
Instantiate(particleSystemPrefab, contact.point, Quaternion.identity);
}
//gameObject.SetActive(false);
GameOverActivated();
ui.gameOverActivated();
am.playerSound.Stop();
}
if (col.gameObject.tag == "Coin")
{
Destroy(col.gameObject);
coin += 1;
coinCount.text = coin.ToString();
Debug.Log("Coin");
}
}
public void GameOverActivated()
{
Time.timeScale = 0;
PlayerPrefs.SetInt("coins", PlayerPrefs.GetInt("coins") + coin);
}
void AccelerometerMove()
{
float x = Input.acceleration.x;
if (x < -0.1f)
{
MoveLeft();
}
else if (x > 0.1f)
{
MoveRight();
}
else
{
SetVelocityZero();
}
}
void TouchMove()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
float middle = Screen.width / 2;
if (touch.position.x < middle && touch.phase == TouchPhase.Began)
{
MoveLeft();
}
else if (touch.position.x > middle && touch.phase == TouchPhase.Began)
{
MoveRight();
}
}
else
{
SetVelocityZero();
}
}
public void MoveLeft()
{
rb.velocity = new Vector2(-playerSpeed, 0);
}
public void MoveRight()
{
rb.velocity = new Vector2(playerSpeed, 0);
}
public void SetVelocityZero()
{
rb.velocity = Vector2.zero;
}
}
You don't need to use Input.Touches, this should work fine:
void Update()
{
#if UNITY_EDITOR
position.x += Input.GetAxis("Horizontal") * playerSpeed * Time.deltaTime;
position.x = Mathf.Clamp(position.x, -2.7f, 2.7f);
transform.position = position;
#else
if (Input.GetMouseButton(0))
{
if (Input.mousePosition.x > Screen.width/2)
{
MoveRight();
}
else
{
MoveLeft()
}
}
else
{
SetVelocityToZero();
}
#endif
}
Hope this helps :)
I am working on 2D infinite runner. I have below code to take input from screen swipe to jump, slide and run fast. I am providing jumpHeight from editor and value is 500 with frame rate of 30. Code works fine generally but sometimes player jumps too high for up swipe. Similar code works as expected if input is from Keyboard. Why this is happening is beyond my understanding of unity. Any help is greatly appreciated.
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
public float ForwardSpeed = 3.7f; //moves player in forward direction
public float speedOffset = 0.0f; //offset speed of player
public float JumpHeight = 250; //moves player in verticle direction
bool grounded = false; //checks if player is grounded or not
public Transform groundCheck;
float groundCheckRadius = 0.3f; //radius of groundcheck circle to check grounded bool
public LayerMask groundLayer;
Vector2 fingerStart;
Vector2 fingerEnd;
void Update()
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
fingerStart = touch.position;
fingerEnd = touch.position;
}
if (touch.phase == TouchPhase.Moved)
{
fingerEnd = touch.position;
if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe
{
if (fingerEnd.y - fingerStart.y > 50)//up swipe
{
Jump();
}
else if (fingerEnd.y - fingerStart.y < -50)//Down swipe
{
//Slide();
}
fingerStart = touch.position;
}
}
if (touch.phase == TouchPhase.Stationary)
{
RunFast();
}
if (touch.phase == TouchPhase.Ended)
{
fingerEnd = touch.position;
if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe
{
if (fingerEnd.y - fingerStart.y > 50)//up swipe
{
Jump();
}
else if (fingerEnd.y - fingerStart.y < -50)//Down swipe
{
//Slide();
}
}
}
}
if (Input.GetButton("Fire1"))
{
speedOffset = 2.5f;
}
else
{
speedOffset = 0.0f;
}
if (grounded && Input.GetKeyDown(KeyCode.UpArrow))
{
grounded = false;
GetComponent<Rigidbody2D>().AddForce(new Vector2(0, JumpHeight));
}
//check if circle overlaps with ground layer
grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
//Debug.Log(grounded);
}
void FixedUpdate()
{
//set players forward velocityto forward speed variable
Vector2 PlayerForwardvelocity = GetComponent<Rigidbody2D>().velocity;
// Vector2 PlayerJumpHeight = GetComponent<Rigidbody2D>().AddForce()
PlayerForwardvelocity.x = ForwardSpeed + speedOffset;
GetComponent<Rigidbody2D>().velocity = PlayerForwardvelocity;
}
void Jump()
{
if (grounded)
{
GetComponent<Rigidbody2D>().AddForce(new Vector2(0, JumpHeight));
speedOffset = 0.0f;
}
}
void RunFast()
{
if (Input.GetButton("Fire1"))
{
speedOffset = 2.5f;
}
else
{
speedOffset = 0.0f;
}
}
}
You have 2 problems with your code.
Your first problem lies in this line of code:
grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
This line of code is failing. grounded is always true. Because of this, jump is called too many times while player is not grounded.
Replace this line of code with
Collider2D playerCollider = gameObject.GetComponent<Collider2D>();
grounded = Physics2D.OverlapCircle(playerCollider.transform.position, 1, groundLayer);
OR
Collider2D playerCollider = gameObject.GetComponent<Collider2D>();
grounded = playerCollider.IsTouchingLayers(groundLayer.value);
Another problem with your code is a false report.Sometimes, collider overlapping returns true even if it is false. I tried moving that part of code to LateUpdate function but that didn't fix it.
You can fix it by implementing a timer. The timer resets to 0 and starts counting to 0.5 whenever player jumps. Don't jump when timer has not reached the value it is counting to. .5 to 1 is a perfect value for this. Increment the timer with Time.deltaTime. Below is your whole code with timer and fixes.
public class PlayerControl : MonoBehaviour
{
public float ForwardSpeed = 3.7f; //moves player in forward direction
public float speedOffset = 0.0f; //offset speed of player
public float JumpHeight = 250; //moves player in verticle direction
bool grounded = false; //checks if player is grounded or not
public Transform groundCheck;
float groundCheckRadius = 0.3f; //radius of groundcheck circle to check grounded bool
public LayerMask groundLayer;
Vector2 fingerStart;
Vector2 fingerEnd;
public float resetTimer = 0.5f; //.5 second
float timerCounter = 0;
Collider2D playerCollider = null;
Rigidbody2D playerRigidBody;
void Start()
{
playerRigidBody = GetComponent<Rigidbody2D>();
playerCollider = gameObject.GetComponent<Collider2D>();
}
void Update()
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
fingerStart = touch.position;
fingerEnd = touch.position;
}
if (touch.phase == TouchPhase.Moved)
{
fingerEnd = touch.position;
if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe
{
if (fingerEnd.y - fingerStart.y > 50)//up swipe
{
Jump();
}
else if (fingerEnd.y - fingerStart.y < -50)//Down swipe
{
//Slide();
}
fingerStart = touch.position;
}
}
if (touch.phase == TouchPhase.Stationary)
{
RunFast();
}
if (touch.phase == TouchPhase.Ended)
{
fingerEnd = touch.position;
if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe
{
if (fingerEnd.y - fingerStart.y > 50)//up swipe
{
Jump();
}
else if (fingerEnd.y - fingerStart.y < -50)//Down swipe
{
//Slide();
}
}
}
}
if (Input.GetButton("Fire1"))
{
speedOffset = 2.5f;
}
else
{
speedOffset = 0.0f;
}
if (grounded && Input.GetKeyDown(KeyCode.UpArrow))
{
grounded = false;
playerRigidBody.AddForce(new Vector2(0, JumpHeight));
}
//check if circle overlaps with ground layer
grounded = Physics2D.OverlapCircle(playerCollider.transform.position, 1, groundLayer);
//OR Use grounded = playerCollider.IsTouchingLayers(groundLayer.value);
//Increment Timer if it is still less than resetTimer
if (timerCounter < resetTimer)
{
timerCounter += Time.deltaTime;
}
}
void FixedUpdate()
{
//set players forward velocityto forward speed variable
Vector2 PlayerForwardvelocity = playerRigidBody.velocity;
// Vector2 PlayerJumpHeight = playerRigidBody.AddForce()
PlayerForwardvelocity.x = ForwardSpeed + speedOffset;
playerRigidBody.velocity = PlayerForwardvelocity;
}
void Jump()
{
if (grounded)
{
//Exit if timer has not reached the required value to jump again
if (timerCounter < resetTimer)
{
Debug.Log("Failed To Jump because timer has not yet reached");
return; //Exit
}
timerCounter = 0; //Reset Timer
playerRigidBody.AddForce(new Vector2(0, JumpHeight));
speedOffset = 0.0f;
Debug.Log("Jumped");
}
else
{
Debug.Log("Not on the Ground");
}
}
void RunFast()
{
if (Input.GetButton("Fire1"))
{
speedOffset = 2.5f;
}
else
{
speedOffset = 0.0f;
}
}
}
I am having a few issues with my touch controls.
1) My game is 2D. When I tested this on my android device the 2D image will almost disappear when shifting from right touch to left touch. The object is being treated as 3D object. I think this has something to do with the Z space.
2) How could I make the character move like in this video - https://www.youtube.com/watch?v=5hckY75j_lg. In this case any place you touch the screen grabs the player (head) and moves exactly exactly as the finger does.
Any help would appreciated!
Here's my code:
public class TouchLogic : MonoBehaviour {
public static int currTouch = 0;
private Ray ray;
private RaycastHit rayHitInfo = new RaycastHit ();
[HideInInspector ]
public int touch2Watch=64;
// Update is called once per frame
void Update () {
if (Input.touches.Length <= 0) {
} else {
for (int i = 0; i < Input.touchCount; i++) {
currTouch = i;
if (this.GetComponent <GUITexture >() != null && (this.GetComponent <GUITexture >().HitTest (Input.GetTouch (i).position))) {
if (Input.GetTouch (i).phase == TouchPhase.Began) {
this.SendMessage ("OnTouchBegan");
}
if (Input.GetTouch (i).phase == TouchPhase.Ended ) {
this.SendMessage ("OnTouchEnded");
}
if (Input.GetTouch (i).phase == TouchPhase.Moved ) {
this.SendMessage ("OnTouchMoved");
}
}
ray = Camera.main.ScreenPointToRay (Input.GetTouch (i).position);
switch (Input.GetTouch (i).phase) {
case TouchPhase .Began:
this.SendMessage ("OnTouchBeganAnywhere");
if (Physics.Raycast (ray, out rayHitInfo))
rayHitInfo.transform.gameObject.SendMessage ("OnTouchBegan2D");
break;
case TouchPhase .Ended :
this.SendMessage ("OnTouchEndedAnywhere");
if (Physics.Raycast (ray, out rayHitInfo))
rayHitInfo.transform.gameObject.SendMessage ("OnTouchEnded2D");
break;
case TouchPhase .Moved :
this.SendMessage ("OnTouchMovedAnywhere");
if (Physics.Raycast (ray, out rayHitInfo))
rayHitInfo.transform.gameObject.SendMessage ("OnTouchMoved2D");
break;
case TouchPhase .Stationary :
this.SendMessage ("OnTouchStayedAnywhere");
if (Physics.Raycast (ray, out rayHitInfo))
rayHitInfo.transform.gameObject.SendMessage ("OnTouchStayed2D");
break;
}
}
}
}
}
public class FollowTouch : TouchLogic {
public float speed=1f;
private Vector3 finger;
private Transform myTrans, camTrans;
void Start () {
myTrans = this.transform;
camTrans = Camera.main.transform;
}
void LookAtFinger(){
Vector3 tempTouch=new Vector3 (Input.GetTouch (touch2Watch ).position .x,Input.GetTouch (touch2Watch ).position .y,
camTrans .position.y-myTrans .position .y);
finger = Camera.main.ScreenToWorldPoint (tempTouch);
myTrans.LookAt (finger);
myTrans.Translate (Vector3.forward * speed * Time.deltaTime);
}
void OnTouchMovedAnywhere(){
LookAtFinger ();
}
void OnTouchStayedAnywhere(){
LookAtFinger ();
}
void OnTouchBeganAnywhere(){
touch2Watch = TouchLogic.currTouch;
}
If you are making 2d game you have to use
Vector3.up
instead of
Vector3.forward
I made a Flappy Bird-like game in Unity 2D for Android. I's working & running on my device, but there is one problem with the contsols:If i tap the screen the bird flaps and flyes, but if I hold the screen the bird is keep going up and up.. I want to only sense one tap.
There is my code:
if (Input.touchCount == 1) {
didFlap = true;
}
Full code:
using UnityEngine;
using System.Collections;
public class BirdMovement : MonoBehaviour {
Vector3 velocity = Vector3.zero;
public float flapSpeed = 100f;
public float forwardSpeed = 1f;
bool didFlap = false;
Animator animator;
public bool dead = false;
float deathCooldown;
public bool godMode = false;
// Use this for initialization
void Start () {
animator = transform.GetComponentInChildren<Animator>();
if(animator == null) {
Debug.LogError("Didn't find animator!");
}
}
// Do Graphic & Input updates here
void Update() {
if(dead) {
deathCooldown -= Time.deltaTime;
if(deathCooldown <= 0) {
if(Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0) ) {
Application.LoadLevel( Application.loadedLevel );
}
}
}
else {
if(Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0) ) {
didFlap = true;
}
if (Input.touchCount == 1) {
didFlap = true;
}
}
}
// Do physics engine updates here
void FixedUpdate () {
if(dead)
return;
rigidbody2D.AddForce( Vector2.right * forwardSpeed );
if(didFlap) {
rigidbody2D.AddForce( Vector2.up * flapSpeed );
animator.SetTrigger("DoFlap");
didFlap = false;
}
if(rigidbody2D.velocity.y > 0) {
transform.rotation = Quaternion.Euler(0, 0, 0);
}
else {
float angle = Mathf.Lerp (0, -90, (-rigidbody2D.velocity.y / 3f) );
transform.rotation = Quaternion.Euler(0, 0, angle);
}
}
void OnCollisionEnter2D(Collision2D collision) {
if(godMode)
return;
animator.SetTrigger("Death");
dead = true;
deathCooldown = 0.5f;
}
}
If you wanna do it with touchcount I think you should do something like this create bool variable in start cangoup=true
Ask
if (input.touchcount==0)
Cangoup=true;
And the didflap statement should be something like this
If(cangoup)
{//everything you wrote
Cangoup=false;}
I wrote this from my iphone so there may be few mistakes but i am sure you can fix them and i think this will do you good if it doesn't just comment on the answer and ill reply
In one of my Android applications (Made with Unity), I would like to move the camera by scrolling with finger on the screen and simultaneously not detect hit, when I touch on any object during scrolling. My problem is that when I want to scroll down the camera with my finger, it firstly also detects hits with the objects. I have one script which is attached to Main Camera.
Here's the code for better understanding.
//Update function for scrolling and detecting touch.
//Do not want to detect touch on objects when scrolling.
void Update () {
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) {
checkTouch(Input.GetTouch(0).position);
}
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) {
Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
transform.Translate(0, -touchDeltaPosition.y * Time.deltaTime, 0);
transform.position = new Vector3(0, Mathf.Clamp(transform.position.y, -30, 0), -10);
}
}
void checkTouch(Vector3 pos){
Vector3 wp = Camera.main.ScreenToWorldPoint (pos);
Vector2 touchpos = new Vector2 (wp.x, wp.y);
hit = Physics2D.OverlapPoint (touchpos);
if (hit) {
//Debug.Log (hit.transform.gameObject.name);
//hit.transform.gameObject.SendMessage ("Clicked", null, SendMessageOptions.DontRequireReceiver);
if (hit.transform.gameObject.tag == "item"){
//do something
}
}
}
I think you can try use something like this
void Update()
{
if (Input.touchCount <= 0)
return;
bool lMove = false;
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
Debug.Log("Touch phase = Moved");
lMove = true;
Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
transform.Translate(0, -touchDeltaPosition.y * Time.deltaTime, 0);
transform.position = new Vector3(0, Mathf.Clamp(transform.position.y, -30, 0), -10);
}
if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
Debug.Log("Touch phase = Ended");
if (!lMove)
{
//onClick
checkTouch(Input.GetTouch(0).position);
}
}
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class LineDirDetector: MonoBehaviour {
public Text texto01;
//inside class
Vector2 firstPressPos;
Vector2 secondPressPos;
Vector2 currentSwipe;
void Update()
{
Swipe();
}
public void Swipe() {
if (Input.touches.Length > 0) {
Touch t = Input.GetTouch(0);
if (t.phase == TouchPhase.Began) {
//save began touch 2d point
firstPressPos = new Vector2(t.position.x, t.position.y);
}
if (t.phase == TouchPhase.Ended) {
//save ended touch 2d point
secondPressPos = new Vector2(t.position.x, t.position.y);
//create vector from the two points
currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
//normalize the 2d vector
currentSwipe.Normalize();
//swipe upwards
if (currentSwipe.y > 0 && currentSwipe.x > -0.5 f && currentSwipe.x < 0.5 f) {
Debug.Log("up swipe");
texto01.text = "ARRIBA";
}
//swipe down
if (currentSwipe.y < 0 && currentSwipe.x > -0.5 f && currentSwipe.x < 0.5 f) {
Debug.Log("down swipe");
texto01.text = "ABAJO";
}
//swipe left
if (currentSwipe.x < 0 && currentSwipe.y > -0.5 f && currentSwipe.y < 0.5 f) {
Debug.Log("left swipe");
texto01.text = "IZQUIERDA";
}
//swipe right
if (currentSwipe.x > 0 && currentSwipe.y > -0.5 f && currentSwipe.y < 0.5 f) {
Debug.Log("right swipe");
texto01.text = "DERECHA";
}
}
}
}
}