how can create touch screen android scroll in unity3d? - c#

I want to create an Android game with Unity3d. This game has an upgrade list with a touchable scroll. I use this code to create that but when I move finger in touch screen, scroll move hard and with a jump, I want it to move softly and like Android effects.
scrollPosition1 = GUI.BeginScrollView(Rect (0,400,Screen.width,175),
scrollPosition1, Rect (0, 0, 650, 0));
// touch screen
if(Input.touchCount==1 &&
Screen.height -Input.GetTouch(0).position.y > 450 - scrollPositionHome.y &&
Screen.height - Input.GetTouch(0).position.y < 600 - scrollPositionHome.y)
{
var touchDelta2 : Vector2 = Input.GetTouch(0).deltaPosition;
scrollPosition1.x +=touchDelta2.x;
}
for (i=0;i < ImgSliderProducts.Length;i++)
{
GUI.DrawTexture(Rect(20+(i* 100),10,100,100),
ImgSliderProducts[i],ScaleMode.ScaleToFit,true);
}
GUI.EndScrollView();

using UnityEngine;
using System.Collections;
public class scrollView : MonoBehaviour {
Vector2 scrollPosition;
Touch touch;
// The string to display inside the scrollview. 2 buttons below add & clear this string.
string longString = "This is a long-ish string";
void OnGUI () {
scrollPosition = GUI.BeginScrollView(new Rect(110,50,130,150),scrollPosition, new Rect(110,50,130,560),GUIStyle.none,GUIStyle.none);
for(int i = 0;i < 20; i++)
{
GUI.Box(new Rect(110,50+i*28,100,25),"xxxx_"+i);
}
GUI.EndScrollView ();
}
void Update()
{
if(Input.touchCount > 0)
{
touch = Input.touches[0];
if (touch.phase == TouchPhase.Moved)
{
scrollPosition.y += touch.deltaPosition.y;
}
}
}
}

Related

I don't know how to check for position of gameObjects in Unity

What I'm building is a Tetris word game where you have a goal word that you need to spell but you also get points for spelling other word with those letters. (for example the goal word is seaweed and you get points for spelling words like sea and weed and you win once you actually spell seaweed). Anyway, what I have right now is the starting of a tetris game without the part where it clears a line (because I want a word to clear, not a line). Each letter is its own gameObject and I don't know how to check for words. I get how to add to the score and everything, but it's the checking for words that has me stuck. This is what the game looks like sort of:
Screenshot of my screen in Unity
I was thinking maybe I could check if the gameObject for each letter is in a specific sequence (positioned next to other letters that would spell out a word) but I don't know how to do that or if it would even work. If anyone could help me figure this one out I would really appreciate it. Here's the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TetrisBlock : MonoBehaviour
{
private float previousTime;
public float fallTime = 0.8f;
public static int height = 280;
public static int width = 160;
private static Transform[,] grid = new Transform[width, height];
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
transform.position += new Vector3(-20, 0, 0);
if (!ValidMove())
{
transform.position += new Vector3(20, 0, 0);
}
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
transform.position += new Vector3(20, 0, 0);
if (!ValidMove())
{
transform.position += new Vector3(-20, 0, 0);
}
}
if(Time.time - previousTime > (Input.GetKey(KeyCode.DownArrow) ? fallTime / 10 : fallTime))
{
transform.position += new Vector3(0, -20, 0);
if (!ValidMove())
{
transform.position -= new Vector3(0, -20, 0);
AddToGrid();
this.enabled = false;
FindObjectOfType<SpawnerTetromino>().NewTetromino();
}
previousTime = Time.time;
}
void AddToGrid()
{
int roundedX = Mathf.RoundToInt(transform.position.x);
int roundedY = Mathf.RoundToInt(transform.position.y);
grid[roundedX, roundedY] = transform;
}
bool ValidMove()
{
{
int roundedX = Mathf.RoundToInt(transform.position.x);
int roundedY = Mathf.RoundToInt(transform.position.y);
if (roundedX < 0 || roundedX >= width || roundedY < 0 || roundedY >= height)
{
return false;
}
if (grid[roundedX, roundedY] != null)
return false;
}
return true;
}
}
}
yes, you can definitely do this.
First, you need to track the GameObject or Transform of the letters, for example: Transform[] letters
Then, you need to set their position, for example:
int width = 100;
for(int i = 0; i < letters.Length; i++)
{
letters[i].position = new Vector3(i*width, 0):
}
Another thing that you can do is, have a prefab of each letter perhaps, even have an array of 26 where 0=A and 25=Z then instantiate the letters based on the word and place them in order.
A final idea, is to Instantiate your letters into an object with a Horizontal Layout Group.

