How to I transition from "Start Game" page to playing the actual game? - boolean

var start = true; // the game will begin on the "start" screen
var play = false;
var gameOver = false;
clickX = 0; // track the mouse click location
clickY = 0;
function setup() {
createCanvas(640, 480);
}
function draw() {
//Leave this draw() function alone
if (start){
startScreen();
}
else if (play){
playScreen();
}
else if (gameOver){
gameOverScreen();
}
}
function mousePressed(){
clickX = mouseX; // grab the X location of the mouse
clickY = mouseY; // grab the Y location of the mouse
}
function startScreen(){
background(50);
textSize(20);
fill(255, 0, 0);
text('To begin playing, click mouse',60,80);
if(dist(clickX, clickY, width/2, height/2) < 100){
}
}
function playScreen(){
}
function gameOverScreen(){
}
My teacher said "add some branching logic to the mousePressed() function so that mouse clicks will change the canvas from one screen to the next. Think about how to use if() and else if() statements and those boolean "flag" variables at the top of the sketch (8 points)."
I am trying to create code that will switch the starting screen to the actual game! I'd like to do it so that when you click your
I've been looking everywhere and can't find anything helpful :( So if you have any references I can check out, I will take those too! Thank you!

to manage that state I would recommend you a switch statemen where you can iterate it using a variable with the scenario name:
let scenario ; // the game will begin on the "start" screen and will change to play or gameOver according the needs
function setup() {
createCanvas(640, 480);
scenario = 'playing'
}
function draw() {
startScreen()
text(scenario,width/2,height /2);
}
function mousePressed(){
// Here you can add different check according to each scenario
switch(scenario){
case 'start':
if(dist(mouseX, mouseY, 60, 80) < 100){
scenario = 'playing'
}
break;
case 'playing':
if(dist(mouseX, mouseY, 60, 80) < 100){
scenario = 'gameOver'
}
break;
case 'gameOver':
if(dist(mouseX, mouseY, 60, 80) < 100){
scenario = 'start'
}
break;
}
}
function startScreen(){
switch(scenario){
case 'start':
background(50);
textSize(20);
fill(255, 0, 0);
text('To begin playing, click mouse',60,80);
break;
case 'playing':
background(200,0,0);
textSize(20);
fill(255, 0, 0);
text('Click to continue to GameOver',60,80);
break;
case 'gameOver':
background(0,255,0);
textSize(20);
fill(255, 0, 0);
text('Click to go to start',60,80);
break;
}
}

Related

Collider triggers firing on launch

I have a "zone", with four borders; north, east, south and west. On these borders, I have 2d colliders, like this :
So, on a zone, I would have four instances of this, for each border. In the script for GridBorderController, I have this :
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == Const.TAG_PLAYER)
{
print("enter " + gridBorderSide.ToString());
/*var pos = new Vector3(20, 20, 0);
var zoneInstance = Instantiate(this, pos, Quaternion.identity, this.transform);
var tileMaker = zoneInstance.transform.GetChild(0);
var terrainDrawer = tileMaker.GetComponent<TerrainDrawer>();
print(terrainDrawer.sprites.Length);*/
}
}
When I launch the game, I create an instance of this zone, and this is what I get in my console :
This is how I start the controller :
void Start()
{
boxCollider2D = GetComponent<BoxCollider2D>();
terrainDrawer = GetComponentInParent<TerrainDrawer>();
collider = GetComponent<Collider2D>();
collider.enabled = false;
var gridRadius = terrainDrawer.gridRadius;
float borderOffset = borderWidth / 2;
switch (gridBorderSide)
{
case GridBorderSide.North:
case GridBorderSide.South:
{
boxCollider2D.size = new Vector2(gridRadius/2 , borderWidth);
if(gridBorderSide == GridBorderSide.North)
{
boxCollider2D.transform.position += new Vector3(0, (gridRadius / 4) - (borderOffset));
}
else
{
boxCollider2D.transform.position -= new Vector3(0, (gridRadius / 4) - (borderOffset));
}
break;
}
case GridBorderSide.East:
case GridBorderSide.West:
{
boxCollider2D.size = new Vector2(borderWidth, gridRadius / 2);
if (gridBorderSide == GridBorderSide.East)
{
boxCollider2D.transform.position += new Vector3((gridRadius / 4) - (borderOffset), 0 );
}
else
{
boxCollider2D.transform.position -= new Vector3((gridRadius / 4) - (borderOffset), 0);
}
break;
}
}
collider.enabled = true;
}
When I walk over the collider with my player, it does fire as well, so I know that part works, but can anyone explain the me why the triggers fire immediately on launch?

