#archived-code-advanced

1 messages Β· Page 136 of 1

fresh salmon
#

Yeah that's pattern matching

#

Also losing the switch expression string x = someVar switch { ... }

#

Was introduced in C#8

misty glade
#

yes, i love that, btw, and use it a lot already on my server

#

I don't know if everyone thinks that this is the cleanest but it has saved me a ton of vertical space

#
            Person activeCrewOfActivePlayer = (isC1Active, b.C1ActiveCrew, b.C2ActiveCrew) switch
            {
                (true, 1, _) => b.C1Crew1,
                (true, 2, _) => b.C1Crew2,
                (true, 3, _) => b.C1Crew3,
                (false, 1, _) => b.C2Crew1,
                (false, 2, _) => b.C2Crew2,
                (false, 3, _) => b.C2Crew3,
                (_, _, _) => null,
            };
#

something like that would require a bit more nonsense if/elseif statement checking and assignment

fresh salmon
#

Yeah that tuple pattern matching, beautiful

misty glade
#

or assigning multiple values at once using tuples:

                    (int crewPosition, string who) = (isC1Active, b.C1ActiveCrew, b.C2ActiveCrew) switch
                    {
                        (true, _, 1) => (1, "C2-1"),
                        (true, _, 2) => (2, "C2-2"),
                        (true, _, 3) => (3, "C2-3"),
                        (false, 1, _) => (1, "C1-1"),
                        (false, 2, _) => (2, "C1-2"),
                        (false, 3, _) => (3, "C1-3"),
                        _ => (0, "_"),
                    };
#

(so "friendly" messages to the console and/or players look like this)

                    s += $"{who} does {damage}HP damage, bringing {target} from {activeCrewOfInactivePlayer.CurrentHP}HP to ";
                    activeCrewOfInactivePlayer.CurrentHP -= damage;
                    s += $"{activeCrewOfInactivePlayer.CurrentHP}HP";
#

anyway.. ❀️ switch expressions

vestal heath
#

That's partly the reason why I don't like C# and its approach to e.g. lambda args - it's so unreadable.

undone coral
#

no, you have to write it against netstandard2.0

#

you have to modify the projects to target netstandard2.0 as the framework

misty glade
#

yeah, i'm in the process of bringing this all back to a 4.7.2 DLL

#

I'm hopeful that setting the <LangVersion> to 8 or 9 will compile a framework DLL that still works

#

i really do like pattern matching and switch expressions

undone coral
#

you can use later c# language features on netstandard2.0

misty glade
#

oh?

undone coral
#

you should target netstandard2.0 as your "Framework" option in the project settings

misty glade
#

and standard2.0 works with unity?

#

hmm

#

lemme go that route then

undone coral
#

with regards to the Api Compatibility Level* setting in the player settings, in 2021.1 and earlier, the most robust option in netstandard2.0

#

in 2021.2b6 and later, in practice all external library usages are broken until some bugs are fixed

misty glade
#

k

#

i'm just swimming in this terminology 😐

undone coral
#

yes, it's very confusing

misty glade
#

.net standard .net framework .net core

#

I saw "2.0" and assumed that .net standard 2.0 was outdated or similar to .netcore 1

undone coral
#

no

misty glade
#

yeah .. like i said, this terminology is .. a bit triggering for me

undone coral
#

yeah the unity api compatibility level makes it seem like netstandard2.0 is "less" than .net 4.x when the truth is the other way around

#

the way C# 9 features are / will be supported on 2021.2b5 and earlier is by adding a dll

#

oh that's funny

#

they even say 2021.2.0b6 in the microsoft doc

misty glade
#

yeah, i don't mind if c# 9 isn't supported in unity for scripts (i mean, it would be nice but it's not critical to me).. but i really am going through a lot of effort to get my shared library DLL in place, as most of my code lives there.. and it would be nice if it supported c# 9+ features and worked in unity without too much headache

#

yeah, I saw that, and I'm in unity uh.. 2021.2.x

#

but I can try 2.0 and see how that goes first

undone coral
#

you're using the beta version?

misty glade
#

Encouraging initial pass - all my language features work

#

Yeah

undone coral
#

hmm

#

there is a lot of pain right now

misty glade
#

I haven't upgraded in a few months but I don't have anything blocking me from doing so

undone coral
#

you sure you don't mean you're in 2021.1?

misty glade
#

2021.1, actually, you're correct

#

2021.1.3f1

undone coral
#

okay

misty glade
#

Why? what's going on with .2?

undone coral
#

it's buggy for external libraries

#

since they are adding netstandard2.1

misty glade
#

ah.. will stay away from that then

#

I really don't want to be dealing with this 😐 Have enough normal code/configuration to write! πŸ™‚

#

Error NU1202 Package Redzen 12.0.0 is not compatible with netstandard2.0 (.NETStandard,Version=v2.0). Package Redzen 12.0.0 supports: net5.0 (.NETCoreApp,Version=v5.0) ISG-Shared-Standard D:\projects\ISG\ISG-Shared-Standard\ISG-Shared-Standard.csproj 1

#

sigh

#

I ❀️ redzen, too

#

wonder if I can just compile a version for standard2.0 myself

undone coral
#

if you had it working before it's compatible

misty glade
#

this is just giving me a headache...

undone coral
#

hard to say

#

@misty glade just use version 9.1.0

misty glade
#

aye, thanks

#

I tried grabbing the source from the latest version and compiling it myself but there's too many dependencies to resolve

#

and of course the features I'm using are > 9.1.0

#

lol

#

the features I want were checked in on July 26 2020, and 9.1 became 10.0 just a month earlier

#

ripped the redzen stuff out (with a tear in my eye) and put it back on the server, nugetted what I need and

========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
#

now to see if this DLL works seamlessly in unity as a plugin

devout orbit
#

yow,

can anyone explain this?

#

How does that method get 0 as input as the debug clearly shows its not

#

Am I just missing something obvious?

long ivy
#

targetFollow.FollowSpeed is 0

devout orbit
#

Well I agree, but if you look at the if statement if distance is greater then 1.5 which it is as the debug log shows 2.2

#

It should use the Default one ?

long ivy
#

if the distance is greater than 1.5, then FollowSpeed will be used .Otherwise, GetDefaultSpeed will be used. You printed out GetDefaultSpeed, which is not being passed to the method

#

condition ? true expression : false expression

devout orbit
#

I see rip, thanks

short imp
#

Not sure exactly where to post this question, but which would be more efficient. A prefab with 45 different tile geometry states and setting them active / inactive based on neighbors updating. Oooooorr 1 mesh filter with a list of 45 meshes, and set that 1 mesh filter to the right mesh on update

#

(basically think a 2d tile set but with 3d geometry)

#

or if there's a wonderful 3rd way i'm all ears

quartz smelt
#

So I have a pretty advanced section of code

#

and Ive optimized it three times

#

to the point where I am using a hashmap (dictionary in c#) for item lookup

#

it has to do with the way my game is generating item from a lootbox

#

essentially a "Lot" (lootbox) has a spawn pool of items that can be in it

#

and a number of items you get from opening it

#

so im mapping the items to a dictionary with <float,item> where float = the upper bound of the spawn chance for each item incremented as we go

#

so for example if I have a spawn pool of items that looks like this

#

itemOne 50%
itemTwo 50%

then my hashmap should look like

50 : itemOne
100: itemTwo

#

because item two has a 50% chance on top of the 50% of its predecessor, which sums as it goes

#

I then create an array of dicerolls from 0 to 100 using random.range(0,100) and sort that array

#

then for each slot in the diceroll array I retrieve the item that is in the dictionary for its upper bound in the spawn chance array

#

ergo if the diceroll was 35, which is below 50, I retrieve the item for 50 in the dictionary, in this case itemOne

#

I then do this FOR EACH LOOTBOX that was purchased

#

to summarize, make a map of spawnable items by summing spawnchances and making that summed spawnchance the key in a dictionary of <float, item>

#

then perform dicerolls * the number of items you should receive, and the closest number to your diceroll is the item you receive

#

the problem is that if the player buys like 20 lootboxes, this code can take around 10 seconds to execute

#

does anyone have any further optimization suggestions

#

Feel free to ping me if youd like to discuss the code as I know this is complex

undone coral
quartz smelt
#

thanks ill give it a good look

undone coral
#

lootboxes are drawing without replacement

#

so if you want it to behave like lootboxes, you need to do drawing without replacement

#

that means it behaves like a deck of cards

quartz smelt
#

yeah this is drawing with

undone coral
#

sorry if you want to not make it take 10s to execute you gotta use the right thing you can't just hack it together

undone coral
short imp
#

thanks. Follow up question, does it matter if every tile has the the same list<> of meshes, or should i have some kind of tileset manager so there's only 1 List<> that all the tiles grab from

undone coral
#

it sounds like you are reinventing unity's tilemap

#

you probably just want to use a prefab

#

for each tile

#

you can model the different tiles as a prefab variants

#

then, use unity's tilemap

short imp
#

i didn't realize unity's tilemap could support 3d objects

#

thanks for the pointers

quartz smelt
undone coral
#

and not feel overwhelmed

#

if you feel like you looked at "Sampling" and just felt like "okay this doesn't help me"

#

it does

#

you will see that you were halfway there

#

the hard part is using the binomial

ocean violet
#

meta question; what is the difference between an advanced coding question and a general-coding one? (I guess whats the cut off or is there a gray area here)

sly grove
#

it's gray of course

#

and subjective

ocean violet
#

aighty. I was going to ask about how something like Slay the Spire or other turn based games handles effects parsing/order, but I'm not 100% sure if that's a general question since it's vague or advanced since there's not any 1 way to go about it.

harsh grotto
#

when it doubt just use general

ocean violet
#

I'll take it to general then and see, tyty

viral plinth
#

my doubt is that I wanna make a combat game (2D)
& I wanna make it multiplayer
but I also wanna add slow motion
I want advantage or disadvantage cause you need to unlock these powers & to unlock you need to dm me for code to unlock
these are my ideas for making worst game ever
issue is that how do I make 1 character move in slow motion & 1 character will see the other character in very fast motion
like happens in real time
uhh
I dont know if you guys understood cause my english is a bit weak

hard lily
#

You can't slow time for someone awhile accelerating it for others while they interact with each other, that's physically impossible

viral plinth
#

oh 😦

hard lily
#

What you can do is slow down everyone while one is unaffected

#

The effect will be the same

viral plinth
#

oh yeah

hard lily
#

But the players who were slowed down will know that someone is faster than them

hard lily
#

I only mentioned that because your original intent was that players always moved at "normal" speed from their POV

#

But that's impossible, the closest you can achieve that is having one of the parties with altered speed even from their POV

viral plinth
#

ok

#

Thanks for the explanation @hard lily

#

πŸ™‚

#

I'll try somehting else

unique zenith
#

Hey guys, I hope this is the right channel to post this in! I have a video of my problem too, I am just not sure if I am allowed to post it here πŸ™‚

I have a very strange problem happening. I use a VideoPlayer in my UI and it works actually pretty nice.

My game is split in a pretty low performance part and a more demanding part.
The videos play super nice and smooth in the first part but they barely play at all in the second part. That's the only thing I was able to say for sure.

It's all mp4 videos, 2,5kbps, 1280x720, no audio.

I tried using videoPlayer.Prepare() in multiple different ways and awaiting the callback too but this didn't change anything unfortunately. It seemed like it starts preparing the first 10-20 frames over and over again.

Does anyone have an idea what the cause might be here? I'm releasing on Monday so this is pretty urgent for me haha! πŸ˜„

Thank you so much in advance!!

regal olive
#

what’s the math behind scaling resolution and uiscale at once?

#

(posted in beginner but no one had a answer trying here)

devout hare
#

You need to be a bit more specific

regal olive
#

I want to scale my ui with resolution and uiscale

#

But I want to know the math behind it

#

the math is unity internal so I’d have to reverse it

undone coral
unique zenith
elfin tundra
undone coral
#

but one that you didn't create

unique zenith
unique zenith
undone coral
#

it's unavoidable

#

there's nothing wrong with the video player

unique zenith
undone coral
#

are you saying slow as in time scale or slow as in performance?

unique zenith
#

But I am not even close to maxing out my RAM, VRAM or anything on my system

regal olive
#

Hey guys, do you have an idea how to make a loadbar (non UI elemnt) ingame? Like showing only half an object when a float is at 50%

livid kraken
#

With a shader that lerps a mask

pale pier
#

More of a vent than a question, but why do the overloads for GetComponent - that take in a list instead of returning an array - clear that list everytime you call those methods 😀, now I have to have two lists and copy from one to the other between operations

#

And why do Awake & Start methods not get called for disabled objects anyway, I'm in this whole mess because of that basically.
I have Awake & Start methods on disabled UI game objects and I need to invoke them with the rest of the active game objects

livid kraken
#

You can simply make a custom init method in them and call that from a active awake/start. The monibehaviour methods are not supposed to run on disabled objects by drsign

fresh salmon
#

I also saw that constructors were run on disabled objects, might be of use

sly grove
sly grove
misty ibex
#

Is there a way to make a child collider, trigger the on trigger events from a parent object?
i have a bunch of sub colliders that all have the same functionality. im trying to call on the parent object (On trigger stay) and have the collisions from the sub colliders trigger the event
does anyone have an idea?

#

basically i want to detect the collision on the Sub Colliders but have them all act collectively and pass the collision up to the parent object

sly grove
#

you may need to have a Rigidbody on the parent though

#

(it can be kinematic)

misty ibex
#

Calling ontriggerstay on the parent ignores the child objects and only takes the collision directly related

#

ahhh i need a rigidbody

sly grove
#

You don't "call" ontriggerstay

pale pier
misty ibex
#

is there anyway to get around that?

sly grove
#

around what

#

needing a rigidbody?

#

not really

livid kraken
#

And have one script on the parent. Then all child colliders will trigger up the chain. If you have a script on a child it will eat the msg

sly grove
#

but currently they don't even return the count

#

so you couldn't

#

anyway is it really a big deal?

#

Clearing <10 elements from a list is nothing

#

unless you're doing some crazy thing like having hundreds of components on the object?

misty ibex
#

I have the script on the parent object (Hitbox) checking for "OnTriggerStay"

then the children objects all have a sphere collider and are positioned NOT OVERLAPPING. I added a rigidbody and tried again but still no collision being detected

pale pier
pale pier
livid kraken
misty ibex
#

yeah

#

Hitbox is the parent object, then there are 3 subcolliders as children, each holds a sphere collider marked with trigger

#

private void OnTriggerStay(Collider other)
{
Debug.Log("sucess");
}

#

^ this is the only code that is attached to the parent script

livid kraken
#

Maybe it needs to be public to get called

sly grove
#

it doesn't

misty ibex
#

🀣 i was like wow if thats really the issue

#

but nah that didnt change anything

sly grove
livid kraken
#

Yeah was just spitballin here it should work from what you are telling us

misty ibex
#

even when i add a rigidbody i dont get any messages

#

would it be bad practice to make a method on the parent object "CollisionDetected()" and then on the sub colliders use OnTriggerStay(){hitbox.CollisionDetected()}

sly grove
misty ibex
#

yeah

sly grove
#

is the cylinder actually overlapping the sphere?

misty ibex
#

yeah im moving it over all of them

sly grove
#

they are invidsible

#

which object has the script

#

and which has the rigidbody

misty ibex
#

in play mode i drag the capsule over all the colliders

#

Hitbox has the script

#

Rigidbody is on the parent of hitbox

sly grove
#

put the script and the rigidbody on the parent

#

on the same object

#

GameObject(1)

#

or whatever it's called

misty ibex
#

yeah that worked!

#

thank you

#

Is it going to matter if i have random Rigidbodys on my characters though? in the actual game i use Character Controllers and physics is driven by Code which is why i didnt use rigidbodys in the first place

sly grove
#

if you make the CC kinematic you're fine

#

sorry

#

the RB

#

if you make the RB kinematic you're fine

misty ibex
#

ok so Kinematic basically just disables the rigidbody?

sly grove
#

it makes it so the body isn't affected by forces or collision/impacts and is instead fully controlled through scripting.

misty ibex
#

so would it be bad for performance if instead i make a method on the parent object "CollisionDetected()" and then on the sub colliders use OnTriggerStay(){hitbox.CollisionDetected()}

#

so bascially each sub collider will check for collision on its own and then call a method on the parent object

#

that way i dont need the rigidbody and i can grab the specific collider that was hit also

undone coral
#

it's going to be some bug in your stuff

#

which isn't saying much

sly grove
undone coral
#

but it doesn't sound like it's the video or video player

undone coral
undone coral
misty ibex
unique zenith
undone coral
#

right now it sounds like there's just a kitchen sink of stuff going on in your scene

#

what is the game, what is going on with the video, etc.

#

maybe show a snippet so we know how well you program

unique zenith
undone coral
#

yes but a video is very uninformative

#

i think you can just write what is going on

#

in the game

#

like why are you playing a video?

#

why are you baking a navmesh

#

what is the gameplay

misty glade
#

I'm getting the following error on build to PC:

System.Windows.Forms.dll assembly is referenced by user code, but is not supported on StandaloneWindows64 platform. Various failures might follow.

With a rather unreadable and large stack trace: https://pastebin.com/xpkN7EdR

Do I need to be worried? App works fine as far as I can tell, no other errors, runtime or otherwise..

unique zenith
#

Ok so:

The game is a festival tycoon game. The player starts in build mode (where the video works) and continues into live mode (where it doesn't work).

The transition form build mode to live mode is basically just a loading screen, a lot of nav mesh stuff behind the scenes and UI updates. No scene change.

This is the bug: https://youtu.be/6PqCQydcRy8

This is the code for the video player, Play() called whenever the overlay opens up (see video).

public class UI_VideoPlayer : UI_Element
{
    private static event Action<UI_VideoPlayer> EBeforePlay;


    [SerializeField] protected RawImage rawImage;
    [SerializeField] protected Image iconLoading;
        

    private VideoPlayer videoPlayer;


    protected override void AwakeIntern()
    {
        base.AwakeIntern();
        videoPlayer = GetComponent<VideoPlayer>();
            
        EBeforePlay += OnBeforePlay;
    }
    protected override void DestroyIntern()
    {
        base.DestroyIntern();
        EBeforePlay -= OnBeforePlay;
    }
        
    private void OnDisable()
    {
        StopAllCoroutines();
        Stop();
    }

    private void OnBeforePlay(UI_VideoPlayer player)
    {
        Stop();
    }

    public void Set(VideoClip video)
    {
        videoPlayer.clip = video;
    }

    public void Play()
    {
        EBeforePlay?.Invoke(this);

        if (videoPlayer.isPrepared)
        {
            videoPlayer.Play();
        }
        else
        {
            StartCoroutine(PrepareVideoAsync());
        }
    }
    public void Stop()
    {
        videoPlayer.Stop();
    }


    private IEnumerator PrepareVideoAsync()
    {
        videoPlayer.Prepare();
        iconLoading.gameObject.SetActive(true);

        while (!videoPlayer.isPrepared)
        {
            iconLoading.transform.Rotate(Vector3.up, 25f * Time.deltaTime);
            yield return null;
        }

        iconLoading.gameObject.SetActive(false);
        videoPlayer.Play();
    }
}
misty glade
#

Where's the iconLoading gameobject? Not that that's the cause of anything, just trying to understand it all

#

I'm wondering if maybe your videoPlayer.isPrepared boolean isn't working properly?

unique zenith
misty glade
#

(I'm assuming you're calling Play() on mouse enter)

#

Like - if a video isn't prepared and you kick off the call to PrepareVideoAsync() twice, what happens?

unique zenith
unique zenith
misty glade
#

Yeah, that's what I meant.. hmm

#

I think the code you've pasted looks reasonably correct? I imagine maybe there's some bug with how you're calling play or preparing the video..? It seems as if it's playing for a very short time sometimes - like 1-2 frames..

#

Like how is OnDisable() being raised?

unique zenith
#

The weird thing is to me that this seems to work without any problem, I do not have any issues in the mentioned part of the game, only later on and then they're always appearing, without exception

misty glade
#

What's always appearing..? the bug?

unique zenith
unique zenith
misty glade
#

So maybe a trick to debug this is to add a debug hotkey - whatever, like F1 or somethign unused, and when you experience the bug, press F1, and tie that to a console dump

#

And list all the things like.. videoPlayer.isPrepared for the current video, number of coroutines running on the GO, etc

#

Since you can't just breakpoint the coroutine (since it sounds like it's working fine normally)

#

even just make sure the Set() is properly .. working.. like output videoPlayer.clip.name or some property that identifies it, if you have it

#

and obviously I'm assuming your AwakeIntern() method is ... only getting called once, at Awake() or something else

#

(so you're not subscribing twice to the event handler on accident)

unique zenith
unique zenith
regal olive
misty glade
#

You can either have test methods or debug methods - they tend to look the same - and you can tie into the debug messages with hidden hotkeys or buttons that only show up in debug mode. I like to make a little panel with debug buttons that I can show/hide depending on whatever I'm doing in the development process

#

(it also contains a simple panel with a textmesh element in it and my logging library outputs to that as well so I can see the "console" output even in the windows PC mode, if i need to)

unique zenith
#

Yes, I do have that too πŸ™‚

I'll double check the event and if that's fine, I'll do a print thingy haha πŸ˜„

#

Thanks a lot in the meantime!

misty glade
#

No worries.. sorry I couldn't find an obvious bug

#

I suppose in this channel that's going to be status quo... brainstorm together to find obscure bugs

undone coral
#

lots of code smells

#

for example, OnBeforePlay calls Stop(), there's an AwakeIntern idea, the coroutine

undone coral
#

it'll tell you

#

what is slow

cyan bluff
#

hi guys, what is the best data base to use for a mobile game? I have a multiplayer game project, but some stuff i dont know where to begin and are my biggest issues at the moment, like the data base and the authentication with the play store, any recommendations?

plucky dagger
#

I have a worldspace canvas with some buttons. Each button has an additional canvas that should load (be active) everytime I hover my mouse over it (see figure). This is not happening. Any suggestions on what I can change?

Here's a basic code:

public class ShowAdditionalUI : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    [SerializeField] Canvas additionalCanvas;
    public void OnPointerEnter(PointerEventData eventData)
    {
        additionalCanvas.enabled = true;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        additionalCanvas.enabled = false;
    }
}
#

WorldSpaceCanvas with additional canvas

#

Secondary canvas when active.

#

Secondary canvas when active.

sly grove
#

are you having that issue?

plucky dagger
#

Let me check.

sly grove
#

otherwise - check the standard event system stuff:

  • make sure nothing is blocking the object you're trying to hover
  • make sure you have an EventSystem in the scene
  • make sure your canvas has a GraphicRaycaster
  • make sure the event camera is set on the canvas
  • make sure you have an InputModule on your Event System
plucky dagger
unique zenith
plucky dagger
sly grove
plucky dagger
#

Yes

sly grove
#

but your code is dealing with enabled/disabled for the Canvas component only

#

did you mean to do additionalCanvas.gameObject.SetActive(true);?

plucky dagger
sly grove
plucky dagger
sly grove
#

if the new panel is a child of the one with the script on it - does that work?

plucky dagger
#

Nope.

plucky dagger
undone coral
#

it looks like you are trying to build world space UI which is sort of a bad idea. the best thing to do is use only one screen space canvas, but position its elements based on the world space objects they are "tracking"

urban warren
tropic lake
#

i don't know if having everything in one canvas is a good idea, that seems like a tough organisational thing
the canvas also needs to refresh everything every time one element is updated

The problem is that, when one or more elements change on a Canvas, the whole Canvas has to be re-analyzed to figure out how to optimally draw its elements.
https://unity.com/how-to/unity-ui-optimization-tips#divide-your-canvases--2
so splitting canvases is a good idea

Unity

Discover quick and easy-to-implement tips on how to create optimized Unity UI elements for your content.

undone coral
#

world space UIs are hard to make look nice

#

the costliest part of rendering in UGUI is text

#

canvas hijinks will not change that

regal olive
#
if (up.GetComponent<TileWall>().GetTileID() == 2) 
        {
            Debug.Log("UP is Wall");
            var s = gameObject.GetComponent<SpriteRenderer>();
            s.sprite = Resources.Load("WallTopConnected") as Sprite;
        }```
I'm not sure why, but whenever this is called in update the ``gameObject``'s sprite turns to ``None`` even though I have WallTopConnected in Resources
sly grove
#

Where is it in the project and what are the import settings?

regal olive
#

@sly grove

#

its in Resources

#

and it's a 16-bit type of game

sly grove
#

instead of the thing with the as Sprite

regal olive
#

I don't know what it is about you, but it worked! Thank you @sly grove

#

I literally tried

#

the exact line of code

#

lmao

sly grove
regal olive
#

Now to duplicate this and change it for the right, left, down, up-left, up-right, down-left, down-right, up-left-right, and down-left-right πŸ™‚

regal olive
sly grove
regal olive
#

I was going to do if up && down == wall etc

sly grove
#

e.g.

public string[] tileNames = {"WallLeft", "WallRight", "WallTopConnected"}; // etc...

private Sprite GetSpriteForTileId(int tileId) {
  var sprite = Resources.Load<Sprite>(tileNames[tileId]);
  return sprite;
}

// then later...

int tileId = up.GetComponent<TileWall>().GetTileID();
var s = gameObject.GetComponent<SpriteRenderer>();
s.sprite = GetSpriteForTileId(tileId);
#

so you don't need a bunch of if statements

regal olive
#

Oh I see, so it matches with the name

#

I don't think I can do that with how I structured the TileBase class with TileWall in it

desert folio
#

Anyone tried using System.Numerics.Vector in Unity 2021.2? Was working fine in earlier versions but now I'm getting ambiguous reference.

#

The IDE (Rider) tells me there's one in netstandard and one in System.Numerics.Vectors. Can't use either

undone coral
#

the beta is not reliable enough due to a weird netstandard2.1 thing they're doing

flint sage
#

Did you copy your own DLL to unity? If so, it sounds like it's not included by default

fickle ether
#

Hi everybody, i want to change the Graphic API (DX11 , DX12) in build windows game, but i can't find a way except i build two .exe file (once with DX11 and the other with DX12) can i make it one build and give player a setting to change it in game?

midnight violet
#

I guess most games have a launcher software for that that loads the specific exe file, same es some Game32 and Game64.exe thing @fickle ether

fickle ether
midnight violet
#

I guess so. You could at least turn off auto api and set dx12 on top of dx11, then Unity will try to use dx12, if not available, try to use dx11

#

Not sure if you have cloud build, but this could help you do that stuff in parallel, while keep on working on other stuff in your machine.

fickle ether
# midnight violet I guess so. You could at least turn off auto api and set dx12 on top of dx11, th...

good idea... but what if player wants to play with only DX11 to get more FrameRate or i dunno for any reasons...
so this must be the result: a luncher must made to let player chose to what version wants to play... but another problem is here, the game storage is 10 GB, so now if i build two different versions, it's gonna be 20 GB... can't i make it in one build all assets but with two .EXE files ? like one for DX11 and other DX12 ?

untold moth
midnight violet
#

DX12 is slower in some cases, depends on the game.

untold moth
#

I'm still not convinced. The api is just a tool. What matters is what you do with it.

midnight violet
#

I mean, his question is, how to start with different API levels. And I guess, there is no out of the box way yet

#

you can use playersettings to set it while building it, but at runtime, cant find a solution online yet

sage radish
#

There should be a command line argument to force the graphics library used

unique zenith
#

Ok so I just wanted to let you know that got my video issue working. The problem was totally on my side (who'd have guessed lol) and the fix was the following:

Every time a possible step-completion condition was triggered through an event, the steps were updated. Looked like that:

steps.ForEach(s => s.gameObject.SetActive(false));

var shownSteps = TutorialManager.CurrentVisibleSteps(steps.Count);
for (int i = 0; i < Mathf.Min(steps.Count, shownSteps.Count()); i++)
{
    steps[i].gameObject.SetActive(true);
    steps[i].Set(shownSteps.ElementAt(i));
}

You see this steps.ForEach() ? Don't do that πŸ˜‰

I fixed it by replacing the code with this:

var shownSteps = TutorialManager.CurrentVisibleSteps(steps.Count);
for (int i = 0; i < shownSteps.Count(); i++)
{
    if (steps[i].RequireUpdate(shownSteps.ElementAt(i)))
    {
        steps[i].gameObject.SetActive(false);
        steps[i].Set(shownSteps.ElementAt(i));
        steps[i].gameObject.SetActive(true);
    }
}
steps.ForEach(s => { if (!s.IsUsed) s.gameObject.SetActive(false); });

I introduced RequireUpdate(step) which checks if the step actually changed and only then set the clip. SetActive() was actually the issue. And because the live mode has a lot more condition checks, that's why it was never a problem in build mode. πŸ™‚

It's still a bit ugly but I don't have the time to make it nice right now, will get back to it tho (or at least that's what I say now) πŸ˜„

Thanks for your help tho! Really appreciated!

(sorry for interrupting haha)

midnight violet
fickle ether
sage radish
#

If shownSteps is an IEnumerable, it would be better to use a foreach but increment your own index variable to keep track of it.

unique zenith
modern forum
#

Hey everyone
Is it possible to export convex mesh collider as .obj file?

midnight violet
modern forum
#

Is there any way to get convex mesh collider data as triangulated mesh? Or read vertices and indices from collider directly?

flint sage
#

Mesh collider just has a Unity Mesh as one of it's fields, you can read that and get verts, indices, and probably other things

untold moth
#

I assume that he wants to get the simplified (convex) version of the mesh that's generated.πŸ€”

modern forum
#

Yep. To reduce the export obj file size, my aim is to keep tris as low as possible.

untold moth
#

I don't think that it's accessible on c# side.

#

You could generate a convex mesh in blender though.

modern forum
#

Is it possible? How to do that?

modern forum
#

Sadly convex hull wraps the object from outside.

untold moth
#

Wdym?

#

It's what it does in unity too, no?

modern forum
#

Let's say I have a 3D of house and it's one mesh, then convex hull can't create mesh for interior

untold moth
#

You could separate it into several meshes and then apply convex hull to them separately.

glacial sentinel
#

Can u run a function async with the Invoke?

#

Or at that point do I use a coroutine with a yeild return new WaitForSeconds.

untold moth
#

In a sense it's already async if you call it with Invoke, since it runs independent of the place where you call it.

#

What you mean is whether it's possible to keep it running over several frames, right?

glacial sentinel
#

yea I don't want the function to block my game

#

Basically my game will run 24/7 on a server and has to make API calls every second. The API requires credentials that will expire after x amount of time. So i am trying to find the most efficient way to renew the credentials in the background every day

#

and renewing the credentials is also an API call which is why I want it async

tropic lake
#

coroutines would probably be best

glacial sentinel
#

Alright so the coroutine with yield return seconds then

tropic lake
#

yeah

glacial sentinel
#

thanks

bleak edge
#

what would be more efficient?

devout hare
compact ingot
bleak edge
#

i've always learned that using stringbuilder is more efficient ? :v

devout hare
#

I suspect that all the extra operations cancel out the concatenation efficiency many times over.

flint sage
#

StringBuilder is only faster on larger amounts of appends, just one append is going to be slower

#

Interpolated strings are just concatenated strings behind the scenes

kindred tusk
compact ingot
compact ingot
# flint sage Interpolated strings are just concatenated strings behind the scenes
TEST()
{
  var a = 1;
  var b = "foo";
  string x = a + b; // compiled to use array concatenation
  /* compiles to:
    IL_0010: ldloca.s     a
    IL_0012: call         instance string [mscorlib]System.Int32::ToString()
    IL_0017: ldloc.1      // b
    IL_0018: call         string [mscorlib]System.String::Concat(string, string)
    IL_001d: stloc.2      // x
  */

  string y = $"{a} {b}"; // compiled to use string builders
  /* compiles to:
    IL_001e: ldstr        "{0} {1}"
    IL_0023: ldloc.0      // a
    IL_0024: box          [mscorlib]System.Int32
    IL_0029: ldloc.1      // b
    IL_002a: call         string [mscorlib]System.String::Format(string, object, object)
    IL_002f: stloc.3      // y
  */
}

string.Format(...) uses and internal, cached, thread-specific StringBuilder that is reused for for all format calls. So it already does all the general purpose optimization that the OP attempted in the background.

string.Concat(...) uses array concatenation

Whichever is faster, depends on the use case. In general, the compiler does a great job of optimizing stuff like that... improving on those optimization requires detailed understanding of the IL code that the compiler produces, which again requires detailed understanding what the JIT or IL2CPP/LLVM compiler does and then again what the CPU architecture likes to work with.

undone coral
#

try to describe in gameplay terms

#

what you're trying to achieve

#

in two sentences

#

@spare garden "a one coordinate system to another as two right-angle triangles due to different scaling techniques." this is hard to understand

autumn summit
#

I don't know what level of intermediary code this falls under, but how do I properly get Unity to read the alpha values from a webcam device in a webcamtexture? Seems like it's just defaulting them to 255 no matter what.

#

The WebCamtexture constructor doesn't seem to accept a TextureFormat for some reason, so I'm kind of at a loss.

devout hare
#

Definitely not my area of expertise but how can a webcam have alpha values?

autumn summit
#

Virtual camera.

#

Specifically, I'm reading from a virtual camera coming out of another Unity application, which I can confirm is being transmitted with alpha, because OBS properly respects the alpha value when it's added as a video input source.

regal olive
#
            if (up.GetComponent<TileWall>() != null) 
            {
                Debug.Log("UP is Wall");
                var s = gameObject.GetComponent<SpriteRenderer>();
                s.sprite = Resources.Load<Sprite>("WallTopConnected");
            }
            else if (down.GetComponent<TileWall>() != null)
            {
                    Debug.Log("DOWN is Wall");
                    var s = gameObject.GetComponent<SpriteRenderer>();
                    s.sprite = Resources.Load<Sprite>("WallBottomConnected");
            }

So I have these two statements running in an update method in a class that's derived from an abstract class type. The first if statement works fine, but the 2nd doesn't work. When I place a tile above another tile, the bottom tile changes to WallTopConnected, but the top tile stays the same

#

like it keeps stopping after the first if statement, it wont go to the else if

plain abyss
#

So, the second one should only run if up doesn't have a tile wall, right?

regal olive
#

yes

#

so if up is null, go check down

plain abyss
#

So, I'm assuming this code gets run on all tiles involved, right?

#

Are you sure you're not getting a NullReferenceException if up is undefined?

regal olive
#

It runs on tiles with TileWall in it

plain abyss
#

That'd stop the function entirely, no if

regal olive
#

Hmm

plain abyss
#

Do you get an NRE?

regal olive
#

I have a try catch{} that's stopping it

#

or catching that error

plain abyss
#

If it throws the error it instantly warps to the catch block

#

Do not pass go

#

do not collect $200

regal olive
#

I see

plain abyss
#

You should probably check if up is null before doing stuff to it instead of just try-catching

#

try-catch isn't a magic "make errors go away" button, it still throws them

compact ingot
plain abyss
#

it just lets you do catch instead of dying instantly

modest lintel
#

You should be only using try-catch when you don't know if the exception will be thrown and which you can't priorly check against ..(things out of your control)

regal olive
#

I'm getting a MissingReferenceException instead of NRE

plain abyss
#

Same error, different hat

regal olive
#

yeah

plain abyss
#

You need to check if up exists before you try to get component on it

regal olive
#

I get the MRE on line else if (down.GetComponent<TileWall>() != null)

#

instead of the up one

plain abyss
#

Then down isn't set on something

regal olive
#

so I guess I'm double checking an existing component

#

no nvm

#

basically GM is class of GridManager

#

the GridManager generates tiles of gameobjects in a grid with TileBase added

regal olive
modest lintel
#

might as well also cache that Resources.Load somewhere

compact ingot
#

or not use Resource.Load in the first place

plain abyss
#

And the Resources.Load call too, store the sprite for each wall type and only call Resources.Load once each

compact ingot
#

can't you make the sprite an editor reference?

plain abyss
#
if (up != null and up.TryGetComponent(out TileWall tw)){
  renderer.Sprite = TopConnectedSprite;
}
#

Doesn't that look much cleaner?

regal olive
#

no

#

lol

#

im joking

regal olive
#

Above the if statement

plain abyss
#

Why do it in this condition?

#

It never changes

misty glade
#

For anyone who's been following along at home with my headaches the last few days, I have shared libraries with dependencies working pretty smoothly now, so I thought I'd take a moment and outline the process if anyone wanted to reproduce it for their own projects. Feel free to DM me, there's a lot of details that are important.

The requirements for me were to make as "least-fragile" a solution as possible for a shared codebase (client in unity, server in !unity).

  • Make a new project in MSVS of type Class Library (.NET Framework). NOT "Class Library" (which targets standard2.0 - I didn't have luck resolving dependencies with it).
  • Plop your code in here, and edit the post-build script macro (Right click solution / properties).
  • In this post-build script, copy the DLL to unity's Assets/Plugins/ special folder.
  • IF YOU HAVE DEPENDENCIES - it's better to import them into Unity rather than try to get all the DLLs (gotten from NuGet) included in the build to copy over to the Plugins folder as well.
  • I use MessagePack, which has a separate step for generating code, so I do that here as well.

My post-build script for my shared project looks like this:

#
cd "$(SolutionDir)"
dotnet mpc -i "ISG-Shared.csproj" -o "$(SolutionDir)Networking\Generated\MessagePackGenerated.cs"
copy "$(SolutionDir)Networking\Generated\MessagePackGenerated.cs" "\projects\unity\Idle Space Test\Assets\Scripts\Generated\"
copy "$(SolutionDir)$(OutDir)$(TargetFileName)" "\projects\unity\Idle Space Test\Assets\Plugins\"
copy "$(SolutionDir)$(OutDir)$(TargetFileName)" "\projects\ISG\lib\"

I also copy the DLL to a lib folder in my "project" root because:

  • On the server solution, you have to "import project reference" and browse to a DLL. This works great, but obviously you don't want to have to fiddle with Debug/Release directories, so doing the above copy to a /lib folder can ensure that whatever the "latest" version of my DLL is can be properly referenced on the server codebase.

Voila, you've got 3 projects - client, server, and shared - and you can (and probably should) check them into their own repos. No more duplicated code or copying code around or anything like that.

HTH

#

Also - NuGet for Unity does not work very well... It took me a long time to diagnose that it was unable to pull down older versions of things and was often getting the version of the dependency wrong, especially when it was strongly-typed - I was getting errors like "Assembly 5.0.0.2" is not valid, dependency is strongly typed for "Assembly 5.0.0.0"

#

Now after burning 3 days to this little exercise, I'm going to nerd it up with D2:Resurrected. Have a nice weekend y'all.

broken socket
regal olive
#
        if (up != null && up.TryGetComponent(out TileWall tw)){
            Debug.Log("UP is Wall");
            renderer.sprite = Resources.Load<Sprite>("WallTopConnected");
        }

        if (down != null && down.TryGetComponent(out TileWall tww))
        {
            Debug.Log("DOWN is Wall");
            renderer.sprite = Resources.Load<Sprite>("WallBottomConnected");
        }```
#

I moved the debug.log after the renderer.sprite, apparently it returns after I set the sprite

plain abyss
#

Do you still have it in a try-catch?

regal olive
#

I don't

plain abyss
#

There's no return in there. If it's ending on the renderer.sprite line it's erroring

#

Put a debug log before and after it

#

If you get the before but not the after, it's erroring

regal olive
#

It works before, I moved the Debug.Log("UP is Wall"); after it

#

and it stopped printing

#

I might need try catch {} for this

plain abyss
#

Then it's crashing

#

You shouldn't have try catch anywhere

#

If you don't have a damn good reason to expect an error and not care, you should just let it error

regal olive
#

It might be because it's in update, so it's continuously setting the sprite

plain abyss
#

It'll still print

regal olive
#

hm

plain abyss
#

Put a log before and after the renderer line

#

if you get one, but not the other, you're erroring

#

and you've probably got a try-catch hiding it so it gives you zero useful information

regal olive
#

I don't have try-catch anywhere

#

Well now its printing "UP is Wall" after I set the sprite

#
if (up != null && up.TryGetComponent(out TileWall tw))
        {
            renderer.sprite = Resources.Load<Sprite>("WallTopConnected");
            Debug.Log("UP is Wall");
        }```
plain abyss
#

And is it not setting to WallTopConnected?

regal olive
#

wait

#

okay

#

for some reason, it's only detecting the instance it's placed down

#

like the 2nd tile placed in the sequence isn't updating, but the one adjacent to it is

plain abyss
#

Are you re-setting up and down after a new piece is placed on the old ones?

regal olive
#

basically yeah

#

except it should be unique per tile

queen plover
#

Anyone have some good sources on architecture for things like a tower defense game with branching upgrades? I want to make this but am unsure where to start, do people just make a bunch of classes that inherit from something like Upgrade<T> where T : Tower, and use reflection to find the upgrades, assuming upgrades change towers in ways that are more then just stats-

modest lintel
#

How does reflection come into play here?

regal olive
queen plover
#

Just spitballing, I assume that'd be the easiest way to get all of these classes

#

since you can't drag them in unity for reference ; considering it's all done in code

#

I'll take any specific way of how people do it; I want to know them all so I can make a decision on what I'd like to do

compact ingot
#

feels to me like you are kinda overthinking it a bit

queen plover
#

That's very likely

#

but I also don't like jumping into coding with absolutely no image of how I'm going to do something

regal olive
#

For my game, I organize my tiles from an abstract class called TileBase

#

you could do something like StructureBase

compact ingot
#

best way is to build it the way you think it would work... fail, rewrite, fail, rewrite.... best way to figure it out

queen plover
#

I know about Polymorphism, abstract classes and all that jazz, I'm talking specifics

regal olive
#

like how specific?

queen plover
#

What other developers did, ideally

regal olive
#

because from that point it's up to you

compact ingot
#

definately DO NOT USE INHERITANCE

regal olive
#

lol

queen plover
#

:P

compact ingot
#

other than that... don't worry about language features... worry about data transformations

modest lintel
#

Well, its a tad bit difficult to explain specifics over text, so I'll try and solve one problem for you. You can't serialize generic classes, but if you inherit from them and make them concrete, you definitely can

regal olive
#

I don't know why tile detection is so difficult to code for me :/

compact ingot
#

@queen plover an idomatic game-type thing would be to upgrade an actor/entity by adding/activating components on it that handle a specific gameplay ability

regal olive
#

Maybe I should have an entirely separate script meant for it, so it gathers all tiles in a for loop, looping through all the tiles. Then if it has like if tile == wall, check neighbors

#

instead of writing it in a class that derives from an abstract class

compact ingot
regal olive
#

state machines are nice yeah

#

used a lot of those in a previous game

compact ingot
#

depending on how "big" the game is supposed to be... aim for a data-oriented/driven architecture i.e. make behaviour configurable through the editor, use scriptable objects to share events/data... you could for example make abilities scriptable objects and allow designers to "drag & drop" them onto actors.

queen plover
#

So no Inheritance; So the tower is just that; a class "Tower", that decides what to do with whatever "abilities" it is given

compact ingot
queen plover
#

and I'd probably end up with configurable but 'generic' (not in the code meaning) abilities;

e.g. Projectile and the a field 'effect' set as 'knockback', rather than "TornadoProjectile"

compact ingot
#

yeah, sounds about right

#

but also: don't over-do the architecting

queen plover
#

Would ExecuteAbility(), have Tower as their parameter, and let that do whatever it wants?

misty glade
regal olive
misty glade
queen plover
#

I know I shouldn't over do the architecting ( but I must admit I like doing it - sometimes thinking about developing a game can be more fun then starting it :P )

compact ingot
#

just to get started... then learn from what i dont like about that primitive version

queen plover
compact ingot
#

and rewrite the whole thing

#

i'd pass the context to the ability-SO, kinda like an event

queen plover
#

I'll also have to figure out how this interacts with upgrades and the like...

compact ingot
#

always have data flow in one direction only, from the more general/bigger to the more concrete/smaller thing

queen plover
#

I don't really want to have scriptable objects for upgrades and abilities

#

going to end up with very bloated folders

compact ingot
queen plover
#

Perhaps every ability has a bool ShouldBeExecuted(LoadsofContext)

#

still not sure how to handle animation and all that shizzle

#

Also I'm wondering how tower defense towers decide on

  1. What is the "first enemy" in "my range"
    without horribly looping over every single enemy on the track
compact ingot
queen plover
#

The ability gets the context every frame?

#

So ExecuteAbility() is called every frame; and it decides if it just wants to break out or not

compact ingot
queen plover
#

See, with that; I'm unsure how I know when to activate it

#

because different abilities are bound to have different activation

misty glade
#

I'm coming to the convo late, @queen plover , but one thing you could do is... when it's appropriate, check for the upgrade with a switch on the type pattern

#

Lemme dig up a code sample

queen plover
#

Perhaps I ought to predefine animations too;

Force tower upgrades to have
"Idle Anim"
"Attack Anim"
"Special1 Anim"
"Special2 Anim"
and keep it strict to that

misty glade
#
    public abstract class PlayerAction {}
    public class PlayerActionConcedeGame : PlayerAction {}
    ... etc ...

    ... then later when you need to dispatch an action based on the type ...

            foreach (PlayerAction pa in playerActions)
            {
                switch (pa)
                {
                    case PlayerActionConcedeGame _:
                        break;
                    case PlayerActionFieldMove paFieldMove:
                        break;
                    case PlayerActionGridMove paGridMove:
                        break;
                    case PlayerActionSkipTurn _:
                        break;
                    case PlayerActionUseActiveAbility paUseActiveAbility:
                        break;
                    default:
                        throw new NotImplementedException();
                }
            }
queen plover
#

and then abilities can just decide if they use those animations

misty glade
#

(if it's a tower "ability" anyway, that works)

#

if it's an upgrade, then you just ... check for the upgrade when you "consume" or "calculate" the value

#

Like, if you're calculating the max HP of the tower and the tower has an upgrade, you could instantiate the tower and check for that specific upgrade when you instantiate it (and maybe the upgrade has details about the % of HP increase, or whatever)

queen plover
misty glade
#
public abstract class TowerUpgrade {}
public class TowerHPUpgrade : TowerUpgrade 
{
  public int PercentUpgrade {get; set;} = 0;
}
compact ingot
#

pseudo (inefficient):

Update() {
  var readyAbilities = abilies.Where(it => it.IsReady).ToList()
  if (readyAbilities.Count > 0)
    abilities[Random.Range(0, readyAbilities.Count)].Execute(context)
}
queen plover
#

It's probably be IsReady(Context) too

misty glade
#

You don't have to modify tower to add abilities - you just make sure you "fall through" properly on your "if ability is __" if statements, buuuuuuut, it's not broaching SOLID because tower has to know about abilities/upgrades - they don't make sense outside of the concept of a tower, i think

compact ingot
queen plover
#

I can kinda visualize what I'll try and do

misty glade
#

I would suggest that your tower provides the only public interface to values like "cooldown" or "hitpoints" or whatever, and put the domain logic for upgrades there (and literally no where else)

queen plover
#

It's alright if not; It's a bit outside what I'm already asking

#

but I feel like it'd be good to know; because I reckon I'll make the enemy system before the tower one

misty glade
#

Looping over every enemy is fine, although you could likely "denormalize" it by having a location manager subscribe to all enemies locations, and any time they move, it updates their location in some sort of custom data structure

queen plover
#

It gets bad when Looping over every enemy contains distance checks as well though

misty glade
#

ie - a zone, or a hard coded integer "path" Id - then your towers on that path only check the enemies on that Id

queen plover
#

I'm not sure how else I'd check if it's in range

misty glade
#

I suspect that it's probably not that bad - if it is, check for enemies in range less often - or perhaps have a tower "lock on" to an enemy and only find a new enemy when the current one is dead or out of range

compact ingot
#

how many enemies are you planning?

misty glade
#

I'd probably do it with the "locking on" approach

queen plover
#

I'll see if I have performance problems when I do it

#

I don't want to do the locking on approach, because I want to give specific targetting options

misty glade
#

makes for a better gameplay experience i think - it might suck to have your towers just spraying bullets everywhere instead of focus-firing down a single enemy in range? i dunno

#

So you don't have to do that calculation every frame - only every time the tower needs to fire

compact ingot
#

you can always compare distances with Vector.SqrMagnitude(from - to) < weaponRange * weaponRange ... that is very efficient

queen plover
#

I'll try have the "Path" class or whatever try and collect as much info as it can to cut down on how much stuff is happening for every single tower

misty glade
#

and you certainly don't want to check for the tower needing to fire in Update().. i would do it with callbacks/events, if you're comfortable with that

queen plover
#

though I reckon "First/Last in My range" could be tricky; I suppose I'll find out

misty glade
#

It's maybe a bit more fragile then simply looping over all your towers every update() and seeing if they're ready to fire, and if so, firing.. but it'd be much much more optimized out of the gate

compact ingot
#

or just add trigger-colliders to everything and have unity physics do the optimized range checking

queen plover
misty glade
#

no - probably an event when you start firing and end firing that you consume internally, along with a public call to "check for enemy"

#

so.. something like this:

#

some boilerplate for you:

public bool IsFiring = false;
public IEnumerator FireBullet()
{
  // find the nearest enemy, if any. If we found one..
  isFiring = true;
  // else return

  // instantiate a bullet
  // animate it toward the enemy 
  // calculate and apply the damage
}
public void StartFiring() { // start coroutine firebullet 
}

... and then in some sort of TowerManager ...
public void Update() {
// if TimeSpan last checked towers to fire is > 1 second or something reasonable
// loop over all towers that aren't .IsFiring and .StartFiring()
}
#

that's .. really hacked together but hopefully you get the general idea?

compact ingot
misty glade
#

basically you have some manager that literally just loops over all the towers once per second or two (maybe not even that often? play with it - should be a very very lightweight call) and then your FireBullet just restarts itself when it finishes firing

#

there's a lotta different ways to skin this cat, tbh

regal olive
#

it detects if theres one up or down

misty glade
#

I think I generally err towards "premature optimization is the root of all evil" (google that) but in this case, it does sound reasonable that "every tower checking the distance to every enemy every frame" is going to be way too much calculation

regal olive
#

but not if there's both

misty glade
#

@queen plover (I forgot to include a call to "firebullet" at the end of firebullet, as well - it should just run continuously as long as there's a target in range)

compact ingot
misty glade
#

for sure.. i actually think that this approach (every tower check every enemy every frame) is probably still fine for 20+ towers and 20+ enemies? sorta just guessing

compact ingot
#

and can be very quick to do if they update their own position inside a spatial index (quad-tree, BVH, ...)

misty glade
#

this approach also allows you to have weapons that are like "lasers" that apply damage every tick, rather than having discrete bullets

#

the laser just automatically switches targets whenever one is in range, and applies damage uniformly and instantly to anything in range.. which is kinda cool

compact ingot
#

i.e. instead of comparing vs. all actor positions, just have the tower query "who is in this box"... and check distances only for actors in the box

misty glade
#

well, i mean, that's still the same calculation, no?

compact ingot
#

no

#

nlog(n) instead of n^2

queen plover
#

I plan for the enemy count to be quite high, and tower count is practically up to the player (it's going to be freeform placement)

misty glade
#

oh i see what you're saying

queen plover
#

Optimization will be needed- but I won't do it too much prematurely

misty glade
#

sure but "practically up to the player" is still bounded by you - is it 10-100? 1000-2000? πŸ™‚

misty glade
#

(at least for the "findClosestTarget()" method)

compact ingot
#

trigger colliders do that automatically and very efficient... just need to make sure the collision matrix is set up right

misty glade
#
private Vector2 topLeftOfRange = ...;
private Vector2 bottomRightOfRange = ...; // or use a rect2d, whatever
...
private Enemy GetClosestEnemyInRange()
{
  List<Enemy> enemiesToCheck = BattlefieldManager.GetEnemiesIn(topLeftOfRange, bottomRightOfRange); //foreach all enemies, check their position - no distance check required
  foreach (Enemy e in enemiesToCheck)
  {
    ... find the closest ...
  }
  return closestEnemy;
}
#

or yeah, colliders

queen plover
#

I'm going to head to bed now- @misty glade @compact ingot @regal olive Thank you very much for all the Info <3

regal olive
#

goodnight, i still have my bugs to fix lol

misty glade
#

GN - don't forget to wake up in the middle of the night and jot down your solution

#

πŸ™‚

queen plover
#

In a cold sweat after a nightmare about trying to figure out how to optimize things of course

#

but then I forget the solution before i can find a pen and paper :P

regal olive
#

I'm still trying to figure out why my tiles detect if there's an up or down tile but not both

misty glade
#

@regal olive I tried to find the original code/question - I'm piqued, could you restate the problem and paste your code again..?

regal olive
#
private void Update()
    {
        var renderer = GetComponent<SpriteRenderer>();

        if ((down != null && down.TryGetComponent(out TileWall twww)) && (up != null && up.TryGetComponent(out TileWall twwww)))
        {
            Debug.Log("DOWN and UP are Walls");
            renderer.sprite = Resources.Load<Sprite>("WallTopBottomConnected");
        }
        if (up != null && up.TryGetComponent(out TileWall tw))
        {
            Debug.Log("UP is Wall");
            renderer.sprite = Resources.Load<Sprite>("WallTopConnected");
            Debug.Log("UP is Wall 2");
        }

        else if (down != null && down.TryGetComponent(out TileWall tww))
        {
            Debug.Log("DOWN is Wall");
            renderer.sprite = Resources.Load<Sprite>("WallBottomConnected");
            Debug.Log("DOWN is Wall 2");
        }
    }```
#

1 = first tile placed, 2 = 2nd, etc

#

once I placed down 1, it has the unconnected texture. Then I placed down 2 on top of it, then 1 changes to topconnected but 2 does not change to bottom connected

#

basically the previoustile placed isn't updating all the time

misty glade
#

(separate issue.. you shouldn't be doing a Resources.Load() in Update())

#

yeah, i'm digesting.. standby πŸ˜›

regal olive
#

okie

misty glade
#

where/when/how do you set "down" and "up"?

#

(you also don't want to GetComponent() every update.. that's gonna bring your app to a crawl real quick)

regal olive
#
private void Awake()
    {   
        GridManager GM;

        GM = GameObject.Find("GridManager").GetComponent<GridManager>();

        //Start detecting neighbors
        thisPosition = GM.tiles[Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().x), Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().y)];
        up = GM.tiles[Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().x), Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().y + 1)];
        down = GM.tiles[Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().x), Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().y - 1)];
        left = GM.tiles[Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().x - 1), Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().y)];
        right = GM.tiles[Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().x + 1), Mathf.FloorToInt(gameObject.GetComponent<TileBase>().GetGridPosition().y)];
    }```
#

in awake I set up down left right

#

since that's the immediate frame when the tile spawns

misty glade
#

k

#

and you're sure that's working? and not giving you the wrong floor when you're around 0

#

cuz remember floor of -0.5 is 0, but so is 0.5

regal olive
#

yes, I debugged it already

#

up is precisely 1 position up from the tile placed

misty glade
#

k - i might also make this a bit easier to read by not calling the GetGridPosition 10 times when you need to once -

regal olive
#

yeah lol

#

before this I didn't have getgridposition

#

so it was a thousand times worse

misty glade
#
using static Unity.whatever.Mathf;
private void Awake()
    {   
        GridManager GM;

        GM = GameObject.Find("GridManager").GetComponent<GridManager>();

        Vector thisLocation = gameObject.GetComponent<TileBase>().GetGridPosition();

        //Start detecting neighbors
        thisPosition = GM.tiles[FloorToInt(thisLocation.x), FloorToInt(thisLocation.y)]; 
        /// ..etc ...
    }
#
        if (up != null && up.TryGetComponent(out TileWall tw)) // shouldn't this be else if?
#

I honestly suspect that your Awake() logic is what's broken - I would probably add something just to verify that down isn't null when you place 2

#

aren't you getting array out of bounds errors whenever you place down a tile?

#

unless you wrote a custom indexer for the .tiles member of GridManager?

#

show me your definition of GameManager.tiles

regal olive
#

lemme show the whole script

#

its apart of an abstract class

misty glade
#

I wanted to see GridManager - can you hatebin that?

regal olive
#

yeah

misty glade
#

So also, while I was looking here.. I don't think these tiles need to be subclassed.. they just look like variations on a tile?

#

(with hard coded properties..?)

#

anyway, different thing.. stay on target @misty glade :p

regal olive
misty glade
#

oh duh

#

you're setting down/up/right/left in Awake and never again

#

so obviously once you place a tile down, the existing tiles aren't going to magically get new down/up/right/left values

regal olive
#

I see

#

I don't think I can set them in update

#

but lemme see

misty glade
#

oh gosh no

#

you don't want to do that

regal olive
#

oh

misty glade
#

your code is already going to suffer from optimization issues with your update function but you can worry about those later πŸ™‚

#

do this instead:

regal olive
#

there's probably a simpler way to do a texture update system

misty glade
#
public void CalculateNeighbors()
{
 //... your code that's in awake that figures out up/down/right/left
}
public void Awake()
{
  CalculateNeighbors();
  GM.RecalculateAllTiles();
}

... then in GridManager ...
public void RecalculateAllTiles()
{
 // for each tile in tiles
 // {
   tile.CalculateNeighbor();
 // }
}
#

also you should move all that texture setting and stuff to CalculateNeighbors(), realistically, so it only happens when the user places a new tile, not each and every frame

regal olive
misty glade
#

Resources.Load() is something you want to call as few times as possible

regal olive
#

the issue is that I can't use the inspector for this script

misty glade
#

well you have logic in awake that is figuring out who it's neighbors are, but once a tile goes down, awake never gets called again (so a tile will never get "new" neighbors)

#

you could use the inspector for this script but that requires a bit of work

regal olive
#

that makes sense

#

kind of sad this is the only feature I implemented this week lol

misty glade
#

you'd want some sort of field that makes sense in the inspector for an object

#

or alternatively you could rename your instantiated prefabs to their grid location or something else

#

Anyway, hope that helps.. gonna get back to my work :]

regal olive
regal olive
#

I have:

public void RecalculateAllTiles()
    {
        for (int i = 0; i < Columns; i++)
        {
            for (int j = 0; j < Rows; j++)
            {
                tiles[i, j].GetComponent<TileWall>().CalculateNeighbors();
            }
        }
    }```
For that
#

I'm getting a nullreferenceexception on tiles[i, j].GetComponent<TileWall>().CalculateNeighbors();

sly grove
#

figure out which one and why

#

Adding log messages is a good way to figure out which.

regal olive
#

advanced isnt really defined anywhere here

tough tulip
#

meaning of advanced is pretty much straightforward. you'd find more and quicker help in #πŸ’»β”ƒcode-beginner is what he meant to convey

misty glade
# regal olive advanced isnt really defined anywhere here

He's not wrong, unfortunately - how to check for null and how to write code that doesn't expose NRE's is generally a beginner topic. In any case, you are likely calling Recalc in your Awake() method in GridManager, but you're not initializing the array until your Start() method (unless you changed it from before)

#

Awake() comes before Start()

#

and also you shouldn't @ someone for an answer.. one of the mods might pull out the spanking stick πŸ˜‰

tiny echo
#

What would be the best way to write a snapshot of the current scene into a byte array so it can be sent to clients?

flint sage
#

Pretty sure you don't, there's no way to restore scene state like that

native hinge
#

Does anyone know how to save tilemap data to files?

sly grove
#

There aren't really any shortcuts for this

undone coral
#

Okay honestly reading what you wrote that was not clear at all

#

The way to cut a wedge in half is, you make a prefab with the wedge and its halves, and you toggle between them

#

It seems simple so I must be missing something

oblique lake
#

How would you folks go about implementing a Status Effect system? Scriptable Objects? Inheritance? Etc?

I'm trying to figure out the best way to actually handle all of this.

sly grove
#

all of the above maybe?

oblique lake
#

Maybe. Lol

sly grove
#

probably make a base class for a StatusEffect that has some common methods on it that let you process them all generically each turn (does your game have turns?) e.g.

void OnTurnPassed()
void OnEffectAdded()
void OnEffectExpired()
void OnEffectRemoved()
#

then have a list of effects for the character and something that processes adding them, removing them, and processing them each turn?

#

and have each effect class implement those methods?

#

Β―_(ツ)_/Β―

oblique lake
#

Yeah, I'm really not sure?

oblique lake
#

I'm fairly sure Interfaces are the best way forward, I'm just not entirely sure how to handle update ticks on it etc.

sly grove
oblique lake
#

Yeah, also what I was thinking.

plucky dagger
#

I have a web-gl game (uploaded to itch io). I want the user to copy the string from the game. One approach that I know is to have Unity call a javascript function (a popup box) and pass the string to the popup box (mentioned here: https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html). I see that I'm able to pass the string but the user still isn't able to copy the string from the popup box. Any ideas how to do this?

normal dune
#

i have an abstract class, in it an abstract Execute() method. I have different classes that inherit that class and does different things. i want to be able to save a list of those classes as json, then after load it, and be able to call that Execute() method. i tried saving the class name and assembly in the json file, then load it using Activator.CreateInstance(), but it seems to crash unity. Having a switch statement for each class works but id rather a better practice. Im doing this in the goal of game modding. Does anyone have any ideas on the best practice to achieve this?

long ivy
#

does your abstract class inherit from MonoBehaviour?

normal dune
#

no it doesnt

long ivy
#

CreateInstance should work, then. Do your constructors have any arguments?

#

one hang up I've come across is that it doesn't implicitly convert arguments well, so make sure they match exactly

normal dune
#

constructors for the abstract class? there are none in it.

long ivy
#

the derived classes

normal dune
#

they dont have any either

long ivy
#

are there any clues in the logs or crash message, then? Your approach should work

normal dune
#

it isnt so much of a crash as more of a freeze. theres no clues i can find.

#

im glad to hear im on the right track at least πŸ™‚

#

hm, i wonder if im just using CreateInstance wrong?

#

NodeInstance is my abstract class, and the error isnt shown

   if(type != null)
        instance = Activator.CreateInstance(type) as NodeInstance;
    else
        UnityEngine.Debug.LogError("GetType() returns null: " + nodeName);```
long ivy
#

OnStart is the name of the class? Does instance = Activator.CreateInstance(typeof(OnStart)) as NodeInstance; cause a similar issue?

normal dune
#

OnStart inherits the abstract NodeInstance yes. sorry, should have mentioned.

#

i switched that line, and unity is frozen now. it appears so

long ivy
#

Is OnStart itself also abstract? Does it implement all abstract methods?

normal dune
#

its not abstract itself, and it implements all methods

#

unfortunately i have to leave for work, thanks for the help so far, ill be back

long ivy
#

try:
instance = new OnStart() as NodeInstance; and if that works, then
instance = Activator.CreateInstance(typeof(OnStart), null) as NodeInstance; next

normal dune
#

ill try once i get home, sorry to cut off like this πŸ˜›

long ivy
#

np, maybe someone else will see in the meantime and you'll have your answer when you get back

harsh current
#

Is it possible to set UnityEvent to invoke a function from a script, using the inspector?

drifting galleon
#

yes

harsh current
#

I can't see the option. I tried using a c# standard class, a monobehaviour and a component with the same monobehaviour, and none allowed to invoke a function from the class

drifting galleon
#

you have to pick the gameobject in the editor and then you can view the methods on it

harsh current
#

I tried that, but no luck

#

It just won't show

drifting galleon
#

is the method public?

harsh current
cosmic tendon
#

anyone got idea what the hell is happening, stuff disappear from the game and when i check the scene everything is there

faint marlin
#
    {
        var ray = new Ray(Origin, direction);

        var currentMinDistance = float.MaxValue;
        var hitPoint = Vector3.zero;
        var planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
        for (var i = 0; i < planes.Length; i++)
        {
            // Raycast against the plane
            if (planes[i].Raycast(ray, out var distance))
            {
                // Since a plane is mathematical infinite
                // what you would want is the one that hits with the shortest ray distance
                if (distance < currentMinDistance)
                {
                    hitPoint = ray.GetPoint(distance);
                    currentMinDistance = distance;
                }
            }
        }

        // Now the hitPoint should contain the point where your ray hits the screen frustrum/"border"
        lineRenderer.SetPosition(0, Origin);
        lineRenderer.SetPosition(1, hitPoint);
    } ```
#

for some reason i get hit only on left and down the right and top being ignored any idea?

elfin tundra
#

you could try rotating the planes to fix that

faint marlin
elfin tundra
#

yup that looks like it could be the issue so did you try rotating those two planes?

faint marlin
#

no i didn't at what axis should i rotate and at what degree sorry i have no idea

#

i think the calculated Frustum Planes can't be rotated !

sly grove
#

I don't think that would be the problem but to rotate the plane you'd just do plane.Flip();

faint marlin
#

i tried flip there is no difference even with the working one (right,down)

long ivy
#

is your camera orthographic? does your direction lie on the plane defined by the camera forward dir? And finally, I assume you only are interested in the four edges and not the near and far plane, so test the first four planes and ignore the last two in your loop

faint marlin
#

it is perspective

sly grove
#

Yeah I wouldn't think that flipping would make a difference

faint marlin
sly grove
# faint marlin

Based on the video you have some weirdness with the direction?

#

It seems like it's not always following the joystick

long ivy
faint marlin
#

it happen only when there is no hit and that happen with top and right only .... the line should be start drawing from origin which is the stick holder to the direction which is the hit point

sly grove
#

ah yeah ignoring the near/far planes would be a good idea

faint marlin
sly grove
faint marlin
#

yes sure

#
            Vector3 direction = MousePos - StickParent.position;
            GetHitPoint(StickParent.position, direction);```
#

StickParent is just the stick holder

sly grove
#

you've got mousepos that is in screen spacew

#

What is StickParent? Is it a UI element?

faint marlin
#

yes it is UI

sly grove
#

right so

#

the planes you get

#

are in world space

#

and everything here is in screen space Vector3 direction = MousePos - StickParent.position;

#

so you've got a ray in screen space and you're trying to use it against planes in world space

#

that might be part of your issue

faint marlin
#

any idea how to convert those planes to screen space !

faint marlin
#

i guess i don't need CalculateFrustumPlanes since am in screen space

hollow wing
#

this channel feels new πŸ€”

normal dune
#

@long ivy idk what the issue was, but after changing some code around it works now. i wonder if there was an infinite loop or something dumb, but either way i appreciate your time and help! thanks!

hardy inlet
#

in Unity, is it possible to have built project and then work on scenes as levels in other project? And then open those levels in built project. I want to find a level designer, but I don't want to share the whole project right away. First to try what could he do.

livid kraken
#

Sure he can export his scene as a unity package and you can import it

#

You can export a base package as well to have him work with the right tools and settings

#

Not advanced code btw

hardy inlet
#

So he will be able to test level by himself, right? Like export it as package and launch in the built project?

livid kraken
#

Oh the build no sorry I didnt get that. No a unity pacakage will not work in the build. He will send you the package and you put it in your editor. For him to insert custom assets into a build you have to basicly do mod support

#

Look into asset bundles and adresabbles etc

hardy inlet
#

Thanks! Will check it out.
The assets not custom. There are some prefabs he'd have to put on stage. Like where the player spawned.

Just the gameplay script, UI and all that stuff would be taken out. Just in case so he could not give away the source of the game. Cuz I'd probably deal with a dozen or even more people about level design role.

livid kraken
#

You can make them sign a document called a NDA then you have some legal action :)

hallow cove
#

I would like to start splitting my game's processes to multiple threads

#

how could I move pathfinding for the nav mesh agents to other threads?

real blaze
#

hey. I wanna make two animations play alongside. each animation controls one child. the prefab is like so :

root
  - child A
    - subchild A 

these are not RIGS.

any way to do that ?

#

that the anim1 controls child A and anim2 controls subchild A. now the desired result would be that when anim1 moves, it should move subchild A as well, like parent-child relation transform, nothing special. but also the subchild A has to move based on anim2 too. relative

#

it would need something called Mask in Unity. i know that

#

but this parent-child relations aren't rigs . they're simply some GameObjects. so I can't use the built-in mask

kindred tusk
real blaze
kindred tusk
#

This not a programming question, but you use layers in the animator.

#

Each layer has a separate mask

#

Then you set the same condition for each to start

real blaze
kindred tusk
#

If the animations do not affect the same objects you will not need a mask, just make sure that each does not control the same property on the same objecct

kindred tusk
#

Then they'll work independently

real blaze
kindred tusk
#

Oh wait, no

#

But not any of the programming channels, unless you want to talk about the animator API itself

real blaze
kindred tusk
#

Animations do not change everything, only the properties included in their curves

#

I know this because I recently went through this process myself.

real blaze
kindred tusk
#

mm?

#

Animation is an artistic discipline.

real blaze
kindred tusk
real blaze
#

oh , forgot the timezone thing. sorry for bothering u at night then. yeah sure i'll continue in there.

hallow cove
#

can someone help me with serialization?

#

I wanna be able to save a binary file that contains stuff like items, profile names so I can identify the saves

tropic lake
# hallow cove I wanna be able to save a binary file that contains stuff like items, profile na...

https://youtu.be/XOjd_qU2Ido
make a custom class to store data, mark it as serializable, use the unity stream to read/write, and have methods to convert between the data class and the actual class

Here's everything you need to know about saving game data in Unity!
β–Ί Go to https://expressvpn.com/brackeys , to take back your Internet
privacy TODAY and find out how you can get 3 months free.

● Easy Save: https://bit.ly/2BzgdXb

β™₯ Support Brackeys on Patreon: http://patreon.com/brackeys/

Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·...

β–Ά Play video
hallow cove
#

I've used this exact system and I struggle to understand it really

#

I wanna save stuff that's not just in one script so I'm kinda struggling

#

And I'm also very tired nowadays so, that's that

kindred tusk
#

If you just want to get it working

#

And come back to binary later

hallow cove
#

I see

#

It's just that

#

Idrk how I should save from other scripts

shadow seal
#

The save system doesn't really need to be on an object, I tend to use a static class for it

hallow cove
#

I have an inventory script that holds a list of a class I made in it

#

That class has a scriptable object, an int and a scene (which I can just change to a string if I need to)

#

And I also wanna save position

#

Idk how to save from multiple scripts

regal olive
hallow cove
#

Atm, I have a script that's on the player that other scripts on it can reference

#

From that script I call the save and load functions

#

It does change the file size, but still gives me an error

#

And fails to read and load data from it

regal olive
#

and avoid Brackeys when it comes to stuff like this, the info they give is generally outdated.

hallow cove
#

I am using a different method to dave and load

#

Using a try get function

#
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

public class SerializationManager
{
    public static void SavePlayerData(PlayerData playerData)
    {
        BinaryFormatter formatter = GetBinaryFormatter();

        if (!Directory.Exists( Application.persistentDataPath + "/saves/"))
        {
            Directory.CreateDirectory( Application.persistentDataPath + "/saves/");
        }
        
        string path = Application.persistentDataPath + "/saves/" + playerData.profileName + ".save";

        FileStream fileStream = File.Create(path);

        formatter.Serialize(fileStream, playerData);

        fileStream.Close();
    }

    public static PlayerSaveData LoadPlayerData(string profileName)
    {
        string path = Application.persistentDataPath + "/saves/" + profileName + ".save";
        
        if (!File.Exists(path))
        {
            Debug.Log("No profile data saved.");
            return null;
        }

        BinaryFormatter formatter = GetBinaryFormatter();
        FileStream fileStream = File.Open(path, FileMode.Open);

        try
        {
            PlayerSaveData playerSaveData = (PlayerSaveData)formatter.Deserialize(fileStream);
            fileStream.Close();
            return playerSaveData;
        }
        catch
        {
            Debug.LogErrorFormat("Failed to load file at {0}", path);
            fileStream.Close();
            return null;
        }
    }

    public static BinaryFormatter GetBinaryFormatter()
    {
        BinaryFormatter formatter = new BinaryFormatter();

        return formatter;
    }
}
#

here's the saving code

#
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

[System.Serializable]
public class PlayerSaveData
{
    public string profileName;
    
    public Scene scenePlayerWasIn;
    public float[] position;
    public float[] rotation;
    public Inventory inventory;

    public PlayerSaveData(PlayerData playerData)
    {
        profileName = playerData.profileName;
        
        scenePlayerWasIn = SceneManager.GetSceneByName(playerData.scenePlayerWasIn);
        inventory.itemList = playerData.itemList;

        position = new float[3];
        position[0] = playerData.transform.position.x;
        position[1] = playerData.transform.position.y;
        position[2] = playerData.transform.position.z;
        
        rotation = new float[3];
        rotation[0] = playerData.transform.rotation.x;
        rotation[1] = playerData.transform.rotation.y;
        rotation[2] = playerData.transform.rotation.z;
    }
}
#

and the serializable script I made

#

can I serialize scenes?

shadow seal
#

Their index, yes

#

Which is all you ever need really

hallow cove
#

string?

#

I kinda change scenes a lot atm

shadow seal
#

If you wanted to, sure

hallow cove
#

so, can I use a string?

#

yeah

#

cool!

#

how could I save a list?

regal olive
hallow cove
#

I know

shadow seal
#

Well, declare a List in the serialisable class

hallow cove
#

but I change them a lot

#

and it really doesn't matter all that much

#

I change the scenes a lot and it's impossible to work with ints

regal olive
#

what?

#

SceneIndex?

hallow cove
#

if I save the int

#

and then later change the order of the scenes

hallow cove
#

the index isn't gonna be the right one

#

or?

#

it's not gonna be the same then!

#

also

#
    public class ItemSlot
    {
        public Item item;
        public int amount;
        public Scene scene;
    }```
#

I wanna save a list of this

#

can I just directly do that?

shadow seal
#

Yeah

#

Why does an ItemSlot have a Scene?

hallow cove
#

complicated saving system

#

if a player joins another player's world with items from a region that hasn't been unlocked in that world

#

then I can use that variable to remove them from their inventory

#

or just

#

hide them

shadow seal
#

Oh I see, it's multiplayer

hallow cove
#

yes

#

SerializationException Type 'UnityEngine.MonoBehaviour'

#

fricc

#

I really don't understand much of this

#

can we start from like the basics

#

the start I mean

shadow seal
#

One of the things you're trying to serialise appears to be derived from MonoBehaviour

hallow cove
#

yeah, but what

shadow seal
#

I'm not sure, I'm not you

hallow cove
#

omfg

#

I'm giving it playerData to serialize

#

which is a monobehaviour

shadow seal
#

Ah, you should probably use that other class you made

hallow cove
#

the player save data

#

I see

#

and from the monobehaviour one I can call this

#

omfg it works

#

scriptableobject is not marked as serializable

#

nice

tropic lake
#

i don't think you'd want to save an SO

dense cloud
#

hello i am using perlin noise to generate dungeons but the output is repetitive. Is there a way to go about infinitely procedurally generated dungeons without repetition

#

