#archived-code-advanced
1 messages ยท Page 41 of 1
i suppose you could just put all your prefab content into your scene and bake it.
and then it will Just Work
you'd have to put all the prefabs in the scene and bake it
yeah
sounds tough. sounds like, i don't know, 5 minutes of work
5 minutes is horrible
it would all be on top of each other and wouldn't bake
i guess you'd have to space it out or something
might be another horrible 5 minutes
then it can't move
๐ฅบ
can't instantiate it elsewhere
it's baked in the scene at its location
vs just putting your environment content in a scene, loadlevel additive async, then unload when you're done
and you're in the same hub scene
I guess scenes are useful insofar as it's a tool that's already in place to use for static environment loading/unloading
i don't really want to litigate lightmapping. unity's lightmapper sucks, there's not much to say about it
it is almost as bad as scenes
you cna split a giant environment into cells and load/unload nearby ones as you move around
So, in conclusion: people have learnt to do things different ways, both work, both have benefits, and both take at least 10 horrible minutes to setup
and it'd be a huge pain from an artists perspective to work outside of scenes since they allow you to view what's going on in the level vs procedurally working on individual items
you are welcome to deal with LifetimeScope
if you are on a team of 10 people or fewer, and you're the engineer, it's really your decision
you're the Actor in the hollywood movie metaphor for video game development
yeah, I cant imagine a project with 1 scene would go down well in a large team - I wouldn't know thuogh
if you want to constantly work around scenes go for it
prefabs are the same thing
they have superior features, like variants, that make more sense to everyone anyway
besides, large teams in unity... are we talking about engineers? artists? level designers? people who don't know how to use git? you will have bigger problems
it's not scenes
do what you need to do
i've never heard of LifetimeScope
once i heard it i knew you were like
in bad code smell territory
i just want to help you
Thanks - I'll be sticking to VContainer. It has it's drawbacks - and also the first time I'm using DI in a project after vehemently steering clear of it - but I'm a fan of learning new ways of doing things. The company I currently work for also handles DI using a similar framework, and I feel like learning about what's actually going on there will be a benefit in the long run. Appreciate you though
well in my experience dependency injection has never added value in a unity application
Well I for one am still thinking about the differences
you only have 1 implementation of everything
and you own all the code
you can make changes to anything you want
an access modifier is essentially documentation, for example - since you have all the source, go ahead and modify the access from private to public if you want
DI in unity is a code smell
I like removing the cross scene references. Trying to think of drawbacks to using just prefabs
Other than having to make a manager that loads/unloads your prefabs for you
yeah but you have to do that anyway
you eventually, somewhere, have to write code that decides what is on screen
it doesn't matter if that thing is a scene or a prefab
Was tracking of instantiated objects already mentioned?
new scenes let you start out at a position 0 location, if you're in 1 scene you might hit integer imprecision eventually
that's not something you should really be worrying about
this unity open world game genre... i'll just say that there are limited audiences for the colossal terrain game
How do people typically implement mod support in Unity games?
True, just trying to think of what I can
they target mono on pc and mac, and use C# features like assembly loading at runtime to add code to the game
love this edit, lmao
Thank you
doctorpangloss, I'll be back eventually to tell you that this was a shitshow and I won't be touching DI again, I'm almost sure of it
but you can't learn what to steer clear of and why unless you do it
at least I can't, lmao
i usually add to a set in OnEnable / remove in OnDisable...
lol
yeah that makes sense
the greatest feature of prefabs is prefab variants
it obsoletes "scriptable object architecture", scenes, etc.
it makes a ton of sense
mate I love SO architecture ๐ฎ
yeah...
you'll have to show me some stuff one day
i am interested, but currently trying to tackle DI, networking, and the new UGS stuff in my spare time. If I bring another design architecture on board, I'll breakdown and move to UE
lol
okay well i think a lot of this stuff exists because it helps people think, not because it's a good way to engineer a program
that's definitely beneficial
I had some trouble with getting my networking flow + scene changes to work
Took the lazy route and just went with 1 scene
even though it makes no sense to have a menu, lobby, game scene
there is a huge amount of busywork to make those things work together
due to scenes
same with SOA - it truly makes no sense, but it does help people to think
UGS
there is no such thing as an easy to use networked multiplayer sdk for unity
photons pretty easy
who said anything about easy to use? ๐
well, what i mean is, there's no sdk for realtime networked multiplayer that compares to the ease of use of e.g. starcraft 2 map editor
where you don't have to think about networking at all
I just like that there's finally something dedicated to DGS rather than P2P. honestly sick to death of all the shit out there that teaches networking, but only in the context of P2P
yeah it still takes a lot of knowledge
but their cloud thing was really easy to use
easy to hack too but yeah
multiplay?
my technology streams stadia-style each user in a shared executable, so to make a networked multiplayer game in this architecture, you don't have to think about networking at all
PUN2
you can try it here - https://appmana.com/watch/oreo - we just share the same scene for multiplayer
and it's obviously networked
in the sense that you and i are in different physical places
but from an engineering point of view, it's local multiplayer
same as sc2
im a networking noob, so nothing you said makes much sense to me at all
Biggest issue with P2P is the prevalence of carrier-grade NATs. Gotta have some sort of backup relay system even with turn
Video streaming local coop games
or use a service that provide the relay for you as needed
with distinc tcameras
the editor experience lets you easily test two players - https://www.dropbox.com/s/w9qq40jb92a0ngw/Editor Experience.mov?dl=0
this is for https://appmana.com/watch/unity-starter-hdrp
An AppMana Streaming Experience
and that's fine? no issues with latency (i imagine not) or quality?
which shows rigidbodies interacting with each other
it's like webrtc
one of the only game genres where that really matters is an FPS, and you wouldn't stream nor build that in unity anyway
mobile has crap internet
you're welcome to try on LTE
*potential
like driving down the highway, I'm on wifi atm
The latency and quality is most likely similar to other dedicated streaming services
anyway i spend a lot of time think about this stuff
we had to make a prototype VR in a car flying down the road, nightmare
yeah
generating stuff around you with mapbox
and then... for what audience?
mobile carrier
they wanted to sell this 5G device for your car and prototypes to show off potential
yeah
terrible idea
these non technical hype driven product developers at companies are nuts, but come through with budget
well the people who use that streaming tech you see does make sense, has an audience and has a budget
but it's still very hard
in fact the problem is good ideas, not good opportunities
like i would love a good multiplayer game demo
How does the input lag feel?
I tried playing an FPS using a friend's Steam Link
really depends on the interaction. you can try this https://appmana.com/watch/virtualtestdrive and tap drive on your phone
An AppMana Streaming Experience
While the ping was pretty good the video lag meant that you didn't get snappy responses you'd normally get due to the client simulation
yeah, i mean this is not a suitable approach for FPSes
but the world does not need more FPS experiences
Oh right, expectations are different for phone interactions. Thanks for the info ^^
but generally, we don't need more walking simulators
even as an indie game developer
i hope that this approach, where you don't have to think about networking but get a networked experience, means people can do innovative stuff
especially since unity's superpower is making games built around physics
and you would need an Overwatch sized budget to make good networked physics
using this approach, you Just Get Networked Physics For Free
Anyone using UIParticle (the coffee library) and ShaderGraph materials successfully? I'm trying to debug this guys code and I'm just.. lost as to what he's doing, and the library is behaving badly. Can't even tell if it's just editor stuff or in-game stuff. Like, particles are "overwriting" the material in the shader? I have no idea how or why or where to even start debugging this one...
that's from the windows build.. exact same code in the editor doesn't even render particles (or it does but they slowly darken??? over time)
(the "flickering" is normal, but the streaking of the background particles "wiping" the material vertically is not normal)
here's "normal" flickering (with the particles turned off)
this is the lib: https://github.com/mob-sakai/ParticleEffectForUGUI
Alternatively, anyone have a good particle library for UGUI? ๐ฌ
That's a very interesting framework to look at
My code is:
characterPrefabs.Add(Resources.LoadAll("CharacterPack1").Cast<GameObject>());
characterPrefabs is a list and I'm trying to add all prefabs in "CharacterPack1" folder to it.
I get the following error:
cannot convert from 'System.Collections.Generic.IEnumerable<UnityEngine.GameObject>' to 'UnityEngine.GameObject
Any help?
LoadAll returns a list of GameObjects, you are trying to add a list to a field of a single object
You need AddRange
not Add
If you want to add multiple things at once to a list
this is the one i use
@undone coral What version of unity are you using? I'm on 2021* lts and it's just firing zillions of errors into the console
never tried it in 2022
2022 is scary
2021.3.16f1
hmm
i wonder what spellsource uses
i haven't see spellsource ui particle effects in a while since upgrading
I can't decipher this library's editor code so.. aside from a superficial look, I'm not even really going to try
But you're using the same lib? by mob-sakai?
As far as I can see, he's disappeared from the planet a few months ago, maybe
looks like he's there, right? but..... his activity is in this repo
some sort of github auto activity thing? i dunno ๐คทโโ๏ธ
it's working correctly in spellsource
those are UIParticle particles
@misty glade i use 3.3.5 so an older version
I tried to look at the git blame around where the errors are going back to 3.3.5 and unfortunately, there's just too many changes for me to easily see what the issue is.. Basically it's throwing dozens (one for every particle system in the game, it seems?) for every editor ongui.. so yeah, moving my mouse around even generates hundreds/thousands of lines in the console. I'm sort of at wits end with this library though and tempted to just find another.. there's at least 2 more that I surfaced in a quick google.
I just hate refactoring in/out libraries like this.. let alone the work in getting all my particle system prefabs into the new system.. and we are aiming to launch in 11 days
I'm just turning off this particle effect for now and gonna dump this on some other future-me to deal with later. ๐ฆ
Thank you, that makes sense.
I will try that now, thanks
Does anyone know how to test a script that gets data from an API without using an API
Get an example api response and use that as default string to load into your script. I assume its json
Yeah its json
Then just save an example API response, put it in a stringfield in your inspector and use that instead of requesting the webrequest resposne
Alright ty
Created this Scriptable Tile:
[CreateAssetMenu(menuName = "2D/Tiles/QuestionMarkTile")]
public class QuestionMarkTile : Tile
{
[SerializeField] private Sprite spriteAfterTrigger;
private Vector3Int _pos;
private ITilemap _tilemap;
private QuestionMarkTileMB _mb;
private bool _triggered;
public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject go)
{
_pos = position;
_tilemap = tilemap;
_mb = go.GetComponent<QuestionMarkTileMB>();
_mb.OnTriggered += OnTrigger;
return base.StartUp(position, tilemap, go);
}
private void OnTrigger()
{
Debug.Log("Sussesssssfullly trihhered");
_triggered = true;
_mb.OnTriggered -= OnTrigger;
RefreshTile(_pos, _tilemap);
}
public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
{
tileData.sprite = _triggered ? spriteAfterTrigger : sprite;
base.GetTileData(position, tilemap, ref tileData);
}
}```
The problem is that it appears to be used for all of the tiles created under its name, meaning that if I do something in it, it happens on all tiles based on it. How do I change it so that there is a separate instance of this script for each Tile on the screen?
I don't think you can easily. Scriptable objects (like tiles) are supposed to be used for immutable data and share an instance.
You'd have to instantiate a copy of QuestionMarkTile tile for each tile at runtime and then set the tile to the new instance, this is not really what the tilemap system was designed for so i imagine this could have performance implications if you have a lot of different tiles active at once.
As an alternative you could have a dictionary with the position as the key and then the QuestionMarkTileMB as the value (or some class/struct of data), and trigger the right MB through it since you should know the triggered position
Though i'm not sure how that'd work with your sprite change
(you might need to change it to a different tile instead of changing the sprite since that would effect all tiles of the same type)
I don't think I would ever do that type.GetType() mistake, but you never know...
I think I fixed it. Basically I have a static ctor that mimics an OnUnityLoad or OnUnityBoot (with SessionState) behaviours. That static ctor had a bunch of methods, some that apparently were not supported in a static ctor context. I just shifted those methods that created some objects to the custom framework's editor window script.
I usually can debug things. But this error was new to me and had no real explanation. ChatGPT was just insisting in static ctor examples and so I reviewed all my static ctors
What you can do is have a Tile class be declared in a ScriptableTile and set it's values there. And, whenever you need it, you instantiate a copy of that Tile. You'd have to probably create all the copy constructor / copy methods, replacing methods, etc...
A copy method example:
public Tile Copy(Tile tileToCopy)
{
var newTile = new Tile();
newTile.position = tileToClone.position;
newTile.subClass = tileToClone.subClass.Copy();
newTile.owner = this;
// ...
return newTile;
}```
Any idea why this always returns a "null" quaternion? The queternion resulted from the lerp operation only contains nanf's
Any i dont have any clue why
what language is that?
c# and dots
oh, dots, alright, never touched that.
Anyways, is netRot actually a valid quaternion if you log it?
yeah its not nanf atleast
quaternion(0f, -0,6618526f, 0f, 0,749634f) this is valid right?
Log the rotation quaternion before applying the lerp
can you log rotation before the math?
also speed / time - make sure these aren't NaN either
Alright one sec
you sure you can math.lerp on a rotation?
Im pretty sure you can lerp quaternions ^^ but one sec
Oh, yeah, its all dots, forget my questions about syntax here ๐
I thought Quaternion.Lerp would be the right thing to do
So before applying :
BEFORE: quaternion(NaNf, NaNf, NaNf, NaNf) and quaternion(0f, 0,9978189f, 0f, -0,0660108f)
The first quaternion is the rotation, second the network rotation
Cant we lerp a nanf quaternion, is this the issue? So do we need to ensure that two valid quaternions are lerped?
Otherwise it woudl not know where to start from, right?
garbage in, garbage out
you need to start with a valid quat, yes
Ah i see, thanks ^^
Well i also found the issue, nanf quaternion is returned when we nlerp two identity quaternions... is this a valid issue? If so how do we normally solve this, thought identity quaternions are like the default value.
hmm that seems wrong ๐ค
I'm also not familair with what nlerp is though
Im gonna try using slerp to see if the issue persist ^^
I was recommeded nlerp ages ago since its "faster".
Are you sure your t parameter is correct?
Atleast if looks like nlerp causes the issue... before two identity quaternions, after the nlerp only nanf
Maybe your t is NaN
Those are also invalid quaternions
and yeah
at least one of the values should be 1
0,0,0,0 is not the identity quaternion
there's probably a divide by zero happening when you use 0,0,0,0
Hmmm this makes sense, im gonna investigate one sec
i updated and the latest works fine for me. the scale is just wrong
might be a red herring
i use the latest 2021 LTS which is like 18 or something
Appreciate it.. Not sure what I want to do about it though. It's probably polish the game doesn't need (the shader effect, not the particle effects). I'm not sure what's not playing nice but it appears to be having issues on baking meshes, something I know nothing about and it's not really required
and also yeah i think when he went to 4.0 the scale change was a breaking change
uuuuh I made some score that will change by adding
0.1f right?
why the hell the result sometimes is something like 3.99999999
0.1f is not a number that can be represented perfectly in binary
use fixed point math (int etc), or use a number that can be represented perfectly in binary, or just do approximate checks
ok i have an idea
btw this is similar to the way that 1/3 cannot be represented perfectly in decimal
it's an infinite repeating decimal (0.33333...)
which cannot be stored in a finite amount of space
In general it's risky business to rely on floating point math operations to be perfectly accurate
there is always going to be some level of inaccuracy/imprecision when doing floating point arithmetic
Or check if a float has changed within an acceptable difference value, if that works for you
using System;
namespace TG.Utilities
{
public static class FloatExtensions
{
/// <summary>Checks if float changed</summary>
public static bool HasFloatChanged(this float thisFloat, float previousFloat)
{
return Math.Abs(thisFloat - previousFloat) > TGConstants.FLOAT_DIFF_THRESHOLD;
}
}
}```
did you author this?
Before I answer, why do you ask? ๐
it looks like it was originally computer generated, and then you moved the constant and namespace
Rider suggests things like this, but this one was 100% written by me.
I am using the code from this video https://youtu.be/sJSA5Zyg7WM for procedural animation and it works for the small 4 leg spider I have. But my problem is I am trying to use it for a big 8 legged spider and the legs work and everything it just everything is spinning and it seems that the targets keep getting teleported around. I need some help because I have tried so many things for this. If I turn off the rotation for the spider body everything still works so it's something with the rotation
Ironstar Interactive: https://www.youtube.com/watch?v=AHAswF9kvc0&t=171s
Thank you for watching. Comment what kind of content you want to see next.
0:00 Intro
0:20 Wall script
23:10 Setting the values
27:50 fixing some things
38:28 bonus feature
I have tried using it with just four of the legs and it still spins. I even used the exact same setup for the smaller spider but scaled it for the big one and it still spins
Do you understand the code ? Copying a code that you do not understand is like copying art. You gonna make a lot of small mistake that could result in wildly wrong output. Also, you will have a hard time to make any modification.
What you might want to do is ask yourself:
What can I do to better understand the code ?
There is multiple way of doing something like that.
Here a non exhaustive list:
- Scientific Method
- Isolation
- Start from something that works
- Algorithm Trace
I mostly understand the concept I'm just confused because it works on the smaller one but Is spinning on the larger one even when I use the same values
just posting some useful code cause im proud of it, feedback welcome
public static void SetToLocalizedText(this TMPro.TextMeshProUGUI text, string key, string dictionary)
{
IEnumerator AsyncOp(TMPro.TextMeshProUGUI t, string k, string d)
{
var asyncOperationHandle = LocalizationSettings.StringDatabase.GetLocalizedStringAsync(dictionary, key);
while (!asyncOperationHandle.IsDone)
yield return asyncOperationHandle;
text.text = asyncOperationHandle.Result;
}
text.StartCoroutine(AsyncOp(text,key,dictionary));
}
this allows you to, on any textmeshprougui object, ask for the localized text you're looking for, and it can easily be extended to strings if need be
it does rely on your text object being active in the scene, so if you need to get around that, just make a top level coroutine in your extensions/utils class and call StartCoroutine on the game object you call it from
you could extend this to TMPro.TMP_Text instead of just TMPro.TextMeshProUGUI
also you don't seem to be using the k and d parameters at all
so you could remove those
I think you can also remove the while (!asyncOperationHandle.IsDone)
And you can also have a even approach which may be better. I didnt use the assets, but it seem to have already an "Event System" with the event Completed:
https://github.com/nhnpro/unity.localization/blob/master/Documentation~/localization.md
When an Asset is not immediately available, the localization system returns an IAsyncOperation. The IAsyncOperation provides a Completed event that notifies Unity when the operation has finished. It calls this during LateUpdate. If the request has already been completed, such as when the requested data is already loaded from a previous request or during preloading, then the IsDone property can be used to check for immediate access, alternative the Completed event still occurs in the LateUpdate, allowing for all code to follow the same path. You can also yield on an IAsyncOperation inside of a coroutine.```
You would need to investigate by yourself.
asyncOperationHandle.Completed += (asyncOperationHandle) => Debug.Log(op.Result);
good points, i tend to make random mistakes like not using params in this way lol
This is the exact thing i want to avoid, since if you do it this way, every bit of text you want to localize via script has to have its own callback, with my approach you avoid that entirely which cleans up a lot of redundant code
You can do it in the function :P. This way, you wouldnt be stuck with unable to call if the component is inactive. Also, you wont start a coroutine for no reason. Also you would be able to provide the value on the same frame if the value is already in memory.
oh, yeah i guess that is true
looks much cleaner now, thanks! (added optional callback for further text manipulation after its localized)
public static void SetToLocalizedText(this TMPro.TextMeshProUGUI text, string key, string dictionary, Action<string> TextOp = null)
{
void SetText(AsyncOperationHandle<string> handle)
{
text.text = handle.Result;
if (TextOp != null)
TextOp(text.text);
}
var asyncOperationHandle = LocalizationSettings.StringDatabase.GetLocalizedStringAsync(dictionary, key);
if (!asyncOperationHandle.IsDone)
asyncOperationHandle.Completed += SetText;
else
SetText(asyncOperationHandle);
}```
Hey all, Quick question: I'm trying to make a "custom" wheel controller for a monster truck tire. I'm at the point now where I'm trying to get all of the tangents from any contact points on the wheel, but where I'm struggling is trying to find the correct normal that is pointing "clockwise" around the wheel.
in the screenshots, you can see I have the tangent of the contact point on a circle. (Long story short, the collider is a sphere and the contact point creates its own circle/slice of the sphere collider, so just assume it's a 2D circle). The two normals are colored green and red following the tangent of the circles. My issue now is trying to find the direction of each normal, whether it's clockwise around that circle or counter clockwise.
Again in the screenshot example, You can see the ground contact has a green normal line facing "backwards" (to the right), showing what would happen on a real-life wheel when it moves forward. The red line is facing "forwards" to show the opposite or stopping of the wheel. Anyways, the tilted plank above the wheel, touching the top should have its normals reversed. where green is pointing towards the front of the vehicle and red the back since that would be the direction the wheel is turning.
I can show code if required, I just don't want to clutter this any more than I already am.
So I want to have a 3d character stuck to the side of a 3d cube but be able to move 2d around the cube, how would I do that?
Hi everybody! Would anybody know the best formula to have a relative speed based on actual speed and amplitude of a motion? For example, a moving hand back and forth at a speed of 10cm/s. I'm using an amplitude as percent from 0 to 1, same for speed. Then I have max amplitude which would be 10 (distance in cm) and a max speed which would be 1 (seconds required to cover the max amplitude). If we reduce the amplitude factor by half, the new ratio is 5 cm/s but this makes the hand speed move twice as fast. I want the relative speed of the hand to be unaffected by the amplitude factor. I've tried to multiply the speed by the amplitude factor but I doesn't seem to achieve the result I want, the hands still moves too fast. What's the usual way and formula to deal with this case ?
Not sure if I make sense lol
are we talking about sinusoidal motion here?
Linear at the moment but now that you mention it, the animation would be better with sinusoidal. But I think the logic is the same for both.
what do you mean by "relative speed"? not sure I understand that part
Well, it would be the speed to cover the current amplitude.
well the amount of time to "cover" the amplitude is just the period of the wave
aka the inverse of the frequency
if you want to keep the same "actual" speed while decreasing the amplitude, I think you'd need to proportionally increase the frequency
Ok, I had forgotten this from my highschool physics classes lol
so if you cut amplitude from 10 to 5, you'd have to double the frequency i'd guess
if you want to maintain the same actual speed
Yes, that's what I though
So that would be to use the invert of my amplitude factor I guess
Since 1/0.5f is 2
If you think in terms of period rather than frequency then it's just proportional
so if you cut the amplitude in half, you cut the period in half
same thing, different perspective
I guess step one is to make sure your code is just taking amplitude and period (or frequency) as the inputs to create the motion
then all you have to do is make sure you adjust those things in proportion whenever you change one
Yes, that's what I felt like when coding the stuff, but when I tried, it didn't work. I'm applying the result on the timeDelta like this:
`
public float Amplitude()
{
return amplitudeFactor * amplitude;
}
public float Speed()
{
if (amplitude == 0)
return 0;
return maxSpeed * speed / amplitude;
}
IEnumerator MoveObject(Vector3 startPos, Vector3 endPos)
{
float i = 0.0f;
while (i < 1.0f)
{
i += Time.deltaTime * Speed();
pos = Vector3.Lerp(startPos, endPos, i);
transform.localPosition = pos;
yield return null;
}
}
`
It's a simple coroutine which goes back and forth between two transform positions
But for some reason, even when I divide the speed by the amplitude factor, the hand still moves super fast at slow speed the lower the amplitude is.
I'm thinking maybe the deltaTime would make the logic different ?
If I want the speed factor to be related to the time in seconds to reach the current amplitude (back and forth), I think deltatime might not be the variable I need here ?
But I have no idea what else to use :x
Similar to Rigidbody.velocity actually which is 10 units per s
looking for a way to create a wifi controller , from my android to webgl game, tryna find the right way to approach this ,and i literally cant find any unity asset for a wifi controller!
you'd have to show the code in question
For college I have to make a project, I have to launch my unity on 3 different screens all displaying something else. It has to retrieve data from an API and then launch on the screens.
Although i might just suck at google searching but i cant find any information to use. Can anyone link me to any useful arricles
Hi again, I'm having a bit of a math question. I have 3 positions Vector3: A, B and C. I want to find the directional Vector3 A to C as well as the B angle in the triangle ABC. What would be the formulas ?
yw, gl
var dir = (c - a).normalized
var deg = Vector3.Angle(b - a, c - a);
there's a much easier alternative, which is this: https://docs.unity3d.com/ScriptReference/Camera-targetDisplay.html
any downsides to it?
no, and it should be the recommended/standard option
Oh aight, and when you set the display you can call whatever you need from an API right to show onto the screen, i assume altleast
it's just an option for what display the camera should render unto
once you set up 3 cameras (one per display), you can handle the rest from other code
np
Thanks a lot!
np
Is there a way to get the axis needed for the rotation to move A to C from B's perspective? I'm not sure how it works. The idea is that I have an orbital camera (A) around a point (B) at a random distance and a random angle. I'd like to set the position and rotation of the camera based on an angle and a distance relative to B. So let's say I want to move that an angle of (20, 90, 0) (Let's call it R) and a distance (D) of 2 units, I would need to figure out the position of the third position (C).
So far, I use this to get C:
C = B + R.normalized * D
Then I try to rotate the camera:
A.RotateAround(B, ??, Vector3.Angle(B - A, C - A))
I'm missing the axis parameter, not sure how to calculate it
Or maybe I should split it in 3 operations, one for each axis?
Vector3.Angle returns the unsigned angle as float indeed, so that likely won't work in your case
not sure about the proper way if you want the euler angles to perform that rotation.. maybe someone else could help with this
Ok thanks ๐
The axis could be the cross product between A/C and A/B. I'm not sure I understand completely the problem. Beware of the left hand rule, you may have to use SignedAngle instead of Angle.
A.RotateAround(B, Vector3.Cross(B - A, C - A), Vector3.SignedAngle(B - A, C - A))
How would one go about putting a json image into my unity scene. I got code to retrieve it already. I just dont know how to make it appear
Sorry i mean, a json file with an image link inside it
Php
PHP file with a link to an image, i encoded it as json and im using UnityWebRequest to retrieve it from a local server.
so what's the issue? another web request to fetch the image
Use multiple cameras and set them to render to different output
maybe try #๐ปโcode-beginner
what are you actually trying to do? what is the gameplay or the UX here?
you can build il2cpp with full stack traces
which may help
Hey, is there any way of finding out a list of scripts that changed rotation in current frame? Something like hooking a Debug.Log(StackTrace) to a setter of transform.rotation?
Basically, what I want to do is see what changes transform's properties for some object
why
I have several components that change rotation of one object. For some reason, when component1 changes rotation, it's applied correctly, but then when component2 changes object's rotation, the changes seem to be ignored for some werd reason. When logging rotation right after component2 does it's changes, it outputs correct rotation
But in inspector the value is not the same
So, my guess is that something else changes it
I'm trying to figure out what changes it
is it possible 2 different rotation changes happen in the same frame?
I don't see why not, they're both just multiplications
First component does Quaternion.Slerp from current rotation to target, the other one rotates current rotation on set offset
you can set a breakpoint on the property's setter
i don't think this is going to illuminate much for you
what is the effect you are trying to achieve?
it sounds like you should be using an aim or multi-aim constraint
I can't set a breakpoinnt on this setter though, because it's in the Transform.cs file, which is a part of unity
that's the whole problem
you can extend Transform and AddComponent
you can set a breakpoint on the setter
have you tried?
it certainly works in rider
you can have it log the breakpoint instead of breaking
anyway, good luck on this journey. i can help you out if youy tell me what the effect is
i don't think you need to debug this, you just need to approach your effect the right way
I haven't tried it, I though it wouldn't work on decompiled sources, let me check
Oh lol it really works
cool
never thought it would
Me neither. Good to know!
Rider is a godsend
I confirm that you cant with visual studio 2022 ๐ฆ
Or you need other Unity version then 2021.3 or you have to do some extra setup
There is a post on how to do it in Visual Studio. I never thought you could actually do that lol. https://johnaustin.io/articles/2018/01/15/2018-debugging-into-unitys-internals
okay well, when you're ready to tell me what you're actually trying to do, i can help lol
kind of low ROI to have me give IDE tips
I thought I wrote an explanation, I'm trying to find out which scripts change transform.rotation of a certain game object...
i'm saying what effect is this for
c'mon i'm repeating myself
for example "i am trying to make a turret that tracks a target"
xyproblem yada yada
I would look for 3 things:
- Rigidbody / physics that get applied on the Object.
- references to that object on scripts you use
- any scripts attached to the object
I don't remember if there is a specific quick way to debug which script affects an object movement but you should try and see what is causing the movement and than find the component that could be doing it
Yeah, there's no rigidbodies, and I'm working on a huge project, and this object has tons of components, that's why I'm trying to do it without manually checking all of my components
Ok, nvm, did it though rider's conditional break points
That's not it
God damn it
did you find it?
Yeah, I just did this and it showed me all rotation changes through property for certain game object
nice! goodluck on your project!
Moving this to advanced.
I am making a chatbox, and I'm attempting to get it to scroll to the bottom. It is not solved with the standard answers, and the reason is because of this:
For my chat box, each item is a Text component, and each text component has a ContentSizeFitter, so that the component resizes according to the length of the chat message. Further, the parent panel, being the content panel, also has a content size fitter.
So when a new child object is added by instantiation, the scrollbar does not calculate the new changes to the scrollrect.
I would appreciate any tips or advise on this. Canvas.ForceUpdateCanvas does not solve this issue.
As we see in my spam, the last message is "mre"
However, the last message should actually say "whyyy"
Doesn't seem like a code question ๐ค๐ค
here is my current code.
public void AddMessage(string username, string message)
{
string format = $"<color=#C5DFFF><u>{username}:</u></color> {message}";
var item = Instantiate(_itemPrefab, _contentPanel);
var script = item.GetComponent<TextMeshProUGUI>();
script.text = format;
LayoutRebuilder.ForceRebuildLayoutImmediate(_scrollRect.GetComponent<RectTransform>());
ForceScrollDown();
}
// Called at the end of instantiation function.
IEnumerator ForceScrollDown()
{
// Wait for end of frame AND force update all canvases before setting to bottom.
yield return new WaitForEndOfFrame();
_scrollRect.verticalNormalizedPosition = 0f;
}```
You're not actually starting your coroutine
Also WaitForEndOfFrame should just be yield return null
And you should just do the ForceLayoutCanvases thing instead of waiting a frame anyway
ForceLayoutCanvases does not correct the sizing issue.
The ForceScrolldown bit I have covered. my issue is that I do not see all content when the scrollbar is at the bottom.
ForceScrollDown(); this line of code does nothing
You have to actually start the coroutine
Thank you for pointing out that I didn't start the Coroutine, but that is not the issue to any capacity. The line this function executes only moves the scrollbar. I am currently, manually moving it, and the scrollbar at the bottom position cannot see all of the content, due to resizing.
I made the coroutine execute it's function now, and the scrollbar will work automatically (thank you), but I still do not see all of the content.
That's a #๐ฒโui-ux issue
I see. Thank you.
Playing with a sample project, and trying to reference a sample- monobehavior from a new custom monobehavior. But it just doesn't accept the namespace. Note that the sample code appears in a separate "project" in the solution. I suspect I need to reference THAT project from the main project, but how do I do that?
do you use assembly definitions in your project?
no- I usually let unity do all that stuff as it
is always recreating the solution/project files
does the error appear only in visual studio or does it appear in the unity console as well?
both
and you're certain that's the correct namespace?
Hey guys, I'm working on a server reconciliation feature and I need to apply few user inputs to an object. I'm thinking about calling Update multiple times, but I'm not sure it's possible.
the error itself: Severity Code Description Project File Line Suppression State
Error CS0234 The type or namespace name 'Samples' does not exist in the namespace 'UnityEngine.InputSystem' (are you missing an assembly reference?) Assembly-CSharp C:\Data\Unity Projects\InputBindingTester\Assets\BuildActionRemapList.cs 5 Active
regenerate project files and restart visual studio. if that doesn't fix it, you could try deleting the Library folder in your project and restart Unity (delete the folder with the editor closed)
good idea, I'll give that go
this is gonna be a minute, lol
same result. is there some way to add the reference to this uh.. "project" in player settings? I know I can set SOME compiler options in there, just not sure how to do this.
if you imported it through the package manager like you should have then it shouldn't be a problem unless you are using asmdef in your project in which case you need to make sure to reference the assembly
not sure about the asmdef (how do I check that?), but yes, this is a sample project imported from the package manager...
well, I think I actually created the project manually- then imported that circled thing
you would know if you are using asmdefs in your project because it's something that you would have had to set up
ah- then unless it was included in that import, no
well that sample project does use them, but if you are not using them for your code then it wouldn't make a difference
hmmm, perhaps I NEED to create one to reference the sample project stuff?
if you are not using them for your code then it wouldn't make a difference
hmm. possible worth noting.. I CAN use UnityEngine.InputSystem it only craps out at UnityEngine.InputSystem.Samples
the code files are located here:
and my problem script is in the assets folder (root)
FYI: I removed the asmdef from the SAMPLE's folder, now my file understands the namespace, and I can reference to component.
๐คท๐ปโโ๏ธ
just downloaded it myself to check, turns out they have the "Auto Reference" property disabled on the asmdef for whatever reason
How do I properly resize a texture asset from an Editor script? I obtain the texture from AssetDatabase.LoadAssetAtPath<Texture3D>(path) but there doesnโt appear to be a way to change the size directly. If I create a new texture with a new size and save it with AssetDatabase.CreateAsset(texture, path); Unity doesnโt use the existing meta, it creates a new one causing the texture to unlink from my project, so that doesnโt seem to be a solution. In a worse case hack, Iโm considering making a copy of the .meta file, creating a new texture, and then replacing the meta file, but it seems so hacky. Surely, there must be some way to do this right?
Actually looking into this more, the meta file isn't changing, but Unity still shows the file as "Missing" in the editor fields. However, if I restart Unity it shows up correctly again. So maybe I need to do another kind of refresh? Using a combination of AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); AssetDatabase.ImportAsset(path) doesn't seem to change anything. Or maybe this is just a Unity bug?
"Resize" as in you want to modify the file itself or you want to change the TextureImporter setting?
File itself. I'm generating a procedural texture from an editor script.
You could just save the file with regular File APIs and refresh
It'd be same as how you'd do with external image editor
How do I use the File API to save a .asset file? It's not an image since it's a 3D texture.
Hmm 3D texture? In that case I'd say modify loaded texture and SetDirty then SaveAssets
That's what I've been doing, but when it comes to changing the actual dimensions of the texture, there doesn't seem to be a way of doing that without creating an entirely new texture (using the constructor).
It seems like Texture3D lacks Reinitialize API Texture2D has. Weird.
You might have to update the references to the texture, or reimport the assets that referencing the texture
Anyone here good with 3D math? I have a problem that I'm not even sure how to search. I have two objects in world space, and I want to "glue" them together based on "anchor" points as child objects with local transforms, parenting one object to the other and giving a local transform that aligns the position and rotation of the anchor point with the target anchor on the other object. How would I calculate that final local transform? Here's a visual of what I want for reference where the colored arrows represent the anchor points with the before on the left and the after on the right:
I thought that once the second object is parented to the first, multiplying the local transform of the two anchor points together would give me the result I wanted and it's pretty close but it fails when certain transforms are applied to the anchors and I'm not quite sure why.
I'm thinking it might have to do with that fact that I want to not just align the anchor points, but align a specific axis of the anchor point (Z, in blue) in a specific way (+Zs together, facing in opposite directions)
super easy just set up the anchor correctly in the first place, then you do:
attachedObject.position = anchor.position;
attachedObject.rotation = anchor.rotation;```
make sure the attached object's pivot is in the right place of course...
Or I guess you're wanting to go anchor-to-anchor?
Yep! Need to take both anchor transforms into account
That's where it seems to get tricky haha
There's also the matter of aligning the axis. For example I have an anchor that has a (-90,0,0) rotation and when moving it along its local Z, it ends up changing the alignment of the object along the original Z axis (which is now the object's Y)
At least, that's what it's doing with my current method of just multiplying the whole transform
I also tried getting a rotation quaternion that makes the second object look along the first anchor's -Z to align them, then matching the positions but that didn't take into account the second anchor's rotation 
I feel like there needs to be an inverse in here somewhere, but matrix and quarternion math just makes my head hurt
Try this out for the rotation part:
Quaternion myAnchorDesiredRotation = Quaternion.LookRotation(-otherAnchor.forward, otherAnchor.up);
transform.rotation = myAnchorDesiredRotation * Quaternion.Inverse(myAnchor.localRotation);```
if we get rotation working then position will be next
Once rotation is working this should work for the position:
Vector3 diff = otherAnchor.position - myAnchor.position;
transform.position += diff;```
anyone have any better idea on how to have colliders to stop players walking on an area im not lighting, the base idea im working towards is the player moves objects in the level to change where the shadows are cast to allow them to make it to the end and progress to the next stage, this is currently taking data from a render texture, converting to a texture2D, then taking the greyscale float, normalising it to either be 1 or 0 height , then setting terrain to match this
hey guys humor me for a sec but how do I create an AI that can create games? ๐
ask ChatGPT
Step 1: Create a tool that given an input creates a game
Step 2: Connect the output of an AI to the input of the tool from step 1
I think ChatGPT is a perfect example of how AI is not going to do that for you
how so?
Because ChatGPT is as close as an AI is that could do it, and it sucks at it
Maybe Google's variant will be better ๐คท
oh the devs actually tried putting it to test to do that? cool
No
You can just ask it to do it
And there is a pretty big chance some/most of the code will be wrong
Because it has been trained to think the code is valid
Might be less worse with Unity but it is really good at assuming certain packages are real when it comes to typescript, when it's not
well when it comes to code gen AI I think MS's intelliCode thing has got the lead
Either way, it can't create a fully fletched game anyway since it will either break or error after 3 questions, which forces you to wait an hour before you can retry it all again ๐
Maybe when the high demand settles down you can try it
I mean chatGPT is meant to be coherent and linguistically correct, not so much correct on content
So definitely not intended to create games
nah I would expect some working interface like this for the AI to pass the game creation tests:
void CreateSinglePlayerGame(GameGenre genre, int dimensions, int estimatedLengthInMinutes, //dimensions >= 2
List<(string Name, byte[] Model, byte[] Texture)> ModelsAndOrTextures, //null model for 2D
bool allowGeneratingMissingModelsOrTextures = false); //generate missing art if true
Raycast from your light source to your player. Only allow movement when at least one raycast succeed. It would prevent the player from moving, but not push him.
For the pushing part, you could:
- Find the closest valid spot by doing random raycast from the light source to a random location around your player then push your player in that direction.
- Use the movement of the light and reproduce it on the player.
You may want to consider:
- What happens if there is no valid light spot around the characters ?
There is multiple factor you need to take in consideration when making an AI. The first one, being what type of problem you are working with and what solution you want to achieve. Depending on that, you may want to use Machine Learning, Behaviour Tree, Minimax Algorithm, Expectimax Algorithm or any other algorithm that can solve the problem for you.
In game development, we usually use Behaviour Tree as they are flexible and easy to use. One of the down side is that the AI won't be really "intelligent". This method is still considered AI and could be use to construct a game.
In other word, if you define what is the problem (Game with given code part and meshes) and the solution you want to achieve (Minecraft Game), you can create a game with AI.
In that preservative, Procedural Generation would also be a way for AI to make a game.
If you want to create a more complex AI able to create game from scratch you would have to create a network of AI.
Each one of the AI could then use appropriate method to generate the require content. One AI would be specialise in creating code while another would be specialise in Mesh generation. You could then have one AI being the one in charge of putting the piece together.
Cool answer! I think a Behaviour Tree would be completely required yeah. Nothing says I can't include ML on the AI if I use a Behaviour Tree though..
..but in real life scenarios I'd have to manually play the games it provides and provide detailed feedback in order for it to have any actual value, lol, which kinda makes ML lose its meaning -- or be very slow on the 'L' part anyway.
*play the games/review the code/art/whatever.. the point is that feedback would be needed for it to learn.. in which case it might as well just be faster for me to jump in the code and manually make changes I find good xD
Thankyou very much I will work on trying out some raycast systems
@sly grove Thank you for the help! I ended up calling it a night and came back with a fresh brain this morning. Using your hint and thinking it through I figured out that I could take the inverse transform of anchor "B" to put it at the object's origin, then added the inverse of anchor "A"'s rotation (to flip the forward axis) and the normal translation to get the exact transformation I want in local space ๐ฅณ
Hey all, has anyone here worked with photon fusion for networking? Or knows a good video on it?
you can get the glue point on the triangle by linear interpolating the edge vertices.
0.5*edge1 + 0.5*edge2
that gives the middle between both points
can do the same for the square with the edge vertices.
once you got both points, you can calculate an offset
and rotation would be the face normal i guess?
of center of triangle to gluepoint
never mind, i misunderstood you question
It was a tricky one ๐
It's working great for randomly connecting rooms together though
what was the solution? predefined, prealigned anchors and just overlap those?
predefined, prealigned, preadjusted, premedidated premium all premade prefabs
PropertyInfo[] properties = typeof(MonoBehaviour).GetProperties(); //Returns all properties of every component, but All I want is Script public properties on the gameObject that the script is attached to
Help please
huh
can you rephrase/explain that better?
typeof(MonoBehaviour).GetProperties() will give you properties for the MonoBehaviour class specifically
Im trying to get every script inside a gameObject and get its properties too
so shouldn't you start by getting all the scripts on the GameObject?
and when you say "script" how are you defining that?
Any Component?
Just MonoBehaviours?
and finally - why are you doing this?
Script components
serializing scripts
Unity already serializes your scripts
runtime serilaization
yes
Reflection is a pretty poor way to do it
which way would you suggest then?
or rather
Why are you doing your own reflection?
Why aren't you using an existing serializer?
Like JsonUtility, or JSON.NET or something
is there an article or fourm about that for runtime
there are hundreds of JSON save system tutorials yes
in general though the common thing is that generically serializing MonoBehaviours is not a great idea
you want to identify the actual information you want/need to save in order to restore the game state
and only serialize that
generally by creating a separate GameData object
ok
I ended up with more or less my original solution of multiplying the two transforms but for the "target" anchor point I had to take the extra step of inverting only the rotation and not the translation
I try to use ScriptableObject to tag some gameobjects without hardcoding anything. I think it's a good practice but I've had multiple situations where I want to access a specific tag from within code. The only way so far is to create a serialized field that holds a reference to the scriptableobject but it feels redundant.
Is there a best practice to hardcode some scriptableboject references?
the only other options besides the inspector are:
- Copying a reference from somewhere else (which just kicks the can down the road)
- Resources.Load
- Addressables
but actually that first one could be kinda nice - you could make a "SignalDictionary" and key them by an enum or a string name or something
I was thinking of making an addressable pack with all the signals in it but at the end of the day I'm hardcoding the string "OnCastCompleted" and if I ever change in the editor the SO, i'm screwed
I realize there's no other way really ^^ Maybe I can create a dicitonary like you said with all the values I expect to be hardcoded, while still leaving me open for modular design
I try to use ScriptableObject to tag some gameobjects
๐ฅบ
this is not a great way to do a "gameplay ability system"
How so? Seems to be working pretty good for me so far. Maybe I didn't explain myself correctly:
I only use scriptable objects to identify different signals between my ability modules.
this makes sense in Unreal, but that's because in unreal, programming is horrible
Never touched unreal!
well
this idea has a long ancestry that is primarily reacting to how horrible programming is
you don't actually want to program in the inspector
You're suggesting a more code oriented approach? I like the idea of building abilities in the editor
because C# is way easier to program in
than the inspector
whereas in the whole of the history of game traditions, programming int eh game engine is generally horrible
so for example, instead of all of this, you can do
class FireballAbility : BaseAbility /* : MonoBehaviour */ {
protected override UniTask OnCast(AbilityContext context) {
// at this point, the user has clicked the fireball ability button
// first ask for a target
// lots of ways to do this. here are two examples
var target = await context.RequestTarget(
new ConditionalTargetFilter(new WithinRangeCondition(5f, context.caster)));
// or
var target = await context.RequestTarget(targetingContext => {
return targetingContext.target != null && (targetingContext.target.transform.position - context.caster.transform.position).magnitude < 5f;
});
// can be cancelled using built in Task features! so we might not get this far.
context.BeginCasting();
// now shoot the fireball
var fireball = Instantiate(fireballPrefab, context.caster.transform.position);
...
await fireball.DOMove(...);
Instantiate(fireballCollisionParticles, ...);
await context.Damage(target, 100f);
context.EndCasting();
...
}
}
@vale nova obviously if C# 8.0+ existed through 1990-2010 when all these huge multiplayer gameplay ability systems were made, this is how people would do it
but it didn't, people used C++, which is horrible, and programming stresses people out, even though you're still programming just with the far inferior inspector and hierarchy
if the fireball needs animations or whatever you add that to its prefab
and like, write code.
I like the idea of building abilities in the editor
speaking from experience, the code approach, provided you learnasync/awaitand a tool likeUniTask, is better
you're still programming
you're just programming in a half-complete LISP you came up with, splayed out in the hierarchy and the inspector
that's your approach right now
that's how it works in the SC2/WC3 editor
i am not saying these things don't get the job done. they are inferior to the clarity, succinctness and correctness of doing your programming in C#
i wouldn't say the same if it was C++!
programming in a half complete LISP is better than doing anything in C++
but that's the context of the tradition you are doing
I tend to agree, I really love C# and I would be able to program abilities like you've demonstrated...
you are going to be reinventing stacks, a vm, etc.
there's a lot to do to make a LISP
whether you like it or not, that's what you are doing
you can certainly have something that gives you the psychic experience of being productive
but it will be buggy as hell until you essentially reinvent async/await
whereas just from my one example, my one code snippet, you can probably fill in many of those blanks
and it will pretty much be working 100% out of the gate without bugs
anyway tha't smy perspective
There's no tradition on my end really I kind of went in that direction on my own after multiple attempt without much research, I'm not sure why I preferred to go like this rather than code. In my head I should use the power of the inspector to allow modularity in my systems. (Not that I couldn't do it without).
i see what you mean
You are definitely making me reconsider tho, I love programming and the idea of scripting abilities like that sound more streamlined
i agree that trying to use the editor generally for making design decisions is good
but use it for stuff like, the amount of damage the fireball deals
and which prefab should be particle effect(sort of what you are doing)
don't do it to configure the targeting and sequence stuff
If a problem can be solved by programming, the only time I wouldn't go for that is if I need to cooperate with a non programmer.
i am happy to share more examples with you @vale nova looks like you already have a lot of the right goals in mind
just from looking at the hierarchy i figured you knew what you were doing
I'd argue an ability shouldn't even be touched by non programmer, at most they do things like effects icons texts etc.
Okay but long term I have a hard time seeing it. For reference my mental image is WoW abilities. Is it really easier to program each ability as a singular script? What about when I want to make small variations of damage, range, changing icons, target types?
What about single-responsibility classes?
So your structure would be Prefab->AbilityScript(WithParameters)
Is it really easier to program each ability as a singular script?
at least when i last saw the LoL codebase, this was the case, the abilities were in code. many huge teams actually wind up doing blueprints and creating a lisp, AND implementing in code, AND making a duality between them.
What about when I want to make small variations of damage, range, changing icons, target types?
you can still expose that stuff as variables you modify on an ability prefab in the editor
yes
Then make a prefab variant when I change some parameters?
that's one of many great ways to use prefab variants
lemme show you a more complete picture
But what if there's a fundamental logic variation.
I have to rewrite the whole script
I do appreciate the insight, this isn't a perspective I had. Bit bummed that I spent many hours on this xD
What would the alternative be, invent your own equivalent programming language that can be done in editor so you can drag and drop to "rewrite the logic" except slower and worse?
Isn't there an argument for component based architecture at least? Cause in your solution there is no components at all really
That's a depressing thought xD
Also, where do you draw the line? My characters have stats, abilities, buffs... should all this be in one huge monobehaviour???
^ careful graphic content
See cohesion and coupling for more information about dividing your classes https://www.geeksforgeeks.org/software-engineering-coupling-and-cohesion/
public class GameplayAbilitySystem : MonoBehaviour {
public Button castButton;
void Start() {
castButton.OnPointerClickedAsObservable().Subscribe(_ => {
var ability = Instantiate(castButton.GetComponent<AssignedAbility>().abilityPrefab);
var castingContext = new Context() {
caster = GameController.instance.currentPlayer,
...
}
castingContext.Cast(ability);
});
}
}
...
public InputActionReference cancelCastAction;
async UniTask Cast(Ability ability) {
var cancellation = new CancellationTokenSource();
cancelCastAction.action.performed += _ => cancellation.Cancel();
this.currentCancellation = cancellation;
// this might be delegated to the ability instead, like after a target has actually been chosen.
// lots of ways to skin this cat
this.caster.mana -= ability.manaCost;
try {
await ability.OnCast(this);
} catch (OperationCancelledException) {
// rollback effects or UI changes?
}
}
async UniTask<GameObject> RequestTarget(...) {
while (!this.currentCancellation.IsCancellationRequested) {
var targetUnderPointer = ...
if (TargetingRuleEvaluation(targetUnderPointer)) return targetUnderPointer;
await UniTask.Yield(PlayerLoopTimings.NextFrame);
...
}
// was cancelled if we reached here
// e.g. do not spend the mana
throw OperationCancelledException();
}
you can declare virtuals
i do this in my own game
Yeah I guess
lots of effects that are too complicated to do in LISP: https://github.com/hiddenswitch/Spellsource/tree/master/spellsource-game/src/main/java/net/demilich/metastone/game/spells/custom
you can compose the abilities
really depends what they are
but compose them by instantiating things
java doesn't have async await
so it's much more painful
Yeah I get the idea. I understand how to build them. I just have a hard time seeing where they fit in the Unity ecosystem
c# is much better fo rthis
you can use the editor to set up the animations on the prefab
and to tweak the values
wherever your game involves metaprogramming, for example "double the range of all your spells"
then you're going to be really happy you did this in code
there are many ways to skin that cat
but to do it bug free, you'll need C#
So is it better to have a big cast spell logic that checks some modular interfaces in your spell script? For example fireball is IRange, ISingleTarget, IDamage
the editor idea is not well suited for stuff like "double the range of all your spells"
traditionally the engineer just writes a really complex thing to implement that within the context of the LISP they created for designers
then if spell is IRange... check range -- if spell is IDamage... damage target
whereas if you minimize the amount of LISP, it's easier
no your OnCast implementation would call
context.Damage
you turn into methods whatever snippets you find yourself repeating
then await context.Damage(...)
AbilityContext is the current state of an executing ability, and it holds all the code for the english language words written on the card
like "Deal Damage" or "Whenever you take damage..."
and you can progressively support smaller pieces of enlgish language text as you get there
so you can do await context.OnCasterTakesDamage first, and then when you come up with an ability that reads "Whenever your oppponent takes damage" you can make that method more abstract into await context.OnTakesDamage(Actor damagedActor)...
you only use the type hierarchy very sparingly
it is low yield
you can use interfaces for helping the UI visualize stuff
And just so I understand, how does it look on other types of systems? Characters and stats? For example for character movement, do I use a unity component or is it a POCO system inside my character script?
so it's really IAbilityDescription and your ui elements can read it
probably a poco system inside your character script, but movement is strongly coupled in these sorts of games so really any approach is Right
but my poco system has no awareness of transform
unless I pass it to it I guess
It really shatters my perspective of unity, I'll have to think about all that
I've been coding in my corner for a long time
for example
class Movement : MonoBehaviour {
private Actor actor;
void Awake() { actor = GetComponent<Actor>(); }
void Update() {
var context = GameAbilitySystem.BeginUpdate(this.actor);
// tempting, but don't jump into this deep end right away
this.maxSpeed = context.GetAttributeValue(Attributes.Speed);
// instead, start with
this.maxSpeed = context.GetMaxSpeed();
context.Dispose();
// or
context.EndUpdate();
}
does that make sense?
lots of ways to skin this cat
they are all acceptable
this is also tremendously more debuggable
since your C# stacks are your game stacks
suffice it to say AbilityContext will be a huge file
full of stateless, static methods
but that's Good
oy oy oy
Why do every single unity article point to component based systems then
i am still advocating for a component based system
just only very lightly for gameplay logic
these things tend to be so strongly coupled
and algorithmic that it's easier to express in code
unity articles tend to talk about stuff that get the most eyeballs
which is generally not programming
Fair point
normal people Fear Programming
as you can see in that line i referenced, all the rules that are common to casting a spell
there are a lot of them
you can't decouple that stuff
you can even see comments about implementing cards in this hearthstone-esque game
it's complicated
and to do it bug free you're best off using code
i mean it's from a live game that people play and actually works
i can also show you deulyst's code
which is much worse
not really
there's lots of code that implements this game lol
there are many more files
this is a complex game that has been evolved over many years, but cirtically has hardly any known bugs
it supports writing cards in a LISP and also in java
c# is more powerful, a lot of this can be simplified
in C#
it's also commented. there are a lot of rules
yeah its a neat repo
and rules bugs are kind of the bane of LISPing it
you don't wanna LISP it if you don't have to
civilization V is implemented very similarly. they use python instead of a LISP to implement their core game rules
it's smart
and it has a lot of Rules
WoW predated that level of game science. it is also a multiplayer game like Civ V
i'm sure if they could do it all over again
I'm fucking depressed lmao I've been fucking around with components for so long
they'd do it differently
lol
well in my game i have prefabs for many of the visual effects
i haven't even shown you the C# code
I understand using async for cast times etc, but why do you use async for dealing damage
In case there's animations and stuff?
in these sorts of games there's like, a million things that could interrupt control
or require a user decision or something
or something that happens over the network or whatever
unlike Golang, C# requires you to "color" functions... i don't wanna get too theoretical, but as a matter of safety, everything is async until proven otherwise
for example, in spellsource there are cards that read
i'll translate it into hearthstonese
Legacy: Remembered across matches.
"Battlecry: Summon nothing. Legacy: Summon the last minion this destroyed instead"
implementing that could cause a database lookup
after that card kills a minion Ardent Defender, the text will now say
"Battlecry: Summon an Ardent Defender. Legacy: Summon the last minion this destroyed instead"
so the decsription text is also async
do you see what i mean?
Definitely
I don't see how I don't end up with monster scripts with dozens of parameters
what can i say? these games are complex
would you rather deal with that complexity in the editor
or in code
Do you have an example of where you draw the line? What is a component, what isn't?
if i were doing this all from scratch
insofar as a WoW ability is like a card, and there's text on the card (this is how Blizzard prototypes this stuff anyway)
everything that is printed on the card is 1 component. it may derive from a base ability that has a string name and a string GetDescription()
Characters are 1, Abilities are 1, buffs are 1
yeah so there would be a Fireball and a Mage
that's all fine
the individual algorithmic pieces of the card text - that stuff is code
in all senses of the word
Got it
where it lives is a stylistic choice
it can live in a gigafile
it can live spread out in different places
i wouldn't overthink it. i just wouldn't have an array of sub abilities or whatever
i don't want to program in the inspector
so if i want to make a general damage implementation, it's a function somewhere, or maybe it's a new DamageEffect().Cast() or whatever
To be fair it's not a far cry from what I have. I've just been abstracting some of these systems in components rather than POCOs
but it's not subAbilities.ForEach(x => await x.Cast())
yeah
but you have slots and the slots are like
OnDamage
and i would keep using those but for animations
not for game logic
use it for stuff where if it's broken it doesn't matter lol
i wouldn't have a
[SerializeField] private AbstractAbility OnDamage
that's programming through the inspector
i would do
class LavaGiant : AbstractCharacter {
override async UniTask OnSpawn(Context context) {
var trigger = context.AddTrigger(this, new OnDamageTrigger(async damageValue => ...));
trigger.RemoveFromPlayWhen(context, context.AddTrigger(new DestroyedTrigger(this)));
// or, since this will be repetative, let's DRY it!
trigger.RemoveFromPlayWhenDestroyed(context, this);
}
}
do you see how we can always turn some lispy thing (context.addtrigger(new destroyedtrigger...)) into something that reads like what the english language description of the character/ability says?
that's the goal
Yeah I like it acutally
you want to write code that sounds like the text of what the ability does, since that stuff is already algorithmic
you will find yourself repeating some lispy stuff, then you can turn it into a method
you can progressively make things more expressive
you don't have to do it all up front right away
"Lava Giant: Whenever this takes more than 5 damage, summon a Lava Elemental" - you can stick amountOfDamage as a field on LavaGiant
if you have multiple cards that have almost lava giant's exact text
great... you can subclass it
it's all very progressive
declare a virtual and start subclassing
nbd
you can also prefab-variant its effects and animations
it still interacts with unity's most powerful feature (prefab variants) very well
class Fireball : Spell
float damage, cooldown, range, castTime;
override void OnCast()
{
await CastWithoutMoving(castTime)
await Damage(damage)
await SetOnCooldown(cooldown)
}
BlueLavaGiant GreenLavaGiant
maybe they summon different stuff and then you'd add a reference to a prefab of the thing it summons
yea
this makes a ton of sense to me
I want to be able to identify spells that have cooldowns, range etc
Do I use like interfaces?
sure, anything you want to visualize in the UI
IHasCooldown
you shouldn't use it for game logic necessarily
well what about a buff that reduces all cooldowns
is the reduciton in my SetOnCooldown()?
you can always do IUIDescribable { string description { get; }} and the thing writes its own description
but then my tooltip wouldnt show the real cooldown
that would be one place that could make sense yeah
this is why i think you wind up putting all the rules in one big file
they are strongly coupled
yes, and that also suggests how the UI is pretty strongly coupled to a lot of gameplay, so you will be writing a lot of text formatting implementations
you can make it easier when you need to
i have one tooltip class
that introspects everything
yeah that's the goal
well thanks I appreciate the discussion
I'll take a crack at it and see how it goes
do you see how you just like
know what the tooltips are
by looking at this
you don't want a bajillion little shits everywhere
{
tooltips.Add("<b>Supremacy</b>: Whenever this attacks and kills a unit, do this.");
}```
tooltips are a coupled concern
yeah i mean, it's that simple
why not
the text is algorithmic
if a keyword is printed on the card, people will want to know what the keyword means
yeah no that's fair that's not doing what I thought it would
Althought my brain would try to abstract it in a Keyword class lol
yeah so you wouldnt want to couple your keywords with tooltips by having your Keywords implement ITooltipable
you CAN do that
and maybe eventually this WILL do that
but i only have limited time lol
so that's why i keep emphasizing that this approach is progressive
That's fair lol I like the sound of that
You've sold me
But also made me lose my whole week
hahaha
I'm certain I shall return with more questions
this - cannot stress enough how important it is to have your abilities done code-first. it is virtually impossible to give abilities the flexibility and extensibility it needs (i.e, modding), if you aren't utilising everything C# has to offer
sorry for digging that up! just reading it through, found it very interesting
worth highlighting
How do I split a integer number into individual digits for example 100 into 1 0 0? I'm trying to do a sprite based damage popup system instead of using texts
repeated modulo 10 or convert to string and look at individual chars
I have a problem with LoadSceneAsync. It worked sometimes, but often will cause my entire editor to freeze and require me to kill it. After much debugging, I finally have narrowed it down to only happen if I haven't opened (looked at) the scene since starting Unity. Anyone know why that is or any fix to keep me from double-clicking every scene in the game every time I start Unity?
what's the difference between "On End Edit (string)" vs "Deselect (string)" for Unity's inputfields?
would end edit just be after each letter?
https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/script-InputField.html
End Edit
A UnityEvent that is invoked when the user finishes editing the text content either by submitting or by clicking somewhere that removes the focus from the Input Field. The event can send the current text content as a string type dynamic argument.
Deselect would not be fired on submit
is submit just pressing enter
Yes
cool thanks
in terms of performance its the same to disable a gameobject with a meshrenderer inside than disabling the meshrenderer?
Depends. Activating a whole gameobject and a single component naturally have differences, but generally I would just choose based on whether I want to hide or logically disable a gameobject.
If you are in a situation where the details matter, probably just want to run some quick tests. Changing this after the fact shouldn't be a huge undertaking
i've just read it's faster to disable the MR , so i think im taking that one ๐
My program creates a bunch of textures. But if I create too many, Unity crashes with a message like โUnity out of memoryโ. Of course, itโs better to try not creating so many textures. But is there a way to know if Iโm nearing the GPUโs memory limit? Like query current GPU memory? Thanks.
is there ANY way to get a bindless texture functionality in unity for compute shaders?
Hello i got this error in Google Play Console After trying to upload an aab file:
APK or Android App Bundle which has an activity, activity alias, service, or broadcast receiver with intent filter, but without the 'android: exported' property set. This file can't be installed on Android 12 or higher. See developer.android.com/about/versions/12/behavior-changes-12#exported
Pls help me with these errors
They don't help
Guys anyone can help me with photon?
why doesn't the dots forum have a proper discussion channel instead of the forum mode
There's a general discussion thread pinned in the forum. It's practically the same thing, since threads behave the same as channels in Discord.
Hello i got this error in Google Play Console After trying to upload an aab file:
APK or Android App Bundle which has an activity, activity alias, service, or broadcast receiver with intent filter, but without the 'android: exported' property set. This file can't be installed on Android 12 or higher. See developer.android.com/about/versions/12/behavior-changes-12#exported
Cool thanks you
Okay question, why should I use PropertyName when strings are immutable in memory and have very efficient look ups since you aren't checking every character, but the memory location of the strings?
Like comparing memory addresses is just as fast as comparing ints. Even at that now you are adding a hash to get the int value of the string!
Like the comment on PropertyName is
// Summary:
// Represents a string as an int for efficient lookup and comparison. Use this for
// common PropertyNames. Internally stores just an int to represent the string.
// A PropertyName can be created from a string but can not be converted back to
// a string. The same string always results in the same int representing that string.
// Thus this is a very efficient string representation in both memory and speed
// when all you need is comparison. PropertyName is serializable. ToString() is
// only implemented for debugging purposes in the editor it returns "theName:3737"
// in the player it returns "Unknown:3737".
which indecates to me either some tomfoolery going between C++ and C#. Or someone who doesn't understand how strings work in C#.
Even if it is going between c++ and C# why not just pass the string address to c++!
Comparing multiple memory address/values is not as fast comparing 1 int ...? I don't really know how string memory is managed, but it seems to me that you may be talking about String.Intern which is not done on every string. In the event that the string is interned, it would be, like you said, better to do a reference comparison. Otherwise, we still require to compare the individual character of the string. Look into the following for more information: https://learn.microsoft.com/en-us/dotnet/api/system.string.intern?view=net-7.0
Also, immutable in memory does not mean that something is placed in a lookup table.
Also a pointer comparison should be the same performance as an int comparison, as they both are 32bits in memory. And both the string pointer and int would be on the stack.
What you are trying to point out with your reference ? I'm not really sure I get what you want to show.
Also strings instances are stored in the heap, if you try to mutate a string(aka make a new string) it doesn't change the current string on the heap, but creates a new string. This process is less performant, which is why in .net 7+ they created a new way of spliting strings by making sub pointers to the strings on the heap.
That if you are trying to compare strings there are multiple ways of doing it, and a simple object reference comparison is enough for the equivalent need of int comparison.
Except that the string wont be the same object if the are not interned.
string s1 = "MyTest";
string s2 = new StringBuilder().Append("My").Append("Test").ToString();
string s3 = String.Intern(s2);
Console.WriteLine((Object)s2==(Object)s1); // Different references.
Console.WriteLine((Object)s3==(Object)s1); // The same reference.```
okay, so why make a weird internal logic when there is already implemented logic that is just as good?
Because there is a cost in interning a string ?
there is a cost to hashing a string
Less then interning
have you benchmarked that?
Could you ? I'm following the documentation.
That is a great article
So small small performance increase, abasically over engineering.
wait that doesn't include the overhead of hashing strings
Also hashing does have collisions where true string reference comparison won't.
I'm not sure I'm seeing what you want to show. It does not compare hash values vs interned string values.
You also need to take in consideration memory.
Most string are not interned which means that you would need to create a reference in the lookup table for each string.
Each string, being multiple bytes
Where with an hash, you could hold a single int.
By the time memory would be an issue for either you would be facing much bigger problems on both sides.
Also
Figure 2 shows the times for searching for the known string. All the times are pretty small for these collection sizes, but the growths are clear.
Not really, each application do have a lot of unique string in use.
Hashset being better
for 600,000 look ups it was only 22ns
wait sorry for normal strings
for intern it was 4ns
It sure is close, but is there any reason to use intern and all of its down side when you could use an hashset which is better ?
the difference of making the Lists was greater than that for favor if intern strings
Which is a significant cost if we are working with unique string.
There are work arounds to the issue you are seeing in strings also. I see a code smell making people interact with a made up type just to have simple hash(why not just ask for the user to hash the string). For example if string size is your main complaint just have it change the strings on compile to smaller unique strings, which wouldn't have the collision issue of hash.
Though my main complaint is that this is a code smell, and over engineering.
It is an engine, being use by a lot and a lot of people. We want it to be over engineering. I would agree, if it was intern to your company being use on one 1 project, but we are talking about something that will be use by millions of people, we do not have the same values.
The issue you have, is that the PropertyName is being limited in size ?
The people interacting with this on coding side all know what hashing a string is, I had to look at the backworkings of your "Simple" solution to just come to the conclusion it is a hash.
I'm not sure to follow you, because I have not face any issue about this particular thing. I did not even know it was something before.
Then why are you arguing with my if you have no opinion? And yes it is clear you aren't fallowing.
Because I want to learn. You were pointing some element which I found interesting and I wanted to know more.
In what component PropertyName are use ? In animation state name ?
Issues as fallows.
Having a custom type just to hash a string is a code smell.
Having the main form of interaction of something being string, forced on my side of things to a costume type just to be put back on their side as a hash/int is a code smell.
The performance "gains" on this is over engineering and a code smell.
Playables API
Which is the backend of the animator. I see. What issue did you face with them ?
You can use the int version in the animator, I'm sure with the Playables API.
Why I am facing this is because their INotification interface requires a prop of type PropertyName, which now adds complexity to my code when it could have just been an int.
I see. You are frustrated because you cannot control the type of your ID. It is understandable.
It creates un-needed coupling, and complexity. It isn't about controlling the type of the ID. This is bad design aka code smell.
In fact, it could be the inverse if you are following the principle of Primitive Obsession.
Hey, is there somebody who could tell me how to get the 'visual' centroid point of an 2D concave shape?
By visual I rather mean the point inside the shape, which is visually the center of that shape
This isn't a high level domain concepts, let alone it is reverting back to a low level type. It is just a wrapper for a low level concept.
All ID are susceptible to primitive obsession.
Well I would argue the other impacts of coupling and complexity for such a simple concept it greater than that.
The center of mass could be a way to try to find the "visual" center of your object.
I tried it but with some shapes it's still possible to get point outside. The problem is I want to add text label inside the room. The room is created by the player and can be in any shape he wants (of course without intersections)
Because now when ever someone needs to know what my code is doing they need to understand what a PropertyName is, as like even you didn't know what it was, and with it being a struct they may make changes to it that break my functionality in the future, when ultimately it is just a wrapper of a hash.
Sorry to butt in. Is there a way to define a type as the public fields of a class? I'm trying to create a data container that can override the data in another instance of the container. User will be able to choose what to override. I'm thinking of just using a list of fields that are overridden and would like some static typing
You would need to define the center then. By example, what is the center of the following figure, where the black is the room.
Not sure what you mean. You can define nested class as public.
If you treat the black area as the room I would say the top & bottom meets the criteria. Knowing the label has it's width and height the left-right bars would not fit the rectangle without rotating
@fallen magnet, do you mean a generic class https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics
Would that be a "nice" place ?
I would say it is:
Not sure why the vertical one are not correct.
Not sure where this goes as it's not directly shader related but:
Say I'm doing all rendering with a compute shader, the only step after that is plastering a renderTex on a quad and putting it in front of the camera, how much unnecessary work do you think unity's render pipeline is doing? I don't know if it's worth looking into doing a custom pipeline or not.
I define my enemy AI with a scriptableobject. That AI is a state machine and some states will have modified properties, but I want most to be shared. So, I want to define state specific parameters as an override so the designer can easily whip up new enemies by defining a base settings file and then overriding individual values. For example, by default, the enemy's move speed could be 5, but an enemy that's chasing the player will need to move faster, so the pursuit state will have an override of 10 but the rest of the settings will carry over from the default.
How do we know what the user wants to override? My idea right now is to store the name of the property in a list. I can use a list of strings, but I'd prefer type safety
You are describing a prefab.
Where it is true you would want to use Scriptable Object, a prefab would be what you need to rapidly solve your issue.
Otherwise, I would work an editor that would copy the behaviour of a prefab
I'm creating an editor for it
asking this again bc I haven't been able to find an answer in the last few days:
is there a way to create a computeBuffer whose element count depends on the contents of a shader value/buffer? Something like indirect args but for compute buffers.
The override logic is a solved problem
What is the issue then ?
For the editor, I want a dropdown where the designers can select the property they want to override. I want to populate that dropdown with all public fields of a class and while I can get that via reflection, I'd like type safety if possible. So I'm asking whether I can create a type or an enum that is "all public fields of class X"
You could use code generation approach.
Create a partial class.
From the editor, reads the property by reflection.
Then write them in the class.
that sounds like it would work really well. Can you show me some documentation for the relevant classes?
There is not much documentation on the subject unfortunately. I would say that you should be able to figure out the concept easily though. WPF is the best example you could find of program using code generation. Here is a link to the official documentation: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods
beautiful, thank you so much!
I'm not sure I understand your issue. I am not an expert in computesharder, but if you describe your issue maybe we could workout something.
Doing so should not cost anything, but you should look into Scriptable Pipeline instead of that. https://docs.unity3d.com/Manual/srp-custom.html
I'm trying to do some compute shader mesh generation (variation on marching squares) where the vertex/index count per tile is determined in the compute shader, then summed. I want to be able to use this sum to determine the necessary vertex/index buffer size, rather than overestimating.
to me this seems similar to the system of indirect args buffers for dispatching compute shaders, where the GPU is instructed to use the contents of a buffer already on it to determine the number of thread groups
It is possible to send arguments to a compute shader. Is this what you want to do ?
not really. I want to be able to allocate a vertex/index buffer whose element count is determined by the value of a shader variable/buffer
so that I'm able to compact my vertex/index buffers
You want to allocate a buffer for vertex/index for mesh that has been generated or that will be generated ?
will be generated
You then want to use the data from the shader
Is the operation done in loading ?
I'm not sure what you mean by "operation" or "in loading"
Is all the mesh generated before hand, before the player interacts with them.
yes, the compute shader is run once, then the data is read back to the CPU
If I remember correctly, cube marshing is a finite amount of meshes ?
it is, however each tile can have a different amount of vertices and triangles. there's two approaches to allocating buffers that I've seen, but both seem inadequate.
-
set a maximum number of vertices/indices per tile, and calculate where to write them based on the tile index (oops wrote triangle instead of tile)
-
set a maximum number of vertices/indices overall, and use a counter buffer to track where to write the next element
I'd like to use a parallel scan to determine which index to write at (not important to this issue) but this requires me to read back a shader value in order to allocate each buffer without overestimating
If I remember correctly, we can generate all the meshes before hand then assign the correct meshes in runtime without needing to do anything special.
I would generate all the meshes before hand (before runtime).
Combine them in one meshes.
Use the appropriate meshes given a value on the shader.
No need to do any transfer from a compute shader to a shader. (I don't think it is possible)
I never done something like that, but knowing that static bashing is a thing, I wouldnt be surprise you can do that or something similar. Maybe you would need to make your draw call thought.
You could always use the meshrendering component of unity.
You also could use instancing (which should be better) for your batching and not combine them .
All of that, given that I remember correctly cube marshing.
Oh, and your compute shader would only serve in defining which mesh to use.
I'm building my first multiplayer card game and not sure how best to design how cards are referenced by the server (@undone coral, i recall you have a lot of experience in this area).
at the moment, cards are SOs that contain a type reference to its effect/controller - I then have a card pool SO with a list of these cards.
when a client wants to play a card, it sends that card's ID to the server. The server then searches the card pool for that card's ID, does some validation, and then activates an instance of that card's controller to play it.
I feel like my approach is not the most performant or the cleanest - namely, iterating through the card pool and using reflection to grab it's controller. I've thought about the server sorting the card pool by ID on game load so it can then use an index instead, but that doesn't solve the reflection issue, and also feels like I might be digging deeper into the wrong approach rather than finding a more suitable one
What purpose are those SOs actually serving? Move your logic into them and you no longer need any reflection. Indexing your cards by ID when the game loads (or in a content db or caching layer of some kind) seems very reasonable to me.
The SOs themselves hold a card's shared data (name, cost, description, type etc). I'm not sure how I'd be able to achieve that without having a unique SO for each card. I'm not sure how I feel about that
How is that 'shared' data? Doesn't each card have a unique name, cost, description, etc which need to be individually specified somewhere (like a an SO instance)?
Sorry, I wasn't being very clear.
The SO contains data that is common between all cards. The controller is the plain C# class that contains the cast logic.
It effectively works the same way as it would if I had a base SO and created a derived SO for each class
I'm just trying to understand how you get around having an SO per card
because without that piece I have no idea what you're doing
I have an SO instance per card, but they all share the same SO
they share the same...class?
Yes
That doesn't mean they have shared data
@sly grove - I miswrote, this is what I was trying to get across ^