We will implement two classes—FormationPattern and FormationManager:
- Create the FormationPattern pseudo-abstract class:
using UnityEngine; using System.Collections; using System.Collections.Generic; public class FormationPattern: MonoBehaviour { public int numOfSlots; public GameObject leader; }
- Implement the Start function:
void Start() { if (leader == null) leader = transform.gameObject; }
- Define the function for getting the position for a given slot:
public virtual Vector3 GetSlotLocation(int slotIndex) { return Vector3.zero; }
- Define the function for retrieving, if a given number of slots is supported by the formation:
public bool SupportsSlots(int slotCount) { return slotCount <= numOfSlots; }
- Implement the function for setting an offset in the locations, if necessary:
public virtual Location GetDriftOffset(List<SlotAssignment> slotAssignments) { Location location = new Location();
location.position = leader.transform.position; location.rotation = leader.transform.rotation; return location; }
- Create the class for managing the formation:
using UnityEngine; using System.Collections; using System.Collections.Generic; public class FormationManager : MonoBehaviour { public FormationPattern pattern; private List<SlotAssignment> slotAssignments; private Location driftOffset; }
- Implement the Awake function:
void Awake() { slotAssignments = new List<SlotAssignment>(); }
- Define the function for updating the slot assignments given the list's order:
public void UpdateSlotAssignments() { for (int i = 0; i < slotAssignments.Count; i++) { slotAssignments[i].slotIndex = i; } driftOffset = pattern.GetDriftOffset(slotAssignments); }
- Implement the function for adding a character to the formation:
public bool AddCharacter(GameObject character) { int occupiedSlots = slotAssignments.Count; if (!pattern.SupportsSlots(occupiedSlots + 1)) return false; SlotAssignment sa = new SlotAssignment(); sa.character = character; slotAssignments.Add(sa); UpdateSlotAssignments(); return true; }
- Implement the function for removing a character in the formation:
public void RemoveCharacter(GameObject agent) { int index = slotAssignments.FindIndex(x => x.character.Equals(agent)); slotAssignments.RemoveAt(index); UpdateSlotAssignments(); }
- Implement the function for updating the slots:
public void UpdateSlots() { GameObject leader = pattern.leader; Vector3 anchor = leader.transform.position; Vector3 slotPos; Quaternion rotation; rotation = leader.transform.rotation; foreach (SlotAssignment sa in slotAssignments) { // next step } }
- Finally, implement the foreach loop:
Vector3 relPos; slotPos = pattern.GetSlotLocation(sa.slotIndex); relPos = anchor; relPos += leader.transform.TransformDirection(slotPos); Location charDrift = new Location(relPos, rotation); Character character = sa.character.GetComponent<Character>(); character.SetTarget(charDrift);