I need help with trajectory prediction on mobile.
I'm able to do that on PC using the mouse, but I'm not able to do that with touch functions on mobile.
I've the dot that I copy on the start, and while I'm dragging the ball I want to calculate my trajectory.
After touch will end I will destroy these dots.
As I said I'm able to do it using Input.GetMouseButton/Up/Down but I'm not able to do that using touch function.
Here is my code:
private void Update()
{
//if (Input.touchCount > 0)
//{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
startPosition = Input.GetTouch(0).position;
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
}
}
if (Input.touchCount > 0)
{
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
}
if (touch.phase == TouchPhase.Ended)
{
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
endPoisiton = Input.GetTouch(0).position;
force = startPosition - endPoisiton;
ballRigid.gravityScale = 1;
ballRigid.velocity = new Vector2(force.x * power, force.y * power);
}
//}
}
private Vector2 calculatePosition(float elapsedTime)
{
return new Vector2(endPoisiton.x, endPoisiton.y) +
new Vector2(force.x * power, force.y * power) * elapsedTime +
0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}
The code I used for mouse input
if (Input.GetMouseButtonDown(0))
{ //click
startPos = gameObject.transform.position;
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
}
}
if (Input.GetMouseButton(0))
{ //drag
endPos = Camera.main.ScreenToWorldPoint(Input.mousePosition) + new Vector3(0, 0, 10);
gameObject.transform.position = endPos;
forceAtPlayer = endPos - startPos;
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
}
if (Input.GetMouseButtonUp(0))
{ //leave
rigidbody.gravityScale = 1;
rigidbody.velocity = new Vector2(-forceAtPlayer.x * forceFactor, -forceAtPlayer.y * forceFactor);
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
}
So after little changes it's much better, I' am getting closer to what i want there are still some glitches i guess because of touch.moved so when I' am on display with my finger and do only little moves ball is jumping on the screen
Here is the code
private void Update()
{
if (Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
switch (touch.phase)
{
case TouchPhase.Began:
initPosition = gameObject.transform.position;
startPosition = cam.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Moved:
endPosition = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
gameObject.transform.position = initPosition;
force = startPosition - endPosition;
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Ended:
ballRigid.gravityScale = 1;
ballRigid.velocity = new Vector2(force.x * power, force.y * power);
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
break;
}
}
}
private Vector2 calculatePosition(float elapsedTime)
{
return new Vector2(initPosition.x, initPosition.y) +
new Vector2(force.x * power, force.y * power) * elapsedTime +
0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}
Ok i have final soution and it's working correctly
private void Update()
{
if (Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
switch (touch.phase)
{
case TouchPhase.Began:
initPosition = gameObject.transform.position;
startPosition = cam.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Ended:
ballRigid.gravityScale = 1;
ballRigid.velocity = new Vector2(force.x * power, force.y * power);
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
break;
}
endPosition = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
gameObject.transform.position = initPosition;
force = startPosition - endPosition;
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
}
}
private Vector2 calculatePosition(float elapsedTime)
{
return new Vector2(initPosition.x, initPosition.y) +
new Vector2(force.x * power, force.y * power) * elapsedTime +
0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}
So just taking your mouse code and convert it to touch code it might look like
if(Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
switch(touch.phase)
{
case TouchPhase.Began:
// Note: to be more accurate you actually probably would
// rather also here use ScreenToWorldPoint on the touch.position
// same way as later. Otherwise you might allways get a force even if touch wasn't moved at all
//startPos = transform.position;
startPos = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Moved:
// These were missing in your touch version
// You did it only in the end so there were no preview trajectory
// And note that also touch is in pixel screenspace so if you
// want to use world positions you need to convert them just the same as for mouse input!
endPos = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
transform.position = endPos;
force = endPos - startPos;
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Ended:
rigidbody.gravityScale = 1;
// Not sure why but in your mouse code you used a negative force here
// but in this case your trajectory would have been wrong since there you didn't use negative values...
rigidbody.velocity = force * forceFactor;
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
break;
}
}
Btw the calculate method gets better to read like
private Vector2 calculatePosition(float elapsedTime)
{
return endPoisiton
+ force * power * elapsedTime
+ Physics2D.gravity * 0.5f * elapsedTime * elapsedTime;
}
Note: Typed on smartphone but I hope the idea gets clear
Related
I'm making a total war demo game where you drag on the screen to move your units. This bug has been bothering me and I don't know what's the reason behind it. The error I get is below.
FormationScript.cs(119,44): error CS1503: Argument 1: cannot convert from 'UnityEngine.Vector3' to 'System.Collections.Generic.List<UnityEngine.Vector3>'
Here is the code. (sorry for its length)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Debug = UnityEngine.Debug;
public class FormationScript : MonoBehaviour
{
public GameObject[] units;
public Transform formationBarrier;
float unitWidth = 2.0f; // This also includes the gap between them, in this case the unit width is 1 and the gap is also 1
private float numberOfUnits;
private double unitsPerRow;
private float numberOfRows;
Vector3 startClick;
Vector3 endClick;
Vector3 selectedAreaSize;
Vector3 selectedAreaPos;
float startMinusEndX;
float startMinusEndZ;
private List<List<Vector3>> availablePositions;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Formation();
}
void Formation()
{
if (Input.GetMouseButtonDown(1))
{
Plane plane = new Plane(Vector3.up, 0);
float distance;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (plane.Raycast(ray, out distance))
{
startClick = ray.GetPoint(distance);
}
Debug.Log(startClick);
}
if (Input.GetMouseButtonUp(1))
{
Plane plane = new Plane(Vector3.up, 0);
float distance;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (plane.Raycast(ray, out distance))
{
endClick = ray.GetPoint(distance);
}
Debug.Log(endClick);
}
// ======================================================================================================
/*if (startClick.x - endClick.x < 0 || startClick.z - endClick.z < 0)
{
startMinusEndX = startClick.x + endClick.x;
startMinusEndZ = startClick.z + endClick.z;
}
else
{
startMinusEndX = startClick.x - endClick.x;
startMinusEndZ = startClick.z - endClick.z;
}
if (startMinusEndX > 0 && startMinusEndZ > 0)
{
formationBarrier.localScale = new Vector3(startMinusEndX, 1, startMinusEndZ);
formationBarrier.localPosition = new Vector3((startClick.x + endClick.z) / 2, 0, (startClick.z + endClick.z) / 2);
}
else if (startMinusEndX < 0 && startMinusEndZ > 0)
{
formationBarrier.localScale = new Vector3(startMinusEndX, 1, startMinusEndZ);
formationBarrier.localPosition = new Vector3((startClick.x + endClick.z) * 2, 0, (startClick.z + endClick.z) / 2);
}
*/
startMinusEndX = startClick.x - endClick.x;
startMinusEndZ = startClick.z - endClick.z;
formationBarrier.localScale = new Vector3(startMinusEndX, 1, startMinusEndZ);
formationBarrier.localPosition = new Vector3((startClick.x + endClick.z) / 2, 0, (startClick.z + endClick.z) / 2);
// ======================================================================================================
selectedAreaSize = formationBarrier.localScale;
selectedAreaPos = formationBarrier.localPosition;
numberOfUnits = units.Length;
unitsPerRow = (unitWidth / numberOfUnits) * selectedAreaSize.x;
unitsPerRow = Math.Round(unitsPerRow, 0);
if (unitsPerRow < 0)
{
unitsPerRow = unitsPerRow * -2;
}
if (numberOfRows % 1 == 0)
{
numberOfRows = numberOfUnits % (float)unitsPerRow;
for (int i = 0; i > numberOfRows; i++) // i is the number of rows
{
//availablePositions.Add(i);
for (int j = 0; j > numberOfUnits / unitsPerRow; j++) // j is the number of units / the units per row
{
Vector3 pos = new Vector3((selectedAreaPos.x / ((float)unitsPerRow + 1)) + ((j - 1) * (selectedAreaPos.x / ((float)unitsPerRow + 1))), 0.0f, i * 2);
availablePositions.Add(pos); // Heres where the error's coming from
}
}
}
else if (numberOfUnits % (float)unitsPerRow != 0)
{
numberOfRows = numberOfUnits % (float)unitsPerRow;
}
Debug.Log(unitsPerRow);
Debug.Log(numberOfRows);
}
}
I am pretty new to Unity so go easy : )
There is a syntax error in your code. You are inserting pos which is of type Vector3 into availablePositions, which is a List of List of Vecotr3.
Either change availablePositions definition:
private List<Vector3> availablePositions;
or convert pos to list before adding to availablePositions:
availablePositions.Add(new List<Vector3>{pos});
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I was trying to translate something from C++ to C#, now the translation is completely done, however I'm getting an error when compiling that says index of array is out of bounds so I want to know if I declared the array properly.
[Entire Code]
using System;
using SFML.Graphics;
using SFML.Window;
using SFML.Audio;
using SFML.System;
namespace Pruebas_Algoritmia
{
class Program
{
const int num = 8;
static int[,] points = new int[num, 2] {{300, 610},
{ 1270, 430},
{1380,2380},
{1900,2460},
{1970,1700},
{2550,1680},
{2560,3150},
{500, 3300}};
public struct Car
{
public float x;
public float y;
public float speed;
public float angle;
public int n;
public Car(float speed,float angle, int n)
: this()
{
speed = 2;
angle = 0;
n = 0;
}
public void move()
{
x += MathF.Sin(angle) * speed;
y -= MathF.Cos(angle) * speed;
}
public void findTarget()
{
float tx = points[n, 0];
float ty = points[n, 1];
float beta = angle - MathF.Atan2(tx - x, -ty + y);
if (Math.Sin(beta) < 0)
{
angle += 0.005f * speed;
}
else
{
angle -= 0.005f * speed;
}
if ((x - tx) * (x - tx) + (y - ty) * (y - ty) < 25 * 25)
{
n = (n + 1) % num;
}
}
};
static void OnClose(object sender, EventArgs e)
{
RenderWindow window = (RenderWindow)sender;
window.Close();
}
static void Main(string[] args)
{
RenderWindow app = new RenderWindow(new VideoMode(640, 480), "Car Racing Game", Styles.Default);
app.SetFramerateLimit(60);
app.SetVerticalSyncEnabled(true);
app.DispatchEvents();
app.Clear();
Texture t1 = new Texture("c://images/background.png");
Texture t2 = new Texture("c://images/car.png");
t1.Smooth = true;
t2.Smooth = true;
Sprite sBackground = new Sprite(t1);
Sprite sCar = new Sprite(t2);
sBackground.Scale = new Vector2f(2, 2);
sCar.Origin = new Vector2f(22, 22);
float R = 22f;
const int N = 5;
Car[] car = new Car[N];
for (int i = 0; 0 < N; i++)
{
car[i].x = 300 + i * 50;
car[i].y = 1700 + i * 80;
car[i].speed = 7 + i;
}
float speed = 0f;
float angle = 0f;
float maxSpeed = 12.0f;
float acc = 0.2f;
float dec = 0.03f;
float turnSpeed = 0.08f;
float offsetX = 0;
float offsetY = 0;
while (app.IsOpen)
{
Event e;
app.Closed += new EventHandler(OnClose);
app.Display();
}
bool up = false;
bool down = false;
bool right = false;
bool left = false;
if (Keyboard.IsKeyPressed(Keyboard.Key.Up))
{
up = true;
}
if (Keyboard.IsKeyPressed(Keyboard.Key.Right))
{
right = true;
}
if (Keyboard.IsKeyPressed(Keyboard.Key.Down))
{
down = true;
}
if (Keyboard.IsKeyPressed(Keyboard.Key.Left))
{
left = true;
}
//movement
if (up && speed < maxSpeed)
{
if (speed < 0)
{
speed += dec;
}
else
{
speed -= acc;
}
}
if (down && speed >- maxSpeed)
{
if (speed > 0)
{
speed -= dec;
}
else
{
speed -= acc;
}
}
if (!up && !down)
{
if (speed - dec > 0)
{
speed -= dec;
}
else if(speed + dec < 0)
{
speed += dec;
}
else
{
speed = 0;
}
}
if (right && speed != 0)
{
angle += turnSpeed * speed / maxSpeed;
}
if (left && speed != 0)
{
angle -= turnSpeed * speed / maxSpeed;
}
car[0].speed = speed;
car[0].angle = angle;
for (int i = 0; i < N; ++i)
{
car[i].move();
}
for (int i = 0; i < N; ++i)
{
car[i].findTarget();
}
for (int i = 0; i < N; ++i)
{
for(int j = 0; i < N; ++j)
{
float dx = 0;
float dy = 0;
while (dx * dx + dy * dy < 4 * R * R)
{
car[i].x += dx / 10.0f;
car[i].x += dy / 10.0f;
car[j].x += dx / 10.0f;
car[j].x += dy / 10.0f;
dx = car[i].x - car[j].x;
dy = car[i].y - car[j].y;
}
}
}
app.Clear(Color.White);
if (car[0].x > 320) offsetX = car[0].x - 320;
if (car[0].y > 240) offsetY = car[0].y - 240;
//sBackground
sBackground.Position = new Vector2f(-offsetX, -offsetY);
app.Draw(sBackground);
Color[] colors = new Color[] { Color.Red, Color.Green, Color.Magenta, Color.Blue, Color.White};
for (int i = 0; i < N; ++i)
{
sCar.Position = new Vector2f(car[i].x - offsetX, car[i].y - offsetY);
sCar.Rotation = car[i].angle * 180 / 3.141593f;
sCar.Color = colors[i];
app.Draw(sCar);
}
app.Display();
}
}
}
I'm getting the error around line 88 where I have this.
const int N = 5;
Car[] car = new Car[N];
for (int i = 0; 0 < N; i++)
{
car[i].x = 300 + i * 50;
car[i].y = 1700 + i * 80;
car[i].speed = 7 + i;
}
Originally this looked like this in C++
const int N=5;
Car car[N];
for(int i=0;i<N;i++)
{
car[i].x=300+i*50;
car[i].y=1700+i*80;
car[i].speed=7+i;
}
The error I get literally says the index is out of bounds, also I'm getting an exception after this for loop saying that there's unreachable code for every line below the loop
You made a typo in your C# code. You wrote 0 < N instead of i < N.
So I have an object that user can rotate with touch. If needed, here is the script for it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpinWithTaps : MonoBehaviour {
float lastX;
public float xDifference;
public float xDecreaseSpeed;
int xDirection = 1;
float lastY;
public float yDifference;
public float yDecreaseSpeed;
int yDirection = 1;
void Update()
{
//turn in y Axis
if (Input.GetMouseButtonDown(0)) xDifference = 0;
else if (Input.GetMouseButton(0))
{
xDifference = Mathf.Abs((lastX - Input.GetAxis("Mouse X")) * 1.8f);
if (lastX < Input.GetAxis("Mouse X"))
{
xDirection = -1;
transform.Rotate(Vector3.up, -xDifference, relativeTo: Space.World);
}
if (lastX > Input.GetAxis("Mouse X"))
{
xDirection = 1;
transform.Rotate(Vector3.up, xDifference, relativeTo: Space.World);
}
lastX = -Input.GetAxis("Mouse X");
}
else
{
if (xDifference > 0)
{
if (xDifference > 20) xDecreaseSpeed = 0.3f;
else if (xDifference > 15) xDecreaseSpeed = 0.23f;
else if (xDifference > 10) xDecreaseSpeed = 0.16f;
else if (xDifference > 5) xDecreaseSpeed = 0.09f;
else xDecreaseSpeed = 0.02f;
xDifference -= xDecreaseSpeed;
if (xDifference < 0) xDifference = 0;
}
if (xDifference < 0)
{
if (xDifference < 20) xDecreaseSpeed = 0.3f;
else if (xDifference < 15) xDecreaseSpeed = 0.23f;
else if (xDifference < 10) xDecreaseSpeed = 0.16f;
else if (xDifference < 5) xDecreaseSpeed = 0.09f;
else xDecreaseSpeed = 0.02f;
xDifference += xDecreaseSpeed;
if (xDifference > 0) xDifference = 0;
}
transform.Rotate(Vector3.up, xDifference * xDirection, relativeTo: Space.World);
}
//turn in x Axis
if (Input.GetMouseButtonDown(0)) yDifference = 0;
else if (Input.GetMouseButton(0))
{
yDifference = Mathf.Abs((lastY - Input.GetAxis("Mouse Y")) * 1.8f);
if (lastY < Input.GetAxis("Mouse Y"))
{
yDirection = 1;
transform.Rotate(Vector3.right, yDifference, relativeTo: Space.World);
}
if (lastY > Input.GetAxis("Mouse Y"))
{
yDirection = -1;
transform.Rotate(Vector3.right, -yDifference, relativeTo: Space.World);
}
lastY = -Input.GetAxis("Mouse Y");
}
else
{
if (yDifference > 0)
{
if (yDifference > 20) yDecreaseSpeed = 0.3f;
else if (yDifference > 15) yDecreaseSpeed = 0.23f;
else if (yDifference > 10) yDecreaseSpeed = 0.16f;
else if (yDifference > 5) yDecreaseSpeed = 0.09f;
else yDecreaseSpeed = 0.02f;
yDifference -= yDecreaseSpeed;
if (yDifference < 0) yDifference = 0;
}
if (yDifference < 0)
{
if (yDifference < 20) yDecreaseSpeed = 0.3f;
else if (yDifference < 15) yDecreaseSpeed = 0.23f;
else if (yDifference < 10) yDecreaseSpeed = 0.16f;
else if (yDifference < 5) yDecreaseSpeed = 0.09f;
else yDecreaseSpeed = 0.02f;
yDifference += yDecreaseSpeed;
if (yDifference > 0) yDifference = 0;
}
transform.Rotate(Vector3.right, yDifference * yDirection, relativeTo: Space.World);
}
}
I want to do something when the gameObject has rotated let's say... 90 degrees in total. Like so:
if (totalRotated >= 90)
{
//do something
}
How do I find totalRotated? Thanks.
Edit: Or what if I wanted to do something when it rotates 480° in total? Is there any way?
You can rotate along the x, y, or z axis.
if (gameObject.transform.rotation.x == 90) // You might want to use >= to check if it is greater than 90 in this case
{
// do something
}
Haha, I actually found a relatively easy solution.
I added this line of code to my Update function:
totalRotated += (yDifference + xDifference);
(and I created a float named totalRotated) and it's working really well.
private void MoveToNewFormation()
{
squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
float step = speed * Time.deltaTime;
for (int i = 0; i < squadMembers.Length; i++)
{
squadMembers[i].transform.LookAt(newpos[i]);
squadMembers[i].transform.position = Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
//squadMembers[i].transform.rotation = qua[i];
}
}
And calling it in the Update:
void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
ChangeFormation();
}
if (move == true)
MoveToNewFormation();
}
Once when one of the squadMembers reached to the newpos then i want to make
squadMembers[i].transform.rotation = qua[i];
qua is a List and i want to rotate the squad member once he reached the newpos.
Inside MoveToNewFormation i thought to add after the loop the line:
if (squadMembers[i].transform.position == newpos[i])
{
squadMembers[i].transform.rotation = qua[i];
}
But it's after the loop so 'i' not exist.
This is the complete script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SquadFormation : MonoBehaviour
{
enum Formation
{
Square, Circle, Triangle
}
public Transform squadMemeber;
public int columns = 4;
public int squareSpace = 10;
public int circleSpace = 40;
public int numberOfObjects = 20;
public float yOffset = 0;
public float speed = 3;
private Formation formation;
private GameObject[] squadMembers;
private List<Quaternion> qua = new List<Quaternion>();
private List<Vector3> newpos = new List<Vector3>();
private bool move = false;
// Use this for initialization
void Start()
{
formation = Formation.Square;
ChangeFormation();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
ChangeFormation();
}
if (move == true)
MoveToNewFormation();
}
private void ChangeFormation()
{
switch (formation)
{
case Formation.Square:
FormationSquare();
break;
case Formation.Circle:
FormationCircle();
break;
}
}
private Vector3 FormationSquarePositionCalculation(int index) // call this func for all your objects
{
float posX = (index % columns) * squareSpace;
float posY = (index / columns) * squareSpace;
return new Vector3(posX, posY);
}
private void FormationSquare()
{
for (int i = 0; i < numberOfObjects; i++)
{
Transform go = Instantiate(squadMemeber);
Vector3 pos = FormationSquarePositionCalculation(i);
go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);
go.Rotate(new Vector3(0, -90, 0));
go.tag = "Squad Member";
}
formation = Formation.Circle;
}
private Vector3 FormationCirclePositionCalculation(Vector3 center, float radius, int index, float angleIncrement)
{
float ang = index * angleIncrement;
Vector3 pos;
pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
pos.y = center.y;
return pos;
}
private void FormationCircle()
{
Vector3 center = transform.position;
float radius = (float)circleSpace / 2;
float angleIncrement = 360 / (float)numberOfObjects;
for (int i = 0; i < numberOfObjects; i++)
{
Vector3 pos = FormationCirclePositionCalculation(center, radius, i, angleIncrement);
var rot = Quaternion.LookRotation(center - pos);
pos.y = Terrain.activeTerrain.SampleHeight(pos);
pos.y = pos.y + yOffset;
newpos.Add(pos);
qua.Add(rot);
}
move = true;
formation = Formation.Square;
}
private void MoveToNewFormation()
{
squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
float step = speed * Time.deltaTime;
for (int i = 0; i < squadMembers.Length; i++)
{
squadMembers[i].transform.LookAt(newpos[i]);
squadMembers[i].transform.position = Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
//squadMembers[i].transform.rotation = qua[i];
}
//if (squadMembers[i].transform.position == newpos[i])
}
}
You can use a threshold and check the distance using that threshold.
Define threshold like this at start of script.
public float threshold = 0.1f;
Then change the MoveToNewFormation() function like this:
private void MoveToNewFormation()
{
squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
float step = speed * Time.deltaTime;
for (int i = 0; i < squadMembers.Length; i++)
{
squadMembers[i].transform.LookAt(newpos[i]);
squadMembers[i].transform.position =
Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
if(Vector3.Distance(squadMembers[i].transform.position,newpos[i])<threshold){
squadMembers[i].transform.rotation = qua[i];
}
}
//if (squadMembers[i].transform.position == newpos[i])
}
I have made a game in unity which have multiple scenes of different level in which user have to select a colored block to go the next level but i want my code to be in a single scene is there a way i can convert my multi scene game into a single scene .
Code for level 1 grid base is
public IEnumerator Start() {
grid = new GameObject[ySize, xSize];
float x = xStart;
float y = yStart;
ScreenRandom = Random.Range(0, 3);
if (ScreenRandom == 0)
{
img.color = UnityEngine.Color.red;
text.text = "Select all the Red Objects";
yield return new WaitForSeconds(time);
Destroy(img);
Destroy(text);
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 1)
{
GameObject rblock = Instantiate(RedPrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountRed++;
}
else {
GameObject block = Instantiate(NonRedPrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
if (ScreenRandom == 1)
{
img.color = UnityEngine.Color.blue;
text.text = "Select all the Blue Objects";
yield return new WaitForSeconds(time);
Destroy(img);
Destroy(text);
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 1)
{
GameObject rblock = Instantiate(BluePrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountBlue++;
}
else {
GameObject block = Instantiate(NonBluePrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
if (ScreenRandom == 2)
{
img.color = UnityEngine.Color.yellow;
text.text = "Select all the Yellow Objects";
yield return new WaitForSeconds(time);
Destroy(img);
Destroy(text);
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 1)
{
GameObject rblock = Instantiate(YellowPrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountYellow++;
}
else {
GameObject block = Instantiate(NonYellowPrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
}
Code to check and Load Level 2 is:
void Update () {
screen = GridControl.ScreenRandom;
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (screen == 0)
{
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "BlueBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
if (hit.collider.tag == "RedBlock")
{
RedCount++;
Destroy(hit.transform.gameObject);
Correct++;
Score.text = " " + Correct;
if (RedCount == GridControl.CountRed)
{
print("Next Level");
Application.LoadLevel(3);
}
}
if (hit.collider.tag == "YellowBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
}
}
if (screen == 1)
{
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "BlueBlock")
{
BlueCount++;
Destroy(hit.transform.gameObject);
Correct++;
Score.text = " " + Correct;
if (BlueCount == GridControl.CountBlue)
{
print("Next Level");
Application.LoadLevel(3);
}
}
if (hit.collider.tag == "RedBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
if (hit.collider.tag == "YellowBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
}
}
if (screen == 2)
{
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "BlueBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
if (hit.collider.tag == "RedBlock")
{
Destroy(hit.transform.gameObject);
print("Game Over");
Application.LoadLevel(0);
}
if (hit.collider.tag == "YellowBlock")
{
YellowCount++;
Destroy(hit.transform.gameObject);
Correct++;
Score.text = " " + Correct;
if (YellowCount == GridControl.CountYellow)
{
print("Next Level");
Application.LoadLevel(3);
}
}
}
Code for Level 2 GridBase is;
public void Start()
{
grid = new GameObject[ySize, xSize];
ScreenRandom = GridControl.ScreenRandom;
float x = xStart;
float y = yStart;
if (ScreenRandom == 0)
{
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 2)
{
GameObject rblock = Instantiate(RedPrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountRed++;
}
else {
GameObject block = Instantiate(NonRedPrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
if (ScreenRandom == 1)
{
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 2)
{
GameObject rblock = Instantiate(BluePrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountBlue++;
}
else {
GameObject block = Instantiate(NonBluePrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
if (ScreenRandom == 2)
{
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 2)
{
GameObject rblock = Instantiate(YellowPrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountYellow++;
}
else {
GameObject block = Instantiate(NonYellowPrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
}
To start I don't know why would you do that. Technically that is the whole point of having scenes. But still what you could do is put everything (Level 1 and 2) in one scene and then position and disable whatever belongs to Level 2 outside the camera. Then instead of calling Application.LoadLevel I would call a function that will move everything that belongs to Level 1 out of the screen and at the same time moves Level 2 into the screen. If I where you I would group all the objects of one level as child of another GameObject (maybe called LevelX), that way it will be easier to move everything at once. This will even give you nice slide in transition between levels. If you don't want the transition just change the positions instantly.
Be carefull because depending on the amount of levels you could have serious performance issues.
You could use a prefab for the colored blocks and drag it into your different level scenes. If you now attach your behaviour script (managing what happens if a raycast hits it) to your prefab, all instances in all levels will have the same logic. That way you can reuse the same code base for different levels.