GHGC Dev Log 3: Grappling With Hooks

Yep, it’s got a grappling hook!

I have something in particular I want to do with grappling hooks that I’m not ready to talk about yet. But grappling hooking around is also part of a set of interactions that I hope are going to just feel really nice – to some extent this game would be about the pleasure of execution.

This is just a quick demo of how it’s working right now – shoddily, but well enough to give me an idea of how to refine it. I’m pretty pleased to have got this far in three days, despite still really struggling with some Unity stuff.

A question for experienced Unity users:

I’m having trouble understanding how I’m meant to make different components talk to each other.

I have one component that handles the ‘fire a grappling hook’ code.

In that component, I use a boolean variable called grappleAttached to keep track of whether we’re currently grappling.

Other components regularly need to know this information too.

The component that handles walking left and right, for example, needs to make those controls behave differently if we’re grappled onto something.

This is going to come up a lot – almost everything you can do will depend on whether you’re grappled or not.

The only way I know of having any other components access this variable is with GetComponent.

This seems to require three different lines of code: one variable declaration, one in Start to store the component as a variable, and then another wherever I want to check grappleAttached.

Is that really the best way to do it? It seems like a lot of mess, and a lot to change if I ever move that piece of code or rename the component (which seems to be difficult, but commonly necessary as I experiment with what each component should do). I’ve also been warned that GetComponent is slow.

Similarly, I’ve written a function to get the position of the cursor. Do I have to do this whole process in every script on every object that ever needs that information?

14 Replies to “GHGC Dev Log 3: Grappling With Hooks”

Yeah, it’s best to cache off the component since GetComponent is an expensive operation. That’s the best way I’ve seen to do it.

For the other question, you could make a utility class to store/update the cursor position on screen if you wanted. Nothing wrong with that. Use static functions for getting the position so you can call it wherever with MouseUtil.position() or something like that.

Logan does it the way I would recommend. One other step is that you can tell a component that it requires another specific component on the same gameObject in order to work properly. That way you know that GetComponent will always return something of use.

BTW, if you are interested in how I am going to do it (which you probably aren’t :P), I plan to implement grappling hoops “wrapping” by detecting the point on a vector that intersects, and creating a new grappling hook at that point connected to the character (and keep the previous one/s, pointing towards their children)

To determine how they’d unwrap, I would raycast to that hook’s parent hook until it is no longer occluded, then delete the child and attach the character to the parent.

I second Logan’s suggestion above that if you find yourself having to hold references to a component in multiple scripts then it’s a prime candidate for a static function in a singleton class. Unity themselves do this a lot in the API so it doesn’t feel too out of place.

I’d also advise using the generic version of GetComponent (e.g. GetComponent) rather than the string equivalent. This means changes in component name and typos are picked up at compile time rather than runtime. It’s also a bit faster too, but this is less important as you should only be getting the component once and then caching it for future usage.

Hey man, somewhat new to Unity as of a few months ago, I was also struggling with this concept on a game we’re working on. I learned a few methods of getting objects to talk to each other, and actually made me appreciate Unity even more.

The best way to do this is by defining your component class as “public”, and any variables you want accessed by other scripts as “static”. Don’t worry, static vars can still be changed by the owning script.

So for example, you have a grappling script called GrappleManager, and it would have a variable called bGrappled or whatever. You’d initialize bGrappled as “internal static bool = bGrappled”.

Then for your player class, you wouldn’t have to find or do a GetComponent for GrappleManager. You could just reference it as “GrappleManager.bGrappled” , and it’ll find it. I think the downside is, being static, your player class can’t modify bGrappled. But that’s ok — you’d just have your player class run a static function inside GrappleManager that modifies bGrappled.

You could still do GetComponent(), but I wouldn’t use it often. It would be better to initialize the GrappleManager as a saved variable on your player class, that way you’re only using GetComponent() once. So in your player class you’d have a variable like “public GrappleManager GM”, then in the Unity editor you could drag the GrappleManager script from the hierarchy into the PlayerClass field for “GM”.

When the component is on another GameObject, I use public variables (or actually, serialized fields, but the difference isn’t super important right now), that allow you to drag in GameObjects with the component of the given type on them, using the Inspector window and the Hierarchy window in the Unity Editor.

When the component is on the same GameObject, I usually use GetComponent (or one of the built in references, like ‘collider’ or ‘transform’).

Like Logan says, it is a good idea to store the result of ‘GetComponent()’ or ‘myGameObject.transform’ in a variable if you’re going to be using it more often, because you might need quite a few of these, and together they will be quite expensive.

In some cases, where a method that is rarely called might not always need the reference right after loading the level, I don’t retrieve the reference in the Start or OnEnable methods, but by checking if the reference is not yet set. (if (someTransform == null) someTransform = this.transform;)

I guess a static method might make sense for Mouse Input, because you rarely need more than one type of mouse input. But I usually prefer non-static methods.

For renaming variables I usually use MonoDevelop’s built in renaming system (I have it bound to F2, which is similar to the key used in Windows). It will search the project for references to that specific method or variable, and change it (it takes longer for public stuff, because it needs to search outside the file where the method or variable is defined). Keep in mind that if the files are open, they still need to be saved manually after the change (it’s easiest to have other files closed while you change a name, they will automatically be saved). And when you want to rename a component class, you should first rename it inside the Unity Editor, and after that in the code itself. If you were to only change it in the code, Unity would not know about the name change, and the scene might lose references to things with that name.

For components that there is only ever going to be one of I recommend using the singleton pattern:

-In the component create a static instance member for the component type
-Initialize it to ‘this’ somewhere (I recommend OnEnable)

class Foo : MonoBehaviour
{
public static Foo mInstance;

void OnEnable()
{
mInstance = this;
}
}

Once you have done this, you can quickly get access to any of the public variables on the class from anywhere else by referencing them through the static accessor:

Foo.mInstance.var1 = whatever.

This also saves you from having to make a ton of stuff in the class static, which can get confusing.

This is how I handle things like this in my unity game. However, there are lots of different ways to attack this problem, and mostly it comes down to what feels best for you and matches your coding style.

There are also a good amount of arguments against singletons, one of those in the context of unity (or video games) can be found here http://blogs.unity3d.com/2012/04/27/london-unity-usergroup-11/ first video minute 10, which is very much applicable to this situation, since for example if one was to implement MP (which tom francis said the game might have), then having a single state of is hooked wouldn’t work (I think), since one would require one for each player.

With all that being said, considering it’s a prototype and that prototype code is in theory made to be disposable (as in being completely eliminated), one doesn’t really need to worry about good coding practices (which are subjective).

A “controller” as a singleton can hold other things such object states and serves as a communication layer between different objects ( some kind of model view controller ).
But you’re right it might not be the right thing here.
I often directly use GetComponent( ).doSomething( ) directly without storing the component. The thing is that if you call GetComponent only a few times per frame, performance is not issue. But always profile to know the impact.

Coursera.com (a MOOC site) is currently doing a course on programming in C#. It looks like they use it with XNA, which is maybe less useful depending on your jam, but it could be helpful depending on where one is about in Unity scripting (at least that’s what I’m hoping, God help me) :)