How can I move the transform randomly in ping pong? - c#

First I generate new objects in this example 1000 objects over the terrain in height 10 in random positions :
using System;
using UnityEngine;
using Random = UnityEngine.Random;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class CloneObjects : MonoBehaviour
{
public Terrain terrain;
public GameObject prefab;
public GameObject parent;
[Range(10, 1000)]
public int numberOfObjects;
public float yOffset = 10f;
private float terrainWidth;
private float terrainLength;
private float xTerrainPos;
private float zTerrainPos;
void Start()
{
//Get terrain size
terrainWidth = terrain.terrainData.size.x;
terrainLength = terrain.terrainData.size.z;
//Get terrain position
xTerrainPos = terrain.transform.position.x;
zTerrainPos = terrain.transform.position.z;
generateObjectOnTerrain();
}
void generateObjectOnTerrain()
{
for (int i = 0; i < numberOfObjects; i++)
{
//Generate random x,z,y position on the terrain
float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);
float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));
//Apply Offset if needed
yVal = yVal + yOffset;
//Generate the Prefab on the generated position
GameObject objInstance = Instantiate(prefab, new Vector3(randX, yVal, randZ), Quaternion.identity);
objInstance.name = "Waypoint";
objInstance.tag = "Waypoint";
objInstance.transform.parent = parent.transform;
}
}
}
The result is :
And then on each object there is a script attached :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveObject : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position = new Vector3(Mathf.PingPong(Time.time * 3, Random.Range(2f, 9f)), transform.position.y, transform.position.z);
}
}
The problem is that the objects are not moving in ping pong from the original spawned positions like in the screenshot on the top the first screenshot but they are all moving first to the edge of the terrain and making the ping pong there :

PingPong is a lot like Lerp. You need to supply a time value to it, not a delta time. As such, you'll want to store the initial object height, and work out how high you want to pingpong on top of that.
This example code will do just that:
public float Speed;
private float intitialY;
private float pingPongHeight;
private void Start ( )
{
intitialY = transform.localPosition.y;
pingPongHeight = UnityEngine.Random.Range ( 2f, 9f );
}
private void Update ( )
{
var height = Mathf.PingPong ( Time.time * Speed, pingPongHeight );
var position = transform.localPosition;
position.y = intitialY + height;
transform.localPosition = position;
}
I've assumed you used a random value to determine how high each object will travel over the course of the pingpong.

Related

Unity - The LineRender (visual) does not match the Positions of the LineRender