How to fix this unity 2d sidescroller movement/animation problem

So I am creating my first game in unity and I am currently working on the left to right movement.
I move to the left, let go of the left arrow button -> idle animation.
Press right arrow and character moves to right, let go -> idle.
The problem is I have to wait for the idle animation before I can press to go to the other direction chosen. When I press left and same time right the character does not move.
What I would like to do is fe:
press left -> character goes left, and then
press right at the same time -> character goes right.
So the need to be able to press buttons at the same time, and the last key pressed dictates the movement/animation.
Animation code:
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
this.GetComponent<Animator>().SetInteger("pallotila", 1);
}
if (Input.GetKeyUp(KeyCode.LeftArrow))
{
this.GetComponent<Animator>().SetInteger("pallotila", 0);
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
this.GetComponent<Animator>().SetInteger("pallotila", 2);
}
if (Input.GetKeyUp(KeyCode.RightArrow))
{
this.GetComponent<Animator>().SetInteger("pallotila", 0);
}
Player movement code:
if (Input.GetKey(KeyCode.LeftArrow))
{
this.transform.position += Vector3.left * this.nopeus * Time.deltaTime;
this.transform.rotation = this.vasemmalle;
}
if (Input.GetKey(KeyCode.RightArrow))
{
this.transform.position += Vector3.right * this.nopeus * Time.deltaTime;
this.transform.rotation = this.oikealle;
}
Note that you should never use GetComponent in Update better do it once and reuse the reference.
//Here you store the Animator reference
private Animator animator;
private void Awake()
{
animator = GetComponent<Animator>();
}
I'ld also use a switch to define what should happen for which button in order to avoid having the same code over and over again.
private void SetLastPressed(KeyCode code)
{
int value = 0;
switch (code)
{
case KeyCode.None:
value = 0;
break;
case KeyCode.LeftArrow:
value = 1;
break;
case KeyCode.RightArrow:
value = 2;
break;
}
animator.SetInteger("pallotila", value);
lastPressed = code;
}
Simply store and check which button pressed last and make the Input checks exclusive using if-else.
// Here you store the last pressed key
private KeyCode lastPressed = KeyCode.None;
private void Update()
{
if (lastPressed != KeyCode.LeftArrow && Input.GetKeyDown(KeyCode.LeftArrow))
{
SetLastPressed(KeyCode.LeftArrow);
}
else if (lastPressed != KeyCode.RightArrow && Input.GetKeyDown(KeyCode.RightArrow))
{
SetLastPressed(KeyCode.RightArrow);
}
// If none of the keys is pressed reset
else if (lastPressed != KeyCode.None && !Input.GetKey(KeyCode.LeftArrow) && !Input.GetKey(KeyCode.RightArrow))
{
SetLastPressed(KeyCode.None);
}
// And if only one of them is released but the other one still pressed
//go on using that still pressed key again
else if (lastPressed != KeyCode.LeftArrow && Input.GetKeyUp(KeyCode.RightArrow) &&
Input.GetKey(KeyCode.LeftArrow))
{
SetLastPressed(KeyCode.LeftArrow);
}
else if (lastPressed != KeyCode.RightArrow && Input.GetKeyUp(KeyCode.LeftArrow) &&
Input.GetKey(KeyCode.RightArrow))
{
SetLastPressed(KeyCode.RightArrow);
}
For the movement you could simply reuse the lastPresses value than as well
if(lastPressed == KeyCode.LeftArrow)
{
transform.position += Vector3.left * nopeus * Time.deltaTime;
transform.rotation = vasemmalle;
}
else if (lastPressed == KeyCode.RightArrow)
{
transform.position += Vector3.right * nopeus * Time.deltaTime;
transform.rotation = oikealle;
}
Additionally you could/should use a List<KeyCode> to store the last presses. Everytime a button goes down add the button to the end of the list; everytime a button goes up remove it from the list
result => the last pressed button is always the last one in the list.
This makes the return to a previous button way more simple and flexible without adding/changing so much lines of code like
private List<KeyCode> lastPresses = new List<KeyCode>();
private KeyCode lastPressed = KeyCode.None;
private Animator animator;
private void Awake()
{
animator = GetComponent<Animator>();
}
private void SetLastPressed(KeyCode code)
{
int value = 0;
switch (code)
{
case KeyCode.None:
value = 0;
break;
case KeyCode.LeftArrow:
value = 1;
break;
case KeyCode.RightArrow:
value = 2;
break;
}
animator.SetInteger("pallotila", value);
lastPressed = code;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
if (!lastPresses.Contains(KeyCode.LeftArrow)) lastPresses.Add(KeyCode.LeftArrow);
}
else if (Input.GetKeyUp(KeyCode.LeftArrow))
{
if (lastPresses.Contains(KeyCode.LeftArrow)) lastPresses.Remove(KeyCode.LeftArrow);
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
if (!lastPresses.Contains(KeyCode.RightArrow)) lastPresses.Add(KeyCode.RightArrow);
}
else if (Input.GetKeyUp(KeyCode.RightArrow))
{
if (lastPresses.Contains(KeyCode.RightArrow)) lastPresses.Remove(KeyCode.RightArrow);
}
var currentCode = lastPresses.Count > 0 ? lastPresses[lastPresses.Count - 1] : KeyCode.None;
if (currentCode != lastPressed) SetLastPressed(currentCode);
if (lastPressed == KeyCode.LeftArrow)
{
transform.position += Vector3.left * nopeus * Time.deltaTime;
transform.rotation = vasemmalle;
}
else if (lastPressed == KeyCode.RightArrow)
{
transform.position += Vector3.right * nopeus * Time.deltaTime;
transform.rotation = oikealle;
}
}
You can change the "Value" Variable to
animator.SetInteger("pallotila", 0);
break;
in the location of
value = 0;
break;
or change
int value;
to
int value = 0;
in the code by #derHugo

