- Home /
how to use yield in c# (translated from js)
I am having problems with yield in c# I have code in jscript which I need in c# so I started to translate everything but am stuck with yield....
I left the yield expressions as tehy were in the jscript only as notes like this: //yield
this is the c# code:
using UnityEngine;
using System.Collections;
public class Block : MonoBehaviour
{
string[] block;
private bool[,] blockMatrix;
private float fallSpeed;
private int yPosition;
private int xPosition;
private int size;
private float halfSizeFloat;
private bool dropped = false;
// Use this for initialization
void Start()
{
// Sanity checking
size = block.Length;
int width = block[0].Length;
if (size < 2)
{
Debug.LogError("Blocks must have at least two lines");
return;
}
if (width != size)
{
Debug.LogError("Block width and height must be the same");
return;
}
if (size > Manager.use.maxBlockSize)
{
Debug.LogError("Blocks must not be larger than " + Manager.use.maxBlockSize);
return;
}
for (int i = 1; i < size; i++)
{
if (block[i].Length != block[i - 1].Length)
{
Debug.LogError("All lines in the block must be the same length");
return;
}
}
halfSizeFloat = size * 0.5f; // halfSize is an integer for the array, but we need a float for positioning the on-screen cubes (for odd sizes)
// Convert block string array from the inspector to a boolean 2D array for easier usage
blockMatrix = new bool[size, size];
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
if (block[y][x] == "1"[0])
{
blockMatrix[x, y] = true;
Transform block2 = Instantiate(Manager.use.cube, new Vector3((float)(x - halfSizeFloat), size - y + (float)(halfSizeFloat - size), 0.0f), Quaternion.identity) as Transform;
block2.parent = transform;
}
}
}
// For blocks with even sizes, we just add 0, but odd sizes need .5 added to the position to work right
Vector3 pos = transform.position;
pos.x = Manager.use.FieldWidth() * 0.5f + (size % 2 == 0 ? 0.0f : 0.5f);
transform.position = pos;
xPosition = (int)(transform.position.x - halfSizeFloat);
Debug.Log("xPosition1 = " + xPosition);
yPosition = (int)(Manager.use.FieldHeight() - 1);
pos = transform.position;
pos.y = (float)(yPosition - halfSizeFloat);
transform.position = pos;
fallSpeed = Manager.use.blockNormalSpeed;
// Check to see if this block would overlap existing blocks, in which case the game is over
if (Manager.use.CheckBlock(blockMatrix, xPosition, yPosition))
{
Manager.use.GameOver();
return;
}
CheckInput();
//yield;
Delay((1.0f / Manager.use.blockNormalSpeed) * 2.0f);
Fall();
}
// This is used instead of WaitForSeconds, so that the delay can be cut short if player hits the drop button
public void Delay(float time)
{
float t = 0.0f;
while (t <= time && !dropped)
{
t += Time.deltaTime;
//yield;
}
}
public void Fall()
{
while (true)
{
// Check to see if block would collide if moved down one row
yPosition--;
if (Manager.use.CheckBlock(blockMatrix, xPosition, yPosition))
{
Manager.use.SetBlock(blockMatrix, xPosition, yPosition + 1);
Destroy(gameObject);
break;
}
// Make on-screen block fall down 1 square
// Also serves as a delay...if you want old-fashioned square-by-square movement, replace this with yield WaitForSeconds
for (float i = yPosition + 1; i > yPosition; i -= Time.deltaTime * fallSpeed)
{
Vector3 pos = transform.position;
pos.y = i - halfSizeFloat;
transform.position = pos;
// yield;
}
}
}
public void CheckInput()
{
while (true)
{
float input = Input.GetAxis("Horizontal");
if (input < 0.0)
{
//yield;
MoveHorizontal(-1);
}
else if (input > 0.0)
{
//yield
MoveHorizontal(1);
}
if (Input.GetButtonDown("Rotate"))
{
RotateBlock();
}
if (Input.GetButtonDown("Drop"))
{
fallSpeed = Manager.use.blockDropSpeed;
dropped = true;
break; // Break out of while loop, so the coroutine stops (we don't care about input anymore)
}
//yield;
}
}
public void MoveHorizontal(int dir)
{
// Check to see if block could be moved in the desired direction
if (!Manager.use.CheckBlock(blockMatrix, xPosition + dir, yPosition))
{
Vector3 pos = transform.position;
pos.x += dir;
transform.position = pos;
xPosition += dir;
//yield
// WaitForSeconds (Manager.use.blockMoveDelay);
}
}
public void RotateBlock()
{
// Rotate matrix 90° to the right and store the results in a temporary matrix
bool[,] tempMatrix = new bool[size, size];
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
tempMatrix[y, x] = blockMatrix[x, (size - 1) - y];
}
}
// If the rotated block doesn't overlap existing blocks, copy the rotated matrix back and rotate on-screen block to match
if (!Manager.use.CheckBlock(tempMatrix, xPosition, yPosition))
{
System.Array.Copy(tempMatrix, blockMatrix, size * size);
transform.Rotate(Vector3.forward * -90.0f);
}
}
// Update is called once per frame
void Update () {
}
}
Comment
Answer by uta · Dec 27, 2013 at 07:17 PM
this is what I tried but it doesn;t work:
using UnityEngine;
using System.Collections;
public class Block : MonoBehaviour
{
public string[] block;
private bool[,] blockMatrix;
private float fallSpeed;
private int yPosition;
private int xPosition;
private int size;
private float halfSizeFloat;
private bool dropped = false;
// Use this for initialization
void Start()
{
// Sanity checking
size = block.Length;
int width = block[0].Length;
if (size < 2)
{
Debug.LogError("Blocks must have at least two lines");
return;
}
if (width != size)
{
Debug.LogError("Block width and height must be the same");
return;
}
if (size > Manager.use.maxBlockSize)
{
Debug.LogError("Blocks must not be larger than " + Manager.use.maxBlockSize);
return;
}
for (int i = 1; i < size; i++)
{
if (block[i].Length != block[i - 1].Length)
{
Debug.LogError("All lines in the block must be the same length");
return;
}
}
halfSizeFloat = size * 0.5f; // halfSize is an integer for the array, but we need a float for positioning the on-screen cubes (for odd sizes)
// Convert block string array from the inspector to a boolean 2D array for easier usage
blockMatrix = new bool[size, size];
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
if (block[y][x] == "1"[0])
{
blockMatrix[x, y] = true;
Transform block2 = Instantiate(Manager.use.cube, new Vector3((float)(x - halfSizeFloat), size - y + (float)(halfSizeFloat - size), 0.0f), Quaternion.identity) as Transform;
block2.parent = transform;
}
}
}
// For blocks with even sizes, we just add 0, but odd sizes need .5 added to the position to work right
Vector3 pos = transform.position;
pos.x = Manager.use.FieldWidth() * 0.5f + (size % 2 == 0 ? 0.0f : 0.5f);
transform.position = pos;
xPosition = (int)(transform.position.x - halfSizeFloat);
Debug.Log("xPosition1 = " + xPosition);
yPosition = (int)(Manager.use.FieldHeight() - 1);
pos = transform.position;
pos.y = (float)(yPosition - halfSizeFloat);
transform.position = pos;
fallSpeed = Manager.use.blockNormalSpeed;
// Check to see if this block would overlap existing blocks, in which case the game is over
if (Manager.use.CheckBlock(blockMatrix, xPosition, yPosition))
{
Manager.use.GameOver();
return;
}
CheckInput();
//yield
StartCoroutine(Delay((1.0f / Manager.use.blockNormalSpeed) * 2.0f));
Fall();
}
// This is used instead of WaitForSeconds, so that the delay can be cut short if player hits the drop button
//public void Delay(float time)
public IEnumerator Delay(float time)
{
float t = 0.0f;
while (t <= time && !dropped)
{
t += Time.deltaTime;
yield return new WaitForSeconds(5);
}
}
// public void Fall()
public IEnumerator Fall()
{
while (true)
{
// Check to see if block would collide if moved down one row
yPosition--;
if (Manager.use.CheckBlock(blockMatrix, xPosition, yPosition))
{
Manager.use.SetBlock(blockMatrix, xPosition, yPosition + 1);
Destroy(gameObject);
break;
}
// Make on-screen block fall down 1 square
// Also serves as a delay...if you want old-fashioned square-by-square movement, replace this with yield WaitForSeconds
for (float i = yPosition + 1; i > yPosition; i -= Time.deltaTime * fallSpeed)
{
Vector3 pos = transform.position;
pos.y = i - halfSizeFloat;
transform.position = pos;
// yield;
yield return new WaitForSeconds(5);
}
}
}
public IEnumerator yield()
{ yield return new WaitForSeconds(5); }
public IEnumerator CheckInput()
{
while (true)
{
float input = Input.GetAxis("Horizontal");
if (input < 0.0)
{
//yield
yield();
MoveHorizontal(-1);
}
else if (input > 0.0)
{
//yield
yield();
MoveHorizontal(1);
}
if (Input.GetButtonDown("Rotate"))
{
RotateBlock();
}
if (Input.GetButtonDown("Drop"))
{
fallSpeed = Manager.use.blockDropSpeed;
dropped = true;
break; // Break out of while loop, so the coroutine stops (we don't care about input anymore)
}
yield return new WaitForSeconds(5);
}
}
public void MoveHorizontal(int dir)
{
// Check to see if block could be moved in the desired direction
if (!Manager.use.CheckBlock(blockMatrix, xPosition + dir, yPosition))
{
Vector3 pos = transform.position;
pos.x += dir;
transform.position = pos;
xPosition += dir;
//yield
new WaitForSeconds (Manager.use.blockMoveDelay);
}
}
public void RotateBlock()
{
// Rotate matrix 90° to the right and store the results in a temporary matrix
bool[,] tempMatrix = new bool[size, size];
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
tempMatrix[y, x] = blockMatrix[x, (size - 1) - y];
}
}
// If the rotated block doesn't overlap existing blocks, copy the rotated matrix back and rotate on-screen block to match
if (!Manager.use.CheckBlock(tempMatrix, xPosition, yPosition))
{
System.Array.Copy(tempMatrix, blockMatrix, size * size);
transform.Rotate(Vector3.forward * -90.0f);
}
}
// Update is called once per frame
void Update () {
}
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How to translate code with yield waitforseconds to c#? 1 Answer
Trouble Resuming after Yielding while Inside Coroutine 1 Answer