#variables

1 messages · Page 1 of 1 (latest)

past aspen
#

let's do this in a thread

#

show me the code you use for that sanity-drain-zone component

simple sparrow
#

thank you

past aspen
#

!code

outer juniperBOT
#
Posting code

📃 Large Code Blocks
Large code blocks should be posted as 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 get C# formatting the first line should only contain cs or csharp.
Add a comment with a line number if there is an error message.
```cs
// Your code here
```
Do not share screenshots of code unless requested.

simple sparrow
past aspen
#

and then show me the inspector for one of the sanity zones

simple sparrow
past aspen
#

So it doesn't do anything right now?

simple sparrow
#

It does. I can make triggers via box colliders. That all works

past aspen
#

or is this just not configured yet?

#

because none of those events have any targets

simple sparrow
#

my question is getting my sanity to go up when I press the "F" key and turn my flashlight on

#

this works fine

past aspen
#

Gotcha, that makes sense.

#

So, you have another script for your flashlight, I presume

simple sparrow
#

oh boy.. ummm. yes

#

It is way better than it was when I started

#

dont roast me :p

past aspen
#

Where were you trying to add that code with the sanitybar?

simple sparrow
#

here ideally

past aspen
#

okay, so you first need to give the flashlight a way to find the SanityManager in the first place

#

It looks like you were trying to use GetComponent to find it.

simple sparrow
#

i did that in the start with getcomponent

simple sparrow
past aspen
#

Well, both are important

past aspen
#

so GetComponent<SanityManager> would try to find a SanityManager on the flashlight, in this case

#

That doesn't sound right.

past aspen
#

That sounds more like what you want.

simple sparrow
#

What if I have public GameObject sanity; then drag the game object in there then do sanity = getcomponent?

past aspen
#

oops, wrong reply

past aspen
#

You can reference anything that's a unity object.

simple sparrow
#

I did do that too. Obviously missing something

past aspen
#

GameObject is one, sure, but that's not the right type here.

#

You don't want literally any game object

#

that object might not even have a sanity manager on it

#

You want a SanityManager.

#

I rarely use GameObject variables.

#

I only do it when literally any game object would work

#

(which is very uncommon!)

simple sparrow
past aspen
#

If those variables are just used to activate and deactivate objects, then it's fine

#

because literally any object will work

#

but that's not the case with the sanity manager: we can't just assign any random object there

#

we very specifically need a SanityManager

simple sparrow
#

You've explained that well. I've spent so many hours learning variables and you just made it clear

past aspen
#

so, add a new variable that holds a SanityManager. Do it like this:

[SerializeField] SanityManager sanityManager;
#

You could also do this

#
public SanityManager sanityManager;
#

The important thing here is that we need this variable to be serialized. That means it will show up in the inspector and be saved.

#

Public variables are automatically serialized. Private ones aren't, so you need the [SerializeField] attribute.

#

Making variables private is good. It reduces the number of ways different parts of your code can mess with each other.

#

which makes it easier to debug your game when things go wrong

simple sparrow
past aspen
#

Is your flashlight going to be in the scene when the game starts?

#

rather than being a prefab that you instantiate later

simple sparrow
#

it only becomes active once i pick it up

past aspen
#

but it does exist in the scene

#

that means you can drag the Sanity Manager component into the field

#

you can just grab the object the manager is attached to

#

and drag the entire thing into the field

#

You can also grab a specific component, but that's more annoying (you have to open two inspectors)

past aspen
simple sparrow
#

That makes so much sense now.

#

So since I've done this. Do I still need to do getcomponent or has this automatically gotten every component?

past aspen
#

Nothing happens "automatically" -- it's just that you've assigned this reference before the game even starts

#

so you don't need to do it at runtime.

#

GetComponent should be used when you can't reference the thing you need ahead of time.

#

For example, I often do this:

#
void OnTriggerEnter(Collider other) {
  if (other.TryGetComponent(out Player player)) {
    player.Damage(10f);
  }
}
#

TryGetComponent returns true if it found the component and stores it into its out parameter

#

this is basically the same as

#
Player player = other.GetComponent<Player>();
if (player) {
  player.Damage(10f);
}
#

In this case, you obviously couldn't have referenced the player in advance, since you don't know what colliders you're going to be hitting

#

so you have to use GetComponent or TryGetComponent to see if the thing you hit had a Player

#

I do sometimes use those methods to save some effort, though

#

for example, if a component is always on a child of the player, I might just use GetComponentInParent instead of manually assigning the player to all of these different components

simple sparrow
#

Sorry for the delayed replies. I am genuinely interested and absorbing it in

#

It makes sense. I've only ever used Getcomponent a few times

past aspen
#

GameObject and SanityManager have a common parent: UnityEngine.Object

#

But the inheritance tree diverges there.

#

GameObject is a direct child, while SanityManager goes through Object -> Component -> Behaviour -> MonoBehaviour -> SanityManager

#

public class SanityManager : MonoBehaviour means that your class is derived from MonoBehaviour

#

it's a specific kind of MonoBehaviour

simple sparrow
#

I get that now. I thought everything in the Hierarchy was just "GameObject"

