I’m sure some of you know a lot more about performance then me. So here is another “dumb” question for you
I’m working on a game with a different number of Players (1-4 atm, mb endless).
My Camera is set on the point between the X Players. So I created a list in its Script, searching for the “Players”-Tag and sorting them by number. So far so good.
Now I realized that I ll need that kind of List in different scripts.
Should I link to that List and make other scripts reuse it? Or just create a new List in each script?
Actually I guess inheritance would be the wisest? I’m not to experienced in that…
Quite the same problem. I thought about outsourcing the movement in a GameMaster GameObject. Which would use different controll keys for each Player Number. Or would it be smarter/cheaper to just check the Player Number and tell the Player Gameobject which Number he is by SendMessage?
So the core of my Question. What is cheaper? Inheritance? Linking by GetComponent? SendMessage?
As far as I know SendMessage should be awfull and I should use GetComponent in the initialization for often used links. (what is often? O.o)
You can make the list static if multiple scripts need to access it. I’d probably put it in your player script, and have them add/remove themselves from the list in OnEnable and OnDisable as described in the last section of this article.
It’s generally a more legible code structure to have each object responsible for moving itself. You can assign different keycodes in the inspector for their controls like:
public KeyCode upMovement = Keycode.W;
void Update() {
if (Input.GetKey(upMovement) ) {
//move up
}
}
You’re correct that SendMessage is awful (and while we’re on that topic, GameObject.Find is awful, too).
“often” can mean as little as “twice”, really. It costs nothing in terms of processor time and an amount not worth considering in memory to cache the result of a GetComponent, so there’s little or no reason not to cache it.
Inheritance and GetComponent are different tools for different jobs, generally, so comparing efficiency between them is not very productive. They’re also both so close to “free” that even if they did compete for the same task, it’s not worth worrying over.
That sounds good. Static is a great idea for that job. Thanks!
Especially the last part sounds even better - I’m allways happy if I dont have to worry
Atm I tried to avoid defining the controlls by Inspector, because I wanted to generate the player objects when the game starts. But maybe that was a dumb idea anyway
p.s.: How should I find a GameObject if not using Gameobject.find by tag or name?
No, that’s a fine idea. You do need some way to store the different control schemes somehow, though, and most likely it’d come down to setting them in an inspector somehow or some way.
Good job StarManta! You really wrote a nice Article there… I guess transform.Find ll be added later? Then I ll try to check by from time to time.
If I get this right I should use a Multiton. At least I were allready using FindWithTag and came up with the Idea to make it a List myself - so I don’t feel that much noob at all
Yeah, I sort of write them in my free time at work to unwind, so articles fill up as I get around to them. I can say that transform.Find is very unlikely to be a good substitute for GO.Find, except in rare situations - the other techniques will more likely be better.
Transform.Find can be quite useful for a GameObject to find some of its children. Performance isn’t bad, because it’s only looking through children. But it’s still strong based programming, which makes it risky and brittle.
True enough, but I find that in 90% of the cases where transform.Find is a good option, either GetComponent(s)InChildren or an assigned public reference is going to be a better option. Though I guess I didn’t state that quite that way in the previous comment.
Ich habe das ganze nun in einem Multiton umgesetzt. Das Script dazu um eine Sortierung, eine Zählung und eine ID Vergabe ergänzt.
a) Ist das ok, oder wäre es üblich das alles wieder auszulagern?
b) Leider bekommen/behalten bei mir nun Spieler 1 und 2 die ID 0. Während Spieler 3 die ID 2 erhält und Spieler 4 die ID 4. (ein kleiner Erfolg! ) Vielleicht eine Idee woran das liegen könnte?
playerNumber und playerID starten beide bei 0. playerNumber ist static.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Multiton : MonoBehaviour {
public static List<Player_Multiton> all = new List <Player_Multiton>();
I used Google Translate to work out what you needed.
I think your playerID issue is because you are sorting each time one is added, but you don’t recalculate the index numbers for all of them. So as you add them, if their order changes, their ID’s become unpredictable.
In OnEnabled, after adding and sorting, I would loop through and set all of the ID’s to the loop index:
for (int p=0;p<all.Count;p++) {
all[p].GetComponent<Player_Variables>().playerID = p;
}
If you have more than ~5-10 players, then I would figure out a way to avoid sorting and setting ID’s until they’ve all been added, but for small numbers it’s fast enough.
Ups ^^’ Sry, my bad… It was kinda late. Indeed somehow forgot about that
Google Translate 4tw! I hope you didn’t had to guess the language for to long.
Ahh sure, you are right. I somehow expected them to execute their Awakes nice and easy from player 1 to player 4.
That was stupid ofc. But that change should be easy tho