Fade in and out complex GameObject in Unity [duplicate]

I'm fairly new to coding, I'm still trying to develop that logic of thinking to help me create the solutions I'm wanting for games. Currently, I'm in Unity trying to create a 2D GameObject that's a wall hiding a secret door. I want that GameObject to fade out (about 90%) when the player GameObject triggers it, revealing the space behind and the hidden door.
So far, I've managed to figure out how to render the "secret wall" GO inactive on the trigger, so it disappears, but this doesn't produce the visual that I'm going for. As I said, I'm still working on developing that coder's way of thinking, so while I've done a lot of research to solve this problem, many of the results I don't readily understand.
Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SecretDoor1 : MonoBehaviour {
void OnTriggerEnter2D (Collider2D SecretDoorTrig) {
if (SecretDoorTrig.gameObject.tag == "Player") {
GetComponent<SpriteRenderer> ().enabled = false;
}
else {
GetComponent<SpriteRenderer> ().enabled = true;
}
}
void OnTriggerExit2D (Collider2D SecretDoorTrig) {
if (SecretDoorTrig.gameObject.tag == "Player") {
GetComponent<SpriteRenderer> ().enabled = true;
}
else {
GetComponent<SpriteRenderer> ().enabled = false;
}
}
}
Fading a Sprite is almost the-same as moving GameObject over time except that you modify its alpha instead of it's position.
The three most important stuff about fading an Object are Time.deltaTime, Mathf.Lerp/Color.Lerp and coroutine. You need to understand how these work together.
Start coroutine, use Time.deltaTime to increment a variable. That variable is used to use to determine how much that function has ran. In a for/while loop, use that variable that is incremented every-frame and the duration you want the fade to happen to generate the alpha with the help of the Mathf.Lerp function. Create new color with that alpha and and assign it to the Sprite.
This is done every frame until that variable that is incremented with Time.deltaTime reaches the duration you want to the fade to happen within.
Here is a simple SpriteRenderer fade function:
public SpriteRenderer spriteToFade;
IEnumerator fadeOut(SpriteRenderer MyRenderer, float duration)
{
float counter = 0;
//Get current color
Color spriteColor = MyRenderer.material.color;
while (counter < duration)
{
counter += Time.deltaTime;
//Fade from 1 to 0
float alpha = Mathf.Lerp(1, 0, counter / duration);
Debug.Log(alpha);
//Change alpha only
MyRenderer.color = new Color(spriteColor.r, spriteColor.g, spriteColor.b, alpha);
//Wait for a frame
yield return null;
}
}
If you want it to fade in, change Mathf.Lerp(1, 0, counter / duration); to Mathf.Lerp(0, 1, counter / duration); which will make the alpha go from 0 to 1 over-time instead of 1 to 0.
From the example above, writing a fade-out and fade-in functions only requires a way to tell the function to change the alpha from 1 to 0 or from 0 to 1. You can make the function use a boolean or enum variable to determine which type of fade to perform. Of-course, you can separate the fade-in/fade-out functions but it's good to have it in one function.
Here is the extended version of that function that supports fade-in and fade-out. It also supports almost all GameObjects like MeshRenderer(3D), SpriteRenderer(2D), Image, RawImage....You can extend it to support more components that's missing.
IEnumerator fadeInAndOut(GameObject objectToFade, bool fadeIn, float duration)
{
float counter = 0f;
//Set Values depending on if fadeIn or fadeOut
float a, b;
if (fadeIn)
{
a = 0;
b = 1;
}
else
{
a = 1;
b = 0;
}
int mode = 0;
Color currentColor = Color.clear;
SpriteRenderer tempSPRenderer = objectToFade.GetComponent<SpriteRenderer>();
Image tempImage = objectToFade.GetComponent<Image>();
RawImage tempRawImage = objectToFade.GetComponent<RawImage>();
MeshRenderer tempRenderer = objectToFade.GetComponent<MeshRenderer>();
Text tempText = objectToFade.GetComponent<Text>();
//Check if this is a Sprite
if (tempSPRenderer != null)
{
currentColor = tempSPRenderer.color;
mode = 0;
}
//Check if Image
else if (tempImage != null)
{
currentColor = tempImage.color;
mode = 1;
}
//Check if RawImage
else if (tempRawImage != null)
{
currentColor = tempRawImage.color;
mode = 2;
}
//Check if Text
else if (tempText != null)
{
currentColor = tempText.color;
mode = 3;
}
//Check if 3D Object
else if (tempRenderer != null)
{
currentColor = tempRenderer.material.color;
mode = 4;
//ENABLE FADE Mode on the material if not done already
tempRenderer.material.SetFloat("_Mode", 2);
tempRenderer.material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
tempRenderer.material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
tempRenderer.material.SetInt("_ZWrite", 0);
tempRenderer.material.DisableKeyword("_ALPHATEST_ON");
tempRenderer.material.EnableKeyword("_ALPHABLEND_ON");
tempRenderer.material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
tempRenderer.material.renderQueue = 3000;
}
else
{
yield break;
}
while (counter < duration)
{
counter += Time.deltaTime;
float alpha = Mathf.Lerp(a, b, counter / duration);
switch (mode)
{
case 0:
tempSPRenderer.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
case 1:
tempImage.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
case 2:
tempRawImage.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
case 3:
tempText.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
case 4:
tempRenderer.material.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
}
yield return null;
}
}
Usage:
GameObject to fade:
public GameObject SpriteRend;
Fade-out in 3 seconds
StartCoroutine(fadeInAndOut(SpriteRend, false, 3f));
Fade-in in 3 seconds
StartCoroutine(fadeInAndOut(SpriteRend, true, 3f));
The way I have accomplished this has been change the alpha on the sprite color.
Color(R,G,B,A). A is the alpha.
SpriteRenderer.color = new Color(1f,1f,1f,1f) is opaque.
SpriteRenderer.color = new Color(1f,1f,1f,.5f) is about 50%
transparent.
SpriteRenderer.color = new Color(1f,1f,1f,0f) is about
100% transparent, sprite cannot be seen.

