Unity3d lineRenderer is invisible on some parts - c#

I have 3 Spheres and a lineRenderer which is connected to the spheres. I'm using Bezier curves to get a smooth curves between the spheres.
The code is looking like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LineController : MonoBehaviour
{
private LineRenderer lineRenderer;
public Transform p0;
public Transform p1;
public Transform p2;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.sortingOrder = 1;
}
void Update()
{
DrawQuadraticBezierCurve(p0.position, p1.position, p2.position);
}
void DrawQuadraticBezierCurve(Vector3 point0, Vector3 point1, Vector3 point2)
{
lineRenderer.positionCount = 100;
float t = 0f;
Vector3 B = new Vector3(0, 0, 0);
for (int i = 0; i < lineRenderer.positionCount; i++)
{
B = (1 - t) * (1 - t) * point0 + 2 * (1 - t) * t * point1 + t * t * point2;
lineRenderer.SetPosition(i, B);
t += (1 / (float)lineRenderer.positionCount);
}
}
}
The Problem is, that the is invisible on some parts when I move the spheres.
I don't know why this is happening. I'm using Mixed Reality Toolkit. In the best case the line should be displayed as an 3D object like a long cube.
Maybe anybody is familiar with this kind of "error"?

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

how to make a predictive trajectory arc while aiming?

I am trying to build a trajectory arc that would predict the trajectory path of the object, the drag and shoot seem fine but the arc is not working. initially I used an arrow for showing the direction of the movement of the object but later I tried to do the same using an array which would store 2 points and would keep updating after every iteration and it would result in an arc since I used the equations of motion to predict the positions after each frame.
***
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement: MonoBehaviour
{
public float velocity;
float time;
float x;
float y;
float tt;
float g;
Vector2 force;
public float power = 2.0f;
Vector3 startpoint;
Vector3 endpoint;
Camera cam;
public Vector2 maxpower;
public Vector2 minpower;
public Rigidbody2D rb;
Vector3 currentposition;
Vector3 sp;
LineRenderer lr;
int resolution = 10;
Vector3 newpoint;
// Start is called before the first frame update
void Start()
{
time = 0f;
g = Mathf.Abs(Physics2D.gravity.y);
cam = Camera.main;
lr = GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update()
{
time += Time.deltaTime;
x = gameObject.transform.position.x + velocity * time;
tt = time * time;
y = gameObject.transform.position.y + (g * tt) / 2f;
if(Input.GetMouseButtonDown(0))
{
startpoint = cam.ScreenToWorldPoint(Input.mousePosition);
startpoint.z = 5;
}
if(Input.GetMouseButton(0))
{
sp = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, 5);
currentposition = cam.ScreenToWorldPoint(Input.mousePosition);
currentposition.z = 5;
LineRenderer(sp);
}
if (Input.GetMouseButtonUp(0))
{
endpoint = cam.ScreenToWorldPoint(Input.mousePosition);
endpoint.z = 5;
force = new Vector2(Mathf.Clamp(startpoint.x - endpoint.x, minpower.x, maxpower.x), Mathf.Clamp(startpoint.y - endpoint.y, minpower.y, maxpower.y));
rb.AddForce(force * power, ForceMode2D.Impulse);
x = x + velocity * time;
y = y + (g * tt) / 2f;
EndLine();
}
}
public void LineRenderer(Vector3 p)
{
lr.positionCount = resolution;
Vector3 arc = p;
for(int i=0;i<resolution;i++)
{
newpoint = calculate(arc, i / (float)resolution);
lr.SetPosition(i, newpoint);
arc = newpoint;
}
}
public Vector3 calculate(Vector3 point, float t)
{
point.x += velocity * t;
point.y += 0.5f * g * t * t;
return point;
}
public void EndLine()
{
lr.positionCount = 0;
}
}
***
This the code, any help is appreciated.
A bug that I see is your delta-time:
You call Calculate(arc, i/resolution), with i and resolution both being integers.
The parameter might be float time, but C# will first calculate i/resolution as an integer division, then convert the result to float. The result will be zero as long as i is less than resolution.
Change it to: i/(float)resolution to force a floating-point division.

Create a curve to show where an object will be projected in Unity

