#archived-code-advanced

1 messages · Page 45 of 1

orchid marsh
#

Using Lists.. it would be something like... cs //Example of removing any number of elements var positions = new List<Vector3>(lr.GetPositions()); positions.Remove(0); for(int i = 0; i < positions.Count; ++i) positions[i] += offset; lr.SetPositions(positions.ToArray());

#

Where offset would be the direction towards you the person with the rope.

#

And if you wanted it to look usable, you'd probably want to remove the second point rather than the first - assuming you're still wanting the ropes to start from the tip.

#

So... cs positions.Remove(1);instead and offset would be the direction towards you multiplied by some scalar.

rare mortar
#

oh i seee i think i understand little now .. let me chk those Thx Mate

uneven sierra
#

Question on Point: Is there a way to Smooth or fix the flickering in this code?

I got an Item, an Cube(Literally Panel) and the Script that puts the Cube over the Item with y+0.5 when the player is looking at the Item, also the cube always faces the Camera. The Cube should be something like Item Information. Now everything works, except that the Cube is flickering, it goes invisible and Visible back on.
The Code get's executed every Update.

    {
        if (Physics.Raycast(transform.position, transform.forward, out var hit, Mathf.Infinity, mask))
        {
            obj = hit.collider.gameObject;

            if(obj.tag == "Item")
            {
//HERE
                GameObject tablet = GameObject.FindWithTag("PickUp_Background");
                Transform tsf = tablet.GetComponent<Transform>();
                Transform obg = obj.GetComponent<Transform>();

                tsf.localScale = new Vector3((float)1.7917, (float)1.017622, (float)0.002059521);
                tsf.localPosition = obg.localPosition + new Vector3(0, (float)0.5, 0);
                tsf.transform.rotation = Quaternion.LookRotation(-Camera.main.transform.forward, Camera.main.transform.up);
//HERE

            }


            else //Should not bother
            {
                GameObject osd = GameObject.FindWithTag("PickUp_Background");
                Transform tsf = osd.GetComponent<Transform>();
                tsf.localScale = new Vector3(0,0,0);
            }
        }
    }```
dusty wigeon
# uneven sierra Question on Point: Is there a way to Smooth or fix the flickering in this code? ...

This is not "advanced". #💻┃code-beginner

Do not play with the scale of an object when you want to disable it.
Do not use "GetComponent" when the code is executed a lot.
Use the correct "position" for your need. Transform.position instead of Transform.localPosition.
Do not use magical value (0.5, 1.7917) use SerializeField
Use appropriate numeric suffix instead of casting. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types

uneven sierra
#

I wonder why I can't use the transform instead of gameobject, both worked even, just the transform with mistakes

dusty wigeon
#

Use gameObject.transform, that would be tablet.transform and obj.transform

uneven sierra
potent shoal
#

I am writing code for a server, which is not a part of unity. However, I need to use a delta time, similar to what unity has, so that my client can be in sync.

I've written this class which is designed to create a custom delta time.

public class CustomTime
    {
        private double _deltaTime;
        private double _secondFrame;
        private double _counter;

        private Stopwatch _stopwatch;
        public CustomTime()
        {
            _stopwatch = new Stopwatch();
            _stopwatch.Start();
        }

        public float DeltaTime()
        {
            return (float)_deltaTime;
        }

        public void UpdateTimer()
        {
            TimeSpan ts = _stopwatch.Elapsed;
            double firstFrame = ts.TotalMilliseconds;
            _deltaTime = firstFrame - _secondFrame;

            _counter += _deltaTime;
            _secondFrame = ts.TotalMilliseconds;
        }
    }```

It is not accurate, and I'm wondering what I can do to make something more similar.
undone coral
uneven sierra
undone coral
#

you wouldn't usually use an idea like Time.deltaTime in the server

dusty wigeon
undone coral
#

Time.deltaTime is important for rendering

#

it's hard to say anything more without knowing what the game is

uneven sierra
undone coral
#

are you saying you want to drag and drop a UGUI object? or do you want to drag across for some other UX experience?

misty glade
#

Got it all resolved, but yeah, I drag and drop UGUI objects

#

Gotta have it work across platforms

undone coral
#

okay

misty glade
#

I moved all my platform specific code into one class and made one common API that #defines into private methods based on the platform

undone coral
#

okay i'm not sure why you have to do this

#

the pointer ID is in pointer event data

misty glade
#

the gotcha for me was that touches are still in the array on the frame they end

undone coral
#

it corresponds to the touches

misty glade
#

the behaviour for double click dragging with a mouse is slightly different than fingers

undone coral
#

i'm not super clear what the problem is though. if you are not moving the object and your pointer leaves the object, the object that receives onenddrag is different than the object that receives onbegindrag

#

that's the biggest gotcha usually

misty glade
#

like, hard to explain but if a user with a mouse starts a drag with LMB, then presses RMB, then releases LMB, we still want them to be dragging

undone coral
#

the pointer ids are valid

misty glade
#

but if a user with a finger starts a drag with fingerID 1, starts a second touch with fingerid 2, then lets go of finger1 - that ends the drag

#

(because the fingers are in different locations)

undone coral
#

meaning whatever event you received, regardless of platform, even on old Input, you will be able to compare the begin drag pointer id

misty glade
#

but a mouse can't be in a different location

undone coral
#

multitouch just works

#

i mean it's upt o you if it ends the drag

#

it does if you program it that way lol

misty glade
#

well, yeah, but i don't want to get in the business of trying to distinguish touches

undone coral
#

all of my drag code sort of looks like this

misty glade
#

it's sort of a weird edge case and probably won't come up all that often but that's how i wanted it to work (with mouse and touches)

undone coral
#
var pointerId = (int?)null;
this.OnBeginDragAsObservable()
 .Subscribe(startedPDE => pointerId = startedPDE.pointerId);
this.OnEveryUpdate()
 .Where(_ => pointerId != null)
 .Subscribe(_ => {
  // due to limitations in old Input,
  // you have to subclass StandaloneInputModule to expose
  // GetPointer...(int id);
  var pde = SubclassedInputModule.GetPointer...(pointerId);
  if (!pde.dragging) { pointerId = null; return; }
  DoThingWithMousePosition(pde);
  ...
 });
#

with new input system it's easier becaues you can directly query if the pointer was released this frame

#

using ExtendedPointerEventData

#

anyway it's a lot

#

the web has the same issues

hardy sentinel
#

Hey, not exactly a code question but unity-talk is hijacked rn..
What exactly happens if I have multiple assemblies, change code of a single one, then recompile?
Do all assemblies rebuild and get reloaded or is it just the changed one?

sly grove
#

Just the changed one theoretically

#

And any that depend on it

hardy sentinel
#

Are you saying that because it sounds right or u've seen smth regarding it? 😛

stiff hornet
#

It makes sense when you think about it

#

If you changed a function in an assembly which another depends on, then the other must be reloaded to detect any compile faults etc..

hardy sentinel
#

I know this feels natural because of how .net compilers work, but haven't seen any proof regarding that. Benchmarks aren't of much help either

#

