#ABBs spaghetti code hour

1 messages Β· Page 1 of 1 (latest)

hexed token
#

Right, so, I'm still on this damn box drawing problem

#

At the moment, my code is back to only drawing one box over one target when it should be drawing three

dreamy carbon
#

might as well break er down from A

hexed token
#

Yep

#

Going to just share ALL the debug info here

#

To start off with, let me paste the code real quick

dreamy carbon
#

iirc this is the targeting reticles?

hexed token
#

Yep

#

That again

dreamy carbon
#

I may have to go unexpectedly, warning πŸ˜›

hexed token
#

So here's the situation. Got three targets I'm testing on, and the program sends debug logs whenever a target is marked as already boxed

#

Here's the problem with that debug log

#

It's marking those other two as already boxed as well

#

But that's not all

#

When I first acquire all those targets, the box jumps from one target to another like so:

#

Now, I know part of what's happening. The box goes to one, the program says "Hey, one already has a box" and moves on with the others

#

What I don't get is that I never actually specified that a box should be deactivated or moved to an inactive list if a target is alrteady boxed

#

I only ever specified that a new box should be pulled if a target doesn't have a box

#

And at the moment that's not what's happening

#

Now, the inspector is showing that there are three active boxes

#

I guess they're all in the same spot

#

I don't know how to tell for sure though

#

So, you know me, I wouldn't come here and ask for help if I weren't already completely at a loss

#

That's about the crux of the problem

dreamy carbon
#

could be a problem with the candidate references? maybe all the boxes are trying to pile onto candidate 1

hexed token
#

They shouldn't be piling onto candidates, only targets, but that does still stand. Let me try making that a forr loop

dreamy carbon
#

could also be a dumb logic thing, it's getting to a pretty confusing state πŸ˜›

hexed token
dreamy carbon
#

debugs in all the conditionals might shed some light

dreamy carbon
#

not worth junking at this point, imo it shoooould work how youve done it

#

just.. slightly unintended behavior πŸ˜›

#

better than compiler errors πŸ™‚

hexed token
#

Well that didn't do it

#

Now it's not doing the "jumping from 1, to 2, to 3" thing

#

New code

#

New logs

#

new inspector

#

And as usual, I am half a second from smashing my desktop in with my fist

visual ruin
hexed token
#

Oh for fuck's sake

#

They all redirect to "TargetAvailable" in the canvas

#

Not the clones

#

Just that one TargetAvailable

dreamy carbon
#

aha

hexed token
#

It isn't even USING the clones I made despite me specifically telling it to

dreamy carbon
#

so it was a target misreference πŸ˜›

hexed token
#

Right, but I'm specifically telling it to use ones from the inactive list

#

It's not doing that of course, because that'd make too much fucking sense

#

let me try removing the original prefab from the heirarchy

visual ruin
#

I guess that's the issue(line 43):

                    Instantiate(greenbox, holdingtank);
                    greenbox.SetActive(false);
                    inactiveboxes.Add(greenbox);
                    runcandidatecheck--;
#

You add the greenbox(prefab?) to the inactiveboxes list.

hexed token
#

oh great, now it's jus tdoing nothing

visual ruin
#

so all of the elements in inactiveboxes are a reference to the prefab

hexed token
visual ruin
#

give what a shot..?

hexed token
#

instantiating greenbox prefab to the inactiveboxes list

#

I gotta figure out which of the 11 overloads that is for Instantiate real quick

visual ruin
#

You should read what instantiate does and specifically what it returns.

hexed token
#

I know what it does, and what it does is not what I need it to do

#

Right, any way to spawn in from a prefab of something that isn't already in the heirarchy?

dreamy carbon
#

hmm like spawn in part of its contents?

#

or the whole prefab

hexed token
#

The whole thing

visual ruin
dreamy carbon
#

yep, easily enough

#

if it were me that'd be like, my entire solution for this system lol

hexed token
visual ruin
hexed token
#

What's the magic nuance this time?

#

Line 43...

#

it makes a new greenbox and moves it to a transform I have offscreen

#

It doesn't actually move it into the list

#

I know that

visual ruin
#

Line 44

hexed token
#

let me guess, it's not deactivating the greenbox I just spawned but the gameobject that's actually in the heirarchy because fuck making sense?

visual ruin
hexed token
#

Which is the one I actually care about

visual ruin
#

Exactly.

dreamy carbon
#

I think the magic nuance issssss

#

instantiate returns a reference to what it instantiates

#

and you need that instead

hexed token
#

Right, any way to actually refer to the object I just instantiated?

