Created
September 22, 2016 19:10
-
-
Save nulldatamap/72b5f6b4ed36f266c8e635874d7a3aaf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace FSharpTest | |
open UnityEngine | |
type WorkerState = | |
| Idle | |
| GotoMineral of GameObject | |
| Mine of float32 | |
type Worker() = | |
inherit MonoBehaviour() | |
[<SerializeField>] | |
let mutable navAgent : NavMeshAgent = null | |
let mutable state = Idle | |
let maxMineralCount = 10 | |
// Serialize for the inspector | |
[<SerializeField>] | |
let mutable mineralCount = 0 | |
// How far away from the mineral source do we have to be in order to stop | |
let distanceThreshold = 0.1f | |
let miningDuration = 1.0f | |
let findNearestMineral pos : GameObject option = | |
let entities = (GameObject.Find "Map/Entities").transform | |
Transform.children entities | |
|> Seq.filter (fun transform -> transform.name = "Mineral") | |
// Keep track of what minerals have what distance from this unit | |
|> Seq.map (fun mineral -> | |
(mineral, Vector3.Distance (pos, mineral.position))) | |
// Then try to get the GameObject of the clostest one of any | |
|> Seq.sortBy snd | |
|> Seq.tryHead | |
|> Option.map (fun (m, _) -> m.gameObject) | |
member this.Update() = | |
match state with | |
| Idle -> | |
// Try to find something to do | |
match findNearestMineral this.transform.position with | |
| Some nearest -> | |
ignore <| navAgent.SetDestination nearest.transform.position | |
navAgent.Resume() | |
state <- GotoMineral nearest | |
| None -> () | |
// Get in range of the mineral source | |
| GotoMineral mineral -> | |
if navAgent.remainingDistance <= distanceThreshold | |
then state <- Mine miningDuration | |
navAgent.Stop() | |
else () | |
// Mine for a second | |
| Mine timeLeft -> | |
let timeLeft' = timeLeft - Time.deltaTime | |
if timeLeft' <= 0.0f | |
then mineralCount <- min (mineralCount + 1) maxMineralCount | |
if mineralCount = maxMineralCount | |
then state <- Idle | |
else state <- Mine miningDuration | |
else state <- Mine timeLeft' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment