I want to trigger an event after tot seconds of long press on a touch screen.
I'm trying to achieve this goal with the following code.
The problem is that the time that has passed is, in some way, random.
private float timePressed = 0.0f;
private float timeLastPress = 0.0f;
public float timeDelayThreshold = 2.0f;
void Update() {
checkForLongPress(timeDelayThreshold);
}
void checkForLongPress(float tim) {
for (int i = 0; i < Input.touchCount; i++)
{
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
// If the user puts her finger on screen...
Debug.Log("Touch start");
timePressed = Time.time - timeLastPress;
}
if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
// If the user raises her finger from screen
timeLastPress = Time.time;
Debug.Log("Releasing Touch");
Debug.Log("Time passed --> " + timePressed);
if (timePressed > tim)
{
Debug.Log("Closing APP");
// Is the time pressed greater than our time delay threshold?
Application.Quit();
}
}
}
}
The Fact is that this condition "(timePressed > tim)" is never true and i do not understand why.
Time.time returns The time at the beginning of this frame (Read Only). This is the time in seconds since the start of the game..
Fixed pseudo code:
if (Input.GetTouch(i).phase == TouchPhase.Began)
{
_timePressed = Time.time;
return;
}
if (Input.GetTouch(i).phase == TouchPhase.Ended)
{
var deltaTime = Time.time - _timePressed;
if (deltaTime > _maxTimeTreshold)
{
Application.Quit();
}
}
Related
here's my jump code it updates in void Update
void Jump()
{
if(isgrounded == true)
{
amountofjumps = jumps;
}
if(Input.GetKeyDown(KeyCode.UpArrow) && amountofjumps > 0)
{
rb2d.velocity = Vector2.up * jump * Time.deltaTime;
amountofjumps--;
}
else if(Input.GetKeyDown(KeyCode.UpArrow) && amountofjumps == 0 && isgrounded == true)
{
rb2d.velocity = Vector2.up * jump * Time.deltaTime;
}
}
here are the variables I use for my jump code
bool isgrounded;
public float groundcheckradius;
public LayerMask whatisground;
public float jump;
private int amountofjumps;
public int jumps;
here's how I detect the ground
void checkforground()
{
isgrounded = Physics2D.Raycast(transform.position,Vector2.down, groundcheckradius,whatisground);
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, transform.position + Vector3.down * groundcheckradius);
}
thanks in advance
Velocity is often used for moving object try rigidbody2d.AddForce() instead.
void Jump()
{
if (isgrounded == true)
{
amountofjumps = jumps;
}
if (Input.GetKeyDown(KeyCode.UpArrow) && amountofjumps > 0 && isgrounded == true)
{
rb2d.AddForce(transform.up * jump, ForceMode2D.Impulse);
amountofjumps--;
}
}
First of all Time.deltaTime makes no sense when setting a velocity. A velocity already is frame-rate independent so when you multiply a velocity by Time.deltaTime (about 0.017 for 60 fps) it becomes extremely small/slow.
Secondly currently you overwrite the entire velocity so if your player is moving forward it will completely stop any movement on the X axis.
And finally when you are grounded you want always be able to jump ... not only if amountofjumps == 0 which will never be the case since right before you have set it to amountofjumps = jumps;! You don't want to check the amountofjumps at all when jumping from the ground!
You would probably rather use e.g.
// get the current velocoty of the rigidbody
var velocity = rb2d.velocity;
// Only overwrite the Y velocity with the jump
velocity.y = jump;
// re-assign the changed vector to the rgidbody
rb2d.velocity = velocity;
And then I would change the logic to something like e.g.
private void Jump()
{
if(isgrounded)
{
amountofjumps = jumps;
// when you are grounded you can always jump!
// Not only when the amountofjumps == 0
// actually when you are grounded the amountofjumps shouldn't matter at all
if(Input.GetKeyDown(KeyCode.UpArrow))
{
DoJump();
}
}
// As before while not grounded the amountofjumps is taken into account
else if(amountofjumps > 0)
{
if(Input.GetKeyDown(KeyCode.UpArrow))
{
DoJump();
}
}
}
private void DoJump()
{
// get the current velocoty of the rigidbody
var velocity = rb2d.velocity;
// Only overwrite the Y velocity with the jump
velocity.y = jump;
// re-assign the changed vector to the rgidbody
rb2d.velocity = velocity;
// Always reduce the amount of jumps also when jumping from the ground
amountofjumps--;
}
we have a dash button in the game. If we press the button dash button is working well but the problem is if we press anywhere on screen it is working too! We only want to work that function with button.
Anyone help us please?
Code:
public void Dash()
{
if (Input.GetMouseButtonDown(0))
{
activeMoveSpeed = dashSpeed;
dashCounter = dashLength;
}
if (dashCounter > 0)
{
canShoot = false;
dashCounter -= Time.deltaTime;
if (dashCounter <= 0)
{
canShoot = false;
activeMoveSpeed = speed;
dashCoolCounter = dashCoolDown;
}
}
if (dashCoolCounter > 0)
{
canShoot = false;
dashCoolCounter -= Time.deltaTime;
}
}
private void FixedUpdate()
{
Movement();
Dash();
}
Button and Game
Button
The function you specify in OnClick will be called whenever the button is clicked.
Currently, you are not using the button at all. I think you meant something like this (StartDash() is the function that should be chosen in OnClick):
public void StartDash()
{
activeMoveSpeed = dashSpeed;
dashCounter = dashLength;
}
private void DoDash()
{
if (dashCounter > 0)
{
canShoot = false;
dashCounter -= Time.deltaTime;
if (dashCounter <= 0)
{
canShoot = false;
activeMoveSpeed = speed;
dashCoolCounter = dashCoolDown;
}
}
if (dashCoolCounter > 0)
{
canShoot = false;
dashCoolCounter -= Time.deltaTime;
}
}
private void FixedUpdate()
{
Movement();
DoDash();
}
Take a look at the related pages in the Unity Documentation:
Manual - Button
Scripting - UI.Button
Scripting - UI.Button.onclick
i have a 2d platformer with a player that moves. It works perfect in unity and i packaged it and downloaded the apk on my galaxy s7 which also works perfect.
I then tested it in my local supermarkets tablet display and on both tablets i tried, if i touched left, it would pause for a second, then move left.
The animated enemies, spinning coins and physics was working fine so there wasnt that type of lag, just a pause when moving which makes me think the code i have to move is wrong. The tablets looked fairly high spec too.
Here is how i move the player, i call this in the update function:
List<FingerTouch> currentTouches = new List<FingerTouch>();
public class FingerTouch
{
public int id;
public float beganXPos;
public FingerTouch (int fingerId, float fingerBegan)
{
this.id = fingerId;
this.beganXPos = fingerBegan;
}
}
if (!disableMovment)
{
for (int i = 0; i < Input.touchCount; i++)
{
if (Input.GetTouch(i).phase == TouchPhase.Began && !EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
{
float xPos = Input.GetTouch(i).position.x;
if(xPos < Screen.width / 5)
{
playerLeft = true;
} else if (xPos > ((Screen.width / 5) * 4))
{
playerRight = true;
} else
{
playerUp = true;
}
int fingerId = Input.GetTouch(i).fingerId;
currentTouches.Add(new FingerTouch(fingerId, xPos));
} else if (Input.GetTouch(i).phase == TouchPhase.Ended)
{
if (currentTouches.Count != 0)
{
for (int j = 0; j < currentTouches.Count; j++)
{
FingerTouch currentTouch = currentTouches[j];
if (Input.GetTouch(i).fingerId == currentTouch.id || currentTouches.Count == 1)
{
if (currentTouches[j].beganXPos < Screen.width / 5)
{
playerLeft = false;
}
else if (currentTouches[j].beganXPos > ((Screen.width / 5) * 4))
{
playerRight = false;
}
else
{
playerUp = false;
}
currentTouches.RemoveAt(j);
break;
}
}
} else {
playerUp = false;
playerRight = false;
playerLeft = false;
}
}
}
}
It looks a little over the top but it basicily divides the screen into 3 sections 20/60/20 which move left right jump. When the user touches, it stores that touch and when its released, its removed.
This allows multi touch (jumping and moving) while also preventing jumping, sliding ur finger to the right and removing it and being in an unlimited jumping state as you didnt remove your finger in the middle.
Then after that it moves the player like this:
if (hitLeftWall && playerLeft)
{
playerBody.velocity = new Vector2(0, playerBody.velocity.y);
}
Is there anything here that would cause the player to pause before moving? Should this be in fixed update as the player has a rigidbody? Im new to unity so im not sure on the proper way to do things yet.
I have a VR Scene with a C# Script on the camera that allows the user to Click Once to move and again to stop.
public float speed = 1.0f;
public bool startedMoving = true;
public GameObject myCam;
// Update is called once per frame
void Update () {
if (startedMoving) {
transform.position += myCam.transform.forward * speed * Time.deltaTime;
}
// if(Input.GetButtonDown("Fire1")){
if (Input.GetMouseButton(0)){
startedMoving = !startedMoving;
}
}
What I want to know is how I can CLICK & HOLD to move Backwards..?
Thank you!
~ b
Use enum the represent the status of the mouse instead of startedMoving or multiple booleans that will make everything easier to implement. The comment in the code describes how it works.
using UnityEngine;
using System.Collections;
public class ClickAndHeld : MonoBehaviour
{
public GameObject myCam;
CLICK_MODE clickMode = CLICK_MODE.NO_CLICK;
MOVE_DIRECTION moveDir = MOVE_DIRECTION.IDLE;
public float speed = 1.0f;
//If down for 0.5 secods the it is considered Click and Hold instead of Click
float clickHoldDetectTime = 0.5f;
float clickCounter = 0; //Dont not change
void Start()
{
StartCoroutine(mover());
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
//If in NO_CLICK, set to CLICKED
if (clickMode == CLICK_MODE.NO_CLICK)
{
//Change the mode to CLICKED
clickMode = CLICK_MODE.CLICKED;
}
//If in CLICKED mode, start counting to clickHoldDetectTime
if (clickMode == CLICK_MODE.CLICKED)
{
clickCounter += Time.deltaTime; //Increment counter
//Check if we have reached the clickHoldDetectTime time
if (clickCounter > clickHoldDetectTime)
{
//Reset Counter
clickCounter = 0;
//Change the mode to CLICK_AND_HELD
clickMode = CLICK_MODE.CLICK_AND_HELD;
}
}
//If STILL down and the the current mode is CLICK_AND_HELD then do clickedAndHeldDown stuff
if (clickMode == CLICK_MODE.CLICK_AND_HELD)
{
clickedAndHeldDown();
}
}
else
{
//If released and the current mode is CLICKED then do clicked stuff
if (clickMode == CLICK_MODE.CLICKED)
{
clicked();
}
//If released and the current mode is CLICK_AND_HELD, change to RELEASED then do relased stuff
if (clickMode == CLICK_MODE.CLICK_AND_HELD)
{
//Change the mode to RELEASED
clickMode = CLICK_MODE.RELEASED;
mouseReleasedAfterBeingHeld();
}
//Reset each time mouse button is released
reset();
}
}
IEnumerator mover()
{
while (true)
{
if (moveDir == MOVE_DIRECTION.IDLE)
{
}
//Move Forward
if (moveDir == MOVE_DIRECTION.FORWARD)
{
transform.position += myCam.transform.forward * speed * Time.deltaTime;
}
//Move Backward
if (moveDir == MOVE_DIRECTION.BACKWARD)
{
transform.position -= myCam.transform.forward * speed * Time.deltaTime;
}
yield return null;
}
}
private void clicked()
{
Debug.Log("CLICKED");
//If Idle, become Forward
if (moveDir == MOVE_DIRECTION.IDLE)
{
moveDir = MOVE_DIRECTION.FORWARD;
}
//If forward, moves become idle
else if (moveDir == MOVE_DIRECTION.FORWARD)
{
moveDir = MOVE_DIRECTION.IDLE;
}
//--------------------------------------------------
//If backward, moves become idle
else if (moveDir == MOVE_DIRECTION.BACKWARD)
{
moveDir = MOVE_DIRECTION.IDLE;
}
}
private void clickedAndHeldDown()
{
Debug.Log("CLICKED AND HELD");
//If Idle, becomes backward
if (moveDir == MOVE_DIRECTION.IDLE)
{
moveDir = MOVE_DIRECTION.BACKWARD;
}
}
//Called when released after being RELEASED from CLICKED_HELD
private void mouseReleasedAfterBeingHeld()
{
Debug.Log("RELEASED AFTER CLICKED AND HELD");
//If backward, move becomes idle
if (moveDir == MOVE_DIRECTION.BACKWARD)
{
moveDir = MOVE_DIRECTION.IDLE;
}
//--------------------------------------------------
//If forward, move becomes idle
else if (moveDir == MOVE_DIRECTION.FORWARD)
{
moveDir = MOVE_DIRECTION.IDLE;
}
}
void reset()
{
clickMode = CLICK_MODE.NO_CLICK;
clickCounter = 0;
}
}
public enum CLICK_MODE
{
NO_CLICK, CLICKED, CLICK_AND_HELD, RELEASED
}
public enum MOVE_DIRECTION
{
IDLE, FORWARD, BACKWARD
}
Because you only have one trigger action you're going to have to implement something time based for toggling forward/backwards movement. For example, if you press and release the trigger quickly then forward walk could be toggled, but if you're holding the trigger after N length of time then walk backwards.
He's a practical example to get you starting.
Pressing and releasing the trigger within 300ms will toggle forward movement
Pressing and holding the trigger for longer than 300ms will begin backwards movement, releasing the trigger then will stop backwards movement
This is a theoretical example
public float speed = 1.0f;
bool triggerPressed = false;
float triggerHeldTime = 0f;
public bool movingForwards = false;
public bool movingBackwards = false;
void Update ()
{
// increment hold time if we're still holding trigger
if (Input.GetMouseButton(0) && triggerPressed)
triggerHeldTime += Time.deltaTime;
if (Input.GetMouseButton(0) && !triggerPressed)
{
// reset everything when trigger initially pressed
movingForards = false;
movingBackwards = false;
triggerHeldTime = 0f;
triggerPressed = true;
}
else if (!Input.GetMouseButton(0) && triggerPressed)
{
// upon trigger release
triggerPressed = false;
// if we are not moving backwards, toggle forwards movement
if(!movingBackwards)
movingForwards = !movingForwards;
// always reset backwards movement when we release the trigger
movingBackwards = false;
triggerHeldTime = 0f;
}
// if the trigger has been held for 300ms then move backwards
if(triggerHeldTime > 0.3f)
{
moveForwards = false;
moveBackwards = true;
}
// actually perform the movement
if (moveForwards)
{
transform.position += myCam.transform.forward * speed * Time.deltaTime;
}
else if(moveBackwards)
{
transform.position -= myCam.transform.forward * speed * Time.deltaTime;
}
}
I want to switch my skybox from a day material to a night material for this I use :
Material night;
int skyboxflag = 0;
int flag = 0;
float t;
public float smooth = 1;
void Start () {
night = Resources.LoadAll("Night_mat",typeof(Material))[0] as Material;
}
void Update () {
if (skyboxflag == 1) {
if(flag == 0){
t = Time.time;
flag = 1;
}
RenderSettings.skybox.Lerp(RenderSettings.skybox, night,(Time.time - t)/smooth);
if(Time.time - t > smooth){
skyboxflag = 0;
}
}
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.name == "Avatar") {
skyboxflag = 1;
}
}
but nothing happens I keep having the day skybox.
what is the correct way to change the skybox smoothly from a material to another
Thank you