top of page

Keeper Sprint 9: Building My Own Ledge Grab Tool

  • Writer: Alex Frey
    Alex Frey
  • Nov 12, 2017
  • 2 min read

Updated: Apr 4, 2018

For this sprint I wanted desperately to lessen the amount of time I was wasting setting up the colliders on the ledges of platforms. These colliders are what the player will detect when they are near a ledge, allowing them to grab it and hang there for a more forgiving jump distance. These colliders need to be exact so that our player is positioned correctly while hanging, and the amount of time spent making minute corrections quickly became inefficient.


My workaround for this was to develop a tool which programmatically positioned and oriented these ledge colliders to ensure they were exactly where they needed to be. The way it works is you simply make the "Ledge Tool" prefab I made a child of the platform in question and then just place duplicates of the empty game object called "ledge node" at corner of every ledge. When the game starts up, the tool automatically draws the colliders between the nodes you placed, and you're done!


Above: the platformable terrain as it appears in Unity's editor.

Below: the same terrain in play mode. Note the green wireframe colliders on every ledge.

I'm quite proud of this tool as it works perfectly and has significantly reduced the amount of time I was spending on this previously. I had no template or examples to go off of, so everything was entirely created by me.


Here is the code if you are interested in seeing exactly how the function works:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class LedgeMarkingToolScript : MonoBehaviour

{

public GameObject ledgeMarker;

public float zLengthAdjustment = 2.0f;

public bool centerPlayer;


GameObject[] ledgeNodes;



void Awake ()

{

ledgeNodes = new GameObject[transform.childCount];


for (int i = 0; i < ledgeNodes.Length; i++)

{

ledgeNodes[i] = transform.Find("LedgeNode (" + i.ToString() + ")").gameObject;


if (i > 0)

{

Vector3 posOne = ledgeNodes[i - 1].transform.position;

Vector3 posTwo = ledgeNodes[i].transform.position;


Vector3 posCenter = (posOne + posTwo) / 2;


Vector3 rotDirection = (posOne + posTwo).normalized;

Vector3 rotPerpendicular = Vector3.Cross(rotDirection, Vector3.right);


float zLength = Vector3.Distance(posOne, posTwo);


GameObject newMarker = Instantiate(ledgeMarker, transform.position,

Quaternion.identity);


newMarker.transform.parent = ledgeNodes[i].transform;

newMarker.transform.position = posCenter;

newMarker.transform.rotation = newMarker.transform.parent.rotation;

newMarker.transform.localScale = new Vector3(newMarker.transform.localScale.x,

newMarker.transform.localScale.y, zLength / zLengthAdjustment);

}

}

}

}


Comentarios


bottom of page