dreamy carbon
#

yesr indeedy

visual ruin
#

Now look at the Instantiate docs page. Read the first line of the description

#

I assume, you understand what "returns" means, right?

hexed token
#

Fuck it, let's just assume I don't at this point

dreamy carbon
#

declare an empty gameobject, and define it using the instantiation, like objectRef = instantiate(clone, blabala)

#

or.. declare and define it all in one line?

#

idk theres probably a cooler way to do it.

visual ruin
#

Okay, then I'd suggest going over the C# basics. Specifically about functions and what return keyword does.

hexed token
#

This... is not helping me in any meaningful way tbh, damn

#

Thanks tho

dreamy carbon
#

tbh I actually think that may be a different use of the term return?

#

confusing..

#

might be related and I just don't grasp the significance

visual ruin
#

Honestly, I don't even know how to approach educating about something like this. It's just something so basic that there's no specific way of describing it.πŸ€”

#

Okay

dreamy carbon
#

ye im thinkin just an example

#

imma pull up one of my scripts

visual ruin
#

When you do GetComponent, what do you have on the left side?

dreamy carbon
#

so I've got a public GameObject tempragref;, and then when I instantiate, I go tempragref = Instantiate<GameObject>(looselimbsragdollprefab, playerprefab.transform);

#

and then tempragref is a reference to that instantiation

visual ruin
#

In math if you do x = 2 + y you have a function 2+ y, right? And you want to get a result of the function. How do you get that result? By assigning it to a variable on the left side.

#

Function 2 + y "returns" a result.

dreamy carbon
#

looselimbsragdollprefab btw, is a prefab not in the heirarchy, dragged in with direct public reference from assets/prefabs/

hexed token
#

Let me guess tho

#

"Except when it isn't"

#

Right?

#

Don't even worry about it, I just implemented Uthel's advice of instantiating the gameobject in a new gameobject and I'm now actually closer to fixing the problem.

visual ruin
hexed token
#

yeah. And Instantiate returns a value of a clone. But it didn't change the value of "greenbox", I get it

#

Okay?

#

I get it.

dreamy carbon
#

that way I don't actually need an object for it, it just sits empty

hexed token
#

Right

#

Now

#

It's actually spawning three boxes in the inactive list, and moving them into activeboxes as needed, which is good

#

That's a half step forward which is about as much as I've ever managed to get with this dumbshit problem

#

New problem

#

All the boxes are going to only one target. Again.

#

let me paste the new code and stuff

dreamy carbon
#

that sounds to me like perhaps candidates arent getting applied to targets properly

hexed token
#

Yeah, I know that's what it is

dreamy carbon
#

ahhh dunno, hard to say

hexed token
#

But I have no godly idea why

#

Well, I do have an idea why

#

It's reading that the target already has a box around it and doing nothing about it

#

Same thing happened when I used a forr loop for this instead

dreamy carbon
#

sounds like a reasonable course of inquiry- i gtg tho gl

visual ruin
#

This debug would get printed any frame that onscreen is true, so I don't think it's a reliable debug method.

hexed token
#

Yeah, but the point is that it's still not actually taking the fact that the box is already there and using it as a hint to move on to the next item in the targetlist

#

I'm going to try a forr loop for this and see if that does anything

visual ruin
#

Ah, I see

hexed token
#

I don't specify it, my hope was that it'd take "alreadyboxed" as a hint not to box that one, and instead box the next thing in the list. Which was clearly an error on my part, assuming that computers would do reasonable things.

#

I'll try a new strategy for this for tomorrow. Just make some function that goes down every target in that list and draws a box around it with no smart shit to try and see if that target is already boxed.

#

Literally, "go to item 1 on the list, put the box on the target, move to item 2 on the list, do the same thing, move to item 3 on the list, do the same thing, until you're at the end of the list"

visual ruin
hexed token
#

I thought "for each item in targetlist, if it's already boxed, don't bother boxing it" was pretty fucking reasonable

#

For perfectly logical machines they sure don't make sense

visual ruin
#

Your alreadyboxed state is not linked directly to the items in the list. That's the problem.

hexed token
#

To the items in the targetlist or the box list?

visual ruin
#

logical problem I must say. Not code related.

#

sorry, to the items

hexed token
#

Because I would imagine it's tied to the targetlist, given the fact that it is tied to the target list

#

So, what are you saying? Have some boolean attached to the box that determines if that box already has a target?

#

Because I don't imagine that'd solve the problem either

#

Do I have to put something in the code that specifies "if a target already has a box, don't fuck with the box the target already has and leave it be?"

