// If we use Rigidbody we need to assign the velocities in FixedUpdate() private void FixedUpdate() { if (anchor == null) { return; } if (movementType == MovementType.CharacterController) { return; // Oops for some reason we ended up here. Should never happen. } if (state == FormationStates.Move) { if (formationAnchor != null) { float endReachedDistance = formationAnchor.endReachedDistance; Vector3 vlcity = formationAnchor.GetVelocity(); //DebugPanel.Log("Anchor velocity", "Anchor", vlcity.magnitude); for (int i = 0; i < gridPoints.Count; i++) { FormationGridPoint fgp = gridPoints[i]; if (fgp != null) { if (fgp.IsUnitAssigned()) { switch (movementType) { case MovementType.RigidBody: MoveUnitsRigidBodyMode(i, fgp, vlcity, endReachedDistance); break; case MovementType.CharacterController: //MoveUnitsCharacterControllerMode(i, fgp, vlcity, endReachedDistance); break; default: Debug.LogError("FormationGrid.Update(): Unknown movementType"); break; } FormationUnitAnimation formationUnitAnimation = fgp.GetFormationUnitAnimation(); if (formationUnitAnimation) { formationUnitAnimation.velocity = fgp.GetAssignedVelocity(); //DebugPanel.Log("FUA.velocity", "Unit Animation", fgp.GetAssignedVelocity()); } } } oldPosition = anchorPosition; oldRotation = transform.rotation.eulerAngles.y; } } } }
// Update is called once per frame void Update() { if (anchor == null) { return; } if (state == FormationStates.Form) { for (int i = 0; i < gridPoints.Count; i++) { FormationGridPoint fgp = gridPoints[i]; if (fgp != null) { if (fgp.IsUnitAssigned()) { FormationUnitAnimation formationUnitAnimation = fgp.GetFormationUnitAnimation(); if (formationUnitAnimation) { GameObject go = fgp.GetAssignedUnit(); if (go) { #if T7T_ASTAR AIPath aip = go.GetComponent <AIPath>(); formationUnitAnimation.velocity = aip.CalculateVelocity(Vector3.zero); // obselete but velocity property is not available. #else NavMeshAgent nma = go.GetComponent <NavMeshAgent>(); formationUnitAnimation.velocity = nma.velocity; #endif } } } } } } if (state == FormationStates.Move) { if ((oldPosition - anchorPosition).sqrMagnitude > 0.001f * 0.001f) // TODO: potentially we can do this by checking if target has been reached { positionDirty = true; } else { positionDirty = false; } if (Mathf.Abs(anchorRotation.eulerAngles.y - oldRotation) > 0.01f) { rotationDirty = true; } else { rotationDirty = false; } Quaternion target = anchorRotation; if (rotationDirty) { transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * smoothRotation); } // Rotate the units at grid points to align with anchor rotation: // TODO: can we check when not to run this by means of "fully rotated" units? if (formationAnchor != null) { // Vector3 velocity = formationAnchor.GetVelocity(); for (int i = 0; i < gridPoints.Count; i++) { FormationGridPoint fgp = gridPoints[i]; if (fgp != null) { if (fgp.IsUnitAssigned()) { GameObject au = fgp.GetAssignedUnit(); au.transform.rotation = Quaternion.Slerp(au.transform.rotation, target, Time.deltaTime * smoothRotation); } } } } if (positionDirty) { transform.position = anchorPosition; // Move the Formation to Anchor position. TODO: If dampening needed, do Lerp here. if (randomizeOffset > 0.0F) { // Randomize the positions slightly if enabled reRandomizeOffsets += Time.deltaTime; if (reRandomizeOffsets > reRandomizeNextTime) // ReRandomize the gridpoints every 3 seconds { reRandomizeOffsets = 0.0F; reRandomizeNextTime = reRandomizeTimeMin + (reRandomizeTimeMax - reRandomizeTimeMin) * Random.value; for (int i = 0; i < gridPoints.Count; i++) { FormationGridPoint fgp = gridPoints[i]; fgp.RandomizePosition(); } } } CalculatePositionsAllGridPoints(); // Calculate all Grid Points relative to the Anchor which has moved by means of A*Pathfinfing. } // Now move the units (assigned to grid positions) towards their grid position: // TODO: Add a check here to stop if all units have arrived. if (formationAnchor != null) { float endReachedDistance = formationAnchor.endReachedDistance; Vector3 vlcity = formationAnchor.GetVelocity(); //DebugPanel.Log("Anchor velocity", "Anchor", vlcity.magnitude); for (int i = 0; i < gridPoints.Count; i++) { FormationGridPoint fgp = gridPoints[i]; if (fgp != null) { if (fgp.IsUnitAssigned()) { switch (movementType) { case MovementType.RigidBody: // Do nothing since in case of rigidbody we use FixedUpdate() instead of Update() //MoveUnitsRigidBodyMode(i, fgp, vlcity, endReachedDistance); break; case MovementType.CharacterController: MoveUnitsCharacterControllerMode(i, fgp, vlcity, endReachedDistance); break; default: Debug.LogError("FormationGrid.Update(): Unknown movementType"); break; } FormationUnitAnimation formationUnitAnimation = fgp.GetFormationUnitAnimation(); if (formationUnitAnimation) { formationUnitAnimation.velocity = fgp.GetAssignedVelocity(); //DebugPanel.Log("FUA.velocity", "Unit Animation", fgp.GetAssignedVelocity()); } } } oldPosition = anchorPosition; oldRotation = transform.rotation.eulerAngles.y; } } } if (state == FormationStates.Disband) { if (disbandTimer == 0.0f) { // set the directions for each assigned unit for (int i = 0; i < gridPoints.Count; i++) { FormationGridPoint fgp = gridPoints[i]; if (fgp != null) { if (fgp.IsUnitAssigned()) { fgp.SetDisbandDesitination(disbandRadius, mask); fgp.SetPositionToDisband(mask); } } } ChangeMoveStateOnGridObjects(true); disbanded = false; } // start a timer, for x seconds have the assigned units move into a random direction disbandTimer += Time.deltaTime; if (disbandTimer < disbandDuration) { // Move them //DebugPanel.Log("disbandtimer", "disband", disbandTimer); } else { if (!disbanded) { ChangeMoveStateOnGridObjects(false); ChangeAnimationStateOnGridObjects(false); disbanded = true; } } } }