I'm trying to let an object follow a predicent path in Unity.
First I calculate the path in Circle.cs
Then I store the points in the LineRender component
I let an object follow the positions in Path.cs
The problem : The LineRender (visual) does not match the Positions of the LineRender. See : Screenshot Unity
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Path : MonoBehaviour
{
// The linerender path to follow
public LineRenderer path;
// The speed at which to follow the path
public float speed = 5.0f;
// The current position on the path
private int currentPosition = 0;
void Update()
{
// Get the current position and target position on the path
Vector3 currentWaypoint = path.GetPosition(currentPosition);
Vector3 targetWaypoint = path.GetPosition(currentPosition + 1);
// Move towards the target waypoint
transform.position = Vector3.MoveTowards(transform.position, targetWaypoint, speed * Time.deltaTime);
// If we have reached the target waypoint, move to the next one
if (transform.position == targetWaypoint)
{
currentPosition++;
// If we have reached the end of the path, start again from the beginning
if (currentPosition >= path.positionCount)
{
currentPosition = 0;
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Circle : MonoBehaviour
{
public float radius = 3;
// Start is called before the first frame update
private int numPoints = 100;
private Vector3[] positions;
void Start()
{
positions = new Vector3[numPoints];
float angleIncrement = (Mathf.PI / 2) / numPoints; // Quarter circle in radians
for (int i = 0; i < numPoints; i++)
{
float angle = angleIncrement * i;
float x = radius * Mathf.Cos(angle);
float y = radius * Mathf.Sin(angle);
positions[i] = new Vector3(x, 0, y);
}
this.GetComponent<LineRenderer>().positionCount = numPoints;
this.GetComponent<LineRenderer>().SetPositions(positions);
}
}
I tried to adjust the scale of the LineRender.
By default the positions of a LineRenderer component are based on world-spaced coordinates.
Thus, you have two options for a fix here:
Set the useWorldSpace attribute on the LineRenderer to false (either in code or in the inspector)
Add the offset to the points, before you add them to the LineRenderer

Why the transform is rotating 360 degrees even if I limit the rotation randomly between specific degrees ranges?

The guns is rotating 360 degrees and not between -40 and 0
This screenshot is the default before running the game the rotation on x is 0 :
and this screenshot is after I changed the guns x rotation value to -40
I want the guns to rotate up down between 0 and -40 but when I'm running the game the guns rotating 360 degrees.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MissleLauncherRotation : MonoBehaviour
{
public Transform body;
public Transform guns;
public Vector3 spinAxisBody;
public Vector3 spinAxisGuns;
public float timeToSpin = 5f;
public float spinSpeed = 20f;
public bool randomSpin = false;
private void Start()
{
StartCoroutine("Spin");
}
private void Update()
{
}
IEnumerator Spin()
{
float spinTimer;
while (true)
{
if (randomSpin == true)
{
spinAxisBody = new Vector3(0,Random.Range(-180, 180),0);
spinAxisGuns = new Vector3(Random.Range(-40, 0), 0, 0);
}
spinTimer = timeToSpin;
while (spinTimer > 0f)
{
body.transform.Rotate(spinAxisBody, Time.deltaTime * spinSpeed);
guns.Rotate(spinAxisGuns, Time.deltaTime * spinSpeed);
spinTimer -= Time.deltaTime;
yield return null;
}
}
}
}
I tried this :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MissleLauncherRotation : MonoBehaviour
{
public Transform body;
public Transform guns;
public Vector3 spinAxisBody;
public Vector3 spinAxisGuns;
public float timeToSpin = 5f;
public float spinSpeed = 20f;
public bool randomSpin = false;
Quaternion rot;
private void Start()
{
rot = guns.rotation;
}
private void Update()
{
guns.Rotate(guns.up, (spinSpeed * Time.deltaTime));
var rot = guns.rotation.eulerAngles;
rot = new Vector3
(
guns.eulerAngles.x,
Mathf.Clamp(rot.x, -40, 0),
guns.eulerAngles.z
);
guns.rotation = Quaternion.Euler(rot);
}
}
The only thing is working now is the clamping but the clamping is not only on the x and I want to use coroutine or somehow to make that it will rotate ever x seconds.
I did it this way to test the clamping if it's working at all now how do I use it with my first code ?
This script is attached to empty gameobject :
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class DronesManager : MonoBehaviour
{
public Transform dronesUnchild;
private List<GameObject> drones = new List<GameObject>();
private static System.Random rnd = new System.Random();
// Start is called before the first frame update
void Start()
{
StartCoroutine(MoveDrone());
}
// Update is called once per frame
void Update()
{
}
private IEnumerator MoveDrone()
{
// same as you did:
var drones = GameObject.FindGameObjectsWithTag("Drone").ToList();
while (drones.Count > 0)
{
// pick one at random, get it
int index = Random.Range(0, drones.Count);
var drone = drones[index];
// remove it from list
drones.RemoveAt(index);
// TODO: might want to check/guard if drone == null ... this guards against it
// being Destroy()ed and yet still lying around in our list marked as "dead"
// simplified your get-component-and-go-if-not-already-going code here
var droneControl = drone.GetComponent<DroneControl>();
if (droneControl.go == false)
{
droneControl.movingSpeed = 5f;
droneControl.go = true;
drone.transform.parent = dronesUnchild;
}
// wait
yield return new WaitForSeconds(0.3f);
}
}
}
And this script is attached to each drone object :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DroneControl : MonoBehaviour
{
public float movingSpeed;
public bool go = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(go)
{
transform.position -= transform.forward * movingSpeed * Time.deltaTime;
}
}
}
Maybe one of this scripts making the problem that it's freezing when trying to change values of variables in the script MissleLauncherRotation ?
As already mentioned Rotate adds a rotation to the current one.
I would rather precalculate the target rotation and use e.g.
public Transform body;
public Transform guns;
public Vector3 spinAxisBody;
public Vector3 spinAxisGuns;
public float timeToSpin = 5f;
public bool randomSpin = false;
// Yes, if you make Start return IEnumerator it is automatically run as a
// Coroutine by Unity without the need for extra code
IEnumerator Start()
{
while (true)
{
// This is the more convenient way of checking for a bool == true
if (randomSpin)
{
spinAxisBody = new Vector3(0,Random.Range(-180, 180),0);
spinAxisGuns = new Vector3(Random.Range(-40, 0), 0, 0);
}
else
{
// whatever you want to happen otherwise
}
// Pre cache/calculate the start and end rotations
// Rotate per default uses the LOCAL space so we will do the same and use localRotation
// But instead of adding to the existing rotation we will use it as a complete new rotation
var startBodyRotation = body.localRotation;
var targetBodyRotation = Quaternion.Euler(spinAxisBody);
var startGunsRotation = guns.localRotation;
var targetGunsRotation = Quaternion.Euler(spinAxisGuns);
// Basically same as the while loop but I prefer to use a for loop so I can't forget to increase the timer
// In my opinion this is simply better readable
for(var spinTimer = 0f; spinTimer < timeToSpin; spinTimer += Time.deltaTime)
{
// Factor linear moving from 0 to 1 within timeToSpin seconds
var factor = spinTimer / timeToSpin;
// optional add ease-in and -out
//factor = Mathf.SmoothStep(0, 1, factor);
// Interpolate linear (or with ease-in and -out) between the pre cached start and end rotations
body.transform.localRotation = Quaternion.Lerp(startBodyRotation, targetBodyRotation, factor);
guns.localRotation = Quaternion.Lerp(startGunsRotation, targetGunsRotation, factor);
yield return null;
}
// Just to be sure to end up with clean values
body.transform.localRotation = targetBodyRotation;
guns.localRotation = targetGunsRotation;
yield return null;
}
}

How do I set the boundaries of a 2d ortographic camera in unity to modify according to the screen size

Here is the script that I am using for the camera. Right now, I manually have to set the boundaries by positioning the camera where it looks like it's the limit of the border. There are a few problems though. If i change the aspect ratio of the viewport in Unity, the boundaries won't work as intended.
What I'm looking for is a way to
- see the maximum boundaries set(like an empty game objectt idk)
- see where the camera can move(in the inspector with Gizmos.DrawLine)
Basically i want a system that i can reuse for other scenes with different boundaries size and that adapts to the screen's size. Thanks in advance
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowTarget : MonoBehaviour
{
public GameObject target;
public Vector3 offset;
public float cameraSpeed;
private Vector3 velocity = Vector3.zero;
private Vector3 targetPosition;
public float leftLimit;
public float rightLimit;
public float topLimit;
public float botLimit;
// Start is called before the first frame update
void Start()
{
targetPosition = target.transform.position - offset;
}
void FixedUpdate() {
transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, cameraSpeed);
}
// Update is called once per frame
void Update()
{
float clampedX = Mathf.Clamp(transform.position.x, leftLimit, rightLimit);
float clampedY = Mathf.Clamp(transform.position.y, topLimit, botLimit);
targetPosition = target.transform.position - offset;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowTarget : MonoBehaviour
{
private Camera cam;
private BoxCollider2D cameraBox;
public BoxCollider2D boundary;
public Transform target;
private float leftPivot;
private float rightPivot;
private float topPivot;
private float botPivot;
void Start(){
cam = gameObject.GetComponent<Camera>();
cameraBox = cam.GetComponent<BoxCollider2D>();
}
void Update(){
AspectRatioBoxChange();
CalculateCameraPivot();
FollowPlayer();
}
void AspectRatioBoxChange(){
float height = 2f * cam.orthographicSize;
float width = height * cam.aspect;
cameraBox.size = new Vector2(width, height);
}
void CalculateCameraPivot(){
botPivot = boundary.bounds.min.y + cameraBox.size.y/2;
topPivot = boundary.bounds.max.y - cameraBox.size.y/2;
leftPivot = boundary.bounds.min.x + cameraBox.size.x/2;
rightPivot = boundary.bounds.max.x - cameraBox.size.x/2;
}
void FollowPlayer(){
transform.position = new Vector3(Mathf.Clamp(target.position.x, leftPivot, rightPivot),
Mathf.Clamp(target.position.y, botPivot, topPivot),
transform.position.z);
}
}

How can I rotate the camera around group of objects and not only a single one?

The camera is child of one soldier only and also the target is this soldier.
And the script attached to the camera.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
public Transform target;
public float speed = 0.1f;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
transform.RotateAround(target.transform.position, new Vector3(0, 1, 0), 100 * Time.deltaTime * speed);
}
}
But now I want to do two things. To make the camera to rotate around the whole soldiers and not only the specific one. And also to make the camera stop slowly when it's facing the soldiers. Now the camera is behind when starting the game.
Using a bool flag if true to make the camera rotate around the soldiers until it's facing them then stop rotation and keep moving with the soldiers.
If unchecked false make the camera rotating around the solders none stop.
UPDATE what I tried so far:
This code will make it rotating around all the soldiers and it's working fine:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
public float speed = 0.1f;
private List<GameObject> Soldiers = new List<GameObject>();
// Use this for initialization
void Start()
{
Soldiers.AddRange(GameObject.FindGameObjectsWithTag("Soldier"));
}
// Update is called once per frame
void Update()
{
RotateAround();
}
private void RotateAround()
{
transform.RotateAround(GetAverageLocationOfSoliders(), new Vector3(0, 1, 0), 100 * Time.deltaTime * speed);
}
private Vector3 GetAverageLocationOfSoliders()
{
var total = new Vector3();
foreach (var soldier in Soldiers)
total += soldier.transform.position;
return total / Soldiers.Count(); // Assuming Soldiers is List<Soldier>
}
}
Then I tried to add a slowDown bool flag variable, But I messed it all and it's not working at all.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
public float speed = 0.1f;
public bool slowDown = false;
private List<Vector3> SoldiersPositions = new List<Vector3>();
private List<Vector3> SoldiersFacingDirection = new List<Vector3>();
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
RotateAround();
}
private void RotateAround()
{
var getSoldiers = GameObject.FindGameObjectsWithTag("Soldier");
foreach (GameObject soldier in getSoldiers)
{
SoldiersPositions.Add(soldier.transform.position);
SoldiersFacingDirection.Add(soldier.transform.forward);
}
var Center = GetAverageLocationOfSoliders();
var FacingDirections = GetAverageFacingDirectionOfSoldiers();
if (slowDown == true)
{
var D = transform.position - Center;
var CamAngle = Vector3.Angle(D, FacingDirections);
speed = speed - CamAngle;
}
transform.RotateAround(Center, new Vector3(0, 1, 0), 100 * Time.deltaTime * speed);
SoldiersPositions = new List<Vector3>();
SoldiersFacingDirection = new List<Vector3>();
}
private Vector3 GetAverageLocationOfSoliders()
{
var total = new Vector3();
foreach (var soldier in SoldiersPositions)
total += soldier;
return total / SoldiersPositions.Count(); // Assuming Soldiers is List<Soldier>
}
private Vector3 GetAverageFacingDirectionOfSoldiers()
{
var total = new Vector3();
foreach (var soldierfacingdir in SoldiersFacingDirection)
total += soldierfacingdir;
return total / SoldiersFacingDirection.Count();
}
}
I'm not sure if the first code example only for the rotation is fine the way I wrote it. It's working but not sure if this is a good way to do the code ?
It seems to me that in the first code only the rotation the camera is a bit shaking or stuttering I mean the camera is not moving smooth when rotating around. It's almost hard to see in the game view in the editor but you can see it a bit in the scene view I think.
The reason I'm calling RotateAround(); in the Update is that the soldiers are in a move they are walking forward non stop.
How should I do the slowDown part ?
UPDATE 2:
This is the full coed now:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
[Header("Spin")]
public bool spin = false;
public Vector3 Direction;
[Range(0, 300)]
public float speed = 10f;
public bool randomSpeed = false;
public bool randomDirection = false;
[Range(0f, 100f)]
public float timeDirChange;
public Vector3 defaultDirection;
[Space(5)]
[Header("Move in circles")]
public bool moveInCircles = true;
public GameObject rotateAroundTarget;
public Vector3 axis;//by which axis it will rotate. x,y or z.
public float rotationSpeed; //or the speed of rotation.
public float upperLimit, lowerLimit, delay;// upperLimit & lowerLimit: heighest & lowest height;
public bool randomHeight = false;
public bool stopRotatingWhenFacing = false;
private float height, prevHeight, time;//height:height it is trying to reach(randomly generated); prevHeight:stores last value of height;delay in radomness;
[Space(5)]
[Header("Follow objects")]
public GameObject[] objectsToFollow;
public bool randomFollow;
private float nextRotationTime = 0f;
private int counter = 0;
private List<GameObject> Soldiers = new List<GameObject>();
// Use this for initialization
void Start()
{
Soldiers.AddRange(GameObject.FindGameObjectsWithTag("Soldier"));
}
private void Update()
{
if (randomSpeed)
{
speed = UnityEngine.Random.Range(0, 300);
}
if (spin)
{
if (randomDirection == false)
{
nextRotationTime = 0;
timeDirChange = 0;
Direction = defaultDirection;
}
else
{
if (Time.time > nextRotationTime)
{
nextRotationTime += timeDirChange;
RandomDirection();
}
}
transform.Rotate(Direction, speed * Time.deltaTime);
}
else
{
timeDirChange = 0;
randomDirection = false;
randomSpeed = false;
}
if (moveInCircles)
{
MoveInCircles();
}
}
private void RandomDirection()
{
Direction = new Vector3(UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1));
while (Direction == new Vector3(0, 0, 0))
{
counter++;
Direction = new Vector3(UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1));
if (counter == 2)
{
Direction = new Vector3(1, 0, 0);
break;
}
}
counter = 0;
}
private void MoveInCircles()
{
var F = GetAverageDirectionsOfSoliders();
var D = transform.position - GetAverageLocationOfSoliders();
var angle = Vector3.Angle(D, F);
if (angle < 5f)
{
rotationSpeed -= 0.1f;
}
transform.RotateAround(GetAverageLocationOfSoliders(), axis, rotationSpeed);
time += Time.deltaTime;
//Sets value of 'height' randomly within 'upperLimit' & 'lowerLimit' after delay
if (time > delay)
{
prevHeight = height;
if (randomHeight)
{
height = UnityEngine.Random.Range(lowerLimit, upperLimit);
}
time = 0;
}
if (randomHeight == false)
{
height = transform.position.y;
}
if (randomHeight)
{
//Mathf.Lerp changes height from 'prevHeight' to 'height' gradually (smooth transition)
transform.position = new Vector3(transform.position.x, Mathf.Lerp(prevHeight, height, time), transform.position.z);
}
else
{
transform.position = new Vector3(transform.position.x, height, transform.position.z);
}
}
private Vector3 GetAverageLocationOfSoliders()
{
var total = new Vector3();
foreach (var soldier in Soldiers)
{
total += soldier.transform.position;
}
return total / Soldiers.Count(); // Assuming Soldiers is List<Soldier>
}
private Vector3 GetAverageDirectionsOfSoliders()
{
var totalf = new Vector3();
foreach (var soldier in Soldiers)
{
totalf += soldier.transform.forward;
}
return totalf / Soldiers.Count();
}
}
The RotateAround part is working fine:
transform.RotateAround(GetAverageLocationOfSoliders(), axis, rotationSpeed);
But the slow down part is not working. It's not slowing down at all when the camera is facing the soldiers.
This is how I calculate the average transform.forward vector of all the soldiers:
private Vector3 GetAverageDirectionsOfSoliders()
{
var totalf = new Vector3();
foreach (var soldier in Soldiers)
{
totalf += soldier.transform.forward;
}
return totalf / Soldiers.Count();
}
Then inside the MoveInCircles method I did:
var F = GetAverageDirectionsOfSoliders();
var D = transform.position - GetAverageLocationOfSoliders();
var angle = Vector3.Angle(D, F);
if (angle < 5f)
{
rotationSpeed -= 0.1f;
}
But it's never getting to the line:
rotationSpeed -= 0.1f;
To rotate around all the soldiers:
Get the center of the all the soldiers (sum the world position of all soldiers and divide by N number of soldiers)
Get the maximum distance of the soldiers from the center
Rotate the camera about the center, and ensure that it is further than the max distance from the center
To slow the camera down when facing the soldiers' front:
Average out the transform.forward vector of all the soldiers. We call this vector F. This is fair since all your soldiers will typically be facing in the same general direction for this request to even make sense.
Calculate the direction D, which is the direction from the soldiers' center to the camera. This is easy: D = camera.transform.position - soldiersCenter
Finally, find the acute angle between D and F, using Vector3.Angle(). If this angle is lower than a certain threshold, decrease the moveSpeed of the camera.
The actual code is easy to write, but I'll let you practice. Let me know if you need any help
From the sounds of it, it seems you have it already able to orbit around a single soldier, so do to more than one, simply take the average of their locations.
Pseudo code:
transform.RotateAround(GetAverageLocationOfSoliders(), ...);
...
private static Vector3 GetAverageLocationOfSoliders
{
var total = new Vector3();
foreach(var soldier in Soldiers)
total += soldier.transform.position;
return total / Soliders.Count(); // Assuming Soldiers is List<Soldier>
}
Now, Vector3 might not have stuff like Vector3 += Vector3 or Vector3 / int, but if that's the case just create your own methods were you do that manually (adding vectorA.x + vectorB.x, and vectorA.x / num, etc.
As far as making the camera stop when it's in front, that's a bit trickier. You might want to do some checks first to make sure they all have the same rotation, and then check, each Update, if the look at rotation of the camera will point to one of the soldiers.
But, if you want it to slow down, then, instead of checking if the lookAtRotation can point to a soldier, check if it can point to some offset of the camera's rotation, like so:
Pseudo Code:
lookRotation(transform.Rotation + offset) // Use something like this to find Soldiers[0]
Then, if that finds one, you can use a Lerp on your speed to lerp back down to a speed of 0.
You will also have to maintain a List<Soldier> or Soldier[] somehow.

