Fade in and out complex GameObject in Unity [duplicate] - unity3d

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.

Related

Change hand IK over time instead of it just snapping to 0 and 1

I'm trying to get my characters rig to go from hand IK 0 to 1 over a period of time instead of just snapping to it. How could I go about doing that?
public TwoBoneIKConstraint rightHandIK; //on animator manager script // getting hand IK from inspector so can change weight
public TwoBoneIKConstraint leftHandIK; //on animator manager script
if (animatorManager.isAimingGunn)
{
animatorManager.leftHandIK.weight = 1;
animatorManager.rightHandIK.weight = 1;
horizontalMovementInput = 0f;
verticalMovementInput = 0f;
}
else if(animatorManager.isAimingGunn == false)
{
animatorManager.rightHandIK.weight = 0;
animatorManager.leftHandIK.weight = 0;
}
For this purpose you need to run a Tweener. This is a basic float Tweener that smoothly changes the floats by running Coroutine.
public IEnumerator DoTween(Func<float> getter , Action<float> setter, float targetValue, float duringTime = 1f)
{
var progress = 0f;
var init = getter();
while (progress < 1)
{
progress += Time.deltaTime/duringTime;
setter.Invoke(Mathf.Lerp(init, targetValue, progress));
yield return new WaitForEndOfFrame();
}
}
Do this to run Tweener in if code, Also, to zero the weight only, set zero in the targetValue parameter:
// How to run tweener?
// for E.G set IK weight to 1 during 2 seconds
StartCoroutine(DoTween(
() => animatorManager.leftHandIK.weight,
x => animatorManager.leftHandIK.weight = x,
1f, 2f
));
Also, if you want to create similar effects in the code, it suggests using the great DoTween unity plug-in.

Unity 2D Camera Zooms in when character moves, but properties of the camera do not change

After I click play the camera stays as it should be, but when I move my character the camera zooms in for no reason
The properties of the camera do not change at all, zoom and everything stays the same. Tryed changing from orthographic to perspective no change, move z axis no change, change scale no change, change resolution and no change, making the camera not a parent and no change it behaves the same as parent and as child
before character walks
after character walks
I dont think that there is something to do with the code but here is the code attached to my character, the camera behaves the same as child and as parent
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement : MonoBehaviour
{
public float speed = 5f;
public float jumpSpeed = 8f;
private float movementX = 0f;
private Rigidbody2D rigidBody;
public Transform groundCheckPoint;
public float groundCheckRadius;
public LayerMask groundLayer;
public bool isTouchingGround;
public SpriteRenderer box;
private bool canSpawn = true;
private bool canAnimateWalk = true;
private bool canAnimateIdle = true;
private bool canAnimateJump = true;
private bool stopJump = true;
private int spawningSpeed = 1000;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
isTouchingGround = Physics2D.OverlapBox(groundCheckPoint.position,new Vector2(0.9f,0.1f),0f, groundLayer);
movementX = Input.GetAxis("Horizontal");
if (movementX > 0f)
{
if(canAnimateWalk==true && isTouchingGround)
{
canAnimateWalk = false;
StartCoroutine(AnimateWalk());
}
GetComponent<SpriteRenderer>().transform.localScale = new Vector3(2, 2, 1);
rigidBody.velocity = new Vector2(movementX * speed, rigidBody.velocity.y);
}
else if (movementX < 0f)
{
if (canAnimateWalk == true && isTouchingGround)
{
canAnimateWalk = false;
StartCoroutine(AnimateWalk());
}
GetComponent<SpriteRenderer>().transform.localScale = new Vector3(-2, 2, 1);
rigidBody.velocity = new Vector2(movementX * speed, rigidBody.velocity.y);
}
else
{
if(isTouchingGround)
{
StopCoroutine(AnimateWalk());
if(canAnimateIdle==true)
{
canAnimateIdle = false;
StartCoroutine(AnimateIdle());
}
}
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
}
if (Input.GetButtonDown("Jump") && isTouchingGround)
{
canAnimateJump = false;
rigidBody.velocity = new Vector2(rigidBody.velocity.x, jumpSpeed);
StartCoroutine(AnimateJump());
}
else if(!isTouchingGround)
{
StopCoroutine(AnimateWalk());
}
}
IEnumerator AnimateJump()
{
Debug.Log("Animating Jump");
int counter = 0;
while (counter < 10)
{
counter++;
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/j" + counter);
yield return new WaitForSeconds(0.1f);
if(isTouchingGround==true)
{
break;
}
}
while(!isTouchingGround)
{
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/j10");
yield return new WaitForSeconds(0.1f);
}
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/i1");
canAnimateWalk = true;
canAnimateJump = true;
}
IEnumerator AnimateIdle()
{
int counter = 0;
while(Input.GetAxis("Horizontal")==0 && counter <10 && rigidBody.velocity.y==0)
{
counter++;
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/i"+counter);
yield return new WaitForSeconds(0.2f);
}
canAnimateIdle = true;
}
IEnumerator AnimateWalk()
{
int counter = 0;
while (Input.GetAxis("Horizontal")!=0 && counter < 8 && rigidBody.velocity.y==0)
{
counter++;
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/g" + counter);
yield return new WaitForSeconds(0.08f);
}
canAnimateWalk = true;
}
}
What could it be? I tried everything I think
GetComponent<SpriteRenderer>().transform.localScale = new Vector3(-2, 2, 1);
If your movement script is attached to your "guy" gameobject, then you are changing the (local) scale of it. All children will also scale accordingly.
Since your camera is a child of guy, it will scale and produce the result you see.
Try unparenting the Camera from your guy and create a seperate script that follows your guy and attach that to your Camera.
I solved my problem
The issue was in the character scaling. The camera did not change but the size of the character did making me believe that there was a zoom in.
My character x and y scale is 1 and 1 but I used 2 and 2 scale on move
The scale was used to rotate my character when it moves left and right