I have some code below which projects an object along a curve to a given position and it works perfectly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour {
public GameObject platform;
public Vector3 targetPos;
public float speed = 10;
public float arcHeight = 1;
Vector3 startPos;
GameObject line;
// Use this for initialization
void Start () {
startPos = transform.position;
targetPos = platform.transform.position;
targetPos.x -= 0.7f;
targetPos.y += 1.5f;
}
// Update is called once per frame
void Update () {
movePlayer();
}
void movePlayer()
{
// Compute the next position, with arc added in
float x0 = startPos.x;
float x1 = targetPos.x;
float dist = x1 - x0;
float nextX = Mathf.MoveTowards(transform.position.x, x1, speed * Time.deltaTime);
float baseY = Mathf.Lerp(startPos.y, targetPos.y, (nextX - x0) / dist);
float arc = arcHeight * (nextX - x0) * (nextX - x1) / (-0.25f * dist * dist);
Vector3 nextPos = new Vector3(nextX, baseY + arc, transform.position.z);
transform.position = nextPos;
// Do something when we reach the target
if (nextPos == targetPos) Arrived();
}
void Arrived()
{
Destroy(gameObject);
}
}
I want to now be able to add a visible curve which will show the path of the object. I have seen some examples which use LineRenderer but I am unsure about how to incorporate this into my way of moving the object. Any help about how to do this will be much appreciated.
I edited your code to have a LineRenderer create a path. The idea is that you generate the coordinates of your object in advance, using an position as input for the next location. (so not depending only on your object's transform).
Be sure to set a Material in the inspector, otherwise you will just see a pink line. I hope this is kind of what you had in mind.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public GameObject platform;
public Vector3 targetPos;
public float speed = 10;
public float arcHeight = 1;
Vector3 startPos;
GameObject line;
/// <summary>
/// Our linerenderer
/// </summary>
private LineRenderer lineRenderer;
/// <summary>
/// Line material.
/// </summary>
[SerializeField]
private Material lineMaterial;
// Use this for initialization
private void Start()
{
startPos = transform.position;
targetPos = platform.transform.position;
targetPos.x -= 0.7f;
targetPos.y += 1.5f;
// Add a linerenderer.
lineRenderer = gameObject.AddComponent<LineRenderer>();
if (lineMaterial == null)
{
Debug.LogError("No LineMaterial specified!");
}
// If you do not want to use worldspace, set this to false:
lineRenderer.useWorldSpace = true;
// Set preferred texture mode for texture.
lineRenderer.textureMode = LineTextureMode.RepeatPerSegment;
// Shadows, or not?
//lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
//lineRenderer.receiveShadows = false;
// Finally, set the material that you want to assign.
// Remember: If you use default shader, it needs to be set to "Transparent" to get your texture's alpha working.
lineRenderer.sharedMaterial = lineMaterial;
}
// Update is called once per frame
private void Update()
{
movePlayer();
}
private void movePlayer()
{
// Compute the next position, with arc added in
Vector3 nextPos = newPosition(transform.position, speed * Time.deltaTime);
transform.position = nextPos;
// Calculate upcoming positions.
Vector3[] points = generateUpcomingPositions(nextPos);
CreateLine(points);
// Do something when we reach the target
if (nextPos == targetPos) Arrived();
}
private Vector3 newPosition(Vector3 currentPosition, float delta)
{
float x0 = startPos.x;
float x1 = targetPos.x;
float dist = x1 - x0;
float nextX = Mathf.MoveTowards(currentPosition.x, x1, delta);
float baseY = Mathf.Lerp(startPos.y, targetPos.y, (nextX - x0) / dist);
float arc = arcHeight * (nextX - x0) * (nextX - x1) / (-0.25f * dist * dist);
Vector3 nextPos = new Vector3(nextX, baseY + arc, currentPosition.z);
return nextPos;
}
private Vector3[] generateUpcomingPositions(Vector3 currentPosition)
{
int steps = 10;
float delta = (1.0f / ((steps - 1))) * 2.0f;// Double delta.
List<Vector3> points = new List<Vector3>();
Vector3 newPos = currentPosition;
for (int i = 0; i < steps; i++)
{
// Use newPos as input for location.
newPos = newPosition(newPos, delta * i);
points.Add(newPos);
}
return points.ToArray();
}
private void Arrived()
{
Destroy(gameObject);
}
/// <summary>
/// Create a line with a given name, width and points.
/// </summary>
/// <param name="points"></param>
private void CreateLine(Vector3[] points)
{
// Set the positions.
lineRenderer.positionCount = points.Length;
lineRenderer.SetPositions(points);
}
}