(I don't have any big enough project to apply this to and see immediate effects)

#

(and rn it's the 'reload' part that takes time, and not the 'rebuild' part)

stiff hornet
#

that is different to what asmdefs are used for

haughty raft
#

Someone with experience in apk builds please give some advice.

I've built plenty of versions of this game as both standalone windows and apk for android but all of a sudden I'm getting successful builds but when attempting to install the apk I'm getting this wierd error.

I don't know how to debug it

Application not installed because the package appears to be invalid

Is all I get

Loads of random reds in the log cat but I have no clue what is causing it

I transferred all my data to another pc when I upgraded computers but It worked well before

It's been maybe a month since I built to android and I did change render pipelines from built in to urp

I've added some assets here and there and packages from the package manager

Any idea
Or anyone experienced this before

It does not install on any device but builds successfully

Please help

I need to male a build for my manager by tomorrow evening

hardy nymph
kindred remnant
#

@undone coral I'm starting a new project and recall you mentioning prefabs instead of scenes a little while ago. I've decided I've learnt what I can with DI and would love to give this a go. Do you have any resources you would recommend to understand the workflow? It seems straightforward enough (just replace scenes with prefabs & a static service that manages switching between them) - just want to know if there are any common pitfalls I should be aware of.

undone coral
#

it is pretty straightforward organizationally.

#

instead of lightmapping using unity it's probably worth learning how to round trip using the DCC tools

#

and bake lighting in another tool

#

or use bakery and meshcombinestudio which is what i do

#

there are assets that provide their own baking workflow

#

if you want to use huge terrains (like 10s of kilometers) use Gaia Pro's built in terrain loading, which uses scenes under the hood

#

in my experience those are the 3 big pain points

#

that said, whenever i thought i needed this stuff, i end up omitting on-demand loading and still baking everything in one scene

#

the com.unity.ai navigation package seems to be really poorly documented too

kindred remnant
#

awesome, thanks for that. it's pretty hard to find a lot online on the subject, nothing really comes up for a "prefab > scenes" architecture. i'm not massively worried about lightmapping or navmeshes; the game is going to be a pretty simple 2d platform arena fighting game (smash bros, multiversus etc)

#

how would you handle "loading" into a battle? with scenes its just a case of connecting to the server which then loads a fresh battle scene - is it really as simple as connecting to the server, which then instantiates a battle prefab? 😮

undone coral
#

instead of instantiating it, it's ticked on

#

the level-specific geometry - all those prefabs would be referenced right in the scene and ticked on/off

#

to avoid instantiation entirely

dusty wigeon
#

What issue you are trying to solve by using prefab instead of Scene ?

undone coral
undone coral
#

for example, since i have a fixed, maximum number of cards, i use a "fixed object" pool i.e., all the objects that participate in the pool are instantiated already in the scene.

#

then i can design around the maximums

kindred remnant
undone coral
kindred remnant
undone coral
#

in other games i've seen, the ephemeral stuff lives in a separate hierarchy from the static stuff

potent shoal
#

I'm trying to create my own variation of delta time.
The expectation is 0.0172291, but my result is 17.2291.
My code is as follows:

public class TickBehavior : MonoBehaviour
    {
        public int currentTick;
        private CustomTime _time = new CustomTime();

        private float _tickTimer;
        private const float SERVER_TICK_RATE = 30f;
        public const float MIN_TIME_BETWEEN_TICKS = 1f / SERVER_TICK_RATE;

        public float tickRate;

        public void Update()
        {
            _time.UpdateTimer();
            _tickTimer += Time.deltaTime;


            int tickCount = 0;
            while (_tickTimer >= MIN_TIME_BETWEEN_TICKS)
            {
                tickCount++;
                _tickTimer -= MIN_TIME_BETWEEN_TICKS;
                HandleTick(currentTick++);
            }

            tickRate = _time.DeltaTime() / tickCount;

            Debug.Log(_time.DeltaTime());
            Debug.Log($"Real: {Time.deltaTime}");
        }

        public virtual void HandleTick(int currentTick)
        {

        }
    }```
undone coral
#

you have to do it that way anyway for something like MeshCombineStudio

potent shoal
#

@undone coralOh! I looked for my message after work and didn't find it.

#

I assumed it got lost.

undone coral
#

CustomTime i think was measuring milliseconds

#

but that's beside the point here

potent shoal
#

@undone coralI found your materials. Thank you!

undone coral
#

okay

dusty wigeon
# kindred remnant for fun

That is going to be so much pain to deal with. You should also profile carefully, as it was not intended for this and you may find yourself with unexpected performance issue.

If you ever find a real reason to do this, I would be interested to know. Maybe an hybrid approach is better.

kindred remnant
#

i just like learning new ways to do stuff

dusty wigeon
undone coral
#

i think that was a mistake

dusty wigeon
#

No hard feeling.

undone coral
#

i haven't experienced a gameplay related performance issue in a long, long time.

#

i suppose if something is fun you can worry about optimizing it later

#

eventually DOTS will be released and there will be a lot of innovative gameplay around that

autumn topaz
#

generally speaking, is having two command patterns in a single project messy code? Im asking as I am thinking of implementing a command pattern for actions to perform, and a command pattern for the state machines that activate them. is this messy?

undone coral
#

those mass army games look pretty cool

kindred remnant
dusty wigeon
#

It always depends on what you do. At the moment, I'm just trying to see all alternative and try to find out what work the best for my project.

undone coral
kindred remnant
undone coral
#

probably disorganization

kindred remnant
dusty wigeon
undone coral
#

there is just so much inertia around C++ practices that even 15 years of delivering market hits couldn't save unity

#

from C++ification

#

HPC# was bold. they are doing two things simultaneously: repeating the mistakes from the PyPy -> TensorFlow -> Keras -> PyTorch journey, and repeating the mistakes of the C++11 -> 17 -> Rust -> Zig journey

#

all because people are so stubbornly obsessed with the garbage collection column in their frame profilers

#

i really wish they would stop

#

nobody wants to deal with memory management or struct layouts. it's not even necessary to think about. the academy and industry have solved this problem in mass adopted stuff.

undone coral
#

jonathan blow is out there advocating for something something programming languages, but it's not "More C++"

#

gotta record it better

kindred remnant
sacred dawn
#

I have a little problem that is something of a gotcha for Unity's Rect struct.

Observe:

Debug.Log(rect.x + rect.width == rect.xMax);
// output is false```
The expected value is true. If you test this with a rect at 0,0 size 1,1 the output is true.
Therefore a floating point error has occurred.

But what _is_ rect.xMax? I looked on google:

https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Geometry/Rect.cs

This link suggests that internally rect.xMax is the following:
```public float xMax
{
    [MethodImpl(MethodImplOptionsEx.AggressiveInlining)] get { return m_Width + m_XMin; }
    [MethodImpl(MethodImplOptionsEx.AggressiveInlining)] set { m_Width = value - m_XMin; }
}```
But.. b-but that's rect.width + rect.x isn't it?

Does the order of operations affect it? No - I checked.
What if I define x and width as floats and compare those? They behave exactly like rect.x and rect.width - even when you add them together.

So what's going on when I call rect.xMax and why isn't it rect.x + rect.width?
thorny whale
#

it could be floating point error. Try compare with

Mathf.Approximately(rect.x + rect.width, rect.xMax)
sacred dawn
#

I'm not trying to ignore the Epsillon. I want to know what is causing it.

thorny whale
#

i was going to try explain a bit, but floating point stuff is way beyond me :p
especially if you are going to put in variable values into your struct, it won't be reliable trying to compare floats exactly, unless maybe its against 0?

sacred dawn
#

If I could reproduce the error outside of the Rect struct, that would put my mind at ease. I could then say - that is what happens when you call rect.xMax

#

The values in the struct appear to be constant going in and out - that much I have confirmed. The only outlier is rect.xMax - which seems to introduce an error.

thorny whale
#
Var rect = new Rect(20.2f, 0f, 0.8f, 1f);
Debug.Log(rect.x + rect.width == rect.xMax);

float xMax = rect.x + rect.width;
Debug.Log(xMax == rect.xMax);
#

if you absolutely must compare a float try this, the second one is true., it should be the same result as how the Rect does it.

#

i guess the rounding error difference is between having the 2 values stored separately in Rect and added together as later vs rect.x + rect.width being added in directly if that makes sense

#

hence, dont go comparing floats :p

scenic forge
#

I don't use it for my entire game, but for a small performance critical chunk of code I do use it and the performance is amazing.

thorny whale
#

I do feel though DOTS etc is overkill for the majority of Unity users, at least those who make games. It's 'performance' they dont need at the expense of completely changing everything, so I'm not sure whom its for.

Maybe they're trying to target a different audience, but I hope they don't try deprecate GameObjects as I feel it hits a sweetspot between 'pretty easy' to use and performant enough to do some pretty impressive things. It's sufficient for most people's needs.

scenic forge
#

Yeah I'm not so sure about going full DOTS, especially the current state of ECS in Unity seems to be a bit of a mess.

#

But Burst and HPC# is imo very nice, I would say a lot of performance issues in code are purely algorithmic, and just by converting it to a Bursted job it's going to be more than fast enough. Granted not all can be solved this way (eg you write an O(n^2) when it could've been an O(n)), but I believe a huge chunk can.

#

The game I'm working on in particular wouldn't be possible without it, or would have to go down a complete different route.

regal olive
#

hello, I'm trying to access Light2D in my script, but it can't resolve a reference to it. I already have the Universal Rendering Pipeline installed and the Light2D works fine in my scene. however, anytime I reference it in a script, it can't be resolved. It gives me the option add a reference to UnityEngine.Rendering.Universal.Runtime.dll and when I do, it rebuilds then removes the reference automatically. anyone encountered this and know what i'm missing? thanks

URP version is 12.1.10

dusty wigeon
# sacred dawn I have a little problem that is something of a gotcha for Unity's Rect struct. ...

To be honest, you are asking a question that is tricky to know. It can be cause by the compiler for whatever reason. Normally, you would look at the assembly to try to understand such thing, but in unity case it might be harder. I'm not really an expert in optimisation and compilation, so I might be completely of the grid, but I would think that it might be cause by the C++ layer under.

Anyway, you should always do float comparison with an epsilon because of those possible issue. It might even vary from one platform/compiler to an other.

slim breach
#

Is a lambda findObjectOfType the same as doing it on Awake()?

Example
public Foo FooManager => FindObjectOfType<Foo>();

thin mesa
#

no, that's not a lambda that's a read-only property (using expression body syntax) that will call FindObjectOfType<Foo>() every time the property is accessed

slim breach
#

oh really so its not a once and loaded?

#

its a constant reference?

#

or a constant refetch

#

no caching?

thin mesa
#

since you are not storing the returned object from FindObjectOfType into a field, no

slim breach
#

hmm how do you mean?

#

is FooManager not considered a field?

thin mesa
#

no, it's a property

#

properties are basically just getter/setter methods disguised as variables. but this one only has a getter

#

you would need an explicit backing field to cache the result into, or just make it an auto property that you assign to in Start/Awake

slim breach
#

and the auto property is the traditional
FooManager => FindObjectOfType<Foo>();

and its a standard declaration at the top?

#

Gotcha

thin mesa
#

no an auto property would look like public Foo FooManager { get; private set; }

slim breach
#

or do a private/public thing

#

// this is a field. It is private to your class and stores the actual data.
private string _myField = > FindObjectOfType<Foo>();

// this is a property. When accessed it uses the underlying field,
// but only exposes the contract, which will not be affected by the underlying field
public string MyProperty
{
    get
    {
        return _myField;
    }
    set
    {
        _myField = value;
    }
}
#

is this technically the same thing

thin mesa
#

private string _myField = > FindObjectOfType<Foo>(); this is a property not a field

#

remove the > and it's a field. but you also cannot call FindObjectOfType from a field initializer

slim breach
#

I see so basically by using the => it acts a call this method on grabbing of variable via the get/set where as if I where to do a myfield = property the field hold the reference

thin mesa
#

anyway, this isn't really advanced. so if you have further questions about it then ask in #archived-code-general

slim breach
#

brutal.

rare mortar
#

Just like Throw i want to get back rope as well like this how can i do that
for throw this is what im using

        {
            spring.SetVelocity(velocity);
            lr.positionCount = quality + 1;
        }

        spring.SetDamper(damper);
        spring.SetStrength(strength);
        spring.Update(Time.deltaTime);

        var grapplePoint = grapplingGun.GetGrapplePoint();
        var gunTipPosition = grapplingGun.gunTip.position;
        var up = Quaternion.LookRotation((grapplePoint - gunTipPosition).normalized) * Vector3.up;

        currentGrapplePosition = Vector3.Lerp(currentGrapplePosition, grapplePoint, 
          Time.deltaTime * 8f);

            for (var i = 0; i < quality + 1; i++)
            {
                var right = Quaternion.LookRotation((grapplePoint - gunTipPosition).normalized) *                        Vector3.right;
                var delta = i / (float)quality;
                var offset = up * waveHeight * Mathf.Sin(delta * waveCount * Mathf.PI) * spring.Value *
                             affectCurve.Evaluate(delta) +
                             right * waveHeight * Mathf.Cos(delta * waveCount * Mathf.PI) *
                             spring.Value *
                             affectCurve.Evaluate(delta);

                lr.SetPosition(i, Vector3.Lerp(gunTipPosition, currentGrapplePosition, delta) + offset);

            }
    }```
sacred dawn
# thorny whale ```cs Var rect = new Rect(20.2f, 0f, 0.8f, 1f); Debug.Log(rect.x + rect.width ==...

The situation that lead to this discovery was testing for a rectangle overlapping an interval.

I was already subtracting an epsilon but - subtracting an epsilon causes a different kind of error!

The problem was that I was moving the rectangle back and forth by the same amount. The code that used an epsilon allowed the rectangle to phase through the interval, whereas not having the epsilon prevented the error.

However - not having the epsilon caused a false positive going the other way. I was at a loss what to do. No epsilon - error. Epsilon - error.

Do you want to know what stopped the error?
Can you guess?

rect.xMax

And no one knows what it does. No one even wants to know, it's that spooky 👻

timber flame
#

One question
Is it common to keep all changes in player assets (e.g. coins) in a database not only the current value?

player id coin_change date current_coin
1610304354 +100
1610304354 -50
...

violet shoal
#

Not unless you need to know that detail.

#

The presence of "player id" suggests you're dealing with an online title - in which case I suppose it is handy to keep the data if you expect to be auditing it.

random dust
#

Other than that not really

#

If you set up your database in a proper manner then you can also just rollback the whole database.

#

I suppose keeping track of changes is more reliable, but it really bloats your database.

flint sage
#

Can also be used to merge savedata if you're not always online

#

And it's useful to help investigate what a player did but using analytics is better for that

#

(unless you don't trust your analytics)

rare mortar
#

🥲 Why no one have Sekiro rope rapper lol.

pale pier
#

Anyone know why Unity's Mono Socket.ReceiveMessageFrom method is not implemented?
And is there a way around it? Other than binding a socket to every active network interface?

pulsar isle
#

Unity Multiplayer Networking - Playground example. I have added this runtime gizmo control https://github.com/HiddenMonk/Unity3DRuntimeTransformGizmo

I want both players to be able to move the cube using the transform gizmo. So far both players can see the changes in the cube's transform but only the server can move it.

I think it has to do with the concept of authority and I should ping-pong the authority between the server and client or something. Any input will be vastly appreciated.

GitHub

A runtime transform gizmo similar to unitys editor so you can translate (move, rotate, scale) objects at runtime. - GitHub - HiddenMonk/Unity3DRuntimeTransformGizmo: A runtime transform gizmo simil...

stiff hornet
rare mortar
#

UnityChanThumbsUp I Finnaly Made iT
Skeiro Rope 🙂

dusty wigeon
lost sequoia
#

How to program a TicTacToe game, where the player plays against a simple "AI"...

  • Without creating a giant bunch of if Statements?
    Any ideas?...
    (I tried, but my script is 1400+ lines long with a few hundred if statements!)
mortal gust
sly grove
lost sequoia
sly grove
#

follow one of those tutorials

lost sequoia
#

I can not see what are trash tutorials and ehat are gooodys if there are only likes visible.

#

500likes.... 20k dislikes?...

sly grove
#

I can assure you all of the tutorials will be better than your if if if if if attempt

lost sequoia
#

I stoped using youtube, because there are so many scams you can not detect because of the missing dislikes.

flint sage
#

Sounds like you just hang out on the wrong parts

lost sequoia
#

Not specific on tictactoe now...
I am just disappointed of youtube because there are so many trash tutorials you can not detect without like/dislike ratio...
Especially the one where are no comments or where are only vomments that got the heart vote from the video uploader...

obsidian glade
#

ah, someone already answered you, nevermind 👼

lost sequoia
#

The viewers dont knoe it even better thats why they like or there are maybe 500+ dislikes you can just not see.

craggy sierra
soft flare
#

hey unity devs, I've tried everything I could find to resolve this memory leak issue (A Native Collection has not been disposed, resulting in a memory leak) resulting from UnityWebRequest.Post. Anyone have ideas for fixes? I've tried manually disposing, using block, etc to no avail.

craggy sierra
lost sequoia
craggy sierra
craggy sierra
lost sequoia
#

I just got ignored in the general channels, so I thought thats maybe to hard for them to ask them this question.

craggy sierra
lost sequoia
#

Still thanks...

soft flare
#

I had to use that UnityWebRequest object in a slightly different way than shown in the Unity documentation for POST. Honestly that documentation could be a lot better and show more modern examples.

undone coral
undone coral
soft flare
#

before I had a using block like this when getting the request object: using (var request = UnityWebRequest.Post($"{BASE_URL}/battles/{gameId}", "POST"))

#

that was giving me inconsistent memory leak errors

#

the new way is explicitly creating the upload and download handler objects, and sets up the request like this:

#

using (var request = new UnityWebRequest($"{BASE_URL}/battles/{gameId}", UnityWebRequest.kHttpVerbPOST, downloadHandler, uploadHandler))

#

and then setting disposeBlahHandlerOnDispose = true like this

#
   request.disposeUploadHandlerOnDispose = true;
   request.disposeCertificateHandlerOnDispose = true;```
#

and so far with that implementation everything works and I haven't seen another memory leak error

#

I see a ton of post examples using the first implementation I tried tho

soft flare
#

All of Unity's documentation on this seems mostly wrong. As far as I can tell all of their examples would consistently leak memory.

undone coral
soft flare
#

it is an async, my signature is public async Task<BattleResult> CompleteBattle(int gameId)

undone coral
soft flare
#

and I do this in the using block: var operation = request.SendWebRequest(); while (!operation.isDone) { await Task.Yield(); }

undone coral
#

you must use unitask

soft flare
#

async/await are not supported?

undone coral
#

this is why i said you have to post the whole method

undone coral
soft flare
#

sure I can post the whole thing

undone coral
#

write cs after the triple backticks

#

okay

#

and how do you invoke this method?

soft flare
#
    {
        var attemptCount = 0;
        while (true)
        {
            attemptCount++;

            var uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes("{\"gameId\":" + gameId + "}"));
            var downloadHandler = new DownloadHandlerBuffer();
            using (var request = new UnityWebRequest($"{BASE_URL}/battles/{gameId}", UnityWebRequest.kHttpVerbPOST, downloadHandler, uploadHandler))
            {
                request.SetRequestHeader("Content-Type", "application/json");
                request.SetRequestHeader("Accept", "application/json");
                request.uploadHandler.contentType = "application/json";

                request.disposeDownloadHandlerOnDispose = true;
                request.disposeUploadHandlerOnDispose = true;
                request.disposeCertificateHandlerOnDispose = true;

                var operation = request.SendWebRequest();
                while (!operation.isDone)
                {
                    await Task.Yield();
                }

                if (request.result == UnityWebRequest.Result.Success)
                {
                    var json = request.downloadHandler.text;
                    var obj = JsonUtility.FromJson<BattleResult>(json);
                    return obj;
                }
                else
                {
                    if (attemptCount > 10)
                    {
                        throw new Exception("ApiHelper CompleteBattle request failed too many times.");
                    }
                    Debug.LogError($"Request failed: {request.result} ({request.responseCode}), retrying (attempt #{attemptCount})");
                }
            }
        }
    }```cs
#

I would call it with a method like this that I would kick off with StartCoroutine() private IEnumerator FightBattle(int gameId) { var battleTask = ApiHelper.Instance.CompleteBattle(gameId); yield return battleTask.WaitForCompletion(battleResult => { BattleText.ShowText(battleResult.resulttext, () => { Invoke(nameof(EndView), 5.0f); }); }); }

soft flare
#

which seems to work and not block the main thread, but if there is a better way to do this I'm all ears

novel plinth
#

Task.Yield isn't the same with yield return there's a chance that your code before it gets executed twice

#

you'd need customyield for that

#

nevermind, it;s in a while loop. you're good!

#

didn't see it before.. carry on

undone coral
#
private async UniTask FightBattle(int gameId) {
 var request = Encoding.UTF8.GetBytes($"\{\"gameId\": {gameId} \}");
 var url = $"{BASE_URL}/battles/{gameId}";
 var battleResultJson = (await UnityWebRequest.Post(url, request).SendWebRequest()).downloadHandler.text;
 var battleResult = JsonUtility.FromJson<BattleResult>(battleResultJson);
 await BattleText.ShowTextAsync(battleResult.resulttext);
 await UniTask.Delay(TimeSpan.FromSeconds(5f));
 await EndView();
}

@soft flare that's it

#

you have to use unitask if you want to use async await in unity

soft flare
#

can you give an example of how I would consume that?

#

is there a way to do it without StartCoroutine?

undone coral
#

you don't need start coroutine

soft flare
#

ah cool

undone coral
#

invoke nameof endview is also very bad

#

showtext is bad

#

show text should be async

soft flare
#

oh yeah i need to replace that it was mostly just to test out the api results

undone coral
#

do you see?

#

you don't need callbacks

#

if you already know async you never need to use callbacks ever again

#

you need unitask

#

i updated the example

soft flare
#

oh yeah thats way better

#

awesome thank you

kindred remnant
undone coral
brave bear
#

Hello! I'm working on a commercial 2D action roguelike game with fighting mechanics and a scope of 1-2 years. I'm designing a solution for a player controller and my question is -** what general solutions (design patterns and such) for player controllers do you recommend for medium-big games?** I'm interested in a robust, scalable, maintainable solution that would make it easier to implement mechanics like charging attacks, comboing, grappling hook, parrying, action-cancels, etc.

So far I've tried two or three different implementations of FSM, but after implementing just a couple of states and transitions, I'm starting to feel that the number of transitions and the amount of boilerplate will quickly explode and become unmanageable. Going forward I feel like it might not be the right choice. I also feel like I've outgrown most tutorials that are readily available on the internet, now I'm looking for more advanced and professional solutions. Can you provide some examples or references or advice on how to handle the player controller in a professional project?

abstract folio
#

here is a great article on it. takes a awhile to actually get to heierachal ones, but thats cuz it's very step by step...

mortal gust
#

I would recommend looking into command pattern, this can enable you to read history for combos.

brave bear
# abstract folio are you familiar with the hierarchical state machine? Thats my goto for scalabl...

Yes, I've heard of them and read some tutorials. Unfortunately all the examples I could find on the internet are very basic which doesn't help that much. I've read the one that you posted an hour ago (before posting my question here). Still, I'm considering HSM as my only alternative for now. But I'm not quite sure how can I properly divide my actions into hierarchies. If the actions are

  • IdleMovement (idle + run)
  • Dash
  • Attack
  • Block
  • Use grappling hook
  • get stunned
  • die
    ...
    etc. I don't see a way to do a proper hierarchy within those states. I don't have states like "jumping" or "swimming" that are always used in those examples.
abstract folio
#

I'd probably do a "move" super-state(abstract) and then make dash, idle and uh.. "swing on grabble rope" each derived from that. I'd probably also have them all derive from a single "player control" class- where they can each react the same way- or some customized way- to user input.

#

e.g. "stunned" could customize how it reacts to user input, by NOT reacting.

#

or perhaps the jump button, when swinging, lets go of the rope, rather than actually jumping

brave bear
#

I see, so run/dash/grapple are just forms of movement. That makes sense.

I plan on adding things like attacking while moving on the grappling hook. You pull yourself to the enemy and hit it while flying. How would you solve this?

#

Player may choose to attack at a certain time or not, while on the grappling hook.

abstract folio
#

well, if it behaves differently from regular attacking, I'd create a seperate class for "swinging attack". Then you override the attack button function to enter THAT state, from inside your "grapple swing" state's "attack" function.

#

if it behaves the same, then just DONT override that function when defining "swing state"

brave bear
#

yeah it would be different. This still creates a big number of states. Is this how it always has to be and I should just accept it?

#

I can imagine the number of states going into 15-20, is that a usual number of states that I should expect?

#

if I sum up all the possibilities, 15 feels like a conservative number of states

abstract folio
#

yes, that seems very reasonable to me. Keep in mind for MOST you'll only need to override one or two things, so most should be relatively small (coding wise).

#

don't forget, you can also stick abstract states, right in the middle of the heiarchy if you have many similar sub-states of a particular state.

#

I'm sure many would disagree, but my approach is to just start coding states each as their own class- see where I need to "duplicate code" and THEN make a base class for those situations.

kindred remnant
#

@brave bear you risk crippling yourself trying to design the perfect solution before actually getting to writing anything!

abstract folio
#

the best laid plans....

brave bear
brave bear
abstract folio
#

lol

brave bear
#

of course I know what you mean. It's the second month of the project so I'm trying to find solutions that will work long-term, which is a good thing to do during the start (figure out the workflows and patterns etc.), but of course it;s not a good idea to go overboard with it

abstract folio
kindred remnant
#

oh god

#

picturing states as monobehaviours has actually just made me sick, thanks

abstract folio
#

lol, mean!

sly grove
abstract folio
#

hmm.. I always though it would be just one object (the currentState object) when the state changes, that would need to be collected... no?

kindred remnant
#

the states won't need to be instantiated more than once, you can just have a lookup that news them up as and when they're first required

brave bear
# kindred remnant picturing states as monobehaviours has actually just made me sick, thanks

it's a bad idea to have states as monobehaviours? serious question. I kinda feel like NOT doing that is going against the typical Unity workflows. With monobehaviours I can have all the Unity API: references to other monobehaviours or scriptableobjects, Update loop, Unity messages and all the other possibilities. With classes I feel like I'm fighting against Unity constantly.

abstract folio
#

you can certainly reference all those things from within a "plain ol class" you just need to pass them in. Or, make the class serializeable and a member of monobehavior/scriptableObject to set those things in the editor.

#

the question to ask yourself is.. do my states NEED to have all the update/start/enabled/ etc... functionality of a monobehavior. and to keep it simple, I would say they do not.

brave bear
#

my first FSM implementation didn't make every state a monobehaviour and it was annoying that I had to have a PlayerStateMachine monobehaviour with so many fields as a "bridge" between Unity and every state class. This is really how kids these days do their FSM implementations?

abstract folio
#

yes, I keep my scene stuff independent from my state logic. I usually have some kinda "connector" just for making one work with the other.

#

^ in here I keep a bunch of references to scene objects and events the states can use/listen to, and pass that object as a reference to my "most-base" state class constructor.

brave bear
#

but then, if this one single specific state needs to do something Unity-related or scene-related, you need to put it inside the connector as well. Firstly, the connector's size gets bloated extremely by implementation details of specific states. Secondly, as a side effect, a state has access to dozens of fields/methods that they don't need to have access to.

#

fast forward to 15-20 states and it gets really messy

abstract folio
#

I can't disagree.

mortal gust
#

Sounds like you would profit from using events or a service provider pattern

brave bear
#

I'm using a slightly modified scriptableobject event based pattern, yeah. it's fantastic.

#

so if every state is it's own connector, you just put everything state-related (like specific events assets) inside that state, nothing else needs to know about it

undone coral
brave bear
#

no, technically it's a beatem up perspective, but for the purpose of this discussion it works like a top-down 2D game (in terms of controls)

undone coral
#

is there a specific game you are referencing?

#

are there any retro games' mechanics you are trying to recreate?

brave bear
#

yeah! let's say that's the case, the difference being that our controls will be much more complicated in the end.
Our main references are Hades, Streets of Rage 4, Sekiro. Imagine these games mixed together in one boiling pot.

undone coral
#

so this is a retro game genre, in your opinion

#

streets of rage

#

?

#

do you want it to have similar mechanics to a retro game

#

sekiro is very different

brave bear
undone coral
#

hmm

#

do you have some concept art or anything lik ethat

brave bear
#

yes, I have three artists working on it, but why do you ask?

undone coral
#

is your camera projection going to be "cabinet"

#

like Streets of Rage?

#

or something else

brave bear
#

Yes, very similar to Streets of Rage, but probably with more depth in the Y direction (more "boxy" level, more top-bottom gameplay instead of just left-right as in SoR)

undone coral
#

okay

#

so it's 2d sprites in this 3d cabinet world right?

#

will users play with a keyboard, joystick or arcade stick?

#

like there's no role for a mouse / touch

#

it is not really pointer based

brave bear
#

yes, fully 2D sprites that are able to flip only left-right (no top/bottom), but will be able to move 4 directions. World will be technically 2D but will pretend it's 3D

undone coral
#

in unity i would lay this game out in 3d

#

so the world would technically be 3d and pretending to be 2d

brave bear
#

there might be K+M, and controller support (joystick, arcade stick, gamepad)

undone coral
#

what will the mouse do?

undone coral
brave bear
#

one of the main mechanics will be a hookshot, so you can target enemies/obstacles to pull yourself into or pull something onto you.

brave bear
undone coral
#

there are grappling hooks in super metroid

#

there are a lot of hook shot mechanics in platformers

#

is there a specific one you have in mind?

brave bear
#

Hades already has K+M controllers, because you need to target some stuff with a mouse, you use mouse to direct your melee and ranged attacks

undone coral
#

is the idea "streets of rage 4, but with the design space of overwatch heroes, in a single player co-op campaign, networked multiplayer" ?

brave bear
#

so we're going for something similar

undone coral
#

okay, but hades is Diablo

#

which is a retro game

brave bear
#

easy to play, but hard to master.

undone coral
#

hmm

brave bear
#

Hades combat system is very simple, it's not about fighting your enemies, but about clicking on them and dashing around to avoid getting hit

#

we want to do actual combat.

undone coral
#

when you say actual combat, do you mean, like imagine a real time combat design space as large as overwatch

#

is that the idea?

#

like there could be up to 20 playable champions

#

each with 4 fairly distinct abilities

brave bear
#

no, the game is single player only, with a very strong narrative. A rogulike action game.

undone coral
#

sure even if it is single player

#

is that how big the design space is?

#

basically realtime RPG spells?

brave bear
#

well technically the design space is enormous, definitely, it all depends on the scope we decide to go for

undone coral
#

okay

#

are you familiar with the term gameplay attribute system, from unreal?

#

or have you guys worked on something like a digital card game

brave bear
#

it's like in Hades, you can always add more classes/weapons/abilities etc. same with our game

#

I have not heard about gameplay attribute system, no

undone coral
#

okay

#

will players need to carefully time jumps to advance through a level?

#

lol

#

like is finesse with their controller important for this game?

brave bear
#

it's not a platformer and you cannot jump in it, and the challenge will be purely from combat. But yes, the finesse with their controller is crucial.

#

timings, combos, parrying, etc. is very important

undone coral
#

hmm

brave bear
#

we want to be very precise with input, frame data, etc.

undone coral
#

okay

#

do you expect your audience to have already played streets of rage or a similar cabinet style game?

brave bear
#

not necessarily

undone coral
#

this is like asking if the hades developers expected their audience to have played pyre (yes) or diablo (yes)

abstract folio
brave bear
#

Yeah, I'm curious where are we going with this ^^

undone coral
#

my takeaway is that this is mechanically very retro

brave bear
#

I mean, it doesn't really mean anything to me, so sure, why not? let's say it's very retro

undone coral
#

and player expectations are pretty rigid when they have these retro experience

#

hmm

#

experience with retro titles*

brave bear
#

alright?

undone coral
#

and the way the movement systems in retro games work are extremely tightly coupled to input

#

it's all very tightly coupled. there's no architecture, because almost everything was pretty defined ahead of time

#

like megaman's movement code is a huge update loop

#

and much of the weapons code is in that update look

#

and before you say, well i'm not making megaman

#

everything input related with diablo is also in a big update loop, so that includes its combat and movement

#

tightly coupled

brave bear
#

a huge update loop sounds to me like a bug, not a feature.

#

I imagine it was written by 1-2 people, probably not extremely experienced.

undone coral
#

a thousand people try to make retro game feel using a wrong architecture

#

every year

#

what i'm trying to say is that whether you like it or not, there's a specific feel to cabinet (in both senses of the word) action games

#

a lot of that feel comes from tight coupling of input to movement and combat

brave bear
#

I'm entirely confused what's the relation between gamefeel and architecture, and what benefit does putting everything inside a 5k lines of code class give me?

undone coral
#

i'm not advocating for something to be poorly written

brave bear
#

no, I'm seriously curious, I don't understand your point?

#

I think that architecture is more about how the project code is structured, not about what the code does or the game feels like

#

so in extreme cases you technically could make any game in any architecture (but it would be easier or more difficult with a good/bad design)

undone coral
# brave bear no, I'm seriously curious, I don't understand your point?
  • IdleMovement (idle + run)
  • Dash
  • Attack
  • Block
  • Use grappling hook
  • get stunned
  • die
    the way i've seen "state machines" work for diablo and megaman referencing games usually looks like
StateEnum state;
void Update() {
 if (state == StateEnum.Idle) {
  ...
 } else if (state == StateEnum.Dash) {
  ...
 }
 
 // code above may have changed the state, and this waterfalling
 // is on purpose
 if (state == StateEnum.Block) { ... }
 // etc etc
}
undone coral
#

how many people do you expect to be authoring the movement code?

#

something like a grappling hook is tightly coupled to movement. would a different person author that?

brave bear
#

right now we have me + one other guy, I don't expect the number of coders to go more than 3 at any time.

undone coral
#

hmm

#

well only 1 person is going to be able to author the movement code

#

for a retro gamefeel game

brave bear
undone coral
#

i don't author retro gamefeel games

abstract folio
#

why? performance reasons or somthing?

undone coral
#

i have a colleague that makes a lot of them

#

and is quite good at it

undone coral
brave bear
#

Celeste has a very famous Player.cs script that has thousands of lines of code that is completely unmanagable. The game would not be worse if devs added some good coding practices to it...

undone coral
#

i am trying to avoid any normative opinion on good or bad practices here

abstract folio
#

I don't see why. I mean there are a zillion ways to write code that does exactly the same thing. other than performance- whats the different to how the user interacts?

undone coral
#

just the positivist opinion of goals. like for retro game feel, the way things are coupled lends itself to a very specific architecture

brave bear
#

alright, you are stating it as a fact, but I don't see how one leads to another?

undone coral
brave bear
#

can you provide some arguments why those games would not work if the classes would be smaller, or the update loop separated into many files, etc. etc.?

undone coral
brave bear
#

but those are examples, not reasons

#

it's a correlation, not causation

undone coral
#

i haven't myself tried to break down the megaman movement, for example, but i know for example the interaction with ledges is very, very tightly coupled to everything else*

#

in a way that would be much harder to model, maybe impossible to model, with something abstract

brave bear
#

big update loops happen in many games because developers write them like that, often because they don't know how to do it better

undone coral
#

you would wind up leaking a ton of details to whatever state machine abstract you've got going on

#

so your nicer architecture gets in the way

undone coral
brave bear
undone coral
#

maybe developers who try something too abstract don't thrive at making retro gamefeel games

#

and if you have a neutral opinion to updateloopese, and you play a lot of retro games and have a good eye for how they work, maybe you thrive

brave bear
#

maybe this is super-big-brain "architecture" to put everything into an update loop, and I'm doing my best to understand what could be the reason for that

undone coral
#

we'd be having a very different discussion if the game was a cabinet arcade game that you play on your phone

#

because then there would be zero retro game feel - touch doesn't exist in retro games - and then you would architect it totally differently

#

like you COULD make a virtual joystick game for mobile, but that's stupid

#

nobody likes those. they put up with it for ports*, and also because they are literally kids** so they'll put up with anything

brave bear
#

I think that if I put everything into a n update loop, the script will become unmaintainable after three months

#

or even faster

undone coral
#

you're going to be the only person who maintains it

#

and authors it

#

the Player.cs file

#

that's how it's going to go

#

if this is the kind of game you want

#

do you have some concept art you can share?

#

it sounds cool lol just post it

#

it will also help understand a bit how retro this really is

brave bear
undone coral
#

nice

#

this is real time right?

brave bear
#

yep

undone coral
#

there's perspective in this

#

do you want it to be cabinet or vanishing?

brave bear
#

I'm not very familiar with those terms

undone coral
#

like

#

well it doesn't matter you said cabinet i get it

#

i think your audience expects the Ninja Turtles / Simpsons arcade game movement (the things i'm more familiar with in this genre lol)

#

it's okay for it to be updateloopese

#

you can jump in those games

#

and there are holes, but there aren't platforms

brave bear
#

you can't jump in this specific one

undone coral
#

yeah

brave bear
#

but yeah generally you can

undone coral
#

it sounds like the place you want to innovate is in the abilities

brave bear
#

yes, and combat system

#

I understand that this game would technically work in an update loop. Technically an entire game can be made in a single file. Multiple files are just human convenience. But I don't see why would not using this convenience be a good thing?

undone coral
#

i am only talking about the movement

#

which is what you were discussing earlier i think

brave bear
#

well, we were discussing Player state generally, so all of them

undone coral
#

hmm

brave bear
#

including parrying, grappling hook, being stunned, attacking, etc.

undone coral
#

this is simply telling me that building this game will be very hard lol

brave bear
#

that's good, I don't want it easy

undone coral
#

and most architectural choices will get in your way

#

that's what i'm trying to say

brave bear
#

I can definitely agree with that

undone coral
#

abstraction will get in your way

#

an FSM will get in your way

brave bear
#

that's why I'm spending my time to think about the correct abstraction that will be best

undone coral
#

you don't want to declare states using classes and such

#

you will immediately need to leak things

#

the underlying states are really complex, and don't neatly fit into what an FSM is usually good for, like animation*

brave bear
#

that's what I'm worried about, yes

undone coral
#

i suggest trying to nail the movement first, using an update loop and input system*

#

and see if you can model the game in 3d

brave bear
#

we want to have 2D art for sure, but still a 3D world you would recommend?

undone coral
#

using something like kinematic character controller

#

well your life would be a lot easier in 3d

#

because then raycasts will make sense, for example

#

if you want to draw a circle on the ground, it will make sense

#

if you want that kind of design space

#

you can even use a tilt shift camera asset, i think it's called like isometric camera pro or something, and mix and match 3d and 2d assets

#

so that moving in z moves naturalistically along an apparent diagonal, whereas your player will usually move apparently camera up y (so actually some non-orthogonal vector in the xz plane)

brave bear
#

yeah the 3D vs 2D discussion is ongoing. The artists said that they can do anything related to depth and perspective in-asset (with drawing on sprites)

undone coral
#

sure your art can definitely work that way

brave bear
#

but I'm not sure that plain 2D is the right choice

undone coral
#

and everything will look right

#

if your game is 3d and you use sprites and you move the sprites

#

if your camera is Cabinet, great, it will Just Work

#

the trick will be whether or not you can use kinematic character controller, which already deals with a ton of problems

#

in movement

#

that said, retro games usually have non-physical movement, so you end up writing your own character controller whether you like it or not

brave bear
#

we're using rigidbody MovePosition right now, but this is very early stage

undone coral
#

in my opinion, using KCC for emergent behavior in your cabinet game is more interesting, but it not retro

undone coral
#

you will not be able to use rigidbodies for movement at all

brave bear
#

I actually prefer at least some saying since I'm new at this xD

undone coral
#

lol

#

well you can look at corgi engine 2.5d and see that they use "collide and slide" for movement

#

but that's also for platformers

#

but... this and platformers are both retro!! that's why things work this way

#

that's why i keep talking about retro versus not retro

#

because there were no physics and no abstractions 3,000 years ago when all these games came out

#

and unfortunately for commercial game authors, people love nostalgia

brave bear
#

so you would recommend for us using KCC and 3D world, alright

undone coral
#

the two are really strongly related - the lack of abstractions and the movement style

brave bear
#

I appreciate advice and I will certainly take it into consideration

undone coral
#

you're making a 3d game

#

if the retro game feel is not super important i would definitely do this

#

if it's super important, pick a game and try to copy its controls exactly

#

screen record and study frame by frame

#

using an emulator

#

you will be best off achieving this using a big update loop, doing raycasts against colliders to model your level geometry, and by modifying transform.position directly (i.e. using a custom motor approach like corgi engine, kcc)

brave bear
#

huuh, alright, I will try to do that

undone coral
#

for example, in 3d, with kcc, using a cabinet projection

#

like clearly there will be different apparent velocities

brave bear
#

I'm not convinced about the lack of architecture, but if no great idea comes to me, I will be trying that as well

undone coral
#

i don't know if in a retro game, the apparent y velocity is actually the same as the apparent x velocity

#

do you see what i mean?

#

like that's nonphysical

#

you'd have to carefully watch a video of ninja turtles and see what it is

#

if your apparent y velocity when you hold up on the joystick is the SAME as your apparent x velocity when you hold right, that will be hard to model using KCC

#

because it's non physical

brave bear
#

I think the y velocity is the sin(alfa) * x velocity where alfa is angle of the camera perspective

undone coral
#

well... you won't know until you look carefully

brave bear
#

+- what feels good

undone coral
#

because in this sega game

#

it appears to be the same

#

i am just sharing with you what this master of retro gamefeel has shown me

#

that's how these games are made

#

that's why Player.cs in celeste is big

#

it's not because they're stupid but because the behavior is nonphysical

#

it's retro

#

@brave bear so you better download streets of rage for an emulator, screen record, and measure the pixels per second your character moves

brave bear
#

yeah we will be doing that sort of research I guess, no way around it

undone coral
#

well but if that sounds boring to you don't do it lol

#

i mean make a fun game

#

i am personally interested in more design space, but on the other hand i would not play a game that requires a controller

brave bear
#

yeah I've never played with a controller as well

undone coral
#

so i'm not really representative of the audience. people who like controller games like to be rewarded for mastering that skill

#

hmm

brave bear
#

but we found that a lot of playtesters already demand a controller for the prototype

undone coral
#

well go nuts then. i mean focus on what you think is fun

undone coral
#

but i can only suggest what you will thrive doing

#

if you want something that is a cleaner architecture and not controller driven, do kcc and make it work somehow with point and click or touch

#

even multitouch, non virtual joystick multitouch

#

which by the way , the switch has a multi touch screen so it's not that crazy

#

but seriously, people may never buy that game 😦

#

so it's hard to speculate

#

people see cabinet perspective and they want to hold a controller

#

or they want to point and click around in an adventure game or whatever. you get what i am trying to say

brave bear
#

yeah yeah

#

well we're doing controller for sure, and keyboard or K+M

sacred dawn
#

what are you trying to do big picture

brave bear
#

I guess it makes sense for most people to use controller, it's me who is an exception I guess for not using a controller

#

thanks for the discussion though! you gave me a lot to think about

timid ledge
#

Hey guys I'm sorry for asking this once again but I haven't gotten any answers from #💻┃code-beginner or #archived-code-general and I'm completely stumped for an answer despite looking for quite some time now. Hopefully this question involving quaternions will make it worth being in the advanced channel. I am currently trying to get my vehicles gun to correctly adjust to face the target object regardless of the orientation of its base, and its also important for me to be able to control the horizontal and vertical rotation of the gun independently, so no I can't use .LookAt(). I'm using FromToRotation and ignoring the vertical rotation parameter for now in the setRot function (which just takes 2 euler angles and sets both the horizontal rotation of the turret and the vertical rotation of its gun separately) in order to keep things simple and avoid confusion.

The gun SHOULD be adjusting its rotation to always face the "target" object which it is still not correctly doing when I'm rotating the base of the gun and for some reason when the target is behind the guns "eye point" (which is at the centre of the turret and has a eulerAngle rotation of 0,0,0) the gun seems to look directly AWAY from the target. Here is the code I'm using:

    private float newHorizontalRotation()
    {
        Quaternion retQuat = Quaternion.FromToRotation(eyePoint.transform.forward, (targTransf.position - eyePoint.position).normalized);
        Debug.Log(retQuat.eulerAngles);
        return retQuat.eulerAngles.y + horOffset;
    }

    private void run()
    {
        gunScript.setRot(newHorizontalRotation(), 0);

        showPosition(eyePoint);

        Debug.DrawLine(eyePoint.position, targTransf.position);
    }


    void Update()
    {
        run();
    }
#

Does anyone know if I should instead of using eyePoint.transform.forward, be using something else e.g. eyePoint.transform.up? I've been trying different combinations for ages now but nothing seems to work :( every rotation seems to return an incorrect value but this is the closest I could get to it working properly. Any help is much appreciated thanks guys.

#

just to provide some further clarity as to exactly WHAT I am asking for, in this clip I have parented a camera to the turrets base, as such the ball which is currently the target should constantly remain at the horizontal centre of the screen (yet of course still freely move up and down) relative to the camera, however the turrets rotation is only slightly adjusting and not nearly enough

#

as can be seen here however, it has no trouble staying aligned horizontally as long as the base of the vehicle does not have an off center rotation

dapper cave
#

what sets this flag to false? transform.hasChanged does it need to be called in Update for example? always true with zero transforms set

austere jewel
dapper cave
karmic surge
#

in deploying a unity application for the hololens
I need to specify device capabilities,
I can not seem to find the file named
Package.manifest
anywhere
should I create it myself, if so where?

#

nvm what I wanted was under player-setting

hardy sentinel
stray wedge
#

Hi Guys, question, is there any reason why OnTriggerExit wont fire off if the object is disabled inside the collider? It will only fire off if the object moves outside it, which seems weird to me.

stray wedge
sly grove
#

if your object is being disabled, you're disabling/deactivating it too

#

so you can handle that case separately

stray wedge
# sly grove OnTriggerExit

So what I have is 3 location stored inside a list. at start it picks one of the 3 locations to spawn the first building. once the building is spawned the location is removed from that list. and the next building gets place at one of the last remaining spots.. which currently works. But what I can't figure out and thought i could do this with OnTrigger was updating that list to whether or not a building is inside the collider.

runic gazelle
#

Yeah you will probably need to building to have an OnDisble function that lets the system know that the location is available again

sly grove
stray wedge
sly grove
#

it seems to me like spawning would correspond to OnTriggerEnter, NOT OnTriggerExit

#

so I'm assuming you're talking about despawning right?

#

otherwise I'm not sure I follow

sly grove
jovial totem
#

Hey, how do I go about component-izing my classes? I have a hierarchy tree I'd like to be rid of, but I don't know where to start untangling all of it

sly grove
#

wdym by "hierarchy tree"?

#

polymorphism?

jovial totem
#

i meant inheritance map. inheritance.. tree. i dont know what to call it exactly

sly grove
#

well... you just start decoupling functionality into separate components

#

Without knowing details, it's hard to get into specifics. but something like... turning:
Orc : Enemy : Unit
into:

  • HealthScript
  • MovementScript
  • AttackScript
#

for example

stray wedge
jovial totem
sly grove
jovial totem
#

but what about interfaces?

sly grove
#

What about them

#

they solve a problem that can just as easily, or even better be solved by simply having a separate component

#

instead of:
Goblin : IUnit
Rabbit : IUnit
Tower : IUnit

You can just attach a Health script to all those GameObjects

#

and just do GetComponent<Health>

#

and then you only need to write one Health script

#

instead of reimplementing health and death on multiple scripts

jovial totem
#

how can I make sure the implementer has the other ones. The reason Im talking about interfaces is for reasons the entities in my game are not part of any scene, so adding components to them is hard

#

but. maybe I make a base class of Entity, and then make my own GetComponent implementation, which is pretty easy...

sly grove
#

I mean if we're not talking about GameObjects this is perhaps a different conversation, but yes you can also implement the Entity/Component architecture in your custom classes

jovial totem
#

yeah

jovial totem
#

if I make a pseudo-ECS, how would I define archetypes?...

#

also, I'm wondering if an ECS is even necessary, since there's only these things, and probably not much else

#

im just a bit worried that it will all become hard to maintain

jovial totem
#

I think I should go for it, even though I'm about to send the game out for playtesting (probably with the old system), because I want to port this over to DOTS at some point when the platform is more mature (can work well with terrain)

uncut burrow
#

hello chat

whole quest
#

rendering uses a lot of CPU even though my scene is empty, any suggestions ?

mortal gust
dusty wigeon
# jovial totem my graph looks a bit like this

If your graph represent Hierarchy, you might want to review it.

Object Oriented Programming tips:

ECS tips:

  • Look into anemic domain. It is considered an anti-pattern for (OOP), but in case of Data-Oriented Programming (DOP) it works well. In fact, it is pretty much a requirement. https://en.wikipedia.org/wiki/Anemic_domain_model
  • You might want to look into Data-Access Object (DAO) It is more straight forward than repository and suits better the need. https://www.baeldung.com/java-dao-vs-repository https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm
  • What you define in ECS is System and Component. How you find what archetypes you require is by looking at what component your System require. The less archetype your system requires, the best it is.
  • Be sure to use the correct architecture for the needs. Ask yourself how many component of the type X is going to live at the same time. If the answer is 20-50, you should not consider ECS as the performance gain will probably be minimal and you will have an harder time dealing with the interaction between object. ECS is really good with dealing with a lot of component but less with interaction as you require to use a component for the task. (System does not talk between eachother ideally, but through component) Doing so, increase the complexity dramatically.
regal olive
#

Does anyone know how to close a mesh without uvs breaking?
Just one particular face breaks, the one where i make triangles consisting of last vertices, and first vertices of mesh (i need to do it to close the mesh with triangles)

#

uvs:

        float xStep = 1f / (xVertices - 1);
        float yStep = 1f / (yVertices - 1);

        for (int y = 0; y < yVertices; y++)
        {
            int xx = 0;

            for (int x = 0; x < xVertices; x++)
            {
                int uv = y * xVertices + x;
                int yy = y;

                uvs[uv] = new Vector2(xx * xStep, yy * yStep);

                xx++;
            }
        }
#

ohh i have an idea, perhaps my xStep and yStep arent compatible with unity material's tiling, and the reason it breaks because my tiling(step) isnt respected for that particular face, just the material's tiling, so id have to somehow make it so my step value equals materials' tiling

#

just an theory though. NVM wrong

harsh matrix
#

that is probably a face sharing vertices with the first and last vertices in the loop, so they will span the entire space from (0,0) - (1,0), etc. you should duplicate the first vertex and reuse it for the last uv

regal olive
harsh matrix
#

give it the same normals, position, etc, only thre uv value wil be different

#

i hope this illustrates what i mean

#

the vertex has the same position in 3d space/normal space, etc, but in uv space the position is different. so it will need to be duplicated

regal olive
#

i see thanks

regal olive
#

and both uvs and normals have to be the same length as vertices array

harsh matrix
#

are you using Mesh.RecalculateNormals() ?

regal olive
#

yes

harsh matrix
#

yeah, that would do it. it will mess up your normals with the duplicated vertex

#

if you calculate the normals yourself, you don't need to call that

#

with procedural meshes you should be able to calclulate your normals while generating triangles with a cross product if you know how to do that

#

then no need for RecalculateNormals call

raw path
#

Hi there
does anyone know how Selectable.FindSelectable is supposed to be used?
I'm trying to determine neighboring selectables automatically (while having the navigation set to Explicit) but I only get a result Selectable from the function if the selectables are not in a container like a GridLayoutGroup
anyone ever used that function before?

sterile snow
#

So this is a special kind of annoying.

#

Oh nevermind I just needed to mark the layout for rebuild apparently

#

TextMeshPro makes me big mad sometimes

#

Well, when working with animators, how do I get it to immediately appear at the end of the entry animation?

#

My settings panel works by being dismissed or pulled in with an animation via button press, but it needs to start fully dismissed.

sterile snow
#

( Nothing to do with the gif by the way )

split sierra
#

is it possible that when I put my game on itch.io that I can have a textfield where people can write something and then submit the feedback to me so i get an email or something with the content?

sly grove
#

one easy approach is using Google Sheets or Google Forms

split sierra
#

do you know a good tutorial i could follow?

compact ingot
compact ingot
abstract folio
#

just looking for confirmation that accessing commandResult.Result, in this async code, WILL infact await the completion of the command task. Task<CommandResult> commandResult=commandToRun.BeginCommandTask(); CommandResult result = commandResult.Result; If this is NOT correct, how DO I await it's completion?

fresh salmon
#

It'll block the running thread until completion. Use result = await commandResult;

abstract folio
#

🍒 @fresh salmon thank you

abstract folio
fresh salmon
#

What await does internally is wait until the task completes, then if it's faulted it "unwraps" the exception that was thrown for you to catch it (or not), else it gets the result

#

I think it's similar to doing commandResult.GetAwaiter().GetResult(), might be syntax sugar

abstract folio
#

''syntax sugar'' ah, thanks again!

fresh salmon
#

Yeah async/await generates a whole state machine class for you, it's practically unreadable because it uses random names for the types

#

It's a bit like iterators (coroutines), it has a MoveNext method that advances the state as needed

#

mmm, look at this

private void MoveNext()
{
    int num = <>1__state;
    try
    {
        TaskAwaiter awaiter;
        if (num != 0)
        {
            awaiter = Task.Delay(500).GetAwaiter();
            if (!awaiter.IsCompleted)
            {
                num = (<>1__state = 0);
                <>u__1 = awaiter;
                <<Main>$>d__0 stateMachine = this;
                <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
                return;
            }
        }
        else
        {
            awaiter = <>u__1;
            <>u__1 = default(TaskAwaiter);
            num = (<>1__state = -1);
        }
        awaiter.GetResult();
    }
    catch (Exception exception)
    {
        <>1__state = -2;
        <>t__builder.SetException(exception);
        return;
    }
    <>1__state = -2;
    <>t__builder.SetResult();
}
abstract folio
#

<> what the heck? NEVER seen that in actual code afore.

fresh salmon
#

It's so you can't refer to it in your own code

#

That was for a single await Task.Delay(500) call, that you can see transposed in the state machine

#

Yeah a lot of features you use everyday is compiler trickery. Iterators, foreach loops, async methods, auto-properties, etc. these are all "lowered" into code the compiler can understand

raw lily
#

In my card game, I have a cardStateMachine that holds various states for a single card. When the card is dragged, the state changes to dragging and the card hand gets locked: calling each card's cardStateMachine telling it to lock the card state (so they can't be moved or dragged) which allows them to update their displayed (to disabled) accordingly. Is there a way to avoid a circular dependency doing this?

jovial totem
# dusty wigeon If your graph represent Hierarchy, you might want to review it. Object Oriente...

Yes, they are my heirarchy.

  • I am slowly realizing a lot of these are important. I tried to separate out HasInverntory into IHasInventory, but it needed some data that the inherited class would provide. DatabaseItems are kept in a large dictionary<string, DatabaseItem>.
    As for what to do, I stayed up late last night (too late) creating a pseudo-ECS sort of mirroring Unity's GameObject system where DatabaseItems are instead Entities, that each can have a list of Components. - Different from a true ECS, the components have logic within them, like Monobehaviours, although I have also added a way to have systems with queries. At some point I want to move over to DOTS, so breaking it up this way will allow an easier port, although I can't move over right now because DOTS doesn't work with some critical systems I'm using (Terrain and navmesh, for example) and I rely a lot on classes (Moonsharp Lua VMs)
  • The reason I'm reinventing the wheel is, long story short, due to the architecture of my game, all objects that need to "persist" and update outside of being loaded in a scene have their logic in classes kept in the Database, and when they are needed in the scene, control "puppets" that are the actual gameobjects in the scene, commanding them to move around or what have you.
  • However ,this system is entirely experimental and may be stupid, as I wrote it in 3 hours while half asleep.
fickle zodiac
#

Hey all I have two videos

One works just fine in unity, but the other keeps crashing our game on android.

Can someone help diagnose what's going on?

flint geyser
#

Can I launch an iOS build on my iPhone without registering as an iOS developer? How?

abstract folio
humble leaf
dusty wigeon
# jovial totem Yes, they are my heirarchy. - I am slowly realizing a lot of these are important...

First of all, DOTS is an architecture to optimise the game performance. Do not try to mimic DOTS if you do not want to optimise your game because Data-Oriented Programming has a bunch of issue that prevent the creation of easily maintainable game. Object Oriented Programming is by far one of the simplest and most easy to understand paradigm.

There is no reason to reinvent the wheel. There is multiple people that had exactly the same issue that you are describing and found solution that works in most case. Those solutions are what we call design pattern. DAO and repository are two of them.

Also, I don't want to be pessimist, but you will not be able to port to DOTS if you do not respect Data-Oriented Programming paradigm completely as you will do things that are fundamentally not possible in such architecture.

jovial totem
# dusty wigeon First of all, DOTS is an architecture to optimise the game performance. Do not t...

What I am doing is still fundamentally object-oriented. And the "Database" system that stores and handles queries to find and manage both the old DatabaseItem class and the experimental Entity class are basically Repositories already, so I guess I reinvented that data structure. At least I know that I'm on the right track.

As for component-izing my inheritance hierarchy, It will just be easier to maintain this way, because my current system is quickly becoming very monolithic and a bit of a rat's nest internally, which through experience I know will become an issue quickly when things scale up.

As for only half-DOTSing, my goal was not to Become DOTS (although I suppose it did look like that), it's just to structure the classes in a way that, should I try to port my code over in the future (although it isn't possible right now afaik), it would not require a major ground-up refactor/restructuring, and would be more or less just rewriting what is already there to use value types instead or what have you, or moving the business logic that is in the components to systems instead.

compact ingot
#

a little bit of ECS architecture might look like it helps, but really its only a fraction of the work you need to do to get entities working

jovial totem
#

oh, I already know that. This system that I'm trying to untangle right now is a result of a rewrite from when I tried to use a hybrid ECS/GameObject system from sometime before 0.5. That did not go well. The DOTS conversion is only hypothetical and something to be done much in the future only if necessary and when the ecosystem is a bit more mature

#

Maybe I'm just telling myself that I'm preparing to ECS-ify this to make myself feel better, but the real reason is that I'm self conscious about how I lay out my architecture and I'm realizing the way I did it might be a disaster later on and I'm trying to prevent it now before it gets too bad

compact ingot
#

typically a good strategy is to just solve the problems you currently have in the simplest way possible while keeping your code modular and decoupled, such that you can replace any system that gets outgrown by its scope without breaking everything else

upbeat bay
#

Is there an Authoritative server style expert here?

compact ingot
upbeat bay
#

Well I asked a question in general, and seems like it was over their head. and thank you for the link. @compact ingot I'm new here.

upbeat bay
#

I wasn't asking for help. I was asking for opinions.

compact ingot
#

looks like you are running into basic networking issues, you probably find answers to similar problems already answered in #archived-networking history

jovial totem
compact ingot
jovial totem
#

thats what im doing

upbeat bay
#

@compact ingot I searched the history of the channel for a simple two words, "client" and "ownership" and there was only 9 results. My answers are not in there. wish there was a proper discussion! You did have a good post on why you shouldn't do authoritative, but I disagree because of what I want to do for this special case.

dusty wigeon
# jovial totem What I am doing is still fundamentally object-oriented. And the "Database" syste...

You do what you do, and that is fine. From my perspective,
You are over engineering. (Reinventing the wheel)
You are not using the tool you have. (DOTS or GameObject architecture)
You are not defining your priority. (Maintainability, Performance, Quality, Stability)
You are doing code for the fun of doing it. (Making a whole system to copy the component architecture of Unity does not seem really profitable)

All of that will cause you to either, under-deliver, deliver in a long time or even never deliver. If your objective is to make a game, you should make the game, not the engine. You should go fully in DOTS or give up the idea completely.

compact ingot
jovial totem
sharp pond
#

does anyone here know how to resolve memory leak issue on UnityWebRequest? i tried using Dispose() after data is received but i get a null error at UnityWebRequest. here is the code: ``` UnityWebRequest uwr;
IEnumerator PostRequest(string url, string filePath)
{
byte[] dataToPost = System.IO.File.ReadAllBytes(filePath);
UploadHandlerRaw uhr = new UploadHandlerRaw(dataToPost);

        uwr = new UnityWebRequest(url, "POST", new DownloadHandlerBuffer(), uhr);

        uwr.SetRequestHeader("Accept", "application/json");
        uwr.SetRequestHeader("Authorization", "Bearer " + apiToken);
        uwr.SetRequestHeader("Content-Type", "*/*");

        yield return uwr.SendWebRequest();

        if (uwr.result == UnityWebRequest.Result.ConnectionError)
        {
            Debug.Log("Error While Sending: " + uwr.error);
        }
        else
        {
            Debug.Log("Received: " + uwr.downloadHandler.text);
            uwr.Dispose();
            uhr.Dispose();
        }
    }

    IEnumerator UploadProgressCoroutine()
    {
        while (!uwr.isDone)
        {
            HandleProgress(uwr.uploadProgress);
            yield return null;
        }
    }

    void HandleProgress(float currentProgress)
    {
        print("Upload : " + currentProgress);
    }

    public void UploadDataFromStringUnityWebrequest(string path)
    {
        string requestUri = nftStorageApiUrl + "/upload";
        uwr = null;
        StartCoroutine(PostRequest(requestUri, path));
        StartCoroutine(UploadProgressCoroutine());
    }
scenic forge
#

using is just syntactic sugar for automatically calling Dispose for you.

#

If you are getting NRE it's likely that something else already set it to null before you were able to Dispose it, especially because uwr is declared as class field so anything can access it.

#

Eg nothing stops you from calling UpdateDataromStringUnityWebRequest a second time before the first one even finishes, and your uwr is overwritten.

#

I personally would not do any serious async programming with raw coroutine, I would suggest using things like UniTask, UniRx, etc instead.

sharp pond
#

any recommended tutorial i could read through for UniTask/UniRx?

scenic forge
#

For UniTask, just learn regular C# async/await, it's basically the exact same.

#

Refer to the UniTask docs to see what to use instead of the builtin C# stuffs.

oak cedar
sharp pond
scenic forge
#

If you are looking for UniRx, I believe @undone coral knows quite a lot about it and has better recommendations.

oak cedar
sharp pond
sharp pond
scenic forge
#

UniRx is quite a huge change to how you fundamentally approach asynchronous programming, UniTask is just using C# async/await more efficiently and ergonomically with Unity rather than coroutine.

#

If you really don't care about anything else but fixing your problem, you can get coroutine to work, but as I said you will probably run into even more problems down the line anyways.

sharp pond
#

cause i plan to make my game in WebGL

scenic forge
#

You should checkout docs at least, not just watching videos which might have outdated information.

sharp pond
#

wait i need to download that code from github to use?

#

the youtuber never said anything about downloading stuffs

scenic forge
#

It has instructions there, you should be able to figure out the rest on your own.

undone coral
undone coral
sharp pond
undone coral
sharp pond
sharp pond
#

anyone know how do i call the UploadDataFromStringUnityWebrequest i usually call it by using UploadDataFromStringUnityWebrequest(instance.filePath); ``` private UnityWebRequest uwr;

private async UniTaskVoid PostRequest(string url, string filePath)
{
    byte[] dataToPost = System.IO.File.ReadAllBytes(filePath);
    UploadHandlerRaw uhr = new UploadHandlerRaw(dataToPost);

    uwr = new UnityWebRequest(url, "POST", new DownloadHandlerBuffer(), uhr);

    uwr.SetRequestHeader("Accept", "application/json");
    uwr.SetRequestHeader("Authorization", "Bearer " + apiToken);
    uwr.SetRequestHeader("Content-Type", "*/*");

    await uwr.SendWebRequest().ToUniTask();

    if (uwr.result == UnityWebRequest.Result.ConnectionError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}

private async UniTaskVoid UploadProgressCoroutine()
{
    while (!uwr.isDone)
    {
        HandleProgress(uwr.uploadProgress);
        await UniTask.Yield();
    }
}

private void HandleProgress(float currentProgress)
{
    Debug.Log("Upload : " + currentProgress);
}

public void UploadDataFromStringUnityWebrequest(string path)
{
    string requestUri = nftStorageApiUrl + "/upload";
    uwr = null;
    UniTask.Void(async () =>
    {
        await PostRequest(requestUri, path);
        await UploadProgressCoroutine();
    }).Forget();
}```
#

got an error of 'UniTaskVoid' does not contain a definition for 'GetAwaiter' and the best extension method overload 'AwaitExtensions.GetAwaiter(Process)' requires a receiver of type 'Process'

untold grove
#

i have some Questions about the IK weight (animator API) it seems very hard to smoothly bringt the Weight from 0 to 1 for some reasons.
HAs anyone some experiencs with this?

Using Unity Atoms seems not to work, the values are always very small and below -0 instead of 0-1

when I set the weight at 0.1 for example, it put the hand already on the target, and to be able to blend back to the other animation, i need to put the weight to 0.01... and that's a problem for the lerp because it lerp from 0 to 1, and if at 0.1 the hand already almost reach destination it's too quick
AvatarIKGoal.LeftHand
is it a normal behavior ?



void OnAnimatorIK(int layerIndex)
    {
        _animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, _leftHandIKPositionWeight_Lerp);
        _animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, _leftHandIKRotationWeight_Lerp);

        _animator.SetIKPositionWeight(AvatarIKGoal.RightHand, _rightHandIKPositionWeight_Lerp);
        _animator.SetIKRotationWeight(AvatarIKGoal.RightHand, _rightHandIKRotationWeight_Lerp);

        //-----------------------

        if(_leftHandIKTarget.Value != null)
        {
            _animator.SetIKPosition(AvatarIKGoal.LeftHand, _leftHandIKTarget.Value.transform.position);
            _animator.SetIKRotation(AvatarIKGoal.LeftHand, _leftHandIKTarget.Value.transform.rotation);
        }

        if(_rightHandIKTarget.Value != null)
        {
            _animator.SetIKPosition(AvatarIKGoal.RightHand, _rightHandIKTarget.Value.transform.position);
            _animator.SetIKRotation(AvatarIKGoal.RightHand, _rightHandIKTarget.Value.transform.rotation);
        }
    }
misty crescent
#

Hey guys, I've been thinking about a slightly difficult problem.
I have some common code shared between 3 projects.

Would I better off making a git submodule or a Unity package?

untold grove
untold grove
#

we use internally scm and client uses git

#

so we use package to put it into the Git verison of the project

#

internally we all commit to our scm

misty crescent
#

so you guys don't use submodules etc?

#

just rely heavily on UPM?

untold grove
#

since unity 2017

#

we never done it differently

misty crescent
#

no issues so far?

#

what if the package has other packages as dependencies?

untold grove
#

packets are so similar to repos

#

wel if they are packets from packet manager its easy to install

#

the manifest will do the job for that

misty crescent
#

got it, so your package itself has another package inside

untold grove
#

no but it is incremental

#

i export only the parts i worked on and if you import it at the other side it will recognize what has been updated and what is old

#

same as if you download a assetstore packet

misty crescent
#

that's fine but what if your package has a dependency that is another package?

#

example:
Package1 (that you made) has dependency Package2 from the Unity Asset Store

untold grove
#

then you add the packet to your .unitypacket on export

#

everything in the Asset folder you can include

misty crescent
#

got it

real blaze
#

hey. how'd you decrypt a JWT token in Unity?

real blaze
devout hare
real blaze
#

think I haven't already searched that before coming here?

scenic forge
devout hare
scenic forge
#

I have not tried it, but the first one is maintained by Microsoft and supports NS 2.0.

real blaze
real blaze
# devout hare It does look that way

the solutions using dlls aren't good since they're windows specific. and that github page dates back to 7 years ago for it's latest git commit

scenic forge
#

.NET dlls are IL and not platform specific.

#

Which one are you trying?

real blaze
devout hare
#

There are more than 1 search result

scenic forge
#

As the name suggests, IL2Cpp just converts IL to C++.

real blaze
real blaze
random dust
#

Latest Unity is on that AFAIK

real blaze
karmic surge
#

is there a simple way to do RTSP with unity in my application?
(the machine I am sending to, does not support webrtc)
I just have a working application that I need someone to view it in real time
any suggestions or something that people would recommend?

compact ingot
karmic surge
compact ingot
karmic surge
onyx violet
#

Hi there
does anyone know if there's an event to listen to for when the UI was completely rendered?

compact ingot
compact ingot
onyx violet
compact ingot
#

Otherwise they are complete in late update if all changes are applied in update

onyx violet
#

hmmm

#

quite inconvenient

compact ingot
#

It’s required behavior for performance reasons

#

Automatic Multi pass layouts would be too expensive

onyx violet
#

jeez, all that just to track navigation manually for nested UI elements

compact ingot
#

Whatever that means

onyx violet
#

thats what I'm trying to do, automatic navigation doesnt properly work in unity for UI so I'm trying to set the up/down/left/right selectables manually through code
there is the FindSelectable function that does this well enough (probably will have to modify it), but it doesnt work for nested UI elements (like in a GridLayoutGroup) before the nested Rect s are finished constructing

#

which is some time after Start

compact ingot
#

I’d go for an architecture where the nav can be derived from the data model instead of the ui placement, I.e. layout and nav connections can be computed independently but deterministically

lusty basalt
onyx violet
#

the content are just a bunch of identical buttons

#

at least in transform

lusty basalt
# onyx violet thats what I'm trying to do, automatic navigation doesnt properly work in unity ...

like anikki said, It might be easier to generate a 2d-data strutcture with an object per button and then a reference to that button inside the object and do assignation that way, but if you want to avoid that try running a cooroutine at start that checks if FindSelectable is working for the button last created(or all of them mb, you're only doing this at start) and then have it do the navigation-mapping when you get a green light?

onyx violet
#

I've checked the internal Unity code and found out that FindSelectable is being used on-demand, not at startup
Now I have to figure out how to trigger that myself

lusty basalt
#

do the buttons currently know who their neighbors(the buttons they are actually supposed to navigate to) are?

onyx violet
#

only if navigation is set to automatic/horizontal/vertical
but that doesnt work properly with containers, because you cant limit navigation within one and the user navigates outside something he's not supposed to

#

but if I set it to explicit, any FindSelectable variation inside Unity code doesnt work because that mode excludes the navigation from finding targets automatically

lusty basalt
#

ah, I meant for your custom scripts on the buttons

onyx violet
#

nope

#

the container does know what the children are, it does track each instance of a button

#

but the GridLayoutGroup doesnt offer a good way of figuring out the current layout depending on size or resolution if it's set to flexible

lusty basalt
#

oh i did some reading in the docs, is it true that it runs findselectable every time you make a UI input?!
so right = moveright(findselectableright())

#

?

onyx violet
#

yeah pretty much, on-demand

#

but only when not set to explicit

#

I've figured it out

#

you can use a IMoveHandler in a script to listen to move events in the ui and then basically do the same as the Selectable class in OnMove

lusty basalt
#

oh that would work

#

Apparently the navigation struct has settable properties for ever cardinal aswell

#

but I guess that doesnt help you since you need to know the current grid layout anyway

onyx violet
#

yeah that struct is only for holding references to other selectables

lusty basalt
onyx violet
#

yeah I kinda only needed that in my last approach, but now that I know that I can do it on demand as well, it's fine with IMoveHandler

lusty basalt
#

apparently the layoutgroup isnt a canvaselement anyway, so I guess it wouldve taken some more work. Maybe registering when all of the buttons have invoked the graphicsudatecomplete or whateves. 🙂

But cool that you found a solution

#

QUESTION:
I'm trying to cop/emulate the behaviour of marvel snap when you drag around a card with the mouse(without using rigidbodies or the physics system). Rotate the card in the X & Y axis so that its forward is at an angle relative to the mouse direction like in the picture. the larger the magnitude of the mouse direction the smaller the relative angle
Above is the closest ive gotten so far, though admitedly this is before I just now realised that the above was what I wanted to do. Has anyone done somehting similar and can set me on the right path?

golden quail
lusty basalt
#

yes, but If i do that the card will look flat toward the position. Im trying to get it to look at a point somewhere between its original forward and the mouse pos

#

or a % between depnding on the magnitude of the movement I suppose

golden quail
lusty basalt
#

Once i manage to get it to be a % of the mouse direction, I will clamp it to maybe 30% percent of the angle at most)

#

but to do that I need to be able to angle it on the projected forward for a specific angle

undone coral
#

for receiving

lost badger
#

So I am making a game where I need to make a timer. The timer needs to count up in minutes seconds and decimals and be in minimal 100 levels... If you reach the end time need to stop. If it stopped it needs to check for the best time and save it so that It can be displayed in another scene. So it actually needs to be a Best Time timer or something. Just like speedrun games. I have the timer working but not the best time and the display in the other scene. Can someone help me with this, because I wasted like 3 hours and motivation.

undone coral
#

in principle you can do this yourself, since you know the algorithm the tokens will be issued with

karmic surge
undone coral
#

oh

#

right

#

it sends too doesn't it?

#

i think there are also paid services that may alleviate your pain a bit

karmic surge
# undone coral it sends too doesn't it?

I did not check it, but I was commenting on the receiving part. Will check it tomorrow.
I have been recommended 3 packages, I will need to check them and compare them.
The one i am sure is paid was VLC

undone coral
#

well...

#

what is it like 6 weeks left

#

🫡

karmic surge
velvet rock
#

Question. Can I get all instances of components of an unbound generic type using GetComponentsInChildren(typeof(MyGenericType<>))?

#

I just need them as Object/object types ultimately.

jolly token
velvet rock
#

Eh yeeeaaahhhh. Actually I could make a base interface that all my generic ones inherit, that would be clean. Other wises I could get all components then can iterate over them with reflection,,, which wouldn't be efficient or clean.

kindred tusk
#

But using an interface is certainly how I'd approach it

#

Like:

interface IMyGenericType {
  void DoThing();
}
abstract class MyGenericType<T> : MonoBehaviour, IMyGenericType {
  public void DoThing() {
    // do some thing
  }
}
class MyIntType : MyGenericType<int> { }
// ...
foreach (var c in GetComponentsInChildren<IMyGenericType>()) {
  c.DoThing();
}
#

How you do it exactly really depends what you're doing with them

scenic forge
#

There's also:

interface IFoo {
    // ...
}

interface IFoo<T>: IFoo {
    // ...
}

I do wish we had IFoo<_> though.

limpid prairie
#

Looking for general feedback on how to improve optimization of my game!
Here is just a general look at my Stats view:

#

A big hint is, in my game, I use blocks to procedurally generate a map (think Minecraft), but I am not sure if I am optimizing the benefits of using the same material properly.

#

Looking at my Stats view, does it seem like my batching and whatnot is working?

violet valve
#

If this is running on a phone then my god man, you've solved time.

limpid prairie
#

I've looked through the profiler a lot and eliminated anything that was like a "low hanging fruit" type mistake. Anything that was too large in usage, etc.
Now, it's just small stuff that takes <1mb, but a lot of these things.

#

And yeah, the goal platform for this game is webGL so I'm looking to optimize pretty much as much as possible

limpid prairie
long ivy
#

your numbers look bad to me. 10.1ms for 1512x850, almost 4k batches, 1.2m tris

limpid prairie
#

What is the most obviously large stat? I'm still new to these. I know for tris/verts I need to optimize the meshes

violet valve
#

Your numbers might be fine, but any advice you receive is coming from different people working within different pipelines with different stress cases. Your picture doesn't do anything to show where your project sits in the potential range of efficiency. Some games will chug and some games are just going to render a couple UIElements.

limpid prairie
#

I made quality settings for this game, and when you use the lowest quality setting, it's this:

long ivy
#

Batches are still way too high for a mobile game. You are probably breaking batching in some way, or you have set things up such that you're not taking full advantage of it

#

Use the frame debugger and find out what's happening

limpid prairie
#

yeah, true, I need to look into that, I feel like Saved by batching: shouldn't be 0. (Also this game is for webGL, not mobile, but yeah this is still bad optimize)

#

I reduced the build size from 300mb, down to like 90mb, made every texture compressed and reduced in resolution, so i think that department is good, now I need to work on batching

limpid prairie
#

Why does the canvas take 39 draw calls, if I'm seeing that correctly? My UI is very minimal, but sure it has a lot of small images (circles), but I thought they'd be drawn together?

midnight violet
limpid prairie
#

I use TextMeshPro a lot.
And I also use ContentSizeFitter a lot, could that be a problem?

The 39 draw calls from the canvas are probably cause I use a lot of small shapes to make up the UI, instead of 1 custom made shape, I guess.

novel plinth
#

Nice to know that we got Awaitable api now in Unity. so coroutines can go die in a ditch blushie

mortal gust
scenic forge
#

async/await is not the same as multithreading.

dusty wigeon
#

And they don't respect Unity LifeCycle I heard.

onyx violet
#

Hello there
does anyone know a way to figure out if UI objects are currently visible within a ScrollRect?

compact ingot
# mortal gust How does this work with main thread stuff like instantiating stuff?

the idea of the new Awaitable is to unify the idea of an async operation that happens either on your custom code side or in the native engine code into one thing that can potentially run in parallel (on actual threads) but also access the unity API from there, it was stated that it is not (meant as) a replacement for async/await or things like UniTask / Jobs / AsyncOperation. Its probably going to be confusing/unclear for a while when to use it vs other options.

mortal gust
glacial wedge
#

what's the point of EventHandler ? Action do the same thing but doesn't require the object sender parameter that is never used

timber flame
dusty wigeon
# glacial wedge what's the point of `EventHandler` ? `Action` do the same thing but doesn't requ...

https://learn.microsoft.com/en-us/dotnet/standard/events/
.NET provides the EventHandler and EventHandler<TEventArgs> delegates to support most event scenarios. Use the EventHandler delegate for all events that don't include event data. Use the EventHandler<TEventArgs> delegate for events that include data about the event. These delegates have no return type value and take two parameters (an object for the source of the event and an object for event data).

It is a way to unifying Event Delegate. It has the advantage of not requiring to rewrite every callback whenever you modify your definition. That being said, I am pretty sure it requires allocation. Like the documentation and @timber flame pointed out, it is nothing more than Delegate. Also, you can consider extra pattern with event like event buffer that could not be possible (or hard to do) with standard System.Action.

timber flame
#

Object sender is sometimes useful when you want to know which instance has raised that event, it is like an identifier

hazy hearth
#

How'd you guys store a list/array of string that you can find by name?
I mean like a list of scriptable objects with two fields each: name & description

ember temple
hazy hearth
#

that's not a bad idea.
But is it correct to have as values such large texts?
100+ words each

warm remnant
#

i mean as long as it works it works

warm remnant
#

no problems should iccur

#

occur*

hazy hearth
#

Alright

#

I'm going with this approach thank you 😄

true cosmos
#

this method ScreenCapture.CaptureScreenshotIntoRenderTexture(rt); always captures 2nd display, can i force it to capture 1st display instead?

#

ok i found out the solution: set higher camera priority that has 1st display

undone coral
#

like what's the gameplay

abstract hill
#

Hi everyone, I know this isn't strictly unity related but I'm unsure on the best place to ask this (let me know if there is a C# only discord if this is the wrong place).

But I am looking to run a Task using an async lambda expression. However it uses Unity engine logic so has to run on the main thread. If I use Task.Run it fails due to being places on the thread pool, and I cannot seem to find anything on forcing this to run on the main thread.

But using Task.Factory.StartNew and then passing the TaskScheduler works, but it does not await correctly, from what I've read Task.Factory.StartNew does not work with async lambdas.

The project im using is to big to add more packages without requesting permission which most likely won't be granted. So I can't use anything like UniTask. Is there a way to use Tasks that let's me choose which thread it runs on AND let's me await it?

velvet rock
#

I am trying to use Serilog in unity. I have it all working to a point, but the Serilog.sink.unity example is pretty vague and isn't working.
The code I currently have.

namespace Levels.Universal {
    using System;
    using System.Linq;

    using Levels.Universal.Functional;

    using Microsoft.Extensions.Configuration;

    using Serilog;
    using Serilog.Core;
    using Serilog.Sinks.Unity3D;

    public class SerilogLoggerFactory : ILoggerFactory, ISetup<SerilogLoggerFactory, bool> {
        public static ILoggerFactory Service { get; } = new SerilogLoggerFactory();
        private readonly Logger _logger;

        public SerilogLoggerFactory() {
            // Configure Serilog logger
            var config = new ConfigurationBuilder()
                .AddJsonFile(UnityEngine.Application.dataPath + "\\gamesettings.json", optional: false)
                .Build();

            _logger = new LoggerConfiguration()
                .MinimumLevel.Information()
                .WriteTo.Unity3D()
                .CreateLogger();

            Log.Logger = _logger;
        }

        public ISetup<SerilogLoggerFactory, bool> _Setup { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public Serilog.ILogger CreateLogger(Type type) {
            string sourceContext = type.FullName;
            ILogger logger = _logger.ForContext("SourceContext", sourceContext).WithUnityTag("My custom tag");

            return logger;
        }

        public SerilogLoggerFactory Setup(bool args, SerilogLoggerFactory source = null) {
            Type type = typeof(ILogger);
            type.GetCustomAttributes(true).ToList().Add(new Settings.DI() { PassTags = true });

            return this;
        }
    }
}
#

The problem I have is that it is returning Serilog.ILogger and not logging to the debugger. Now if the Unity sink github they state that I should be getting the Unity logger from this?

public class MyObject : MonoBehaviour
{
    // ...
    private ILogger _logger = new();

    public void DoLog()
    {
        _logger
            .ForContext(this)
            .WithUnityTag("My custom tag")
            .Information("This is an info log");
    }
}

is their example, but uhm, well that isn't even functioning code in the first place.

#

Note I moved away from loading a configuration to track down what is going wrong.

#

If I instead return UnityEngine.Debug.unityLogger I don't have any of the methods available that they state like ForContext or WithUnityTag

long ivy
#

why not? those are extension methods

#

or is the ILogger different from Unity's ILogger?

velvet rock
#

Ah yes those extension methods are for Serilog.ILogger

#

So those are showing up, but for some reason it still isn't logging to the console...

distant tree
#

so im trying to save data for a custom behaviour tree graph to a scriptable object (this is just saving data, not the actual nodes or edges).
everything is saved to the BehaviourGraphData.Node classes, but all the data is deleted whenever i enter play mode.

save button:

toolbar.Add(new Button(() =>
{
    if (!behaviourGraphData) return;

    behaviourGraphData.update = new BehaviourGraphData.InputNode()
    {
        pass = behaviourGraphView.updateBehaviourNode.CreateNodeData()
    };
    behaviourGraphData.fixedUpdate = new BehaviourGraphData.InputNode()
    {
        pass = behaviourGraphView.fixedUpdateBehaviourNode.CreateNodeData()
    };

    behaviourGraphData.lateFixedUpdate = new BehaviourGraphData.InputNode()
    {
        pass = behaviourGraphView.lateFixedUpdateBehaviourNode.CreateNodeData()
    };
}) { text = "Save" });

scriptable object:

public class BehaviourGraphData : ScriptableObject
{
    public InputNode update;

    public InputNode fixedUpdate;

    public InputNode lateFixedUpdate;

    public class Node
    {
        public virtual void Run() { }
    }

    public class InputNode : Node
    {
        public Node pass;

        public override void Run()
        {
            if (pass != null)
                pass.Run();
        }
    }

    public class CheckNode : Node
    {
        public Node pass;

        public Node fail;

        public Check check;

        public override void Run()
        {
            if (check.Evaluate() && pass != null)
                pass.Run();
            else if (fail != null)
                fail.Run();
        }
    }

    public class ActionNode : Node
    {
        public Node pass;

        public Action action;

        public override void Run()
        {
            action.Execute();

            if (pass != null)
                pass.Run();
        }
    }
}
#

probably shouldnt have pasted that all straight into discord sorry

compact ingot
distant tree
#

they are marked dirty, accidentally deleted that

#

ill try that tho, ty

compact ingot
#

would probably be better/more robust/predictable if you saved them to some json file

distant tree
#

maybe

velvet rock
undone coral
# abstract hill Hi everyone, I know this isn't strictly unity related but I'm unsure on the best...

Task using an async lambda expression. However it uses Unity engine logic so has to run on the main thread.
to run an async method on the main thread without unitask, the following works:

void Start() {
 var task = DoOnMainThread();
}
async Task DoOnMainThread() {
 Debug.Log(System.Threading.Thread.CurrentThread.ManagedThreadId);
 // you can await things here. you will continue on the same player loop you invoke on.
}

see https://github.com/Unity-Technologies/UnityCsReference/blob/af7ab1aae08dab2edd9924872080b505ebef0d8d/Runtime/Export/Scripting/UnitySynchronizationContext.cs

GitHub

Unity C# reference source code. Contribute to Unity-Technologies/UnityCsReference development by creating an account on GitHub.

distant tree
undone coral
#

@abstract hill alternatively, you can upgrade to unity 2023.1.0a21 or later, which has a working implementation of async await comparable to unitask

velvet rock
abstract hill
#

As I understand that that would only work since Start is running on main, but if the original invoke happened from somewhere other then one of Unities base funcitons (i.e from another task that is running in parralell) then is there anyway to force it to await and sync back up with the main thread?

abstract hill
undone coral
#

@abstract hill

// do not construct here.
static TaskCompletionSource<string> coordinate;
void Start() {
  coordinate = new TaskCompletionSource<string>();
  DoAsync();
}
async Task DoAsync() {
 var result = await coordinate.Task;
 Debug.Log(System.Threading.Thread.CurrentThread.ManagedThreadId);
}

// some other thread
coordinate.SetResult("test");
abstract hill
#

Could you explain a bit about what this is doing sorry? I've not really seen the TaskCompletionSource object before

undone coral
#

it is a promise

#

it stores a value of type string

#

you can wait until it has a value using var value = await tcs.Task

#

you can store a value inside of it using tcs.SetResult(value)

#

as soon as you do that, tcs.Task finishes and returns the value passed to SetResult

#

if the value is already set, await tcs.Task returns immediately as expected

#

construct the task completion source in the player loop you would like to continue on

#

do not construct it in another thread

#

the purpose is you must pass the tcs to the asynchronous work thread elsewhere

#

threads should never "return" tcs

#

does that make sense @abstract hill ?

abstract hill
#

I think so, does that mean that the main thread would be completly halted while the other threads are running?
So the logic would be:

Main Thread

  1. Create TaskCompletionSource
  2. Start Task
  3. Waits for the task to replace the value in the TCS
  4. Continues?

Other Thread
3) Task Started
5) Does some stuff
6) Sets TCS value

#

Or since the DoAsync is not awaited, does that mean that the main thread isn't halted but still returns once the TCS is done? Also does it matter what is set in the TCS or is it just that SetResult was called at all?

undone coral
#

you cannot await DoSync, Start is not async

#

you can declare async Task Start. see what happens

#

i think all this threading and task stuff has really confused you

abstract hill
#

Yeah, sorry I know I'm proberbly being a bit dense right now.

undone coral
#

it's okay

grim oxide
undone coral
#

async Task DoAsync() { ... } and DoAsync() inside Start is the same as StartCoroutine(...)

grim oxide
#

But it's not producing a time value that is correct

#

My naive implementation is to take distance-to-target and divide it by projectile speed. That is the time value I use to forward-predict the target's movement distance. This works pretty well, but it's not perfect.

#

However if I use the algorithm I linked to generate the time value, it's not even close

abstract hill
#

Also one final thing, what about the above code makes the DoAsync function run on main? Is it that it was started on main? Or is it that the promise was created on main?

#

For example, say I create the promise on main, then call the DoAsync task, but before I reach the point in which I await the promise I await a seperate bit of code that does cause DoAsync to shift to a new thread. Does this then invalidate the promise as a way of returning to main?

If so then I think I understand that I would need to seperate the code into seperate functions each with a promise to return to main. If its the case that the promise is the thing that is returning it then I can just use one function,
So what I mean is this:

Start()
    // Create Promise
    // Call Async Function

Async Function
    // Await some other code which does move to another thread
        // This is now running on that seperate thread
    // Await the promise
        // What thread is this running on now?
undone coral
undone coral
#

have you ever worked in nodejs or java before?

abstract hill
#

I've used Java but years ago in college, and that was very breifly.

undone coral
#

okay

#

so you probably do not know what a CompletableFuture is right?

abstract hill
#

I don't sorry

undone coral
#

i think what you want is UniTask.SwitchToMainThread.

#

because all of this other stuff is too complicated for you

#

and that's why UniTask.SwitchToMainThread exists

#

so you have to tell your colleagues that's how it's going to be

abstract hill
#

Yeah, if it was a peraonly project I think I would need to but I don't really have the option with this unfortantly.

abstract hill
#

Is there a resource that you know of that I could learn this?

undone coral
#

you can use new Thread() to create threads, and then inside those threads, write to a static and read it elsewhere

abstract hill
#

I need to since pretty much all the networking code uses it xD

undone coral
#

in an Update loop

#

i can only help in situations that make sense

#

using UniTask makes sense, not using UniTask does not make sense

#

i am sorry

undone coral
abstract hill
#

It's okay, sorry I'm not grasping things easily.

#

Thank you

velvet rock