/// <summary> /// OccupyIntermediateSlot attempts to find the closest (in distance) that is available, and is closer to the /// occupant than the harness gameObject. This is used to ensure slots that are behind or to the side /// of the harness are not chosen. If a Navigator is specified, a path check is done to make sure the slot is reachable /// </summary> /// <param name="aOccupant">The occupant for the slot</param> /// <param name="aSlot">An out parameter - returns the slot if assigned, or -1 if no slot could be assigned</param> /// <param name="aNavigator">An optional parameter. If a RAINNavigator is specified then a reachability test will be performed</param> /// <returns>true if a slot was found, false otherwise</returns> public virtual bool OccupyIntermediateSlot(GameObject aOccupant, out int aSlot, RAINNavigator aNavigator = null) { //Clamp max positions since it is a public variable maxPositions = Mathf.Clamp(maxPositions, 0, cnstMaxPossiblePositions); //If the occupant already has a slot, just return that for (int i = 0; i < maxPositions; i++) if (occupants[i] == aOccupant) { aSlot = i; return true; } //Check all unoccupied slots. For any that are closer than distanceToGameObject and reachable, //find the one closest to the occupant float distanceToGameObject = Vector3.Distance(gameObject.transform.position, aOccupant.transform.position); float bestDistance = float.MaxValue; int bestSlot = -1; for (int i = 0; i < maxPositions; i++) { if (occupants[i] != null) continue; Vector3 slotPosition = GetSlotPosition(i); float distance = (aOccupant.transform.position - slotPosition).magnitude; if (distance > distanceToGameObject) continue; if (aNavigator != null) { RAINPath path; if (!aNavigator.GetPathTo(slotPosition, 100, 10, false, out path)) continue; } if (distance < bestDistance) { bestDistance = distance; bestSlot = i; } } //Set the return value (aSlot) aSlot = bestSlot; if (bestSlot < 0) return false; //Occupy the slot occupants[bestSlot] = aOccupant; return true; }
/// <summary> /// OccupyFirstAvailableSlot cycles through all slots in slot order (0 to max) and occupies the first unoccupied slot. /// If a Navigator is specified, a path check is done to make sure the slot is reachable /// </summary> /// <param name="aOccupant">The occupant for the slot</param> /// <param name="aSlot">An out parameter - returns the slot if assigned, or -1 if no slot could be assigned</param> /// <param name="aNavigator">An optional parameter. If a RAINNavigator is specified then a reachability test will be performed</param> /// <returns>true if a slot was found, false otherwise</returns> public virtual bool OccupyFirstAvailableSlot(GameObject aOccupant, out int aSlot, RAINNavigator aNavigator = null) { //Clamp max positions since it is a public variable maxPositions = Mathf.Clamp(maxPositions, 0, cnstMaxPossiblePositions); //If the occupant already has a slot, just return that for (int i = 0; i < maxPositions; i++) if (occupants[i] == aOccupant) { aSlot = i; return true; } //Stop at the first unoccupied and reachable slot aSlot = -1; for (int i = 0; i < maxPositions; i++) { if (occupants[i] != null) continue; Vector3 slotPosition = GetSlotPosition(i); if (aNavigator != null) { RAINPath path; if (!aNavigator.GetPathTo(slotPosition, 100, 10, false, out path)) continue; } //Set the return value (aSlot) aSlot = i; //Occupy the slot occupants[i] = aOccupant; break; } return (aSlot >= 0); }