#using UnityEngine;public class UnitAdder...
1 messages · Page 1 of 1 (latest)
Instantiate takes a param for the parent
var unitObject = Instantiate(singleSlotUnit.GetUnitData.UnitPrefab, selectedSlots[i].transform.position, Quaternion.identity);
unitObject.transform.SetParent(selectedSlots[i].transform);
Can just be
var unitObject = Instantiate(singleSlotUnit.GetUnitData.UnitPrefab, selectedSlots[i].transform.position, Quaternion.identity, selectedSlots[i].transform);
If you spawn your prefabs slightly differently, you do not need to do the GetComponent<T> () here
selectedSlots[i].SetCurrentUnit(unitObject.GetComponent<Unit>());```
Read this:
https://bronsonzgeb.com/index.php/2021/05/01/unity-architecture-pattern-structured-prefabs/
oh, interesting
so I dont have to reference the prefab
i can referece a component on that prefab
You reference the component you want from the parent transform on the prefab
i tried doing it like
Instantiate(doubleSlotUnit.GetUnitData.UnitPrefab, selectedSlots[1].transform.position, Quaternion.identity) as Unit
but that didint work
i remember someone was doing it that was with the as keyword
I think because you've assigned the GameObject as the reference
You can't convert GameObject > Unit
I did try with Unit aswell
Unit unit = Instantiate(singleSlotUnit.GetUnitData.UnitPrefab, selectedSlots[i].transform.position, Quaternion.identity) as Unit;
so the UnitPrefab should be as Unit, not GO?
shouldn't need the 'as Unit'
yes
oh, it worked
i also tried to extract the duplicate code to methods
but thats kinda hard
since the index are changing and stuff
I'd do this with the spawning
private Unit SpawnUnit(Unit unitToSpawn, Transform parent)
{
return Instantiate(unitToSpawn, parent.position, Quaternion.identity, parent);
}```
var unitObject = SpawnUnit(singleSlotUnit, selectedSlots[i].transform);
if (selectedSlots[0].GetAdjacentSlots[0] == selectedSlots[1])
{
var leftSlotUnitObject = SpawnUnit(doubleSlotUnit, selectedSlots[1].transform);
var rightSlotUnitObject = SpawnUnit(doubleSlotUnit, selectedSlots[0].transform);
selectedSlots[0].SetCurrentUnit(rightSlotUnitObject);
selectedSlots[1].SetCurrentUnit(leftSlotUnitObject);
selectedSlots[0].SetCanBeSelected(false);
SlotSelector.Instance.ClearSelectedArray();
return;
}
yea that looks much cleaner
i
can I refactor it real quick and send you the new version?
You could even do this
if (selectedSlots[0].GetAdjacentSlots[0] == selectedSlots[1])
{
selectedSlots[0].SetCurrentUnit(SpawnUnit(doubleSlotUnit, selectedSlots[1].transform););
selectedSlots[1].SetCurrentUnit(SpawnUnit(doubleSlotUnit, selectedSlots[0].transform););
selectedSlots[0].SetCanBeSelected(false);
SlotSelector.Instance.ClearSelectedArray();
return;
}
The method returns the object the param requires
Just depends if you like how readable that is
it could be even simplier i think?
go refactor, test.. then re-share
okay
line 85
Unit unit = Instantiate(doubleSlotUnit.GetUnitData.UnitPrefab, selectedSlots[i].transform.position, Quaternion.identity, selectedSlots[i].transform);
Unit unit = Instantiate(doubleSlotUnit, selectedSlots[i].transform.position, Quaternion.identity, selectedSlots[i].transform);
No?
SO being ScriptableObject?
yes
then i dont need both of this classes
but getting rid of Unit will cause some issues
Well, you'd still use the damage/ health from the SO
yea, later on
so i dont need to have reference to the preafb in SO file
i can keep them (references) in UnitAdder
is that okay?
correct
I already said it's ok ;p
here you go
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
looks much cleaner now
Yep, lovely
also, do you think i should add more comments?
Good code doesn't need commenting
Not anymore
xD
Is this a solo project?
yes, I am trying to get a job in game dev but before i submit any CV im trying to learn making good code so im making some projects
what about thing like this?
public void AddSlotToSelectedArray(Slot slotToAdd)
{
if(selectedSlots[0] != null && selectedSlots[1] != null)
{
selectedSlots[0].ChangeSlotState();
selectedSlots[0] = slotToAdd;
//Swap slots, so the first index is always the earliest selected one
Slot tempSlot = selectedSlots[0];
selectedSlots[0] = selectedSlots[1];
selectedSlots[1] = tempSlot;
selectedSlots[1].ChangeSlotState();
}
else if(selectedSlots[0] != null && selectedSlots[1] == null)
{
selectedSlots[1] = slotToAdd;
selectedSlots[1].ChangeSlotState();
}
else if(selectedSlots[0] == null && selectedSlots[1] == null)
{
selectedSlots[0] = slotToAdd;
selectedSlots[0].ChangeSlotState();
}
}
is it worth refactoring?
Great - having finished projects in a portfolio is a must have
i can make another method called like AddSlot
oh nvm actually
i think its fine its not that complex
I got my first junior role with lots of repeated code
as unit dev?
Yep
nice, where are you at now?
You're already way ahead of where I was
thanks thats nice to hear
my problems are mostly architecture stuff
like communication between classes
which pattern should I use etc
but im getting there 😄
Actions are my go to
i tried Actions in this project
but I didint like it
or I probably did it wrong
like.. my slot has OnPointerClick method from the interface
and I fired an event from that method
but I didint know how to make SlotSelector listen to this event correctly
or should it be the other way around? so SlotSelector is invoking the event and Slots are listening?
do you know any youtube channel that is well explaining patterns?
im literally using singleton everywhere
public class SomeClass : Singleton<SomeClass>
{
public Action OnSomethingHappened;
public Action<bool> OnSomethingElse;
private void Start()
{
OnSomethingHappened?.Invoke();
OnSomethingElse?.Invoke(true);
}
}
public class SomeOtherClass : MonoBehaviour
{
private void Awake()
{
SomeClass.Instance.OnSomethingHappened += DoThing;
SomeClass.Instance.OnSomethingElse += DoOtherThing;
}
private void OnDestroy()
{
SomeClass.Instance.OnSomethingHappened -= DoThing;
SomeClass.Instance.OnSomethingElse -= DoOtherThing;
}
private void DoThing()
{
// whatever
}
private vod DoOtherThing(bool someBool)
{
// whatever
}
}```
I used a Singleton here for ease of demostration, but don't use a tonne of Singletons
okay so live example, how would you do that? without code just short explanation
I have SlotSelector.cs that has an array with selected slots that is of size [2], you can have only 2 selected slots at 1 time.
Now, I am trying to make a SlotSwapper.cs that will swap units between slots, so if you choose 2 slots and click the SWAP button, they will swap. I can make some public method like CanSwap() in SlotSelector, since its a singleton, but I dont think that SlotSelector should know anytyhing about swapping
but i dont know how can i make this work without making CanSwap() in SlotSelector()
i'd ideally want to have this method in SlotSwapper and then if canswap, handle rest of the logic
What's the purpose of CanSwap() ?
well, sometimes you cannot swap units
like you cannot swap X1 unit with X2 unit
and some other things
like space relevant etc
X2 untis take 2 slots, X1 untis take 1 slot
so i have to actually know if I can swap
if ther will be enought slots for X2 unti after swapping etc
SlotSwapper would need to know the data to be able to determine itself if CanSwap
this scenario doesn't sound like it needs actions, but, SlotSelector would have some properties (2 getters?) and SlotSwapper would access them to do its own CanSwap()
yes, i can gather the data from the SlotSelector because its singletone
i probably asked the question wrong
how could I do this without singletone?
and what if, for example CanSwap would require data from SlotSelector and a Unit idk, just an example
Unit is not a singletone
probably a wrong example, because I can get a unti from a slot, bnut you know what i mean
lets assume i cannot
you'd still need a reference to SlotSelector
private SlotSelector slotSelector;
private void Awake()
{
GetRequiredComponents();
}
private void GetRequiredComponents()
{
slotSelector = FindObjectOfType<SlotSelector>();
}
ohh, FindObjectOfType? really?
im avoiding those methods as hell
when I had 3 month practice at a gamedev company
It's fine as long as it's not being called every frame
they told me to never use them
either in udpate and start/awake etc
so i didint
what if i have a lot of files in the hierarchy?
any performance issue?
the other option is to expose the field in the inspector with [SerializeField] and assign it manually
Never noticed a performance issue with FindObjectOfType
yea, but thats a issue since im spawning them in the runtime
so manually assigning wouldnt work
You're manually spawning the SlotSelector and SlotSwapper ?
no no
just an example, my english sucks probably
if i spawn things in the runtime
Your English is fine 🙂
manually assignment wouldnt work
If you spawn things at runtime , the thing that spawns them can already have the relevant references, and assign them on spawn
so you're saying that I shouldn't be afraid using FindObjectOfType<T>
obviously not calling every frame
but just when needed
If you're spawning a thousand things, then FindObjectOfType<T> is probably gonna be an issue, even in Awake/ Start.. but one or two.. no it's fine
im still afraid how would potentional CTO reviewinng my recrutiment task look at it
its so confusing since there are a lot of "ways" to code things
and if the CTO doesnt like my "way" but it works and it's fine
then im basically fked
I assume you're going for junior level roles?
yes
Any interviewer reviewing your code isn't going to dismiss you for 1 thing
learning till end of summer then im looking for a job
Anyone who dismisses you for doing things differently, instead of seeing a potential learning opportunity for you.. is probably someone you don't wanna work with anyway - depending on country and work culture I guess
If you're not sure on FOT, profile it when you use it
im from Poland, in my opinion we have some great studious over here like CDP, Techland etc
so the gamedev industry is nothing new here
You can back up your use of it then "I profiled the use of it when I added it, and it gave no performance issues"
oh yea
actually I have to go now pick up my gf from the work
thanks for the time Sir
cleared my mind
np - laters
hey @civic jasper , got a question about architecture, so:
just to visualize things, this is my gameplay screen
ADD X1, ADD X2 - add 1 or 2 slot units to the selected slots
DELETE - deletes the units on the selected slots if there is any to delete
now as I mentioned previously, I am trying to make a SWAP mechanic that swaps the selected units and we already discussed it so I got it covered. The problem is that I want to add something like - pseudocode:
when 2 slots are selected the SWAP button is either clickable or unclickable (lets say it also changes color)
and im having issues implementing this from the architecture side.
my SlotSwapper.cs has a TrySwap() public method that is assigned to a SWAP button then it checks if it can swap etc etc, but I want to dynamically set the SWAP button to clickable or unclickable as soon as 2 slots are selected. How would I do that?
I hope you understand
===
TLDR: everytime I select a slot and I have two slocts selected I need to make the SWAP button clickable/unclickable
Is making a reference to SlotSwapper.cs in the SlotSelector.cs, then in the Update() in the SlotSelector.cs do check if there are 2 slots selected then do a check if they are swappable then turn on/off the button a good idea?
or is it better to use Actions and invoke them everytime a slot is selected?
I wanted to use actions at first, but I didint use them anywhere in my project and I think it'd look bad for the potential recruiter if he sees it, because he might think like: "Why didn't you use Actions earlier for deleting/adding the units? It'd be easier etc" but in the other hand, the recruiter might see that I know some stuff about events aswell so im confused
OnPointerClick method from the interface is on Slot.cs which makes things harder, if it'd be onSlotSelector.cs it'd be much easier but I cannot change it now