visual ruin
#

Here's a simplified algorithm of what you want to do. Correct me if I'm getting it wrong.

foreach(target)
{
  if(target is not boxed but within the screen)
  {
    var box = GetABoxFromPool();
    ApplyBoxToTarget(box, target);
  }
  else if(target is boxed but outside of the screen)
  {
    var box = GetAppliedBox(target);
    PoolBox(box);
  }
}
hexed token
#

Yes

#

Which I figured is what I was already doing

#

With my own method names

visual ruin
hexed token
#

Also I thought Csharp doesn't have "else if" statements

hexed token
visual ruin
hexed token
#

What I want it to do is this:

#

foreach (target in targetlist){
  if (target is onscreen and doesnt already have a box){
     giveitabox();
     tie that box to the targets transform
     move to the next target in targetlist;
}
  
  if (target already has a box){
     dont give it another goddamn box and move on to the next target in the list();
     dont fuck about with the box it already has, leave it be for god's sake();
}

}

#

It's struggling with that second part

#

It can recognize that the target already has a box

#

It just does nothing with that information, gives the target a second box anyway (sometimes, sometimes it just moves all three boxes to the last target in the targetlist), and repeats this cycle

visual ruin
#

I think the main problem is the return on line 107. It returns right after the first target, so it just doesn't go to the next targets.

#

But there a bigger overall problem with your code

#

it's convoluted

#

hard to read and debug.

hexed token
visual ruin
#

Here's how you can rewrite your code in a more readable fashion:

//A separate script/class
public class Target
{
  public GameObject Box { get; set;}
  public bool OnScreen { get ; set;}

  public void AssignBox(Gameobject box)
  {
    Box = box;
    //Set parent and position of the box, etc...
  }
}
//in your update method
foreach(target)
{
  if(target.OnScreen && target.Box == null)
    target.AssignBox(GetABoxFromPool());
  else if(target.Box != null && !target.OnScreen)
    PoolBox(target.Box);
}
hexed token
#

Okay

visual ruin
#

8 lines vs 32 in your code.

#

Of course, you'll need to define the new class and some new methods, but the algorithm itself would be crystal clear

hexed token
visual ruin
hexed token
#

So, let me just go through this revision line by line here

#

I already get the box gameobject,

I already declare a bool for whether or not an object is on screen

I already have a script to assign boxes

