#archived-code-advanced
1 messages · Page 45 of 1
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.
oh i seee i think i understand little now .. let me chk those Thx Mate
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);
}
}
}```
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
Was a neat mistake, instead of saying tsf.transform.rotation i need to say tablet.transform.rotation
I wonder why I can't use the transform instead of gameobject, both worked even, just the transform with mistakes
Use gameObject.transform, that would be tablet.transform and obj.transform
Oh, Thanks for the extra information
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.
you're on the start of a very long journey
reedit, the Raycast is a little buggy with update, if using raycast i should use the FixedUpdate event, because the Ground gets sometimes raycasted too
both works literally
delta time unity is calculated in a complex way. you can read about https://blog.unity.com/technology/fixing-time-deltatime-in-unity-2020-2-for-smoother-gameplay-what-did-it-take for some insights
you wouldn't usually use an idea like Time.deltaTime in the server
I am not sure why you need to synchronise your client with your server in that manner.
Time.deltaTime is important for rendering
it's hard to say anything more without knowing what the game is
Couldn't you clean that up by just using a normal timer?
are you saying you want to drag and drop a UGUI object? or do you want to drag across for some other UX experience?
Got it all resolved, but yeah, I drag and drop UGUI objects
Gotta have it work across platforms
okay
I moved all my platform specific code into one class and made one common API that #defines into private methods based on the platform
the gotcha for me was that touches are still in the array on the frame they end
it corresponds to the touches
the behaviour for double click dragging with a mouse is slightly different than fingers
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
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
the pointer ids are valid
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)
meaning whatever event you received, regardless of platform, even on old Input, you will be able to compare the begin drag pointer id
but a mouse can't be in a different location
not in my experience
multitouch just works
i mean it's upt o you if it ends the drag
it does if you program it that way lol
well, yeah, but i don't want to get in the business of trying to distinguish touches
all of my drag code sort of looks like this
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)
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
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?
Are you saying that because it sounds right or u've seen smth regarding it? 😛
I'm sure theres doc's somewhere but that is also how I think they work
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..
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)
domain reload?
that is different to what asmdefs are used for
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
Putting here just in case #archived-code-general message
@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.
the ones people keep bringing up are very real - lightmapping and navmeshes can be really annoying to deal with
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
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? 😮
you can do that, i would usually have the battle prefab right in the scene
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
What issue you are trying to solve by using prefab instead of Scene ?
to connect to the server, i toggle on my loading panel. you can use https://github.com/AppMana/appmana-unity-plugin/blob/master/AppManaPublic/InteractionToolkit/ScreenView.cs screenview, some abandonware i adopted*, to easily set up multi-screen UIs
so there isn't even instantiation. this is how it works in spellsource. it makes things way easier to design too, since i can always visualize everything in context
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
i had thought of that originally, but that seems like extra complexity for handling level-specific objects that's state can change - i.e. destroyed boxes etc. how do you get the same clean reset you would get between scenes?
yeah for the sake of simplicity that should prob be instantiated
fair enough, still cool though
for fun
in other games i've seen, the ephemeral stuff lives in a separate hierarchy from the static stuff
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)
{
}
}```
you have to do it that way anyway for something like MeshCombineStudio
i think we discussed this
@undone coralOh! I looked for my message after work and didn't find it.
I assumed it got lost.
@undone coralI found your materials. Thank you!
okay
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.
see: doctorpangloss
i just like learning new ways to do stuff
I'm block
No hard feeling.
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
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?
those mass army games look pretty cool
im avoiding DOTS like the plague
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.
yeah i'm not sure why they're trying to put C++ into your C#
why though
probably disorganization
something something masochists
I was block. Probably because multiple conversation at the same time. (There is no temporary hide in Discord)
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.
i can't think of a single piece of innovative gameplay that was enabled by manual memory management in C++. not one game.
jonathan blow is out there advocating for something something programming languages, but it's not "More C++"
gotta record it better
thanks for that, looking forward to the improved one aha
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?
it could be floating point error. Try compare with
Mathf.Approximately(rect.x + rect.width, rect.xMax)
I'm not trying to ignore the Epsillon. I want to know what is causing it.
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?
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.
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
I don't think manual memory management is the main motivation for HPC#, being able to write C# yet still get near native level of performance with vectorization is desirable.
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.
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.
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.
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
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.
Is a lambda findObjectOfType the same as doing it on Awake()?
Example
public Foo FooManager => FindObjectOfType<Foo>();
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
oh really so its not a once and loaded?
its a constant reference?
or a constant refetch
no caching?
since you are not storing the returned object from FindObjectOfType into a field, no
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
and the auto property is the traditional
FooManager => FindObjectOfType<Foo>();
and its a standard declaration at the top?
Gotcha
no an auto property would look like public Foo FooManager { get; private set; }
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
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
using => in this way is using expression body syntax for a read-only property
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members#read-only-properties
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
anyway, this isn't really advanced. so if you have further questions about it then ask in #archived-code-general
brutal.
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);
}
}```
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 👻
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
...
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.
Useful for rolling back changes
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.
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)
🥲 Why no one have Sekiro rope rapper lol.
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?
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.
[ServerRpc(RequireOwnership = false)] i think is what you need, that lets any client run the ServerRpc (if that is how you are sending the movement data)
I Finnaly Made iT
Skeiro Rope 🙂
It can be use to detect cheat, perform rollback or even just analytics to know what is happening in the game. It really depends on what you are dealing with and what you want. Data storage is not really expensive, you just need to manage them well.
Personally, I had to setup a small analytic report for balance purpose. To know what the player does in each level.
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!)
This question should not be in this channel.
Use minimax algorithm. https://en.wikipedia.org/wiki/Minimax
there are tic tac toe AI tutorials aplenty online. Imagine if you'd tried chess! 😱
I got ignored in the general coding channel, so I expected that it was to hard for general...
follow one of those tutorials
I can not see what are trash tutorials and ehat are gooodys if there are only likes visible.
500likes.... 20k dislikes?...
I can assure you all of the tutorials will be better than your if if if if if attempt
I stoped using youtube, because there are so many scams you can not detect because of the missing dislikes.
Sounds like you just hang out on the wrong parts
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...
can take a bit of experience to get a feel for which are good and which aren't - typically anything that tells you to "just type in x like this" is an immediate red flag
as for your question, you can look up the minimax algorithm as a starting point for a simple game decision "AI"
ah, someone already answered you, nevermind 👼
TicTacToe was just one of many issues, but after youtub3 disabled the dislike, it got so hard to still find specific tutorials without wasting the time because the youtube itself creates spagethi or endless many if if if if.
But 50 likes seems good....
The viewers dont knoe it even better thats why they like or there are maybe 500+ dislikes you can just not see.
there is SO MANY good tutorials on youtube tho
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.
also REALLY no offense but i dont think this belonds in #archived-code-advanced
Thats the curse of something getting started and drifting away in another topic somewhere, I knoe its bad, sorry...
well even then i wouldnt really call tictactoe ai super advanced idk
let this guy have his question tbh
I just got ignored in the general channels, so I thought thats maybe to hard for them to ask them this question.
try #🤖┃ai-navigation maybe no clue
Still thanks...
oh I might have fixed it
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.
without any code it's impossible to say what's wrong
what are you trying to do? big picture
What did you change?
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
All of Unity's documentation on this seems mostly wrong. As far as I can tell all of their examples would consistently leak memory.
it doesn't make sense to have using in async IO without await
it is an async, my signature is public async Task<BattleResult> CompleteBattle(int gameId)
you can't use plain async await
and I do this in the using block: var operation = request.SendWebRequest(); while (!operation.isDone) { await Task.Yield(); }
you must use unitask
this is wrong
async/await are not supported?
this is why i said you have to post the whole method
it is supported
sure I can post the whole thing
{
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); }); }); }
okay
which seems to work and not block the main thread, but if there is a better way to do this I'm all ears
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
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
can you give an example of how I would consume that?
is there a way to do it without StartCoroutine?
FightBattle(010101).Forget();
you don't need start coroutine
ah cool
oh yeah i need to replace that it was mostly just to test out the api results
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
still interested to see if you get the time!
standby
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?
are you familiar with the hierarchical state machine? Thats my goto for scalable state machines.
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...
I would recommend looking into command pattern, this can enable you to read history for combos.
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.
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
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.
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"
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
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.
wouldn't disagree at all - in fact I'd say this is likely ideal
@brave bear you risk crippling yourself trying to design the perfect solution before actually getting to writing anything!
the best laid plans....
Yeah that makes a lot of sense, thank you! After I refactored each state to be it's own monobehaviour (instead of a plain class) I saw a lot of potential in the FSM pattern for Unity. I'll refactor it now to have some common abstract classes.
crippling myself trying to design the perfect solution is what I'm known for!
lol
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
I end up NOT making my states monobehaviors, simply because I like to set the next state with something like currentState=new GrappleSwingState(some data it needs);
oh god
picturing states as monobehaviours has actually just made me sick, thanks
lol, mean!
I'm not saying MonoBehaviours would be better here, but if your states are classes that seems like a lot of garbage collection 😬
hmm.. I always though it would be just one object (the currentState object) when the state changes, that would need to be collected... no?
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
true enough but that's not how they're doing it here: #archived-code-advanced message
thats a good idea
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.
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.
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?
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.
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
I can't disagree.
Sounds like you would profit from using events or a service provider pattern
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
I'm designing a solution for a player controller... 2D action roguelike game
do you mean an x-y 2d platformer with megaman/metroid/castlevania conventional platformer controls?
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)
okay, so like hotline miami
is there a specific game you are referencing?
are there any retro games' mechanics you are trying to recreate?
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.
okay
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
I'm not sure what exactly do you mean by that, but I don't think we want to borrow too much from retro, no. This is a modern game.
yes, I have three artists working on it, but why do you ask?
is your camera projection going to be "cabinet"
like Streets of Rage?
or something else
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)
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
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
in unity i would lay this game out in 3d
so the world would technically be 3d and pretending to be 2d
there might be K+M, and controller support (joystick, arcade stick, gamepad)
what will the mouse do?
i would say this has more depth in the Z direction
one of the main mechanics will be a hookshot, so you can target enemies/obstacles to pull yourself into or pull something onto you.
there is an ongoing discussion right now on how should we approach this. So we are not sure about it yet.
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?
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
is the idea "streets of rage 4, but with the design space of overwatch heroes, in a single player co-op campaign, networked multiplayer" ?
so we're going for something similar
no, this is more like "Hades, but with an actual deep combat system, that is more like Sekiro than hack&slash"
easy to play, but hard to master.
hmm
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.
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
no, the game is single player only, with a very strong narrative. A rogulike action game.
sure even if it is single player
is that how big the design space is?
basically realtime RPG spells?
well technically the design space is enormous, definitely, it all depends on the scope we decide to go for
okay
are you familiar with the term gameplay attribute system, from unreal?
or have you guys worked on something like a digital card game
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
okay
will players need to carefully time jumps to advance through a level?
lol
like is finesse with their controller important for this game?
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
hmm
we want to be very precise with input, frame data, etc.
okay
do you expect your audience to have already played streets of rage or a similar cabinet style game?
not necessarily
this is like asking if the hades developers expected their audience to have played pyre (yes) or diablo (yes)
interesting Q- why do you ask this?
Yeah, I'm curious where are we going with this ^^
my takeaway is that this is mechanically very retro
I mean, it doesn't really mean anything to me, so sure, why not? let's say it's very retro
and player expectations are pretty rigid when they have these retro experience
hmm
experience with retro titles*
alright?
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
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.
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
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?
what's the relation between gamefeel and architecture,
😬
i'm not advocating for something to be poorly written
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)
- 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
}
whom is this for? you?
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?
right now we have me + one other guy, I don't expect the number of coders to go more than 3 at any time.
hmm
well only 1 person is going to be able to author the movement code
for a retro gamefeel game
That might be true, I've seen code like that hundreds of times, but that doesn't mean it's the optimal way to do it right?
in my opinion, it is optimal for retro gamefeel
i don't author retro gamefeel games
why? performance reasons or somthing?
the tight coupling is essential to the feel
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...
i am trying to avoid any normative opinion on good or bad practices here
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?
just the positivist opinion of goals. like for retro game feel, the way things are coupled lends itself to a very specific architecture
alright, you are stating it as a fact, but I don't see how one leads to another?
well without going into too many opinions - like i said i do not really author this kind of game - my impression is that to nail the movement of megaman or diablo, a lot of the "micro" / details / small features of the movement are emergent from the tight coupling and "updateloopese" of the underlying implementation
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.?
i can only speak to what i've seen in actual source code
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
big update loops happen in many games because developers write them like that, often because they don't know how to do it better
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
this is pretty low level in the expanding brain meme of this opinion
maybe! I'm very inexperienced in game dev, so maybe I'm at this low level stage right now
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
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
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
I think that if I put everything into a n update loop, the script will become unmaintainable after three months
or even faster
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
yep
I'm not very familiar with those terms
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
you can't jump in this specific one
yeah
but yeah generally you can
it sounds like the place you want to innovate is in the abilities
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?
i am only talking about the movement
which is what you were discussing earlier i think
well, we were discussing Player state generally, so all of them
hmm
including parrying, grappling hook, being stunned, attacking, etc.
this is simply telling me that building this game will be very hard lol
that's good, I don't want it easy
I can definitely agree with that
that's why I'm spending my time to think about the correct abstraction that will be best
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*
that's what I'm worried about, yes
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
we want to have 2D art for sure, but still a 3D world you would recommend?
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)
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)
sure your art can definitely work that way
but I'm not sure that plain 2D is the right choice
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
we're using rigidbody MovePosition right now, but this is very early stage
in my opinion, using KCC for emergent behavior in your cabinet game is more interesting, but it not retro
yes, it goes without saying that will not work
you will not be able to use rigidbodies for movement at all
I actually prefer at least some saying since I'm new at this xD
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
so you would recommend for us using KCC and 3D world, alright
the two are really strongly related - the lack of abstractions and the movement style
I appreciate advice and I will certainly take it into consideration
i think if you want something with a lot of design space, or you're not sure yet, kcc is the most "in control" character controller for 3d
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)
huuh, alright, I will try to do that
for example, in 3d, with kcc, using a cabinet projection
like clearly there will be different apparent velocities
I'm not convinced about the lack of architecture, but if no great idea comes to me, I will be trying that as well
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
I think the y velocity is the sin(alfa) * x velocity where alfa is angle of the camera perspective
well... you won't know until you look carefully
+- what feels good
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
yeah we will be doing that sort of research I guess, no way around it
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
yeah I've never played with a controller as well
so i'm not really representative of the audience. people who like controller games like to be rewarded for mastering that skill
hmm
but we found that a lot of playtesters already demand a controller for the prototype
well go nuts then. i mean focus on what you think is fun
yeah... listen i'm not wrong
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
what are you trying to do big picture
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
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
what sets this flag to false? transform.hasChanged does it need to be called in Update for example? always true with zero transforms set
You should get my browser extension so you can see nice community notes like the one that answers this question
https://github.com/Developer-Notes-Extension
hasChanged needs to be set to false by hand
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
Visual scripting -- any form. Single goal of 'can be used for both gameplay and cutscenes' will be good enough
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.
It just doesn't work that way
What would be the best way to check if an object is no longer inside a collider then?
OnTriggerExit
if your object is being disabled, you're disabling/deactivating it too
so you can handle that case separately
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.
Yeah you will probably need to building to have an OnDisble function that lets the system know that the location is available again
Yep just use OnDestroy or OnDisable on the building
Not sure I follow.. because if the building is being spawned inside the OnTriggerCollider or Being disabled inside it . The onTrigger isn't going to fire off.. unless im missing something, lol.
I'm assuming from your earlier description that you are trying to detect when one of the buildings moves out of one of the 3 spawns so you know that the spawn is free again right?
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
Yes, mainly the despwaning.
so then you just do the same thing in the building's OnDisable (or OnDestroy) that you would have done in OnTriggerExit
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
i meant inheritance map. inheritance.. tree. i dont know what to call it exactly
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
I gotcha now.. it's weird that OnTriggerEnter I can spawn the object and get it to work but despwaning it on OnTriggerExit doesn't work, lol .. I got it working in my test So I think im good now Thank you! 😄
but what if one component relies on another? That's kind of why I used an inheritance hierarchy in the first place
You can have scripts depend on each other without inheriting from each other, that's easy
but what about interfaces?
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
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...
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
yeah
my graph looks a bit like this
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
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)
hello chat
rendering uses a lot of CPU even though my scene is empty, any suggestions ?
Look in frame debugger mayhaps.
If your graph represent Hierarchy, you might want to review it.
Object Oriented Programming tips:
- You should use the repository pattern for your DatabaseItem. https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design
- The HasInventory should be a component. https://en.wikipedia.org/wiki/Composition_over_inheritance
- From experience, NPC and Player should not inherit from Mob or Character. Instead, picture them as driver for the character/mob. You might want an NPC that controls something else than your standard Mob, same for the player.
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.
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
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
then that will create normals with seams/hard edges
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
i see thanks
i did that before, it creates normals with hard edges where duplicated vertices are
and both uvs and normals have to be the same length as vertices array
are you using Mesh.RecalculateNormals() ?
yes
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
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?
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.
( Nothing to do with the gif by the way )
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?
of course
one easy approach is using Google Sheets or Google Forms
do you know a good tutorial i could follow?
you could just enable comments on the itch page
its pretty self explanatory https://www.google.com/forms/about/
Use Google Forms to create online forms and surveys with multiple question types. Analyze results in real-time and from any device.
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?
It'll block the running thread until completion. Use result = await commandResult;
🍒 @fresh salmon thank you
Just curious now... any idea how it knows to extract the .Result member from the Task<CommandResult> commandResult? (I'd get a type-mismatch compiler error WITHOUT await)
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
''syntax sugar'' ah, thanks again!
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();
}
<> what the heck? NEVER seen that in actual code afore.
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
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?
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.
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?
Can I launch an iOS build on my iPhone without registering as an iOS developer? How?
no- you need apples permission to run your own program on your own device
You can build to a device directly without a dev account, yes. How, just look it up. First google hit:
https://betterprogramming.pub/test-your-unity-game-on-an-ios-device-without-a-developer-account-ac256fb00a1?gi=b8a94696d063
Also #📱┃mobile
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.
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.
converting to Entities is way more quirky than you can anticipate with basic gameobject/OOP code, Entities are cantankerous!
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
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
its usually a bad idea to plan for problems you will not have
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
Is there an Authoritative server style expert here?
you're not supposed to ask for availability of people, also #archived-networking
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.
I wasn't asking for help. I was asking for opinions.
looks like you are running into basic networking issues, you probably find answers to similar problems already answered in #archived-networking history
yeah, my problem is that my code is not modular and decoupled and so it is getting hard to replace systems that have become aged, which is the problem I forsee me having and the problem I seek to solve by componentizing my code
you can always rewrite (the whole thing) 🙂
thats what im doing
@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.
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.
I’m generally an advocate of going authoritative regardless of whether you need it because it’s a cleaner concept
Perhaps you’re right. I should just leave it alone and if it becomes an issue later I’ll deal with it then.
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());
}
also i have searched online regarding UnityWebRequest.Dispose(); but there is no such example, instead i got directed to this link which advise me to use 'using' instead which i have tried but got defination error instead on UnityWebRequest. https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest.Dispose.html
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.
like this? https://morioh.com/p/530cd2a44576
any recommended tutorial i could read through for UniTask/UniRx?
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.
The C# async / await workflow can simplify your code and give you more granular control over your game in Unity.
Learn how to convert your current coroutine workflow, what a task is, how to run sequential and synchronous code and how to return data from an asynchronous function.
UniTask: https://github.com/Cysharp/UniTask (Provides an efficien...
thanks
If you are looking for UniRx, I believe @undone coral knows quite a lot about it and has better recommendations.
That's ok 👍
same as UniRx? so i only need to apply UniTask for my code?
but what is the difference? i just want to solve my memory leak issue for UnityWebRequest
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.
just watched finish the video, the youtuber said that UniTask does not work on WebGL, is it true?
cause i plan to make my game in WebGL
You should checkout docs at least, not just watching videos which might have outdated information.
https://github.com/Cysharp/UniTask
Runs completely on Unity's PlayerLoop so doesn't use threads and runs on WebGL, wasm, etc.
ok reading through
wait i need to download that code from github to use?
the youtuber never said anything about downloading stuffs
It has instructions there, you should be able to figure out the rest on your own.
stuffs
well... you better get used to downloading stuffs
i think i answered this exact question earlier
ya but it was not resolved, cant let it sit around
take a look at this thread: #archived-code-advanced message
ya im remodifying the coroutine script into async unitask, just need to figure out how to call the unitask function to test the script
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'
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);
}
}
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?
i always use the package and commit only with one Unity. I found it less comlicated than merging stuff
interesting perspective
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
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
got it, so your package itself has another package inside
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
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
then you add the packet to your .unitypacket on export
everything in the Asset folder you can include
got it
hey. how'd you decrypt a JWT token in Unity?
tnx but the class is unavailable in Unity
think I haven't already searched that before coming here?
It does look that way
I have not tried it, but the first one is maintained by Microsoft and supports NS 2.0.
there seems to be some pragma key defining issues with it in unity
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
they're supported in IL2CPP and for an android build?
There are more than 1 search result
As the name suggests, IL2Cpp just converts IL to C++.
point taken 👍 will try the dll then
there sure are. very smart observation
Are you on .NET Standard 2.1 by any chance?
Latest Unity is on that AFAIK
not standard 2.1, no. my Player settings is set to Mono||.Net Framework
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?
For a generic/remote client use case https://docs.unity3d.com/Packages/com.unity.renderstreaming@3.1/manual/index.html
For local networks https://github.com/keijiro/KlakNDI
I probably should have mentioned but the machine I am sending to, does not support Webrtc, which I assume what this is using
Then you need to spec your problem better, what platform do you have for the client?
I specifically mentioned RTSP tho.
Hi there
does anyone know if there's an event to listen to for when the UI was completely rendered?
This implements the protocol, the rest (encode/decode) is also supported by various assets/libraries https://github.com/ngraziano/SharpRTSP
UI renders as part of the normal render pipeline. It’s not treated separately
maybe I should specify, I'm trying to the moment when the UI rects are properly constructed inside layout groups, because I'm dependant on their sizes and they're finished after Start
You can force update them
Otherwise they are complete in late update if all changes are applied in update
It’s required behavior for performance reasons
Automatic Multi pass layouts would be too expensive
jeez, all that just to track navigation manually for nested UI elements
Whatever that means
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
Indeed, that’s a gnarly one
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
Im guessing the specific UI setup is generated dynamically and will differ from run to run?
Only in child count
The panel I've built is rather static and only gets enabled/disabled. But once shown it generates the content inside a GridLayoutGroup
the content are just a bunch of identical buttons
at least in transform
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?
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
do the buttons currently know who their neighbors(the buttons they are actually supposed to navigate to) are?
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
ah, I meant for your custom scripts on the buttons
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
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())
?
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
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
yeah that struct is only for holding references to other selectables
Canvaselements have hookable events for both graphics update and layout build, it looks like
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
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?
you have to get the mouse position and make is to world point
Vector3 mp = Input.mousePosition;
mp = cam.ScreenToWorldPoint(mp);```
after that you can use LookAt function to make the card look at the mouse pos
```cs
transform.LookAt(new Vector3 (mp.x , mp.y , transform.position.z + 10 ))
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
i didnt understand the question , do you want to lerp it or clamp the the mouse y axis ?
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
did you look at the RTSP asset in the unity asset store?
for receiving
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.
you'll figure it out! start in #archived-code-general or #💻┃code-beginner
you can explore the forks https://github.com/monry/JWT-for-Unity/network for this and find one that's updated
JWT (JSON Web Token) implementation for .NET 3.5+ (Public Domain) - Network Graph · monry/JWT-for-Unity
in principle you can do this yourself, since you know the algorithm the tokens will be issued with
I only need sending
sending? don't you mean receiving in unity?
oh
right
it sends too doesn't it?
i think there are also paid services that may alleviate your pain a bit
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
something along those lines ^^ probably even less if we consider testing and publishing
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.
You can’t. Use interface instead
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.
If they're generic they're essentially different types, so whatever you plan to do with them is likely able to be abstracted into a non-generic interface.
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
There's also:
interface IFoo {
// ...
}
interface IFoo<T>: IFoo {
// ...
}
I do wish we had IFoo<_> though.
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?
My armchair general advice would be: higher FPS = less work per frame on the CPU. Overall, I'd say Tris and Verts look pretty high for the result if I assume a benchmark to be my laptop on those metrics alone. If you want better advice, you might hire someone to run through the profiler on your own hardware and look at any specific bottlenecks.
If this is running on a phone then my god man, you've solved time.
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
This does not run on a phone at all sadly. Like <5 FPS
your numbers look bad to me. 10.1ms for 1512x850, almost 4k batches, 1.2m tris
What is the most obviously large stat? I'm still new to these. I know for tris/verts I need to optimize the meshes
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.
I made quality settings for this game, and when you use the lowest quality setting, it's this:
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
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
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?
If I see correctly, TextMeshPro is doing a lot of things that result in those drawcalls. But its still very optimised and should not be an issue. Or did you run into any?
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.
Nice to know that we got Awaitable api now in Unity. so coroutines can go die in a ditch 
How does this work with main thread stuff like instantiating stuff?
async/await is not the same as multithreading.
And they don't respect Unity LifeCycle I heard.
Hello there
does anyone know a way to figure out if UI objects are currently visible within a ScrollRect?
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.
Cool, I misunderstood and thought the mention was await and async keyword. The Awaitable API seems great!
what's the point of EventHandler ? Action do the same thing but doesn't require the object sender parameter that is never used
Nothing, as you said it is just an Action delegate with extra argument, object argument
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.
Object sender is sometimes useful when you want to know which instance has raised that event, it is like an identifier
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
sounds like you want to use a Dictionary
that's not a bad idea.
But is it correct to have as values such large texts?
100+ words each
i mean as long as it works it works
I think that should be fine
haha that aint true:P
Alright
I'm going with this approach thank you 😄
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
what is your objective?
like what's the gameplay
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?
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
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...
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
their sample has some more configuration done for the logger which I assume is why it's not logging to console, did you see this? https://github.com/KuraiAndras/Serilog.Sinks.Unity3D/blob/94c67bac8221f20373bab87b989640f0a8062941/Serilog.Sinks.Unity3D/Assets/Sample/Scripts/SimpleLogger.cs#L24
your classes arent marked serializable and you need to mark them as dirty to actually save anything
would probably be better/more robust/predictable if you saved them to some json file
maybe
Okay I tracked it down to probably needing a custom sink. The calls Information() and Error() are working, but not ones like Debug(). So it does work atleast.
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.
}
cleared some errors but still doesnt seem to be working. ive tested it in edit mode so i know the code works as long as the data isnt cleared
edit- actually it might be a problem with the Action and Check classes which are in separate scripts
@abstract hill alternatively, you can upgrade to unity 2023.1.0a21 or later, which has a working implementation of async await comparable to unitask
Never mind even stupider than that. I didn't realize Debug is a lower level then information.
no, still not working
What would be the solution if the task was originally invoked on a seperate task in the thread pool?
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?
This is intresting, I'll need to take a look. Unfortantly I don't think work will be all to happy with upgrading the project. :(
you can do something like
@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");
Could you explain a bit about what this is doing sorry? I've not really seen the TaskCompletionSource object before
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 ?
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
- Create TaskCompletionSource
- Start Task
- Waits for the task to replace the value in the TCS
- 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?
why would the main thread be halted
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
Yeah, sorry I know I'm proberbly being a bit dense right now.
it's okay
Any math brains can explain to me why this algorithm isn't working? https://web.archive.org/web/20190118140922/http://wiki.unity3d.com/index.php/Calculating_Lead_For_Projectiles I don't really grasp the quadratic equation stuff
async Task DoAsync() { ... } and DoAsync() inside Start is the same as StartCoroutine(...)
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
Right, does async Task DoAsync need to return Task? Or could this be void? I've seen a few examples of this sort of thing but usually if its not required to be awaited it just returns void.
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?
okay, maybe it's easier if you forget everything you think you know about tasks
async methods should return Task or Task<T>.
have you ever worked in nodejs or java before?
I've used Java but years ago in college, and that was very breifly.
I don't sorry
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
Yeah, if it was a peraonly project I think I would need to but I don't really have the option with this unfortantly.
then do not use Task
Is there a resource that you know of that I could learn this?
you can use new Thread() to create threads, and then inside those threads, write to a static and read it elsewhere
I need to since pretty much all the networking code uses it xD
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
I book marked that to learn later!