Detect Swipe Even the Finger Hasn't been Released

I want to detect the mouse swipe up and swipe down, I tried the script below but it only works:
1 - if the finger has been released between any two swipes.
2 - if the finger hasn't been released, but only if the second swipe has exceed the original finger position (firstPressPos).
What I want exactly is:
For example, I put my finger on the screen and I swipe down, then after I swipe up (without releasing the finger between the two swipes), I want to detect the two swipes in the real time.
How can I do that?
Script:
if (Input.GetMouseButtonDown(0))
{
firstPressPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y);
}
if (Input.GetMouseButton(0))
{
secondPressPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y);
currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
currentSwipe.Normalize();
if (currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f)
{
//Swipe Up
}
if (currentSwipe.y < 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f)
{
//Swipe Down
}
}
You need to add a couple of flags to know which swipe status you're in if your are in one.
private bool _swiping;
private bool _swipingDown;
private Vector3 _previousSwipePosition;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
_previousSwipePosition = Input.mousePosition;
_swiping = true;
Debug.log("Started Swipe");
}
else if (Input.GetMouseButtonUp(0))
{
_swiping = false;
Debug.log("Finished Swipe");
}
if (_swiping)
{
Vector3 newPosition = Input.mousePosition;
if (newPosition.y < _previousSwipePosition.y)
{
if (!_swipingDown)
{
Debug.Log("Started Swipe Down");
_swipingDown = true;
}
}
if (newPosition.y> _previousSwipePosition.y)
{
if (_swipingDown)
{
Debug.Log("Started Swipe Up");
_swipingDown = false;
}
}
_previousSwipePosition = newPosition;
}
}
This will let you know when a Swipe is Started, Finished and Changes direction using flags.
flags - booleans to signify something

Detect swipes without lifting the finger in Unity [duplicate]