Why when drawing line in the scene view between two positions the lines deleted?

What i'm trying to do is to draw lines between two positions and a route of a cube movement without deleting the lines.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class SpawnObjects : MonoBehaviour
{
public int numberOfObjects;
public GameObject objectToPlace;
public Vector3 newObjectsSize = new Vector3(5, 5, 5);
public float speed;
private int wallsLengthX;
private int wallsLengthZ;
private int wallsPosX;
private int wallsPosZ;
private int currentObjects;
private List<GameObject> objects = new List<GameObject>();
void Start()
{
var wi = GetComponent<WallsTest>();
wallsLengthX = (int)wi.lengthX;
wallsLengthZ = (int)wi.lengthZ;
wallsPosX = (int)wi.wallsStartPosition.x;
wallsPosZ = (int)wi.wallsStartPosition.z;
}
// Update is called once per frame
void Update()
{
Spawn();
var randpos = GenerateRandomPositions(objects[0]);
objects[0].transform.position = Vector3.Lerp(objects[0].transform.position,
randpos, (Mathf.Sin(speed * Time.deltaTime)));
Debug.DrawLine(objects[0].transform.position, randpos, Color.red);
}
private void Spawn()
{
if (currentObjects != numberOfObjects)
{
if (objects.Count != 1) // Why did i make a check if not = 1 ?
{
GameObject newObject = (GameObject)Instantiate(objectToPlace);
newObject.transform.localScale = new Vector3(newObjectsSize.x, newObjectsSize.y, newObjectsSize.z);
newObject.transform.localPosition = GenerateRandomPositions(newObject);
newObject.name = "Spawned Object";
newObject.tag = "Spawned Object";
objects.Add(newObject);
currentObjects += 1;
}
}
}
private Vector3 GenerateRandomPositions(GameObject newObject)
{
float paddingX = Mathf.Clamp(newObject.transform.localScale.x, 0, wallsLengthX) / 2f;
float paddingZ = Mathf.Clamp(newObject.transform.localScale.z, 0, wallsLengthZ) / 2f;
float originX = wallsPosX + paddingX - wallsLengthX / 2f;
float originZ = wallsPosZ + paddingZ - wallsLengthZ / 2f;
float posx = UnityEngine.Random.Range(originX, originX + wallsLengthX - paddingX);
float posz = UnityEngine.Random.Range(originZ, originZ + wallsLengthZ - paddingZ);
float posy = Terrain.activeTerrain.SampleHeight(new Vector3(posx, 0, posz));
return new Vector3(posx, posy, posz);
}
}
When i'm using the Debug.DrawLine:
Debug.DrawLine(objects[0].transform.position, randpos, Color.red);
It's drawing the lines but then delete them. How can i make that it will keep the lines ?
And how can i draw a line in green and also to keep it so it will not delete that show the cube movement route ? The cube is the objects[0]
Well, as you've said yourself, lines are drawn, not created.
They aren't objects, and will not have such behavior as "persisting until deleted". They are "deleted" every single frame.
You can specify a time for the editor to keep (re)drawing them for, using the 4th parameter; but that's the editor taking care of redrawing them every frame; they will still be "deleted" at the end of the frame.
Here is the full method signature: public static void DrawLine(Vector3 start, Vector3 end, Color color = Color.white,float duration = 0.0f, bool depthTest = true);
A duration of 0 means the line is rendered only for the current frame. A value of 0.5f would mean the line will be (re)rendered for all frames within the next half second.

Categories

Resources