perlin function output has so little. with a float input between 0 and 1, also after 4 digits its irrelevant so its just like 10,000 blocks of generation, after that it repeats

hallow cove
#

well

#

what else can I do then?

#

that's how the items are made

#

I found a solution of making a class for each item and then referencing it in the scriptable object class

#

but idk

#

didn't work-

#

:/

tropic lake
#

and if it's not then use the SO

hallow cove
#

wdym?

tropic lake
#

when you create an item, pass in the data class for the item that you got from the save

#

instead of a scriptable object

hallow cove
#

yes but I failed doing that

#

I'll try later idk

#

thanks anyways! at least now I know how this works!

lavish epoch
#

I am trying to make 2d, tile based line of sight/fog of war visibility thing

But I run into these issues when casting my "shadows" from nearby walls

Anyone got solutions?

#

this is the raycasting function

kindred tusk
#

Otherwise you'll only be able to step on diagonals or straight

lavish epoch
#

thats how DDA works

kindred tusk
lavish epoch
#

this method works fine

kindred tusk
#

Roguelike tutorials will cover this exact thing perfectly

#

This exact FOV is in nearly every roguelike

lavish epoch
#

really? I didnt find any information on this at all

lavish epoch
kindred tusk
#

There are a few approaches here

#

Looks like the most robust is to cast to every square in range

#

But if the range is small enough you can just trace the boundary

lavish epoch
#

I am casting to every wall in range, then casting again from that wall to further away to put shadows

#

forget the 1st part of my sentence
I can afford to make walls cast shadows even if the walls themselves arent visible

kindred tusk
#

Right. Well usually shadows are an absence of light

#

So I've done this in euclidean space

lavish epoch
#

in this case shadows are 1x1 squares that block view

kindred tusk
#

Yeah I know

#

But you cast out from the light source

#

To a maximum range

#

And then you fill in between each ray

#

Like in euclidian space you're just generating a mesh