This question already has answers here:
Detect swipe gesture direction
(5 answers)
Closed 5 years ago.
I'm implementing specific type of touch controller.
The player needs to hold their finger on screen in order to move.
Without lifting the finger, the player can swipe in different direction to change direction while still moving.
Once the finger is lifted, the player stops moving.
It's been a hard time isolating specific swipes (i.e. lines drawn on screen) ignoring any other movements that are not intended to draw a line.
For instance slight finger movements done when the player's finger is "stationary", they mess up my algorithm.
I thought about different approaches such as storing the last few touches and evaluate upon them to determine if there has been a swipe or not, but couldn't implement it properly.
Here's what I've tried so far. Most of the time it works fine, but often the player does erratic movement and goes absolutely the opposite direction to what I intended.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TouchInputHandler : AbstractInputHandler {
private const int SWIPE_MIN_DISTANCE = 35;
private Vector2 touchStartPoint;
private Vector2 touchMovePoint;
void Update () {
Touch[] touches = Input.touches;
if (touches.Length == 1) {
Touch firstTouch = touches [0];
if (firstTouch.phase == TouchPhase.Began) {
this.touchStartPoint = firstTouch.position;
fireNextDirectionChanged (currentDirection);
} else if (firstTouch.phase == TouchPhase.Moved) {
this.touchMovePoint = firstTouch.position;
if (Vector2.Distance(touchStartPoint, touchMovePoint) > SWIPE_MIN_DISTANCE) {
detectSwipeDirection ();
}
} else if (firstTouch.phase == TouchPhase.Stationary) {
touchStartPoint.x = touchMovePoint.x;
touchStartPoint.y = touchMovePoint.y;
} else if (firstTouch.phase == TouchPhase.Ended) {
fireNextDirectionChanged (Constants.Direction.NONE);
}
}
}
private void detectSwipeDirection() {
float xDiff = touchMovePoint.x - touchStartPoint.x;
float yDiff = touchMovePoint.y - touchStartPoint.y;
Constants.Direction nextDirection;
bool yGreater = Mathf.Abs(yDiff) >= Mathf.Abs(xDiff);
if (yGreater) {
// direction is up or down
nextDirection = yDiff < 0 ? Constants.Direction.DOWN : Constants.Direction.UP;
} else {
// direction is left or right
nextDirection = xDiff < 0 ? Constants.Direction.LEFT : Constants.Direction.RIGHT;
}
if (nextDirection != this.currentDirection)
{
fireNextDirectionChanged (nextDirection);
this.currentDirection = nextDirection;
}
}
}
I think you simply forgot a line setting the previous touch position to the current one in the TouchPhase.Moved block. Just add touchStartPoint = this.touchMovePoint; and it should work (only tested using mouse inputs but logic remains the same).
Also I commented the TouchPhase.Stationary block: I feel like it does what I suggested before but only when the finger is completely immobile. The final code looks like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TouchInputHandler : AbstractInputHandler
{
private const int SWIPE_MIN_DISTANCE = 35;
private Vector2 touchStartPoint;
private Vector2 touchMovePoint;
void Update()
{
Touch[] touches = Input.touches;
if(touches.Length == 1)
{
Touch firstTouch = touches[0];
if(firstTouch.phase == TouchPhase.Began)
{
this.touchStartPoint = firstTouch.position;
this.currentDirection = Constants.Direction.NONE;
fireNextDirectionChanged(currentDirection);
}
else if(firstTouch.phase == TouchPhase.Moved)
{
this.touchMovePoint = firstTouch.position;
if(Vector2.Distance(touchStartPoint, touchMovePoint) > SWIPE_MIN_DISTANCE)
{
detectSwipeDirection();
}
touchStartPoint = this.touchMovePoint; // <= NEW !
}
//else if(firstTouch.phase == TouchPhase.Stationary)
//{
// touchStartPoint.x = touchMovePoint.x;
// touchStartPoint.y = touchMovePoint.y;
//}
else if(firstTouch.phase == TouchPhase.Ended)
{
this.currentDirection = Constants.Direction.NONE;
fireNextDirectionChanged(Constants.Direction.NONE);
}
}
}
private void detectSwipeDirection()
{
float xDiff = touchMovePoint.x - touchStartPoint.x;
float yDiff = touchMovePoint.y - touchStartPoint.y;
Constants.Direction nextDirection;
bool yGreater = Mathf.Abs(yDiff) >= Mathf.Abs(xDiff);
if(yGreater)
{
// direction is up or down
nextDirection = yDiff < 0 ? Constants.Direction.DOWN : Constants.Direction.UP;
}
else
{
// direction is left or right
nextDirection = xDiff < 0 ? Constants.Direction.LEFT : Constants.Direction.RIGHT;
}
if(nextDirection != this.currentDirection)
{
fireNextDirectionChanged(nextDirection);
this.currentDirection = nextDirection;
}
}
}
Also when using a distance based on in game distance to detect swipe, I'd suggest adding a Screen.width/height ratio somewhere if you want to port your project to multiple resolutions devices (on Start() do something like SWIPE_MIN_DISTANCE *= Screen.width / BASE_SCREEN_WIDTH with private const int BASE_SCREEN_WIDTH = 1024;).
Hope this helps,

Unity game Drag Object with finger movement

I am new to Unity and develop mobile 2d game,now I am able to make an object move right and left when I touch the screen before or after the screen center. But I want to touch the object and drag it on the x axis while my finger is still touching the screen and move,so I want the object to be in the same x position of my finger,
Any One can help me how to do it correctly:
here is the code of how I am moving the object if I touched before or after the screen center:
public class paddle : MonoBehaviour {
public Rigidbody2D rb;
public float speed;
public float maxX;
bool currentisAndroid=false;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody2D> ();
#if UNITY_ANDROID
currentisAndroid=true;
#else
currentisAndroid=false;
#endif
}
// Update is called once per frame
void Update () {
if (currentisAndroid == true) {
if (Input.GetTouch (0).position.x < Screen.width/2 && Input.GetTouch (0).phase == TouchPhase.Stationary)
moveLeft ();
else if (Input.GetTouch (0).position.x > Screen.width/2 && Input.GetTouch (0).phase == TouchPhase.Stationary)
moveRight ();
else
stop ();
} else {
float x = Input.GetAxis ("Horizontal");
//if (Input.GetTouch (0).position.x == rb.position.x && Input.GetTouch (0).phase == TouchPhase.Moved)
if (x == 0)
stop ();
if (x < 0)
moveLeft ();
if (x > 0)
moveRight ();
Vector2 pos = transform.position;
pos.x=Mathf.Clamp (pos.x,-maxX,maxX);
transform.position = pos;
}
}
void moveLeft()
{
rb.velocity = new Vector2 (-speed, 0);
}
void moveRight()
{
rb.velocity = new Vector2 (speed, 0);
}
void stop()
{
rb.velocity = new Vector2 (0, 0);
}
public float getposition()
{
return rb.position.y;
}
}
Easiest way:
Add component DragRigidbody script and you will be able to drag objects via mouse or touchScreen touches.
If I Understand correctly:
1 - Raycast from finger location vertically with your camera into the scene.
2 - select the hit object.
3 - map your camera to world coordinates and move that object according to hit point of your ray with map or game object\objects.
Physics.Raycast();
RaycastHit.collider();
Camera.main.ScreenToWorldPoint(Input.GetTouch(<0 or 1 or all>).position);
If you want to move object across a map you can track your touch and when its close to the corners move the camera on that direct (horizontal - vertical).