and I already have a script to assign boxes (the only part of this script that isn't working properly)

I will admit, there is some extraneous shit in there that I plan on removing once this thing actually works the way I want it to, but it sounds like this code would be just as complicated by the time I'm done defining and writing what all those shortened methods mean

#

If the problem is getting the targetlist, that's in a different script

visual ruin
hexed token
#

I'm gonna keep it 100 with you chief, I fucking give up for the night.

#

I'll figure this shit out tomorrow

#

Last thing I'll say is, I don't have the time to get a fucking PhD in programming, I was a history major in college, I'm fucking stupid, okay? I'm not trying to do this for a living, I'm just cramming all this into the few hours of free time I have in a day

#

My metric for success is just the shit I make working

dreamy carbon
#

tbh im surprised you'd take this approach at all without a background in programming - you'd probably be able to easily get away with just having inactive already placed child boxes on the enemy prefabs, and enable disable it on a simple distance to player check

#

no pooling no lists, super simple

visual ruin
# hexed token Last thing I'll say is, I don't have the time to get a fucking PhD in programmin...

You don't need a PhD in programming, but you need a will to learn and improve. Many people on this server put a lot of time and effort into gamedev/programming. If I see someone that says something like "man, I'm just doing it for fun, I don't wanna learn anything, just give me the complete code", I'm getting really annoyed and discouraged from helping them.

If you want to "make shit working" then you've got to put effort into learning. If you don't, then maybe gamedev is not a suitable hobby.

hexed token
#

I'm fine with learning shit, I think I've been pretty goddamn careful about not asking for complete code, and I usually go to the API and tutorials unless I'm just really at a dead end

#

But when I'm at that dead end and I have to go through a wall of "are you actually fucking stupid, get fucked," yeah, it's not exactly helpful.

#

I'll rewrite the code to make it more abstract

visual ruin
hexed token
#

You said "you should learn what return means" phrased as 'you should learn the basics" when the problem was actually "I don't think that word is referring to what you think it's referring to"

#

One is a lack of effort on my part and the other is just me not catching that something didn't mean what I think it meant

hexed token
#

FINALLY

#

This was the problem code after fixing

#

if (alreadyboxed == false && onscreen == true && i <= boxpool.Count && i >= 0)
                {
                    GameObject box = boxpool[i];
                    box.transform.position = screenposition;
                }
#

this was the problem code before fixing

#
  if (alreadyboxed == false && onscreen == true)
            {
                foreach (GameObject box in activeboxes)
                {
                    box.SetActive(true);
                    box.transform.position = screenposition;
                    alreadyboxed = true;
                }
            }
#

The problem was, I wasn't specifying which box in the box list to draw on

#

I was just saying "iunno pick a fuckin' box shiiiii"

#

And that's what it did

dreamy carbon
#

as dlich says, the computer was acting entirely within reason, doing exactly what you told it πŸ˜›

hexed token
#

Never fucking mind.

#

It's just broken in a different way now.

dreamy carbon
#

Sounds normal

hexed token
#

I'm never going to be done with this

#

I'm going to spend the rest of this project focused on drawing fucking boxes.

dreamy carbon
#

I mean, if you want.

#

you are in charge πŸ˜›

#

you will be hard pressed to find someone who cares -how- the boxes are handled πŸ˜›

hexed token
#

The players, who need this UI to work so they can understand what they can actually lock onto with missiles

dreamy carbon
#

yeah, but how? the method doesn't matter

#

none of them care how

#

is what I meant πŸ˜›

hexed token
#

I can't think of any other way how that makes sense

#

I can't tie the box to the target because the box has to be in the UI canvas

#

I can't just instantiate a new box and destroy it at will becasue that'd be too costly

#

Anyway, the new problem is that it's not actually drawing a box on any target unless the last item in the targetlist is in frame with it

#

I know it's because of all the Forr loops somehow, and I'm so fucking through with this

#

I'm sitting here maniacally laughing at how fucking futile this whole effort is, and it's 11 PM

dreamy carbon
#

and see I'd tie it to the target and don't think instantiating/destroying would be too much, and if in testing, it proved to be, I'd switch to always having the quads on the ships, and enable/disable

#

doesn't need to be on ui canvas

visual ruin
#

As I said previously. There's a systematic problem with your code architecture. You're gonna keep on stumbling on issues, unless you rewrite it.

#

But yeah, what Uthel suggests is way simpler to implement.

dreamy carbon
#

I'd add a script to orient the quads to the camera so they look like dynamic ui elements scaling with the ships, and animate them popping in and out

#

and I can almost guarantee it'd not be obese

#

animate with the overweight animator mind you, not using efficient lerps

hexed token
#

I did what you asked

#

I put everything in a neat little function outside the update function

visual ruin
#
getcandidates(); //get the list

Get the list of what?

hexed token
#

The target list

#

Anyway, as I was saying

dreamy carbon
#

break time for sanity's sake

visual ruin
#

What do you have in these methods? If you just placed whatever you had into a method, nothing changed at all

hexed token
#

I can read my own code just fine, the problem is, every time I account for a new edge case and fix it, a new, different edge case comes up

hexed token
#

Does EVERY if statement have to be its own method?

visual ruin
#

The problem is not just putting code in a method

hexed token
#

I have like seven different methods

#

I can't keep track of all the fucking methods

visual ruin
#

Share your code. I can't say anything specific without seeing how you implemented it.

hexed token
visual ruin
#

Ok, so nothing changed at all.

#

There's literally 0 point in putting that code in the methods.

#

The same code that you had before.

hexed token
#

Fine. Delete the code? Start over a third time?

#

I'll do it! I do not care at this point!

visual ruin
#

You don't even need to restart from scratch. Only refactor.

hexed token
#

Okay

#

I have zero clue how I'll do that without tangling it up more

#

But okay

visual ruin
#

That's the thing. You made it too complicated. You need to simplify it.

#

For starters, listtransfer doesn't make sense. You want to move the boxes between active and inactive lists, but you just move the top element in the list regardless of whether it's the element that you really need.

hexed token
#

And pray tell, how does that happen?

#

Is it amounttomove?

#

Because I have no clue how else to specify that I only want this to happen once, and not on every frame

#

Because that was the problem I was getting last time, when I tried to do it simply

#

I tried making this simple, and then I had to include a fix for the simplicity, and then a fix for the fix, and a fix for the fix for the fix

visual ruin
hexed token
#

Fucking, setactive can be used like that?

visual ruin
#

Why not? You pass it a bool. Of course it can.

hexed token
#

I fucking tried using it as a bool earlier and it didn't work

#

I guess I used it as a bool but not in the right way

#

Alright, making that change

hexed token
#

If I'm setting the box to active, I want it in the active box list

#

Or rather, if it's in the active box list, I want it active

#

This code takes something set to active and removes it from the active box list

visual ruin
#

Yeah, you want to switch them around

hexed token
#

Wait, also, how does this account for the fact that I'm moving things between lists?

#

There's no function here to make sure that I'm actually removing just one thing from one spot and putting it on the same spot in the other list

#

This is just going to lead to the same problem I had earlier before I added all these forr loops where the lists would end up not actually reflecting what they were supposed to reflect, and I'll end up with a ton of errors for being outside the list parameters

visual ruin
hexed token
#

That's what I thought too until I got countless ArgumentOutOfRangeExceptions or some other thing I'm probably forgetting the name of

#

But I'll do it

#

How is that code going to work here? How is it going to know how many boxes to transfer over if there's no parameter for that in the setboxactive method?

#

Actually, wait, that's not going to matter at all in the listmanager because the parameters required to make that block work don't even exist in listmanager

#

Which calls listtransfer the most

#

Would I have to put another forr loop inside the listmanage function at every if statement?

#

Well, I implemented the change in whatever snippet of the code I could before the thing fully broke. It kind of does what I wanted it to do now, but boxes linger on the screen long after targets have left and there's so many errors the framerate drops

#

I don't care anymore. It's midnight, I've run out of spite to keep myself up.

dreamy carbon
#

the solution will come to you in your dreams

#

don't miss it

hexed token
#

Well, that's enough spite to keep me up an hour longer I guess

visual ruin
#

Donno why I'm doing this, but that's all you really need for it to work. No extra methods(aside from the bool check), no additional classes. Super simple.


    private List<GameObject> inactiveBoxes = new List<GameObject>();
    private List<GameObject> targets = new List<GameObject>();

    private List<GameObject> activeBoxes = new List<GameObject>();
    private List<GameObject> boxTargets = new List<GameObject>();
    private void Update()
    {
        for (int i = targets.Count; i >= 0; i--)
        {
            var target = targets[i];

            Vector3 worldPos = target.transform.position;
            Vector3 screenPosition = maincam.WorldToScreenPoint(worldPos);

            if(!boxTargets.Contains(target) && InView(worldPos))
            {
                var box = inactiveBoxes[0];
                box.SetActive(true);
                box.transform.position = screenPosition;
                inactiveBoxes.Remove(box);
                activeBoxes.Add(box);
                boxTargets.Add(target);
            }
            else if(boxTargets.Contains(target) && !InView(worldPos))
            {
                var index = boxTargets.IndexOf(target);
                var box = activeBoxes[index];
                box.SetActive(false);
                activeBoxes.RemoveAt(index);
                boxTargets.RemoveAt(index);
            }
        }

        for (int i = 0; i < boxTargets.Count; i++)
        {
            GameObject box = activeBoxes[i];
            GameObject target = boxTargets[i];
            Vector3 worldPos = target.transform.position;
            Vector3 screenPosition = maincam.WorldToScreenPoint(worldPos);
            if (InView(worldPos))
                box.transform.position = screenPosition;
        }
    }
#

Of course, you need to fill the inactive boxes and targets list on start.

hexed token
#

I am very tempted to use that

visual ruin
#

At the very least read it and see what and how it does it?

#

The InView method is missing:

    private bool InView(Vector3 worldPos)
    {
        Vector3 viewPos = maincam.WorldToViewportPoint(worldPos);
        return viewPos.x >= 0 && viewPos.x <= 1 && viewPos.y >= 0 && viewPos.y <= 1 && viewPos.z > 0;
    }
hexed token
#

I'll be honest, I don't know if it'd work, I'm fully convinced that it'd at least work more than what I have now, but I kind of don't want to use it out of principle at this point

visual ruin
#

Not telling you to use it. Just to read and try understand the logic. Then compare to the logic in your code.

dreamy carbon
hexed token
#

I didn't even know indexof was a function

visual ruin
#

Imagine defining each of them as bool x = viewPos.x >= 0

dreamy carbon
#

ohhhhh

visual ruin
#

then doing return x && y && z && w

dreamy carbon
#

ohhh okay

#

I get it

hexed token
#

It's midnight. Here's what I'm going to do

#

I'm going to delete the code I have because it's worth nothing to me

dreamy carbon
#

well

#

dont delete

#

archive.

hexed token
#

too late

#

I'm going to look at the code dlich posted and see what functions are in there that could help me that I didn't even know existed

#

I can already see a few

#

And then I'm going to write my own code again, because I specifically set out not to be the guy who asks for completed code.

dreamy carbon
#

good plan πŸ™‚