Elevator Prefab

After more than 2 weeks of wrestling with this idea, illness and the slaughter of more than 2500 orcs in Shadow of War (go go Batman in Mordor!!!) the elevator prefab is now functionally complete.

The idea was to create a functional prefab that would take input from the Inspector and set up arrays of elements allowing the player to interact via:

  • elevator call buttons: one on each floor to call the elevator to that floor if not present
  • a control panel of buttons that allow player to select desired floor.
  • an array of doors that open and close as the elevator reaches their floor

The Inspector takes arguments for number of floors and floor height in order to set up an array of floors that have index of floor number and elements of floor heights. Each floor is modular and modelled and imported from Blender. At this point the structure is built in the Inspector to allow easy access to editing functions:


A note on riding platforms:

After finding some really nasty jitter issues with the character when riding rigidbody platforms I found a solution using this thread to derive the following script. This is attached to the rigidbody collider object in the scene (the elevator platform). The main lines are:

  • other.transform.SetParent(this.transform) – sets the GO OnTriggerEnter as child of the RB object (the GO is the player but not explicit in this example)
  • other.transform.SetParent*null) – remove the parent OnTriggerExit
    private void OnTriggerEnter(Collider other)
    {
    numObjsInTrigger += 1;    
    //In order to stop the jittering caused by riding platforms
    //set the other as a child of the empty parent of the platform

    other.transform.SetParent(this.transform);

    //Catch trigger events caused by any of the attached GOs
    //whose names contain 'elevator' and return (nullify)
    //the trigger action . Also remove the registered
    //numObjsInTrigger call
    if (other.gameObject.name.Contains("Elevator"))
    {
        numObjsInTrigger -= 1;
        return;
    }

    if (numObjsInTrigger >= elevatorMechanics.numObjsToTrigger)
    {
        if (other.transform.CompareTag("Player"))
        {
            //Send the bool message
            playerIsInElevator = true;
        }
    }
}

private void OnTriggerExit(Collider other)
{
    numObjsInTrigger -= 1;

    //remove the parenting
    other.transform.SetParent(null);

    //This stops activation when there is still more
    //than one object in the trigger
    if (numObjsInTrigger < elevatorMechanics.numObjsToTrigger)
    {
        if (other.transform.CompareTag("Player"))
        {
            //send the bool message
            playerIsInElevator = false;
        }
    }
}

Outcomes:

This process has served as a great learning experience especially in terms of organising hierarchy and how that relates to script functionality. In the current iteration of this prefab the top level element (Elevator) controls all movement/animation functions by taking references from children.

This has resulted in an efficient code structure that ensures control functions are accessed within the parent object – the ‘brain’ of this structure – by reaching out to the child elements for references to individual elements – doors, control panel, call buttons and trigger events.

In this way the only loops running at Update exist in the parent object – all children may run loops to set up their own arrays at Start but have no update function. This centralisation of functionality will make this prefab extensible in the future – e.g. while this moves a platform on Y, it would be straightforward (until Quaternions!) to make a platform move on X/Z.