Question

Hi I'm working on a restaurant strategy game where customers come in and buy things. I have created an array of Transform type objects that act as way points and I would like the customer to only move towards the way points that are active in the scene. What I'm thinking of doing is using a for loop or a while loop where for every way point that is not active, move to the next way point and check to see if its active. I'm not sure if this is the correct way to do it because I can't seem to get it to work. Anyways I could really use some help. Thanks!

var waypoints : Transform[];
var waypoint : Transform;
var currentWaypoint : int;
var agent : NavMeshAgent;
var script1 : SlideOutMenu;

function Awake(){
agent = gameObject.GetComponent.<NavMeshAgent>();
agent.speed = Random.Range(2.5, 5);
script1 = gameObject.Find("GUIElements").GetComponent(SlideOutMenu);
}

function Update () {
waypoint = waypoints[currentWaypoint];
agent.SetDestination(waypoint.position);
}

function OnTriggerExit(other : Collider){
if (other.name == "0 Start"){
    currentWaypoint = Random.Range(1, 2);
    }
}

function OnTriggerEnter (other : Collider) {
EatMeal();
if (other.name == "0 Start"){
currentWaypoint++;
}
    if (other.name == "1"){
    script1.globalMoney += 50;
    WaitForSoda();
    }
        if (other.name == "2"){
        script1.globalMoney += 100;
        WaitForFood();
        }
    if (other.name == "4 End"){
    Destroy(gameObject);
    }
}

function WaitForSoda(){
yield WaitForSeconds(2);
currentWaypoint++;
}

function WaitForFood(){
yield WaitForSeconds(5);
currentWaypoint = Random.Range(5, 12);
}

function EatMeal(){
if (currentWaypoint >= 4 && currentWaypoint <= 12){
yield WaitForSeconds(Random.Range(5, 12));
currentWaypoint = 4;
}
}
Was it helpful?

Solution

It's usually a Bad Idea™ in game programming when you find yourself taking the solution of "every time I do this, I'll iterate over all objects and check if they're active..." I say this as someone who once upon a time made this mistake on a 100000x100000 grid. The best solution to problems of this type is usually inverting the question. Instead of asking each waypoint whether it's active, each waypoint should ask whether it belongs to the active or inactive set. I'd recommend having at least two lists: activeWaypoints and inactiveWaypoints. If you need it (and sometimes you do), masterWaypoints can be used as a universal set.

Now it's simple: each waypoint knows whether it's active or inactive, when it activates it removes itself from the inactive list and adds itself to the active list and vice versa. When it's created, you have to choose whether it's active or inactive by default (or provide an option to create it with either default), but that's a minor design issue at best. When it's destroyed, just remove it from whichever it currently is and masterWaypoints if it exists.

The benefit to this is that you only have to update things when they change state, rather than check them every frame (or worse: for every NPC agent every frame).

From there, well, now all you have to do with each customer is check activeWaypoints. If you need further filtering for each customer, that gets a little more difficult. In that case it may be acceptable to iterate over all activeWaypoints and just ignore all waypoints that don't meet the criteria. Though depending on how much filtering needs to be done, I'd probably consider writing some sort of WaypointManager with its own logic for filtering based on active/inactive/red/blue/made-of-marmalade/insanity-inducing/etc that's accessed via getWaypointsMeetingCriteria(list of filters). This can use a hybrid of maps, lists, and filtering via iteration depending on what you decide for each tag.

There is a snag here in that the waypoints are, presumably, ordered, which means that when waypoints move from inactive or active they need to have their order maintained, but there are plenty of methods for quickly inserting into and/or constructing a sorted list.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top