// Execute(): When the squad child is in this state. Runs once every frame on every instance public override void Execute() { // Calculates the velocity for all children ExecuteMethod.OnceInUpdate("SC_IdleState.CalculateVelocity", null, null); // toTargetVector: The vector from its tranform position to the angular position Vector3 toTargetVector = PlayerSquadFSM.Instance.transform.position + Quaternion.Euler(0.0f, 0.0f, fAngularPosition) * Vector3.up * s_fIdleRadius - m_scFSM.transform.position; if (toTargetVector.magnitude > s_fIdleRigidity) { m_scFSM.m_RigidBody.AddForce(toTargetVector); } m_scFSM.m_RigidBody.velocity = Vector3.ClampMagnitude(m_scFSM.m_RigidBody.velocity, Mathf.Max(s_fIdleRigidity, toTargetVector.magnitude)); fAngularPosition += fAngularVelocity * Time.deltaTime; // if, else if: Clamping values to be within 0 to 360f if (fAngularPosition > 360.0f) { fAngularPosition -= 360.0f; } else if (fAngularPosition < 0.0f) { fAngularPosition += 360.0f; } }
public override void Execute() { ExecuteMethod.OnceInUpdate("SquadChildFSM.UpdateLandmineList", null, null); m_scFSM.Strafing(); // if: There is more landmine than the production child count if (SquadChildFSM.ListLandmine.Count >= SquadChildFSM.StateCount(SCState.Produce)) { for (int i = 0; i < SquadChildFSM.ListLandmine.Count; i++) { if (Vector3.Distance(SquadChildFSM.ListLandmine[i].transform.position, m_scFSM.transform.position) < 2f) { m_scFSM.Advance(SCState.Avoid); return; } } } // else if: There is lesser landmine state BUT not 0 else if (SquadChildFSM.ListLandmine.Count != 0) { for (int i = 0; i < SquadChildFSM.ListLandmine.Count; i++) { if (Vector3.Distance(SquadChildFSM.ListLandmine[i].transform.position, m_scFSM.transform.position) < 2f) { m_scFSM.Advance(SCState.Attack); return; } } } }
public override void Execute() { if (m_scFSM.attackTarget != null && !isColorChanged) { m_scFSM.m_SpriteRenderer.color = new Color(1f, 0.12f, 0.12f); isColorChanged = true; } ExecuteMethod.OnceInUpdate("SquadChildFSM.GetNearestTargetPosition", null, null); m_scFSM.AttackTarget(); }
// Strafing(): Handles the movement when the cells are in production state public bool Strafing() { if (m_currentEnumState != SCState.Produce) { Debug.LogWarning(gameObject.name + ".SquadChildFSM.Strafing(): Current state is not SCState.Produce! Ignore Strafing!"); return(false); } ExecuteMethod.OnceInUpdate("SquadChildFSM.StrafingVector", null, null); // targetPosition: The calculated target position - includes its angular offset from the main vector and the squad's captain position Vector3 targetPosition = Quaternion.Euler(0.0f, 0.0f, fStrafingOffsetAngle) * m_strafingVector + PlayerSquadFSM.Instance.transform.position; Vector3 toTargetPosition = targetPosition - transform.position; m_RigidBody.AddForce(toTargetPosition.normalized, ForceMode2D.Impulse); m_RigidBody.velocity = Vector3.ClampMagnitude(m_RigidBody.velocity, toTargetPosition.magnitude * 3f); return(true); }
public override void Execute() { // Re-initialisation of variables ExecuteMethod.OnceInUpdate("SquadChildFSM.UpdateLandmineList", null, null); Vector3 finalMovement = Vector3.zero; // finalMovement: The final movement in which will be used for that current frame // if: There is no landmine, return the squad child to idle if (SquadChildFSM.ListLandmine.Count == 0) { m_scFSM.Advance(SCState.Idle); return; } // vectorApart: The distance between the current squad child cells and the current enemy child cells Vector3 smallestVectorApart = Vector3.one * 3f; Vector3 currentVectorApart; // for: Check every landmine and determines the closest landmine to avoid for (int i = 0; i < SquadChildFSM.ListLandmine.Count; i++) { currentVectorApart = m_scFSM.transform.position - SquadChildFSM.ListLandmine[i].transform.position; // if: The current distance between the enemy and child cells is smaller than the current smallest // then use this new vector as the smallest if (currentVectorApart.magnitude < smallestVectorApart.magnitude) { smallestVectorApart = currentVectorApart; } } // finalMovement: The final vector to travel to avoid other cells finalMovement = smallestVectorApart.normalized * (1f - smallestVectorApart.magnitude / 3f); //Debug.Log(m_scFSM.gameObject.name + "::Rigibody->velocity(): " + m_scFSM.RigidBody.velocity + ", finalMovment: " + finalMovement); m_scFSM.RigidBody.AddForce(finalMovement * 10.0f); m_scFSM.RigidBody.velocity = Vector3.ClampMagnitude(m_scFSM.RigidBody.velocity, finalMovement.magnitude * 0.5f); }
public override void Exit() { ExecuteMethod.OnceInUpdate("SquadChildFSM.CalculateDefenceSheildOffset", null, null); }
public override void Execute() { targetNutrients = m_scFSM.GetNearestResource(); // if: The target nutrient is too close to the wall, disable the target if (targetNutrients != null) { if (Mathf.Abs(targetNutrients.transform.position.x) >= 4f) { targetNutrients = null; } } // Seperation Factor // vSeperationVector: The final vector used to space away from all the other nearby cells Vector3 vSeperationVector = Vector3.zero; Collider2D[] array_nearbyCollider = Physics2D.OverlapCircleAll(m_scFSM.transform.position, 0.5f, Constants.s_onlySquadChildLayer); if (array_nearbyCollider.Length > 0) { for (int i = 0; i < array_nearbyCollider.Length; i++) { // if: The current gameObject is itself if (array_nearbyCollider[i] == m_scFSM.gameObject) { continue; } // vDirectionVector: The vector that the current squad child should be travelling in to space away from the current neighbour Vector3 vDirectionVector = (m_scFSM.transform.position - array_nearbyCollider[i].transform.position); // if: Somehow this is triggered, which is very often... if (vDirectionVector.magnitude > 0) { vSeperationVector += vDirectionVector.normalized / vDirectionVector.sqrMagnitude; } } // Average the the final vector to use for spacing away vSeperationVector = vSeperationVector / array_nearbyCollider.Length; vSeperationVector = Vector3.ClampMagnitude(vSeperationVector, 7f); } // Attraction Factor ExecuteMethod.OnceInUpdate("SC_FindResourceState.RecalculateCenter", null, null); Vector3 vAttractionVector = vCenterPosition - m_scFSM.transform.position; vAttractionVector *= 10f; // Final Velocity Vector // toTargetVector: The vector between the target nutrients and the current squad child cells Vector3 toTargetVector; // if: There is no target nutrient, the find nutrients group will idle infront of squad group if (targetNutrients == null) { toTargetVector = PlayerSquadFSM.Instance.transform.position + new Vector3(0f, 2f, 0f) - m_scFSM.transform.position; } else { toTargetVector = targetNutrients.transform.position - m_scFSM.transform.position; } toTargetVector *= 10f; if (targetNutrients != null) { SquadChildFSM.Circle(targetNutrients.transform.position); } //Debug.Log("toTargetVector: " + toTargetVector.magnitude + ", vSeperationVector: " + vSeperationVector.magnitude + ", vAttractionVector: " + vAttractionVector.magnitude); // Apply vector to velocity /* Quick Vector Summary: * toTargetVector -> The vector between the nutrients and the 'FindResource' group * vSeperationVector -> The personal space vector * vAttractionVector -> The 'stay as a group' vector */ m_scFSM.RigidBody.AddForce(toTargetVector + vSeperationVector + vAttractionVector * Time.deltaTime * 100f, ForceMode2D.Force); m_scFSM.RigidBody.velocity = Vector3.ClampMagnitude(m_scFSM.RigidBody.velocity, 3f); // if: The distance between the two bodies is less than a certain distance if (targetNutrients != null) { if (Vector3.Distance(targetNutrients.transform.position, m_scFSM.transform.position) < 0.5f) { // if: The current squad child is added to the nutrients if (targetNutrients.AddSquadChildCount()) { m_scFSM.Advance(SCState.Dead); targetNutrients = null; } } } }
public override void Exit() { ExecuteMethod.OnceInUpdate("SquadChildFSM.CalculateStrafingOffset", null, null); }