Unity - GetKeyDown and GetKey using the same KeyCode to get a delay on input if held down

I an trying to get the user input do two different behaviors with the same input key.
like this :
if (Input.GetKeyDown(KeyCode.D) || Input.GetKey(KeyCode.D))
Making a tetris game: The goal is, tapping "D" once, I want tetromino to move one world unit per tap. AND when holding down the same key "D" I want the block to move right continuously until it reaches the edge of the game board, without having to tap.
This sort of works with the code above but, the problem I have is that tapping once moves 2 or 3 world unit instead of once because there is no delay before unity realizes that I am holding the key down.
I would like unity to wait .5 seconds before activating "Input.GetKey(KeyCode.D)" so that I can keep the behavior "Input.GetKeyDown(KeyCode.D)"
Bottom line,
I want to be able to tap "D" to move one world unit per tap
I want the block to move continuously right until it reaches the edge of the game board if I hold down "D" but, only after holding it down for .5 seconds
How can I do this ?
Full code for the Tetromino.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Tetromino : MonoBehaviour {
//#####################################################################################################
//#####################################################################################################
float fallTimer = 0f; // timer counting the seconds to check if mino needs to fall
public float fallSpeed = 1f; // variable to determine how fast the mino needs to fall
public bool allowRotation = true;
public bool limitRotation = false;
//#####################################################################################################
//#####################################################################################################
// Use this for initialization
void Start () {
}
//#####################################################################################################
//#####################################################################################################
// Update is called once per frame
void Update ()
{
CheckUserInput(); // --------------------------- // Checks the user input every frames
FallBehavior(); // checks if the block needs to fall and increments the timer
}
//#####################################################################################################
//#####################################################################################################
void CheckUserInput()
{
if (Input.GetKeyDown(KeyCode.D)) // moves the mino to the right
{
transform.position += new Vector3(1,0,0);
if (CheckIsValidPosition()) // if minos is not in a valid position, the transform pushes the minos
{ // back to the left, to keep it inside the grid
}
else
{
transform.position += new Vector3(-1, 0, 0); // this counters the first attempt to move
}
}
else if (Input.GetKeyDown(KeyCode.A)) // moves the mino to the left
{
transform.position += new Vector3(-1, 0, 0);
if (CheckIsValidPosition())
{
}
else
{
transform.position += new Vector3(1, 0, 0);
}
}
else if (Input.GetKeyDown(KeyCode.W)) // rotates the mino
{
if (allowRotation)
{
if (limitRotation) //limited rotation ON, to prevent rotating outside the grid
{ // after the tetromino landed at the bottom
if (transform.rotation.eulerAngles.z >= 90)
{
transform.Rotate(0, 0, -90);
}
else
{
transform.Rotate(0, 0, 90);
}
}
else
{
transform.Rotate(0, 0, 90); // 90 degrees rotation on the mino
}
if (CheckIsValidPosition())
{
}
else
{
if (limitRotation)
{
if (transform.rotation.eulerAngles.z >= 90)
{
transform.Rotate(0, 0, -90);
}
else
{
transform.Rotate(0, 0, 90);
}
}
else
{
transform.Rotate(0, 0, -90);
}
}
}
}
else if (Input.GetKeyDown(KeyCode.S))
{
transform.position += new Vector3(0, -1, 0); // makes the mino go down when pressing
if (CheckIsValidPosition())
{
}
else
{
transform.position += new Vector3(0, 1, 0);
}
}
}
//#####################################################################################################
//#####################################################################################################
/// <summary>
/// Makes the block fall by 1 unit and checks how fast it needs to fall
/// </summary>
void FallBehavior()
{
if (Time.time - fallTimer >= fallSpeed) // on the first frame, Time.time = 0 & fallTimer = 0
// so 0 - 0 = 0, is it >= then fallSpeed = 1? no
// so the if statement does not exectute, block dont fall
// after 1 sec, Time.time = 1 & fallTimer = 0
// so 1 - 0 = 1, is it >= then fallSpeed = 1? yes
// so block falls after 1 sec, because we increment it
// in the if statment also
{
transform.position += new Vector3(0, -1, 0); // moves the mino down
fallTimer = Time.time; // Time.time check the time since game started and is assigned
} // to fallTimer so that the timer updates every frame
// when called in the Update method. fallTimer = 0, 1, 2, 3 ...
if (CheckIsValidPosition()) // also helps checking if the Y is invalid, which tells the game to spawn
{ // the next tetromino when Y is less <= to the bottom of the grid
}
else
{
transform.position += new Vector3(0, 1, 0);
enabled = false; // disables the current piece, because it is at the bottom. So that the controls are not still
// attached to the current piece, after the next one spawned
FindObjectOfType<Game>().SpawnNextTetromino(); // spawns the next tetromino after the last one reached the bottom
}
}
//#####################################################################################################
//#####################################################################################################
/// <summary>
/// check the position of the individual tiles of the minos (children of the prefab)
/
/// </summary>
/// <returns></returns>
bool CheckIsValidPosition()
{
foreach (Transform mino in transform)
{
Vector2 pos = FindObjectOfType<Game>().RoundingTheMinoPosition (mino.position);
if (FindObjectOfType<Game>().CheckIsInsideGrid(pos) == false)
{
return false;
}
}
return true;
}
}
Full code of Game.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Game : MonoBehaviour {
public static int gridWidth = 10; // fixed grid size varibles
public static int gridHeight = 20; // for the blocks to fall in
// the grid need to be in a 2d array and we want to store all the x and y values for each world unit of the grid
// so that we can know which point on the grid are beind occupied by tetrominos that fell in.
//
// the array is gonna store the transforms so we use "gridWidth" and "gridHeight" to define the size of the array.
public static Transform[,] grid = new Transform[gridWidth, gridHeight];
// Use this for initialization
void Start () {
SpawnNextTetromino(); // spawns the first tetromino in the game
}
// Update is called once per frame
void Update () {
}
public void SpawnNextTetromino() // the Resources folder is included when the game compiles, we placed our prefabs
{ // in "Assets\Resources\Prefabs" to allow instantiation in the code.
// we cast a gameobject -> "(GameObject)" to let "Instantiate" know what we want to instantiate.
GameObject nextTetromino = (GameObject)Instantiate(Resources.Load(GetRandomTetromino(), typeof(GameObject)), new Vector2(5.0f, 20.0f), Quaternion.identity);
}
//gonna pass in the mino position in this method to see
// if it is still in the grid
public bool CheckIsInsideGrid(Vector2 pos)
{
return ((int)pos.x >= 0 && (int)pos.x < gridWidth && (int)pos.y >= 0);
}
public Vector2 RoundingTheMinoPosition(Vector2 pos)
{
return new Vector2(Mathf.Round(pos.x), Mathf.Round(pos.y));
}
/// <summary>
/// Genreates a random int and assings a teromino prefab to the outcome
/// </summary>
/// <returns></returns>
string GetRandomTetromino()
{
int randomTetromino = Random.Range(1, 8); //
string randomTetrominoName = null;
switch (randomTetromino)
{
case 1:
randomTetrominoName = "Prefabs/Tetromino_T";
break;
case 2:
randomTetrominoName = "Prefabs/Tetromino_Long";
break;
case 3:
randomTetrominoName = "Prefabs/Tetromino_Square";
break;
case 4:
randomTetrominoName = "Prefabs/Tetromino_J";
break;
case 5:
randomTetrominoName = "Prefabs/Tetromino_L";
break;
case 6:
randomTetrominoName = "Prefabs/Tetromino_S";
break;
case 7:
randomTetrominoName = "Prefabs/Tetromino_Z";
break;
}
return randomTetrominoName;
}
}
Looks like I misunderstood the original question. You want to move on "D" key press only but move until your you have reached the Edge when the the "D" key is held down.You need a timer when the the key is held down and this can be done with Time.deltaTime. Check while the key is held down with Input.GetKey, and if the timer reaches the amount of value you think makes it a held down, then you know the key is held down.
Also, check when the key is released with Input.GetKeyUp(KeyCode.D). If the key is released but timer has not reached the value you think makes it a held down,then it's simply a key press. It's worth doing this in a coroutine function instead of the Update function to simplify it and also reduce the amount of variables required to do it.
const float timeToCountAsHeldDown = 0.3f;
float pressTimer = 0;
IEnumerator moveChecker()
{
while (true)
{
//Check when the D key is pressed
if (Input.GetKeyDown(KeyCode.D))
{
//Continue to check if it is still heldown and keep counting the how long
while (Input.GetKey(KeyCode.D))
{
//Start incrementing timer
pressTimer += Time.deltaTime;
//Check if this counts as being "Held Down"
if (pressTimer > timeToCountAsHeldDown)
{
//It a "key held down", call the OnKeyHeldDown function and wait for it to return
yield return OnKeyHeldDown();
//No need to continue checking for Input.GetKey(KeyCode.D). Break out of this whule loop
break;
}
//Wait for a frame
yield return null;
}
}
//Check if "D" key is released
if (Input.GetKeyUp(KeyCode.D))
{
//Check if we have not not reached the timer then it is only a key press
if (pressTimer < timeToCountAsHeldDown)
{
//It just a key press, call the OnKeyPressedOnly function and wait for it to return
yield return OnKeyPressedOnly();
}
//Reset timer to 0 for the next key press
pressTimer = 0f;
}
//Wait for a frame
yield return null;
}
}
IEnumerator OnKeyPressedOnly()
{
Debug.Log("D key was only Pressed");
//Move 1 unit only
transform.position += new Vector3(1, 0, 0);
yield return null;
}
IEnumerator OnKeyHeldDown()
{
Debug.LogWarning("D key is Held Down");
//Don't move for 0.5 seconds
yield return new WaitForSeconds(0.5f);
//Move 1 unit every frame until edge detection is reached!
while (!CheckIsValidPosition())
{
transform.position += new Vector3(1, 0, 0);
//Wait for a frame
yield return null;
}
}