Perlin Noise wave effect on a 3d sphere

I have been trying to figure out how to create wave effect on a 3d sphere using Perlin Noise
I have found some tutorials on how to do it on a plane, however, none on a 3d object,
This code works just fine on a plane, does anyone know how to adapt it on a 3d sphere ?
Thank you in advance for your help
using UnityEngine;
using System.Collections;
public class PerlinTerrain : MonoBehaviour {
public float perlinScale;
public float waveSpeed;
public float waveHeight;
public float offset;
void Update () {
CalcNoise();
}
void CalcNoise() {
MeshFilter mF = GetComponent<MeshFilter>();
MeshCollider mC = GetComponent<MeshCollider>();
mC.sharedMesh = mF.mesh;
Vector3[] verts = mF.mesh.vertices;
for (int i=0; i< verts.Length; i++) {
float pX = (verts[i].x * perlinScale) + (Time.timeSinceLevelLoad * waveSpeed) + offset;
float pZ = (verts[i].z * perlinScale) + (Time.timeSinceLevelLoad * waveSpeed) + offset;
verts[i].y = Mathf.PerlinNoise(pX, pZ) * waveHeight;
}
mF.mesh.vertices = verts;
mF.mesh.RecalculateNormals();
mF.mesh.RecalculateBounds();
}
}
The easiest way would be to apply the 2D noise to the surface. You could do this by using the vertex normal to know which way you should move the position to.
In your code you are only moving the Y position. For a plane this means you moved the vertex in its normal direction by the amount that the noise function gives you. For a spheere you could do something like this:
verts[i] = verts[i] + (Mathf.PerlinNoise(pX, pZ) * waveHeight * mF.mesh.normals[i].normalized);
This will work for any mesh because it takes in account its original position and just moves the vertex in the direction of its normal.
This will move the vertex up which means it will always be higher than original position, you can apply a simple offset to the noise function to make it go lower as well
verts[i] = verts[i] + ((Mathf.PerlinNoise(pX, pZ) - 0.5f) * waveHeight * mF.mesh.normals[i].normalized);
I noticed you are animating this noise, its important to take the original mesh each update and not the new one that had noise applied to it. So in the end it would look something like this
using UnityEngine;
using System.Collections;
public class PerlinTerrain : MonoBehaviour
{
public float perlinScale;
public float waveSpeed;
public float waveHeight;
public float offset;
Vector3[] baseVertices;
private void OnEnable()
{
MeshFilter mF = GetComponent<MeshFilter>();
baseVertices = mF.mesh.vertices;
}
void Update()
{
CalcNoise();
}
void CalcNoise()
{
MeshFilter mF = GetComponent<MeshFilter>();
mF.sharedMesh.vertices = baseVertices;
mF.sharedMesh.RecalculateNormals();
Vector3[] verts = mF.sharedMesh.vertices;
for (int i = 0; i < verts.Length; i++)
{
float pX = (verts[i].x * perlinScale) + (Time.timeSinceLevelLoad * waveSpeed) + offset;
float pZ = (verts[i].z * perlinScale) + (Time.timeSinceLevelLoad * waveSpeed) + offset;
verts[i] = verts[i] + ((Mathf.PerlinNoise(pX, pZ)) * waveHeight * mF.sharedMesh.normals[i].normalized);
}
mF.sharedMesh.vertices = verts;
}
}
But you still have 1 problem. There are multiple vertices that have the same position but have different normal. You will have to figure out which vertices are shared and calculate its normal.
Group the vertices by its position and take the average normal and only iterate over each unique vertex once.
Because it would be called simplex noise
https://en.wikipedia.org/wiki/Simplex_noise
Perlin is the specific name of 2D version

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.

Categories

Resources