Tag: prefabs

Elevator Prefab

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.

Iteration #0: feature updates (and fiddling)

Iteration #0: feature updates (and fiddling)

After managing to deliver on my project management priorities, iteration ) of TGM47 is complete.

Iteration #0 is a series of prefabs that address basic interactions and movement.

The main purpose of this iteration was to create prefabs that would make future iterations a bit more efficient as I can draw and iterate from these general principles to create environment/level specific instances.

Of course, with the explicit approach to development being organic there have been more than a few bits of fiddling and going off on tangents that are perhaps fundamentally opposed to some of the original concepts – specifically eleveators!

Iteration #0 – Features

PlayerMovement()

  • Movement that is inertia based
  • Boost (accelerate on Y) – jump
  • Dash (accelerate on Z)
  • Power consumption

PlayerInteraction()

  • Raycasting to recognise and retrieve information from other GameObjects

PlayerCollisions()

  • RigidBody Interactions

PlayerAudio()

  • Transform based audio for all movement elements

PlayerUI_canvas()

  1. Display and update power consumption
  2. Methods to allow messages from other objects to be displayed linked from CamSpace to WorldSpace
movement and interaction

Door(BC)()

  • A button controlled door opened/closed using the Player Raycast to distinguish between and activate individual doors

Door(PP)()

  • A door controlled via a collision trigger
  • Parameters include options for how many objects (and of which type) are required to activate the door
button controlled and pressure pad controlled doors

Elevator()

  • Based on the door prefab this elevator is activated in the same way as the Door(PP)() but has other customisable options:
  • A button that can call the elevator to this floor
  • Elevator ‘knows’ which floor it is on and responds accordingly – going up/down/already on this floor

Some conclusions and thoughts

Why do I need elevators anyway???? Seeing as how the main player is the TGM camera complete with a boost (fly) function/hover it seems a bit unnecessary.

Having said that it was more the challenge of trying to develop a universal/catch all prefab that could solve what is (at least for me) a quite complicated logical problem. In this example there are only 2 floors so the logic isn’t particularly head scratching but (for the sake of it), I’ll try and develop a more universal script that I’ll then put on the Unity store…..

One of the fundamental lessons learned in this iteration is the need to have some idea of how the logic will work in a given scenario and what objects need access to what data. Rule of thumb (based on research) seems to be to allow parent objects to control and access data in children and try and push scene/level wide data into an overall manager that injects data into the objects in the scene as requires.

Thats an ongoing learning process at the mo but as scenes become more complex this approach will help keep the logic and the code clean, accessible, easy to debug and easy to read.

A future iteration of this needs to include some experimentation with the player itself. The next iteration is focussed on developing a way to ‘shoot’ video textures onto world object, although after having started to experiment with animations in Unity and Blender I want to develop a TPS with Cinemachine option for this project.

(GIFs created with https://ezgif.com/video-to-gif)