how do I hide a button on unity

I want to create a button that when you press it, a new button will open. I know how to make both buttons, but I can't manage to hide the first button once clicked.
This is my code so far:
#pragma strict
function Start ()
{
}
function Update ()
{
}
var isButtonVisible : boolean = true;
var buttonRectangle : Rect = Rect(100, 100, 100, 50);
function OnGUI ()
{
var NewButton = GUI.Button(Rect (Screen.width / 2 - 75, Screen.height / 2 -25,150,50), "this is also a button");
if ( isButtonVisible )
{
if ( GUI.Button(Rect (Screen.width / 2 - 75, Screen.height / 2 -25,150,50), "button") )
{
isButtonVisible = false;
if ( isButtonVisible )
{
return NewButton;
}
}
}
}
I am new to programing so this question might be a bit unclear.
I agree with "Happy Apple's" solution, and just to expand on this if you wanted to integrate reverse functionality you can simply alter the code as follows:
var isButtonVisible : boolean = true;
var buttonRectangle : Rect = Rect(100, 100, 100, 50);
function OnGUI ()
{
if(isButtonVisible)
{
if(GUI.Button(Rect(Screen.width/2 - 75,Screen.height/2 - 25,150,50),"button"))
{
isButtonVisible = false;
}
}
else
{
if(GUI.Button(Rect(Screen.width/2 - 75,Screen.height/2 -25,150,50),"this is also a button"))
{
isButtonVisible = true;
}
}
}
Hope this is helpful.
It was just a logic error. Firstly you're checking if ( isButtonVisible ) inside another if ( isButtonVisible ) bracket, which is redundant. Secondly if we know the condition we want for the second button to appear (first button being clicked) and the boolean flag for said button being clicked (isButtonVisible == false) we can just branch the isButtonVisible condition to display the second button when this is false.
Assuming you wanted a first button to make another one appear and hide itself on click, this should do what you wanted (though it will only logically flow one way, that is the first button will hide itself and show the second button, but not reversable). So your original code was pretty close.
var isButtonVisible : boolean = true;
var buttonRectangle : Rect = Rect(100, 100, 100, 50);
function OnGUI ()
{
if ( isButtonVisible )
{
if ( GUI.Button(Rect (Screen.width / 2 - 125, Screen.height / 2 -175,150,50), "button") )
{
isButtonVisible = false;
}
}
else
{
var NewButton = GUI.Button(Rect (Screen.width / 2 - 75, Screen.height / 2 -25,150,50), "this is also a button");
}
}
Admittedly there's several better ways to implement this but I hope it solved your problem.