public Transform UpdateRail() { RailManager.Node currentNode = railManager.GetNodes()[index]; float speed = currentNode.cinematic ? cinematicSpeed : railSpeed; transform.position = Vector3.MoveTowards(transform.position, currentNode.position, speed * Time.deltaTime); Vector3 directionVector = currentNode.position - transform.position; if (directionVector.sqrMagnitude == 0f) { spawner.InstantiateNextNode(); isTurning = false; index++; if (index < railManager.GetNodes().Length) { transform.LookAt(railManager.GetNodes()[index].position, railManager.GetNodes()[index].worldUp); if (railManager.GetNodes()[index].cinematic) { checkpoint = index; spawner.ClearUpToIndex(checkpoint); if (index < 19) { promptManager.ShowStoryPrompt(); } railSpeed += speedIncrease; } } } // Try to turn towards the next vector smoothly else if (directionVector.sqrMagnitude < (turningDistance * turningDistance) && index + 1 != railManager.GetNodes().Length) { if (isTurning) { transform.rotation = Quaternion.RotateTowards(transform.rotation, lookRotation, angleStep * Time.deltaTime); } else { // Get the end rotation RailManager.Node nextNode = railManager.GetNodes()[index + 1]; lookRotation = Quaternion.LookRotation(nextNode.position - currentNode.position, nextNode.worldUp); // Get the angle we need to turn and the distance we have left float angleRemaining = Quaternion.Angle(transform.rotation, lookRotation); float distanceRemaining = directionVector.magnitude; // Need the actual magnitude :( // Calculate how much we need to turn each second angleStep = (angleRemaining / distanceRemaining) * speed; Debug.LogFormat("AngleStep set to {0}", angleStep); isTurning = true; } } cameraTransform.position = transform.position + (transform.rotation * cameraOffset); cameraTransform.rotation = transform.rotation; return(transform); }
public void InstantiateNextNode() { if (i >= railManager.GetNodes().Length) { return; } RailManager.Node node = railManager.GetNodes()[i]; if (node.cinematic) { currentPosition = node.position; i++; return; } float offsetMax = railManager.GetOffsetMax(); // Loop until we are close enough to move on to the next node while ((node.position - currentPosition).sqrMagnitude != 0f) { // Get the direction towards the node before we move towards it Vector3 direction = node.position - currentPosition; // Move towards node at the given "StepDistance" currentPosition = Vector3.MoveTowards(currentPosition, node.position, stepDistance); foreach (SpawnerElement spawnerElement in spawnElements) { // Roll to see if we should spawn a cell if (UnityEngine.Random.Range(0, 100) < spawnerElement.spawnChance) { // Get the forward vector's rotation Quaternion rotation = Quaternion.LookRotation(direction); // Roll a random angle and return the rotation Quaternion randomAngle = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 360f), Vector3.forward); // Roll a random radius (distance from the rail) Vector3 randomRadius = spawnerElement.isPlaque ? new Vector3(0f, offsetMax) : new Vector3(0f, UnityEngine.Random.Range(0f, offsetMax)); // apply the random angle to the random radius, then apply the forward vector. Vector3 offset = currentPosition + (rotation * (randomAngle * randomRadius)); if (spawnerElement.isPlaque) { spawnerElement.spawnedObjects[i].Add(spawnerElement.prefabPooler.GetObject(offset, rotation)); } else if (!spawnerElement.burst) { spawnerElement.spawnedObjects[i].Add(spawnerElement.prefabPooler.GetObject(offset, Quaternion.identity)); } else { int spawnCount = (int)UnityEngine.Random.Range(0.80f * spawnerElement.burstFactor, 1.20f * spawnerElement.burstFactor); for (int j = 0; j < spawnCount; j++) { Vector3 burstOffset = offset + (UnityEngine.Random.rotationUniform * (Vector3.up * UnityEngine.Random.Range(0, spawnerElement.burstDistance))); spawnerElement.spawnedObjects[i].Add( spawnerElement.prefabPooler.GetObject(burstOffset, Quaternion.identity)); } } } } } i++; }