past aspen
#

Well, that is kind of true.

#

Everything you see in the Hierarchy view is a GameObject

#

when you click on an item in the Hierarchy, the inspector shows you that GameObject

#

every game object has a Transform (hence it shows up at the top)

#

Transform holds the position, rotation, and scale. It also holds the parent, if it has one.

past aspen
still pollen
past aspen
#

a MonoBehaviour must be attached to a GameObject

#

and a GameObject must have a Transform

#

so you always have access to a Transform (and a GameObject)

past aspen
#

for example, Unreal doesn't just have GameObject. You can have many different kinds of things in the world.

#

but in Unity, every single "thing" in the world is a GameObject, with a Transform and, optionally, other components

#

That's why GameObject is a very non-specific type.

#

a GameObject variable can reference any "thing" in the world

#

because every "thing" is a game object

#

If you want something more specific, you can reference a specific kind of component

#

You can also reference a Transform. I use that way more than GameObject, actually

#

it's basically the same thing, because one can't exist without the other

#

but it does make it more obvious what the variable is going to be used for

#
public Transform holder;

...

var entry = Instantiate(uiPrefab);
entry.transform.SetParent(holder);
#

wait, you can just do that directly, can't you

#
Instantiate(uiPrefab, holder);
past aspen
#

I'm working on a game where every unit has a bunch of "states" it can be in

#

I might do this

#
public EntityAttackState state;
#

but then I realize there are many kinds of actions the unit should be able to perform here

#

so I switch to something less specific. maybe just EntityState

#

but the problem is that I can no longer do things specific to EntityAttackState

#

i can't set the damage the attack will do, for example

#

So, the more specific your variable is, the more you can do with it, but the fewer kinds of things you can store in it.

#

In your case, it's pretty clear that we could only ever use a SanityManager here

#

it's not like the flashlight can reduce your hunger meter or restore health

#

if you wanted to do those things, then you'd need to figure out something less specific

#

(maybe use UnityEvent again!)

#

UnityEvent is great for allowing a variety of things to happen

#

you move that logic from the code to the inspector

simple sparrow
#

I am still here. Just processing what you've said.

past aspen
#

all good :p

simple sparrow
#

I feel like you're literally pointing at the obvious answer.

past aspen
#

we should probably come back down to earth and get back to the original question, lol

#

so, have you given the flashlight a SanityManager variable and assigned it in the inspector?

simple sparrow
#

Yes, I have

past aspen
#

as long as the object holding the SanityManager isn't destroyed, that variable will always be a valid reference to the sanity manager

simple sparrow
#

Once the flashlight is active. It won't be destroyed.

#

I still am unsure how to implement what I need into the flashlight code.

past aspen
#

well, now that you have a reference, you can just call sanitybar.AffectSanity whenever you want

simple sparrow
#

what exactly does "call" mean ? I keep seeing it

past aspen
#

calling a method

#

so, sanitybar.AffectSanity(100); or something

#

you were calling the Invoke method on those unity events earlier

simple sparrow
#

correct me if I'm wrong. I'm calling the DoorOpens method from "" right?

past aspen
#

DoorOpens() is calling a method named DoorOpens in the same class

#

it's the same as writing this.DoorOpens()

#

this is a reference to the object whose code you're currently running

#

(sometimes you have to explicitly write this when things are ambiguous)

#
public float foo;

public void Method(float foo) {
  this.foo = foo;
}
#

for example

past aspen
#

you could do this

#
public Door theDoor;

...

theDoor.DoorOpens();
#

(assuming DoorOpens is public, of course)

simple sparrow
#

I get you

#

going back to the sanity manager. Where do I call the method. Wherever I put sanitybar, it has red squigly lines under it.

past aspen
#

show me what you tried to do.

simple sparrow
#

one sec

#

in the start method (I was taking reference to the sanity manager script itself as it has something similar)

#

This in the if flashlight on part. This was one way

past aspen
#

oh, you named it sanityManager

#

I thought you had still named it sanitybar

#

just use sanityManager

past aspen
#

If there is no SanityManager on the flashlight, it will return null

simple sparrow
#

oooh. there is no component on it as we did the serializedfield earlier.

past aspen
#

well, those are two unrelated things

#

there is no SanityManager on the flashlight becauase it wouldn't make sense to put it there

#

There's no reason that GetComponent<SanityManager> couldn't work, even if we also had a serialized field that holds a SanityManager

#

It's just that, in this case, it won't.

#

(and it is true that you usually do one or the other, not both)

simple sparrow
#

I still do not know how to call upon the method

past aspen
#

sanityManager is the variable that holds a SanityManager

#

you can access any public field or method of SanityManager with it

simple sparrow
#

I understand that

#

I also get that. AffectSanity is public

#

What I mean is I do not know where to call it and how exactly to call it

past aspen
#

well, you'd call it when you want to change the sanity value

#

sanityManager.AffectSanity(-10 * Time.deltaTime); sounds pretty reasonable to me

simple sparrow
#

That works. so I need to do "Variable.method(whatever i need)"

#

I would like to say thank you. You have shared a lot of made things extremely clear. Thank you