Intent:
Create a class to handle formation movement that establishes a “Leader” agent who sets the initial destination and will be followed by other selected agents positioned relative to the Leader based on “Rank”.
Current Progress:
I have a class: Formation.cs. In this class I have populated a couple lists of positions, all deriving from an input Vector3. The agents are selected, the issue to MoveAsUnit goes through. The intended location is marked and registers properly for all three classes involved in this drama. Then…
Problem:
I have a list of selected units that prints out correctly (maybe, something keeps itching my brain) but only one unit moves (Leader) to the appointed destination. The others are still on their phones. Further confounding me is that someone (more than one someone, I suspect) starts looking for an element out of the range of the List. If any agent is selected other than Leader the function just fails as soon as it looks to formation for instruction.
I know that I am misunderstanding the process needed to accomplish what I want. If you have read this far, you might as well amuse yourself with a peek at the code. Roll your eyes, do the heavy sigh thing and unload some heckling my direction.
First call to action comes from PlayerControl.cs (read: PlayerController.cs )
public bool UnitIsMoving()
{
movecast = reagon.Movecast();
if (movecast.point != null)
{
if (control.action.Select.IsPressed())
{
movement.MoveToDestination(movecast.point);
target.GetComponent<Collider>().gameObject.GetComponent<EnemyHighlighter>().HideHighlighter();
return true;
}
else if (control.action.Alternate.WasReleasedThisFrame())
{
movement.MoveAsUnit(movecast.point);
return true;
}
}
return false;
}
That is picked up by MovementManager.cs (read: Mover.cs )
public void MoveToDestination(Vector3 targetPosition)
{
agent.destination = targetPosition;
EnableAgentMovement();
}
public void MoveAsUnit(Vector3 point)
{
scheduler.StartAction(this);
ClearPath();
formation.FallInStep(point);
}
Then to a bit of code that would have Euclid spontaneously erupt into flames of stupidity.
public class ReadyUnit
{
public PlayerControl player { get; set; }
public int rank { get; set; }
}
public class Formation : MonoBehaviour
{
enum order
{
loose,
column
}
[SerializeField] order arrangement = order.loose;
[Range(1, 15)][SerializeField] int rank;
ReadyUnit unit;
public static List<ReadyUnit> readyUnitList = new List<ReadyUnit>();
int currentRank;
private void Start()
{
if (IsLeader())
{
currentRank = 0;
}
else
{
currentRank = rank;
}
unit = new ReadyUnit { player = gameObject.GetComponent<PlayerControl>(), rank = currentRank };
Selector.Instance.UnitSelectedEvent += OnUnitSelected;
}
void OnUnitSelected(object sender, EventArgs e)
{
readyUnitList.Clear();
if (Selector.Instance.GetSelectedPlayersList().Contains(gameObject.GetComponent<PlayerControl>()) )
{
readyUnitList.Add(unit);
}
}
void SortUnitsByRank()
{
readyUnitList.Sort((leftHand, rightHand) => leftHand.rank.CompareTo(rightHand.rank));
}
public void FallInStep(Vector3 point)
{
if (point == null)
{
return;
}
if (readyUnitList == null)
{
Debug.LogError("No ready units list available.");
return;
}
SortUnitsByRank();
MoveToPosition(point);
}
void MoveToPosition(Vector3 point)
{
Debug.Log("F - MoveToPosition(" + point + ")");
switch (arrangement)
{
case order.loose:
LooseArrangement(point);
break;
case order.column:
ColumnArrangement(point);
break;
}
}
bool IsLeader()
{
return Selector.Instance.GetSelectedUnit() == gameObject.GetComponent<PlayerControl>();
}
void LooseArrangement(Vector3 point)
{
float offset = Random.Range(-5f, 5f);
List<Vector3> positions = new List<Vector3>
{
point,
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset),
point + new Vector3(offset, 0, offset)
};
for (int i = 0; i < positions.Count; i++)
{
PlayerControl currentUnit = readyUnitList[i].player;
currentUnit.GetComponent<MovementManager>().MoveToDestination(positions[i]);
}
}
void ColumnArrangement(Vector3 point)
{
List<Vector3> positions = new List<Vector3>()
{
point,
point + new Vector3(5, 0, 0),
point + new Vector3(0, 0, -3),
point + new Vector3(5, 0, -3),
point + new Vector3(0, 0, -6),
point + new Vector3(5, 0, -6),
point + new Vector3(0, 0, -9),
point + new Vector3(5, 0, -9),
point + new Vector3(0, 0, -12),
point + new Vector3(5, 0, -12),
point + new Vector3(0, 0, -15),
point + new Vector3(5, 0, -15),
};
for (int i = 0; i < positions.Count; i++)
{
PlayerControl currentUnit = readyUnitList[i].player;
currentUnit.GetComponent<MovementManager>().MoveToDestination(positions[i]);
}
}
}
}
Console after ruthlessly mocking my attempts to move my little agents and agentettes (agentettes is a real word, trust me.);
I do have the whole Unity.3D.RPG series. If this is a subject addressed later in the lesson plan (later than RPG.Core Combat: 11.3) I will defer my attempts until I have reached said lecture. Otherwise, heckle-on Hecklers!