Unity-I can't seem to lerp my GameObject's Color

I'm just trying to make an observer pattern program one object randomly changes color and causes a group of other objects to change the same color, but I wanted them to gradually change over 5 seconds. I'm trying lerp, but it just instantly swaps colors. I think it maybe has something to do with the lerp's starting color, because the main object is constantly shifting colors and new colors become old colors. So I need to think of how choose a starting color for the lerp. I'm not sure if this has to do with my the lerp isn't working, but it's what I'm considering. If anyone else has any suggestions, I would appreciate it. Thank you.
public class Subject : MonoBehaviour {
public float timer = 0.0f;
public GameObject[] observers;
float t = 0;
Color oldColor;
void Update () {
t += Time.deltaTime / 5.0f;
timer += Time.deltaTime;
if (timer >= 10f) {
Color newColor = new Color(Random.value, Random.value, Random.value, 1.0f);
GetComponent<Renderer>().material.color = newColor;
for (int i = 0; i < observers.Length; i++) {
observers[i].GetComponent<Renderer>().material.color = Color.Lerp(oldColor, newColor, t);
}
newColor=oldColor
timer = 0;
}
}
}
What Color.Lerp(Color a, Color b, float t) does is
Linearly interpolates between colors a and b by t
For example, Color.Lerp(Color.blue, Color.red, 0.5f) returns a half way interpolation between blue and red.
When you say Color.Lerp(oldColor, newColor, 5) it will return newColor, because
t is clamped between 0 and 1. When t is 0 returns a. When t is 1
returns b.
So 5 is the same thing as putting in 1.
So you will need to keep a t variable somewhere that starts at 0 and increments up to 1, you put into Lerp.
For example:
float t = 0;
private void Update()
{
t += Time.deltaTime / 5.0f; // Divided by 5 to make it 5 seconds.
this.GetComponent<Renderer>().color = Color.Lerp(oldColor, newColor, t);
}
https://docs.unity3d.com/ScriptReference/Color.Lerp.html
EDIT
Also whats happening in your code, assuming you reset t when timer hit
Timer >= 10.0f
Lerp once
Reset timer to 0
.
What you could do instead is something like this (i took out the observers and stuff just to make it easier to see)
float t, timer;
bool lerping = false;
Color newColor;
void Update()
{
t += Time.deltaTime / 5.0f;
timer += Time.deltaTime;
if (timer >= 10f)
{
lerping = true;
t = 0;
newColor = new Color(Random.value, Random.value, Random.value, 1.0f);
Debug.Log("Lerping!");
timer = 0;
}
if (lerping)
{
GetComponent<Renderer>().material.color = Color.Lerp(oldColor, newColor, t);
if (t >= 1.0f)
{
lerping = false;
Debug.Log("Stopped lerping");
}
}
}

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;
}
}