Cannot make a Rectangle to display with Unity + Oculus Rift

I'm trying to display a simple rectangle right in front of my OVRPlayerController's camera but it seems to be impossible.
I think it might have something to do with the fact that Rect is 2D and my environment is 3D. Does that make sense?
The code is the following (I have ommited the unnecessary stuff):
static int MAX_MENU_OPTIONS = 3;
public GameObject Menu;
private bool showMenu = false;
private float menuIndex = 0;
private bool hasPressedDirectionalPad = false;
public Transform[] buttons = new Transform[MAX_MENU_OPTIONS];
private static Texture2D staticRectTexture;
private static GUIStyle staticRectStyle;
bool DpadIsPressed() {
if (!hasPressedDirectionalPad && Input.GetAxis("DpadY") != 0 && hasPressedDirectionalPad == false){
menuIndex += Mathf.Sign(Input.GetAxis("DpadY")) * (-1);
if (menuIndex < 0) menuIndex = 0;
else if (menuIndex > MAX_MENU_OPTIONS-1) menuIndex = MAX_MENU_OPTIONS-1;
hasPressedDirectionalPad = true;
}
if(Input.GetAxis("DpadY") == 0){
hasPressedDirectionalPad = false;
}
return hasPressedDirectionalPad;
}
void Start() {
Menu.SetActive(false);
staticRectTexture = new Texture2D(1, 1, TextureFormat.RGB24, true);
staticRectStyle = new GUIStyle();
}
void Update() {
if (Input.GetButtonDown("A")) {
DoAction ();
print ("A key was pressed");
}
if (Input.GetButtonDown("Options")) {
showMenu = !showMenu;
if (showMenu) {
Time.timeScale = 0;
menuIndex = 0;
Menu.transform.rotation = this.transform.rotation;
Menu.transform.position = this.transform.position;
} else
Time.timeScale = 1;
}
if (DpadIsPressed ()) {
print ("Dpad key was pressed and menuIndex = " + menuIndex);
}
if (showMenu) {
Menu.SetActive (true);
}
if (!showMenu) {
Menu.SetActive (false);
}
}
void OnGUI() {
if (showMenu) {
Vector3 offset = new Vector3(0, 0, 0.2f);
Vector3 posSelectRectangle = buttons[(int)menuIndex].transform.position + offset;
Rect selectionRectangle = new Rect(posSelectRectangle.x - (float)177/2,
posSelectRectangle.y - (float)43/2,
177.0f, 43.0f);
GUIDrawRect(selectionRectangle, new Color(255.0f, 0, 0));
}
}
void DoAction () {
if (menuIndex == 0)
Salir ();
/*else if (menuIndex == 1)
Guardar ();*/
else if (menuIndex == 2)
Salir ();
}
public static void GUIDrawRect(Rect position, Color color ) {
staticRectTexture.SetPixel( 0, 0, color );
staticRectTexture.Apply();
staticRectStyle.normal.background = staticRectTexture;
GUI.Box( position, GUIContent.none, staticRectStyle );
}
The functions are visited, but the rectangle doesn't show up. Do you see the mistake? Maybe it has something to do with the Oculus Rift?
OnGUI and Screen-space Canvas are not supported in VR mode. This is because there is no way to handle stereoscopic rendering. (Note: They will render to the duplicate display on the user's PC though).
If you want to render in front of the user's camera (like a HUD), you can:
Use a Canvas:
Create a canvas, then add your UI, and set the canvas in world-space. Parent the canvas to the VR Camera game object, and scale it down (it defaults to very very big) and rotate it so it faces the camera.
Or, Use 3D:
Create a 3d Object (Plane, Cube, Quad, whatever!) and parent it to your VR Camera. You can use standard 3d techniques to update it's texture or render texture.

Categories

Resources