#The Great Refactoring
1 messages · Page 1 of 1 (latest)
Your game looks good. It's got good graphics and personality and whatnot. The code is just a mess. So let's start seriously combing through it and see if we can untangle it
ok
Let's start with the Checkpoint script. Just to make sure we have all the info, can you show the inspector of the Checkpoint object, and the code for any of the scripts on it?
starcheck is for the checkpoint sprite when it is not passed. while the sprite starpassed is when you have passed the checkpoint which you can respawn from.
public bool checkpointReached; is to check is the checkpoint is passe dby any of the players or not
private SpriteRenderer checkpointSpriteRenderer; is so that the sprite can be changed to being passed
while i don't know about private GameObject _gameOverScreen; but it is used for if the player lost all lives down to 0 lives and when you die agian, it goes to a gameover screen
So, it looks like the purpose of the checkpoint currently is to:
- Detect when a player has touched it
- Change sprite based on whether it's "active" or not
- Spawn the player when they die
I'd argue that 3 doesn't need to be the responsibility of the checkpoint. If there's a thing that tracks the last known checkpoint, it can ask for things like position from that checkpoint.
I notice a lot of code that is designed around pulling the player objects out of the ether to get references to various scripts. Perhaps it'd be better to have a sort of "Player Manager" that handles the respawning and referencing? The checkpoint would simply identify if a player touches it, and let that player manager know to update the most recent checkpoint.
Does this seem like something that makes sense?
https://gdl.space/hofehuquro.cs well here is the player manager script
https://gdl.space/iwimeyesub.cs this is the code when takes damage
https://gdl.space/rodiduzobi.cs this is for health
There's a good bit of ambiguously named variables here.
public static PlayerManager instance = null;
public bool p2 = false;
public bool _nextScene = false;
[field: SerializeField] public int X { get; private set; } = 1920;
[field: SerializeField] public int Y { get; private set; } = 720;
[field: SerializeField] public bool P2 { get; private set; } = false;
private int _playerLives = 3;
[SerializeField] private GameObject _gameOverScreen;
The static instance makes sense. _playerLives is straightforward as well.
The X and Y are a bit less concrete. Are they the size of the screen? What values do these represent? There's probably better names than just "X" or "Y".
I'm unsure about the two separate booleans called just P2, what are those supposed to be? Also _nextScene, what does this bool represent? And another reference to _gameOverScreen? Why does everything reference this, it'd probably be better for the game over screen to have a script of its own that checks data. We'll get to that later.
i think it is the size of the screen if you're just single player
P2 stands for player 2. _nextscene i think it is part of other scenes if you want to go to the next scene like hwen you press a button and you go over to the new scene
and that it have playermanager in every scene so that you can choose player 1 or 2 players
So, X and Y should probably be renamed to ScreenWidth and ScreenHeight respectively. If you're using Visual Studio, you can highlight a variable and hit Ctrl+R Ctrl+R (yes press it twice) and type in a new name, and it'll update everywhere that uses it to the new name. If you use VSCode I don't know the shortcut for that but it's a Refactor -> Rename in the right click menu I think
So, P2 is true when there's two players? A better name for that would be isMultiplayer. And you have two copies of it, you probably don't want both.
_nextScene doesn't seem to be used in this script at all, so it's a candidate for being removed to go somewhere else later. For now, just move it somewhere else and we'll put in a comment that it's potentially to be removed later. So, let's start from a base that looks like this:
public static PlayerManager instance = null;
[field: SerializeField] public int screenWidth { get; private set; } = 1920;
[field: SerializeField] public int screenHeight { get; private set; } = 720;
[field: SerializeField] public bool isMultiplayer { get; private set; } = false;
private int _playerLives = 3;
//TODO: Determine if these variables need to be here
[SerializeField] private GameObject _gameOverScreen;
public bool _nextScene = false;
i use visual studio
Okay, so the Ctrl+R, Ctrl+R shortcut should pop up a box where you can bulk rename a variable. Using readable, expressive variable names goes a long way to making the code more maintainable and easier to fix down the line. Then you won't need to guess what a variable might mean
Or accidentally use it thinking it means something different. This is a small fix, but we're gonna make big changes by stacking a buncha small ones on top of each other
aren't we gonna fix that with respawn thing?
Like I said, at this point, fixing it with another bandaid is just going to make the next fix take exponentially longer. The stuff I'm suggesting right now isn't going to directly fix the problem but is going to give you and anyone reading your code a much better understanding of what's happening and make the problems easier to solve.
If you don't want to go through with this refactor, that's entirely on you but it is at this point simply too much of a mess for anyone to reasonably be able to help at this point.
Or you could just slap this warning at the top of your code files
All right cool beans. Now, I think a good job for the player manager to have is to be the thing that holds the one true canonical reference to the player objects, don't you think? Before we add code for that, let's take a look at the player objects. Can you send a screenshot of the entire player inspector, with all the components and tags and whatnot on them? Multiple screenshots is fine if it can't all fit on screen at once.
ok
but first, ever since that it were a red line in one of the scripts with p2
Your boolean has a private set, meaning it can't be changed from another script. If you intend for other things to change it, it shouldn't be private
but it is public though
Look at the line where you declare it. Do you see the word private anywhere
Yes that is what I said. The setter is private
It can't be modified from outside of this script
they all always had get; private set;
And I presume the last time you got this error instead of finding out what it means you just made a second p2 boolean instead of fixing the problem
If this variable is intended to be changed outside of this class it should not have a private setter.
if i go back to the previous script, it no longer have the red line. but i don't have a secon p2 though
oh wait..
broguht the public bool p2 = false back
This line was not the incorrect one. It should be using the new isMultiplayer bool
No
Do not
It was deleted for a reason
but that's the only way so the red underline is no longer there anymore
but i need it there, or else it won't work, and i need it for the player select button
This should not be p2. This should use isMultiplayer
it still won't work
how can i change get; private set into public while i will only get red underline for this?
Why is the setter private
You seem to be absolutely unwilling to change this
Why is it so important to you that the setter is private
do you even know what that means
i said how can i change "get; private set" into public while i will only get red underline for this?
By not making the setter private
Instead of marking it as private, simply don't
what i meant by should i cahnge or remove it?
Again I ask, do you know what private set; means
private means "Cannot be accessed by other classes".
private set; means "This variable cannot be changed by other classes".
If you want another class to change this variable, why did you make the setter private. That's literally the entire point of the private access modifier
That doesn't just happen. If that access modifier is there it's because you put it there. Why put it there if you didn't actually want it to be private
here are the screenshots of inspector
So, the first one doesn't need to use p2 and p2 should not exist any more. Delete it if you put it back.
The isMultiplier being a normal variable without getters and setters is fine. That would also resolve the problem. You can remove the [field: SerializeField] since it's no longer a property
Yes. There we go
While you're on that line, ditch the Find. PlayerManager is a singleton and instance exists purely to avoid having to use find
PlayerManager.instance.isMultiplayer =
ok, there
screenshots here
Okay. Now we can move on to making the PlayerManager much more useful. It looks like your player object has two scripts of your own creation, Player2D and HitPoints. Everything else is built-ins. Correct?
built-ins?
Components provided by Unity, such as colliders and animator and whatnot
The only actual scripts on the player are Player2D and HitPoints, right?
well yeah
while the 5th image is checkpoint and 6th image is playermanager
Just wanted to make sure I didn't miss anything.
So, it seems reasonable to make the Player2D script the "Primary" script. Whenever you want to reference a player object, that variable should be of type Player2D. You can use that script to get references to the others. The alternative would be creating a brand new script whose sole purpose is to just hold references to each of these components on the player. Either one would work and both have benefits. Do you have a particular attachment to either design?
What do you mean by "make that type of script"?
Like, how would we make one that holds references?
It'd just be a component with a bunch of public variables
the fact you said creating a brand new script whose sole pupose is to just hold references to each of these compnents on the player?
We don't have to do that. Having that means your Player2D script would be simpler, but it means you have an extra .Something every time you want to use a reference
So, it's up to you. We can do either.
wasn't there someone who said respawning the same object would be better than respawing a new one?
That literally has absolutely nothing to do with what I have been saying
We are nowhere near that yet
i don't know how to make that type of script
We can get to the how later. For now, just pick one design. Smaller Player2D or simpler reference chains
uhh.. what? one design? smaller player2D? simpler reference chains? I don't get that
Okay, let me back up a bit.
We need to pick a component that is the single core representative of "Player". This script is the thing that you will be making variables to hold in order to reference a player. This can either be Player2D which you already have, and doing something like getting the player's animator would mean another script would be doing PlayerManager.instance.player1.animator.
The alternative would be having a script whose sole purpose is to just have public variables holding the components. This would mean that inside of your Player2D script, instead of having a variable animator and collider and whatnot, you'd have one field holding your new script (let's call it PlayerComponents) and you'd do this.playerComponents.animator instead of this.animator. This means your Player2D script no longer needs to have all those variables, making it shorter, but increasing the length of each line that tries to reference another component
This is purely your own choice. There is no "right" answer. Which one do you want to do
hmm... let's.... try the alterantive, i don't knwo what ot decide
Okay, so, a landing script. Let's start by making one. Make a script named PlayerComponents, and give it a public variable of each type the player has on it
So, for every component on this object (other than Transform which all scripts have access to already) make a public variable of that type
public Rigidbody2D rb, etc.
like this?
Yes. For every component type. And minor nitpick but public variables don't start with a _ in the C# style guide, but that's not actually a problem, just against the usual norms of C# code.
there you go
Include Player2D and HitPoints as well
Okay cool. Now, this is going to serve as the main script through which you're going to reference a "Player". No matter which component you want from the player, you'd reference this PlayerComponents script to get it.
As an example, we're gonna make the PlayerManager better, add these two variables to it:
public PlayerComponents playerOne;
public PlayerComponents playerTwo;
Now, we can make a decision. Currently, you are destroying and respawning the players when they die which is breaking referencing. As suggested before, we can just teleport and reset the player whenever they die instead of spinning up a new one, or we can fix the referencing whenever a player respawns. Again, there is no "right" answer. Do you want to re-use the same player objects, or spawn new ones?
No, these two would be in PlayerManager. They'd reference this script
but you made this script so your PlayerManager can reference them
hmmm.... let's start with spawn new ones. because i feel cahnging something would change a lot with other things for the player
Okay, good. Now, this means we need prefabs for player one and player two. You probably already have some by the look of things, so let's go add on a PlayerComponents script to them and setting all these references. Just drag the object into each of those slots, and it'll get that component from the object.
uhh... about the player2d script. since player2D is for the player like move around, jump, climb, groundpund and stuff
also, i can't drag the play prefobso nto the player one and player two components
Yes, I know. This script will reference it.
You won't be able to until it has a PlayerComponents script on it, which is the step we're currently on
should the player prefab object have the player components script?
Yes. That's what I said to do up here:
#1237461875633950770 message
so let's go add on a PlayerComponents script to them and setting all these references
there we go
Yep. Now just drag the Player1 object into each of these slots.
And then do the same for your Player2 prefab if it's different
Yep. Just like that. Once you have it on the Player 2 prefab (if there even is a player 2 prefab) let me know and we can move on
Okay, now, back to the PlayerManager. We'll have this script be responsible for holding the references to the prefabs as well. Note that these are different than the ones we already added:
public PlayerComponents playerOnePrefab;
public PlayerComponents playerTwoPrefab;
And then drag in your prefabs (not the instances in the scene! The actual prefab files from the assets window) into those two slots
Keep the playerOne and playerTwo variables we made earlier. Those ones refer to the object that currently exists in the scene, that will be changed when the player respawns
hm, what?
At no point did I say to add these to Player2D
I said to add them to PlayerManager.
Since the PlayerManager is responsible for holding both the prefabs and the current instances, it'd make sense for this script to be responsible for spawning them.
public PlayerComponents SpawnPlayer(int playerNumber, Vector3 position, Transform parent = null){
if (playerNumber == 1) {
playerOne = Instantiate(playerOnePrefab, position, Quaternion.identity, parent);
return playerOne;
} else {
playerTwo = Instantiate(playerTwoPrefab, position, Quaternion.identity, parent);
return playerTwo;
}
}
Yep, exactly
playerOnePrefab is the template file that you copy into the scene to make a new player one
playerOne is the actual object in the world that can move around and do stuff
I updated the thing I posted. Gonna make some minor mistakes since I'm typing directly in Discord without autocomplete
So the updates should fix it
oh
Once that's taken care of, the next question: Do the players start in the scene already, or do you want to spawn them in after the game starts?
uhh... what's the difference?
Well, one of them starts with the players already in the scene.
The other one spawns them in after the game starts.
Again, no wrong answers. You just have to decide on one.
players already in the scene
Okay, so the SpawnPlayer function will only be called when a player dies. This means you should drag in those objects already in the scene to the playerOne and playerTwo variables on your PlayerManager
Okay, and just to make sure, the two prefab variables are referencing the actual prefabs, right? Dragged in from somewhere in this window?
yes
Okay good. Now, let's take a moment and look over what we've got, and how it might be used.
PlayerManager now has a canonical reference to the player one and player two objects at all times. Whenever you want to reference the player one object, you'd do PlayerManager.instance.playerOne
yet when after i playtested it and hwen i die and respawn, i'm still unable to move and the health bar doesn't go back to full
hu
If you ever want to respawn player one, you'd call PlayerManager.instance.SpawnPlayer(1, [ ], [null probably])
We're almost there. We need to rewrite the respawning to use SpawnPlayer, and the health bar and whatnot to use PlayerManager.instance.player___ instead of dragged in references
in the playermanager script?
The PlayerManager script is now what we call the "Source of truth". Other objects might need to reference the player, and rather than keeping their own reference around which might become "stale" when the player dies, they should always go through the PlayerManager. As a practical example, let's fix the health bar. Can you show the code for where you set that health bar?
i meant should i put t in the playermanager script?
Put what
PlayerManager.instance.SpawnPlayer(1, [ ], [null probably])
I haven't asked you to put anything anywhere yet
That's just how you'd spawn a new player.
You'd call that wherever you want to respawn a player
and just to be clear that's psuedocode
Just an example to show how you'd call it
https://gdl.space/rodiduzobi.cs this is health bar, it always works.
https://gdl.space/maqowiyuce.cs and this is for when you get taken damage and have the healthui script attacehd there
Okay, so, ditch the _player variable entirely, and give it an int playerNum instead.
This reminds me of another change we should make in PlayerManager to make things easier:
public PlayerComponents GetPlayer(int playerNum)
{
if (playerNum == 1) return playerOne;
else return playerTwo;
}
Then, inside of PlayerHealthUI, instead of using _player, use PlayerManager.instance.GetPlayer(playerNum).hitPoints
You following so far? You figuring out how this is gonna work?
but what about public HitPoints?
Absolutely nothing but PlayerManager should have direct references to any component on the player objects.
This means that whenever a player respawns, only the player manager needs to be notified. Everything else will just work with no extra effort
And here. The operative word is using. You are using the variable inside of UpdateGraphics. Not when you declare the variable.
That should be gone
And instead of using _player, use what I said
playerNum instead?
Think this through
Do you know what PlayerManager.instance.GetPlayer(playerNum) does
no
what
why
I've gone though so much trouble explaining all of this
why are you just
ignoring it all
Are you just waiting for me to write code and not taking any effort at all to read the words I'm saying to explain it all
i am doing what oyu said instead of using _player use PlayerManager.instance.GetPlayer(playerNum).hitPoints
Why would checking if i is greater than your player number make any sense
Then what the hell is this
Why are you checking if the index of the image is greater than the player number
why would that make sense
Why are you just making changes without thinking about what any of this means
Do you know what this line does
Do you know what you are trying to check for
Going back to your own code, can you even tell me what this is doing
That's closer but why did you change the one that was already working into something that doesn't
Also you still aren't checking what the hit points are
Stop guessing
Take a moment
think about what you want to check
and then think "how do I get that value?"
Okay, pause on the code changes
We're not touching code for a bit until you actually understand what you are doing
From your old code, what does this line do
What is this checking for
all you said to me is that instead of _player, use PlayerManager.instance.GetPlayer(playerNum).hitPoints. nothing more
Yes, and you didn't even do that
You did a whole bunch of other shit that didn't make any sense
So we're backing up
Because you've missed something very very fundamental
so we're going back to explain whatever it was that was missed
I need to know where you've missed something so please give your best answer to that question
the i = 0 meant like if there's 0 lives
Just, that if condition
What is it checking
i don't know, it was a long time ago since last time i checked on the heaalth ui script
Even if it's been a while, you can just read it
what is it checking
i don't know....
_imglist is how much health you have you can choose
and check if there's.... no life on the health bar left?
Just, that one line. Rephrase this line into words:
if (i >= _player.hitPoints)
Do you know what an if statement is
will... a decision statement which... will execute if the condition evaluates to true?
Yes, exactly. So you know what if means
That leaves
i >= _player.hitPoints
What does that mean
..... i don't know, i don't even know anymore what it means. that... if the player takes hit.. the health heart get's broken image to show you lost a health?
Literally just this line
i >= _player.hitPoints
What does literally just this line mean
What is this checking
Code is not magic.
Every line means a thing
in plain english
What does this line mean
I DON'T KNOW! I don't know what it means anymore! i don't remember!ðŸ˜
I'm not asking if you remember
I'm asking you to read
what do you not understand
Do you know what >= means
Is that it? Do you not know what that symbol means?
Is that why this is hard for you to explain?
i know that = is like if the same and i know that > as in if 6 is bigger than 5
Okay, so, what do you think >= means from that information
idk
Listen, and I mean this with the no disrespect. If you cannot combine these two thoughts into one, then you should not be making a game
This is literally the answer
You just need to synthesize both of these into one statement
and if that's not something that you're capable of, then this is probably not a good hobby to try.
......greater than or euqal?
Yes
correct
So, knowing that >= means "is greater than or equal to", we go back again:
if (i >= _player.hitPoints)
What does this sentence mean? What is it checking for?
so... i (0) >= (greather than or equal) _player.hitpoints (player's health of 5)?
Yes. It is checking if i is greater than or equal to the hitPoints variable on _player
So, _player was previously something you dragged in, right?
and no longer exists
yeah
Because we're trying to avoid having anything reference a player that you've dragged in. Since we're trying to make sure PlayerManager is the only object the player gets dragged to
This means that whenever PlayerManager changes the object it's using, then this object will use that new one, without us having to change this object as well
Does that make sense so far? You understand why we need to change this?
yeah..
Okay, so, since _player previously held the HitPoints component on the player and we dragged it in
How might you get that same component using our new PlayerManager system?
hmmm... i >= playerNum? since it already the the other thing called PlayerManager.instance.GetPlayer(playerNum).hitPoints somewhere?
playerNum is just which player this is for
Player 1 or Player 2
Does i is greater than or equal to the player number mean the same thing as i is greater than or equal to the player's current hit points?
no
So, we are trying to rewrite this line so that they both mean the same thing
It must end up meaning i is greater than or equal to the player's current hit points
in order to know that, we need to know what the player is
So, how do we get the player from PlayerManager?
If you don't know, let's start smaller: How would you get the current instance of PlayerManager?
get the... playercomponents from.. there? since it have both of the players, the current ones and the prefab ones
Yes.
And we added the GetPlayer function
that gets us the object for that player number
If you do GetPlayer(1) it gets the playerOne object
And GetPlayer(2) gets playerTwo
oh, so GetPlayer(playerNum) is either GetPlayer(1) or GetPlayer(2)?
It'll call GetPlayer with whatever the current value of playerNum is
You'd set that in the inspector for the health bar. 1 for player 1s health bar. 2 for player 2s
so this is the first one
while i >= _player.hitpoints should bec alled something else instead of _player too
So, this part is a bit confusing because your hit points script has a variable named hit points
You want to call .hitPoints on the HitPoints component of the current player
this is playerhealthui script i am in
Yes, I know
Right here, you know how to get the HitPoints component of the current player.
You need to get the .hitPoints from that
Then check if i is greater than or equal to that
hmmm... instead of i >= _player.hitpoints.... i >= playerNum.hitpoints?
(since before that it was called _player != null and don't have hitpoints)
Yes, that was going to be my next suggestion, but I wanted to wrap up this other if statement first
Does int have anything named hitpoints
Let's break this into numbered steps.
- Get the
HitPointscomponent of the current player. - Get the
.hitPointsfrom that - Then check if
iis greater than or equal to that
Let's answer these sequentially. What is the answer to question 1?
hmmm.... I don't know what's the answer... the hitpoints script?
Remember when we added the PlayerComponents script to the PlayerManager
So we can access all the components on the player
yeah
And remember how we added a function GetPlayer that gets a player for a given slot number?
yeah
So, if GetPlayer gets the PlayerComponents instance, and that has a reference to the player's HitPoints component
How might you get the HitPoints component for the player with a given slot number?
hmmm... (i >= PlayerManager.PlayerComponents.hitPoints)?
You are on the right track
But you're skipping steps
- How do you get the current PlayerManager instance?
- How do you get the
PlayerComponentsfor a player of a given number? - How do you get the
HitPointscomponent from aPlayerComponents? - How do you get the
hitPointsvalue from aHitPointscomponent?
Literally just answer these one at a time
Don't try to write the whole line
Start with 1. What is the answer to that one?
.... i don't know
||Instance||
So look back at the code I've had you write. What looks like it might be a way to get the instance from PlayerManager?
...get the playermanager script first? PlayerManager.instance?
Correct! PlayerManager.instance is the way to get the current instance of PlayerManager!
Now, question 2:
How do you get the PlayerComponents for a given player number from a PlayerManager?
hmmm... I would say PlayerManager.instance.PlayerComponents, but...
Is there anything on PlayerManager named PlayerComponents
hmm... no.. except for the four public to hold onto and.. the two lines with SpawnPlayer and GetPlayer
PlayerManager.instance.SpawnPlayer?
So, if you're trying to get the player of a given number
Why is your thought going to "spawn" player
You're just guessing again
please, think it through
How many times have I said that GetPlayer gets a PlayerComponents for a specific playerNum
You just aren't reading the things I'm saying
you're randomly guessing wrong things until I get frustrated enough to write the answer
I've said this many many times
PlayerManager.instance.GetPlayer?
(I guess i am just a dumb person because of having a low iq mind...)
Ignorance is a place everyone starts from and can grow beyond.
Stupid is a choice.
Don't choose to be stupid.
If you say "I cannot understand this because I am dumb" then you're right
You have to actually try. The only way you end up stupid is if you decide to be
hhh...
Or impromptu (on the spot response), new to coding, not interested in learning to code etc
Investing in learning a bit can save you a lot of time and headache.
I did way back then in school but i always tend to forget everything, everytime.
I'm gonna tell you something you might not want to hear:
None of the problems encountered here are due to not understanding how to code.
They have all been failures in logical thinking and information synthesis
this is not something you can learn from a tutorial
Pretty normal, as my old professor once said "you don't use it, you lose it". I prefer, "you don't use it, you'll not be so good at it".
You are going to need to put conscious effort into breaking things down into systems of rules and recombining them into single ideas
Start with a collection of things known to be true. Make conclusions from them
.... to try and get the public Hitpoints?
you kinda of ignored my comment here
It's not wrong but incomplete
I didn't ignore it, it's missing part of the answer and I gave you the links to where in the conversation I've said how it's used
GetPlayer is a function that gets a player with a given number
You need to tell it if you want player 1 or 2
PlayerManager.instance.GetPlayer(playerNum)?
PlayerManager.instance.GetPlayer(playerNum).hitPoints?
that one... is tricky, since there's no hitpoints value name in PlayerManager
You don't need to look in PlayerManager
you just got the HitPoints component
- How do you get the
hitPointsvalue from aHitPointscomponent?
that is your life and which you can lose a life
They mean what Type is the variable hitPoints you've just gotten access to
So it's not an int? Referring to the hit points member of the player component
I mentioned earlier
This is confusing because HitPoints has a hitPoints
should it be called "health" ?
Probably
That'd make things easier
Remember the refactor thing?
Change that int variable's name to health
public int health
yes exactly
Now, how would you get the health value from this?
So the refactored question would be
How do you get the health value from the
HitPointscomponent
Where I'm assuming the player component had a reference to the HitPoint component, which you've gotten now but have yet to get the health value.
hmmm.... HitPoints.health?
now put it all together
questions 1-4
how would you get the health value of the current player
PlayerManager.instance.GetPlayer(playerNum).HitPoints.health
Yes
Congratulations
Now, we go back to the original question we were trying to fix
How would you now write
if i is greater than or equal to the health of the current player
Reminder that HitPoints is the class. You'll want to use the variable from whatever player component returned - assuming it's not Pascal case unless a property.
i >= PlayerManager.instance.GetPlayer(playerNum).hitPoints.health
There you go
Now, you have finally learned what I meant when I said to replace _player with PlayerManager.instance.GetPlayer(playerNum).hitPoints
yeah
Hopefully you've learned how all this worked because your homework is now to replace every single dragged in reference to a player with the one from PlayerManager in any of your scripts
If you need a refresher, just read through this thread again
I'm gonna go be somewhere else for a while
ok, while one reminder is that the checkpoint script have some erros after that
Which are?
So what do you think you need to do?
Probably something related to this #1237461875633950770 message
replace _player with PlayerManager.instance.GetPlayer(playerNum)?
I'm not sure what the stuff before the variable access is but you likely do not need any of it.
this is the script i sent
You've got access to the player manager instance which has access to every player.
but if i remove them, then the player health bar image won't be changed to damage
an on top of that, the enemy doesn't die
Everything-to-be-replaced = go.GetComp..
uhh.... go.GetComp?
The other side (stuff on the left hand side of the assignment operator) should be your concern
what?
left-hand-side = right-hand-side
You'd want to assign the hitPoints variable the new instantiated game object's component and not the health value.
you kinda ignored the script i sent here
What do you think goes where player number is?
There wasn't a question.
I'm not on the correct platform to be writing code. I can only direct you in a lazy fashion towards what needs to be changed. You're almost done with that statement.
You might want to read this again.
there is no health value there though
I did not mention health 
yes you did
I don't know what I'm doing,
I don't know how to fix that line
You'd want to assign the hitPoints variable the new instantiated game object's component
yeah, but idk how witht he new current code that's in there
and i don't know what else to write there
Just focus on line 53
And think about this
I. Don't. Know. How. Right. Now
You've got the player now. When you type the dot after the Get Player method, what's available?
idk what to write there. hitPoints?
Is your ide configured? There should be suggestions.
So you need to replace playerNum with something
I'm guessing this is player 2 relative to the remainder of the code
I'm pretty certain it wants an Integer
healthUI is for player 1
what?
What does the GetPlayer method expect?
So it's player 1.
I am so stuck right now
is this what i'm supposed to write or not?
Well, Player1 is a bool.. and it doesn't seem to want a bool.
Maybe you ought to give it an integer instead.
These are integers: 0, 1, 2, 3 ...
what am i supposed to write?
aghhh. I am so stuck right now
Try 1
what do you mean by that? where do i write 1 somewhere?
You'd write it where you're supposed to write - an argument to be passed to the Get Player method
Where the Get Player method is expecting an integer
I'm assuming everything is working now? 😂
hang on
nope
you see, this is why i use _player or else i am unable to but the hitpoints script in player in there
the first one is from my previous scrip,t and the second image is from the newe one
The entire point was to not drag in the player
The fact that the field there is missing is a feature, not a bug
what feature is missing?
Please reread the sentence
public int playerNum;?
the health images are working, but however. there problem is still the same that when i die and respawn, I am sitll unable to move and the health bar is not back to full
Have you changed your player respawning to use SpawnPlayer
uhh... no? where should i put it?
Instead of instantiating the player normally, use that function
should I replace GetPlayer with SpawnPlayer and where in which script?
Instead of instantiating a player directly, call SpawnPlayer
that was not an answer to the question
Because it was the wrong question
how do i changed my player respawning to use SpawnPlayer if I don't understand where to write? in which script?
Wherever you are instantiating a player, don't. Use SpawnPlayer instead
HOW THEN? how can i instantiating a player if I don't know what I'm supposed to write or do or what to replace on?
Replace your code that instantiated a player with a call to SpawnPlayer
I've spent the better part of seven hours trying to get you to put two and two together and every single step along the way you've just taken random code snippets and either thrown them blindly into your own code or just posted random bullshit until I correct you out of exasperation. You've fought me every step along the way and have put in zero effort to solve your own problems. I'm done.
You have all the pieces here. If you need me to repeat it, scroll up and re read it instead of insisting I type it again
like this? (also I'm sorry, It's just that by just you saying that got me confsued)
..hello?
Why .hitPoints
Please think things through
Why would that make any sense
oh I didn't noticed that one.
hmm... GameObject go = PlayerManager.instance.SpawnPlayer;? and... something else to be added..
Are you calling the spawn new player method somewhere?
yeah
Can you show us where? Just to be certain.
GameObject go = Instantiate(player, transform.position, transform.rotation) as GameObject; but in this current image is GameObject go = PlayerManager.instance.SpawnPlayer;
Where do you call SpawnNewPlayer?
idk
Well, that's a big problem.
If you're not calling the method, you're likely just having the program do what you had before writing this method - likely teleporting and becoming stuck.
I see your spawn point system above but somewhere in code (likely on player death) you're teleporting the player. This would be where you'd want to call the SpawnNewPlayer - assuming you aren't pooling but need to respawn-a-player/spawn-player-2 etc
well there's player death in the hitpoints script
hmm... how do i call it?
So you've set is dead to true which implies it's being polled (used) elsewhere.
Where do you evaluate is dead and teleport the player(s)?
I don't know how to work with that response.
it's just there to see if player have lost all life on health bar
You'd search through your scripts for code that uses the is dead variable.
SpawnNewPLyaer doesn't have the call for death
I'm pretty certain you have got to be doing something now than that with that bool value
How are you teleporting?
That fine but you're needing to determine when you ought to call this method
after you die you teleport to the checkpoints you passed
Where in code do you teleport to the check point?
in SpawnNewPlayer
So the method is being called somewhere in code?
GameObject go = Instantiate(player, transform.position, transform.rotation) as GameObject;
go.GetComponent<Player2D>().lastCheckpoint = this;
I had assumed it were new code and that you had something else prior unrelated to this method
this was from the previous code
GameObject go = PlayerManager.instance.SpawnPlayer;
go.GetComponent<Player2D>().lastCheckpoint = this;
Alright, so the method is being called.
So relative to this, the player can respawn but is immobilized and health bars are missing now?
health bars is not back to full health
So it's present, just not refilled?
yeah
Can you show the updated code for heat refill?
also the red underline
Using a paste site please !code
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
I meant to show just this
That would be a method
Methods usually (always) have parenthesis - ()
SpawnPlayer(...)
it still have the red underline
You probably would. Can't expect immediate relief.
And what does the red underline state? (Likely invalid, incorrect number of arguments, etc)
It says you're missing some arguments
At the time of the error, it said you did not provide a position argument.
how do i fix it?
Provide a position argument
Maybe the position where you'd want the player to spawn
hmm... what do i write then?
What have you written thus far?
GameObject go = PlayerManager.instance.SpawnPlayer();
I'll give you an example (only an EXAMPLE)cs PlayerComponent go = SpawnPlayer(1, lastCheckPoint);
huh.. 1 for player 1?
Intellisense tells you what each argument is for - relative to naming convention (player number)
and i don't think about PlayerComponent
Typo, missing an s
oh
I'm typing on mobile-discord, don't expect valid working code without errors
So, I'm sure you know what goes there but how you would get it would be questionable.
Which class has this variable?
I only used the variable name relative to some images above (the check point code)
Player2D
Do we happen to have a reference of player2d?
Maybe say, from Player?
Where hopefully the player is accessible from the manager?
it only have public checkpoint lastCheckpoint;
Who, the player?
yeah, the player2d script
Does anything have a reference to the player2d component?
what?
I think I saw digi tell you to drag and make a whole lot of references in the inspector somewhere above
Where you had referenced like.. every component on the Player object
Does this include the player 2d component?
So yeah?
as shown in the scriot in the inspector
So, just access the previous player, it's player 2d component and acquire the position of the last check point - assuming the player hasn't been destroyed yet.
in the checkpoint script?
The data you want would be in the check point script, yes.
How you'd get it would be #1237461875633950770 message (obviously broken down into steps though)
like this?
- access previous player
- access player 2d component
- access check point
- access position of check point
Non code (pseudo code): GetPlayer(num).player2d.checkpoint.position
Where num would be whichever player is being spawned
where do i put that?
It's not valid code
You'd put it where you had needed a position though
I'm sure you've seen the usage of the GetPlayer method above before like when assigning the hit point component #1237461875633950770 message
you kinda ingored the image here
I don't know what that is or what you're implying.
you said i'm supposed to write in the checkpint script to access these 4
Your last check point is a reference to some component on an object in the scene. Every object has a position. I'm assuming that's why you've referenced this prior.
ok now i don't get what i'm doing now
You aren't supposed to be creating new variables
You need to access the previous player, it's player 2d component, it's check point and the position of the check point.
then i don't know what I'm supposed to write
Use your manager to acquire the previous player.
I don't get what you're saying now
what do you mean?
I know that
How would you get the player object?
Well get it..
Then access it's player 2d component.
Then the last check point variable.
And finally the position of that object
there is already Player2D component in places
It's going to ultimately look something like(not valid code)cs PlayerComponents go = PlayerManager.instance.SpawnPlayer(1, PlayerManager.instance.GetPlayer(1).player2d.lastCheckPoint.transform.position);
I'm on mobile discord and using swype. I cannot type the code for you.
I know it's not valid code
I'm not going to type everything Edited. Some stuff are implied.
You've been using GetPlayer for the last few hours now. It's implied above that you should be aware of what I'm suggesting.
#1237461875633950770 message
It's not anything new that you haven't done recently.
oh
i do know it's not valid, but the second image is what i edited
With the first image, you'd want to look at what members you've got available from your player component class
yeah
I recall Digi asking you to reference all components on the player object
There should be a player 2d variable (possibly under a different name)
yeah
If not, worst case scenario you can call GetComponent<Player2d>() in place of the player2d part.. but I'm pretty sure you had referenced all of your components.
So it's case sensitive
camelCase - correct
PascalCase - incorrect
Relative to your case
Player2D
player2D
uhh.... does it work?
Did you resolve your issue?
no
What's the current issue?
Player2D
player2D thing?
What's the problem?
about what you said here
You'd used that variable name you had in code. The inspector is just for legibility (always capitalize first characters and space, which is objectively invalid)
You'd use the first image and not the second.
The second makes no sense whatsoever, relative to #1237461875633950770 message
i am trying to get the lastCheckpoint
And you'd get that with the first image - you're missing the 1, btw
yeah
yet it would become 1, PlayerManager.instance.GetPlayer(1) like it have player 1 twice
I'm not sure what you're talking about but the spawn player method wants to know which player is being spawned so you'd give it the player number as the first argument. The second argument requests for a position. You pass it the last check point's position using the manager instance to access the previous player object's player component (a component) to access the player 2d component to access the last check point reference (an object in the scene that was last reference) where yours acquire the position from it's transform property.
I've got to run, take care and good luck.
I meant since there's two 1's
this is going to be so hard for me to know what to write because of the red underline...
everything is working now, but however... when I'm in a different scene, in a world when you select a stage and when i spawn in that stage scene and when i die and repsawn, it doesn't work
PlayerComponents go = PlayerManager.instance.SpawnPlayer(1, PlayerManager.instance.GetPlayer(1).player2D.lastCheckpoint.transform.position);
and it sent me over to this line of code