scaling issue on click event

I am developing a 2D game in Unity. I've created a character panel in that to let player select different character. In panel, there are thumbnails for different character. By tapping on a particular character thumbnail, the player can view that character. The original scale of thumbnail is 1, and when player taps on thumbnail, the scale get doubles. All is fine till this. but issue is that whenever player taps on thumbnail its scale gets double. But i want to limit it to once only. I've used flag to stop scaling, But still issue is there. After flag it stops scaling, but now player can click on multiple character simultaneously. I am copying snippet here.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class ViewCharacter : MonoBehaviour {
[SerializeField]
private GameObject TempCharacterHolder ,TempCharacter, TempCharacterText, TempCharacterPrice;
// Use this for initialization
void Start () {
for (int i = 0; i < ShoppingManager.instance.ShoppingList.Count; i++) {
if (i == TheGameController.instance.GetSelectedCharacter ()) {
PlayerPrefs.SetInt ("CharacterScaled" + i, 1);
} else {
PlayerPrefs.SetInt ("CharacterScaled" + i, 0);
}
}
}
public void ViewCharacterFunc()
{
int ClickedCharacter = int.Parse (TempCharacterText.GetComponent<Text> ().text);
foreach (var characters in ShoppingManager.instance.ShoppingList) {
if (string.Equals (characters.CharacterName, TempCharacterText.GetComponent<Text> ().text)) {
if (PlayerPrefs.GetInt("CharacterScaled"+characters.CharacterName)==0) {
ShoppingManager.instance.IncreaseScale (TempCharacter, TempCharacterHolder);
for (int i = 0; i < ShoppingManager.instance.ShoppingList.Count; i++) {
if (i == ClickedCharacter) {
PlayerPrefs.SetInt ("CharacterScaled" + i, 1);
} else {
PlayerPrefs.SetInt ("CharacterScaled" + i, 0);
}
}
}
} else {
Color clr = characters.Character_Holder.GetComponent<Image> ().color;
clr.a = 1;
characters.Character_Holder.GetComponent<Image> ().color = clr;
Vector3 TempVector = characters.CharaacterObject.GetComponent<RectTransform> ().localScale;
TempVector.x = 1f;
TempVector.y = 1f;
characters.CharaacterObject.GetComponent<RectTransform> ().localScale = TempVector;
}
}
}
}
If I understand your question correctly, your characters scale numerous times when you click on them instead of scaling once.
If that's the case, I'd suggest controlling that with a bool:
bool hasTouched = false;
void OnMouseDown()
{
ShoppingManager.instance.Message.SetActive (false);
foreach (var characters in ShoppingManager.instance.ShoppingList) {
Color clr = characters.Character_Holder.GetComponent<Image> ().color;
clr.a = 1;
characters.Character_Holder.GetComponent<Image> ().color = clr;
if (!hasTouched) //if we havent touched
{
Vector3 TempVector = characters.CharaacterObject.GetComponent<RectTransform> ().localScale*Time.deltaTime;
TempVector.x = 1.0f;
TempVector.y = 1.0f;
characters.CharaacterObject.GetComponent<RectTransform> ().localScale = TempVector;
hasTouched = true; //then we scale it, and we have touched it
}
}