#coroutine
Explore tagged Tumblr posts
mrmatrix1 · 1 year ago
Text
Coroutine Gotchas – Dispatchers | Blog | bol.com
This takes approximately 2,7 seconds to finish, quite a latency to collect some data. In this example, every RestTemplate call blocks the thread it is running on until the call returns some data and then hands over the thread to the next RestTemplate call. It works like this because RestTemplate, by nature, is a synchronous, blocking operation. If you want to know how blocking and non-blocking…
View On WordPress
0 notes
tinchicus · 1 month ago
Text
Hoy veremos un concepto que es muy utilizado en otros lenguajes y aqui es todo una novedad como son las corutinas. Espero les sea de utilidad y tengan un buen finde!
0 notes
sumikatt · 1 month ago
Text
Tumblr media
i feel like you can tell i learned coding on scratch dot mit dot edu
0 notes
theskyexists · 1 year ago
Text
Managed to get something done that the documentation and most topics seemed to say was not possible. It is possible.
1 note · View note
milkshakebattlecat · 1 year ago
Text
Tumblr media
here's more on how to make an RPG-like text writing system! To complete the text upon key press, you'll want to make two new bools for control and add this^ to your Update function. Checking for typeTextCoroutineRunning will prevent you from setting inputDetected true when the text isn't even being written.
For the input detection, you can choose to look for any key press you like; I like to use anyKeyDown which picks up any key press as well as mouse clicks.
Tumblr media
then just add these checks to the TypeText function and it should work accordingly!
to note, however you go about displaying text, you'll want to make sure that two TypeText routines don't run at the same time or you'd get some weird results. for my use, I have another coroutine which calls TypeText and waits for it to finish before proceeding to whatever needs to happen next. like this:
Tumblr media
1 note · View note
foone · 2 years ago
Text
A fun thing about computer skills is that as you have more of them, the number of computer problems you have doesn't go down.
This is because as a beginner, you have troubles because you don't have much knowledge.
But then you learn a bunch more, and now you've got the skills to do a bunch of stuff, so you run into a lot of problems because you're doing so much stuff, and only an expert could figure them out.
But then one day you are an expert. You can reprogram everything and build new hardware! You understand all the various layers of tech!
And your problems are now legendary. You are trying things no one else has ever tried. You Google them and get zero results, or at best one forum post from 1997. You discover bugs in the silicon of obscure processors. You crash your compiler. Your software gets cited in academic papers because you accidently discovered a new mathematical proof while trying to remote control a vibrator. You can't use the wifi on your main laptop because you wrote your own uefi implementation and Intel has a bug in their firmware that they haven't fixed yet, no matter how much you email them. You post on mastodon about your technical issue and the most common replies are names of psychiatric medications. You have written your own OS but there arent many programs for it because no one else understands how they have to write apps as a small federation of coroutine-based microservices. You ask for help and get Pagliacci'd, constantly.
But this is the natural of computer skills: as you know more, your problems don't get easier, they just get weirder.
33K notes · View notes
loveletterworm · 2 years ago
Text
Hmm. Hmm. Well it seems to be working thus far, but the input script does have an error message on launch now for some reason. And updating that script will not help me, because that script now labels itself as being for the long term stable. Which i was not using at any point.
1 note · View note
sunless-not-sinless · 1 year ago
Text
shitGPT
for uni im going to be coding with a chatGPT user, so i decided to see how good it is at coding (sure ive heard it can code, but theres a massive difference between being able to code and being able to code well).
i will complain about a specific project i asked it to make and improve on under the cut, but i will copy my conclusion from the bottom of the post and paste it up here.
-
conclusion: it (mostly) writes code that works, but isnt great. but this is actually a pretty big problem imo. as more and more people are using this to learn how to code, or getting examples of functions, theyre going to be learning from pretty bad code. and then theres what im going to be experiencing, coding with someone who uses this tool. theres going to be easily improvable code that the quote unquote writer wont fully understand going into a codebase with my name of it - a codebase which we will need present for our degree. even though the code is not the main part of this project (well, the quality of the code at least. you need it to be able to run and thats about it) its still a shitty feeling having my name attached to code of this quality.
and also it is possible to get it to write good (readable, idiomatic, efficient enough) code, but only if you can write this code yourself (and are willing to spend more time arguing with the AI than you would writing the code.) most of the things i pointed out to the AI was stuff that someone using this as a learning resource wont know about. if it never gives you static methods, class methods, ABCs, coroutines, type hints, multi-file programs, etc without you explicitly asking for them then its use is limited at best. and people who think that its a tool that can take all the info they need, and give it back to them in a concise, readable way (which is a surprising lot of people) will be missing out without even knowing about it.
i got it to write tic-tac-toe (the standard babee) in python (the lang i have to use for uni ;-; (held at gunpoint here)). my specific prompt was "write me a python program for tictactoe that is written in an object oriented way and allows for future expansion via multiple files"
it separated it into three files below (which i think would run, but i never actually ran any of this code. just reading and judging)
Tumblr media Tumblr media Tumblr media
why does board use display instead of __str__ and __repr__?
why is the board stored as 1d instead of 2d? thats just confusing
why does it never early return aside from check_winner? (not a big issue here but kept on choosing to never early return when i asked it to add more methods)
why is there no handling of non-number user inputs?
why are non-int inputs truncated instead of telling the user that they should input ints only?
why is display implemented like that?
why are so many lines so bloody long (wide)?
why is there a redundant self.check_winner() after the while loop in TicTaacToe.play()? and if it wasnt redundant then you could finish the game without there being anything printed telling you that the game is finished?
why is the only comment useless? (this comment wouldnt be useless if it was a doc comment tho, but it aint a doc comment. speaking of, why is there no doc comments?)
these are the more immediate things i saw, but there are other things that are bad here.
whenever i write * this is where it updated the api without changing any usage of the api.
so i ask it to change board.display into __str__ and __repr__, it changes it to __str__*, it does not add a __repr__. asking it to add a __repr__ 1) removes the __str__ and 2) gives me this (the other methods are unchanged)
Tumblr media
what. the. fuck. this would imply that board takes in an argument for the boardstate, but it clearly doesnt. after 4 more asks it finally has both __str__ and __repr__, without fixing the fact its implying board takes an optional arg, so i get it to add this arg. anything that needs to print the board still calls display btw.
the reasoning it gave for using display over the repr and str magics was this
While using __str__ and __repr__ is a more idiomatic approach in Python, choosing to have a separate display method can still be a valid choice, especially if the display logic is more complex or if you want to keep the __str__ method for a more concise or formal representation of the object.
which, erm what? why would __str__ be for a concise or formal repr when thats what __repr__ is for? who cares about how complex the logic is. youre calling this every time you print, so move the logic into __str__. it makes no difference for the performance of the program (if you had a very expensive func that prints smth, and you dont want it to run every time you try to print the obj then its understandable to implement that alongside str and repr)
it also said the difference between __str__ and __repr__ every damn time, which if youre asking it to implement these magics then surely you already know the difference?
but okay, one issue down and that took what? 5-10 minutes? and it wouldve taken 1 minute tops to do it yourself?
okay next implementing a tic-tac-toe board as a 1d array is fine, but kinda weird when 2d arrays exist. this one is just personal preference though so i got it to change it to a 2d list*. it changed the init method to this
Tumblr media
tumblr wont let me add alt text to this image so:
[begin ID: Python code that generates a 2D array using nested list comprehensions. end ID]
which works, but just use [[" "] * 3 for _ in range(3)]. the only advantage listcomps have here over multiplying is that they create new lists, instead of copying the pointers. but if you update a cell it will change that pointer. you only need listcomps for the outermost level.
again, this is mainly personal preference, nothing major. but it does show that chatgpt gives u sloppy code
(also if you notice it got rid of the board argument lol)
now i had to explicitly get it to change is_full and make_move. methods in the same damn class that would be changed by changing to a 2d array. this sorta shit should be done automatically lol
it changed make_move by taking row and col args, which is a shitty decision coz it asks for a pos 1-9, so anything that calls make_move would have to change this to a row and col. so i got it to make a func thatll do this for the board class
what i was hoping for: a static method that is called inside make_move
what i got: a standalone function that is not inside any class that isnt early exited
Tumblr media
the fuck is this supposed to do if its never called?
so i had to tell it to put it in the class as a static method, and get it to call it. i had to tell it to call this function holy hell
like what is this?
Tumblr media
i cant believe it wrote this method without ever calling it!
and - AND - theres this code here that WILL run when this file is imported
Tumblr media
which, errrr, this files entire point is being imported innit. if youre going to have example usage check if __name__ = "__main__" and dont store vars as globals
now i finally asked it to update the other classes not that the api has changed (hoping it would change the implementation of make_move to use the static method.) (it didnt.)
Player.make_move is now defined recursively in a way that doesnt work. yippe! why not propagate the error ill never know.
Tumblr media
also why is there so much shit in the try block? its not clear which part needs to be error checked and it also makes the prints go offscreen.
after getting it to fix the static method not being called, and the try block being overcrowded (not getting it to propagate the error yet) i got it to add type hints (if u coding python, add type hints. please. itll make me happy)
now for the next 5 asks it changed 0 code. nothing at all. regardless of what i asked it to do. fucks sake.
also look at this type hint
Tumblr media
what
the
hell
is
this
?
why is it Optional[str]???????? the hell??? at no point is it anything but a char. either write it as Optional[list[list[char]]] or Optional[list[list]], either works fine. just - dont bloody do this
also does anything look wrong with this type hint?
Tumblr media
a bloody optional when its not optional
so i got it to remove this optional. it sure as hell got rid of optional
Tumblr media
it sure as hell got rid of optional
now i was just trying to make board.py more readable. its been maybe half an hour at this point? i just want to move on.
it did not want to write PEP 8 code, but oh well. fuck it we ball, its not like it again decided to stop changing any code
Tumblr media
(i lied)
but anyway one file down two to go, they were more of the same so i eventually gave up (i wont say each and every issue i had with the code. you get the gist. yes a lot of it didnt work)
conclusion: as you probably saw, it (mostly) writes code that works, but isnt great. but this is actually a pretty big problem imo. as more and more people are using this to learn how to code, or getting examples of functions, theyre going to be learning from pretty bad code. and then theres what im going to be experiencing, coding with someone who uses this tool. theres going to be easily improvable code that the quote unquote writer wont fully understand going into a codebase with my name of it - a codebase which we will need present for our degree. even though the code is not the main part of this project (well, the quality of the code at least. you need it to be able to run and thats about it) its still a shitty feeling having my name attached to code of this quality.
and also it is possible to get it to write good (readable, idiomatic, efficient enough) code, but only if you can write this code yourself (and are willing to spend more time arguing with the AI than you would writing the code.) most of the things i pointed out to the AI was stuff that someone using this as a learning resource wont know about. if it never gives you static methods, class methods, ABCs, coroutines, type hints, multi-file programs, etc without you explicitly asking for them then its use is limited at best. and people who think that its a tool that can take all the info they need, and give it back to them in a concise, readable way (which is a surprising lot of people) will be missing out without even knowing about it.
40 notes · View notes
piratesexmachine420 · 7 months ago
Text
I love (despise) how Ruby mangles common terms and keywords for no reason other than, I assume, to annoy me.
"throw" and "catch" are used to break out of tightly-nest loops or other control structures. (throwing and catching exceptions are done with "raise" and "rescue", respectively)
"lambda" defines a closure, not a lambda.
"yield" is used to call a closure passed as an argument. (I have no idea how coroutines are implemented, if at all.)
"collect" is a synonym for "map".
"Iterators" are exclusively internal iterator methods; "Enumerators" are external iterator types. (.NET does this too, and I don't give either of them slack for it.)
And likely many more. What are we doing here.
7 notes · View notes
ar-fmp-year-2 · 1 month ago
Text
Development - 02/04 pt1
Here's the plan for the rest of today:
Tumblr media
So first I make a frame to support all the states inside of a coroutine:
Tumblr media
The plan is that it will repeat a cycle of states:
sleep -> stalk -> flee -> hunt / stalk -> sleep
I don't want the player to be attacked too much, as the less it attacks the more suspense is built between the attacks. I also make the sleep and flee states abundant as I want the player to be able to explore and loot without there being too much inference as I don't want the player to become annoyed or frustrated.
I also want it to be very obvious when he is in the hunt stage, I can achieve this by making the foot steps of the monster are very loud and very quick; generating panic within the player.
So I was making the sleep state first, as this is always going to be the starting state; but after testing I realized that the monster wasn't coming out of the state. Upon further inspection I realize that the do/while method would keep resetting the timer so that it would never end:
Tumblr media
So after making a boolean to control whether the timer resets or not:
Tumblr media
I try it out, and it freezes... The infamous while loop causing issues once again.
This time I really do need the while loop for this script, so I take a look at why it might be doing this, and find this on StackOverflow:
Tumblr media
So I tried this:
Tumblr media
And wow, it works just fine. This knowledge will be very useful in later projects as I have always tried to stay away from the while loop.
Now that the state changes work, I make the stalk state:
Tumblr media
And then the flee state:
Tumblr media
At the moment, he looks a little silly when fleeing:
3 notes · View notes
amadeusgame · 9 months ago
Text
I have spent today working on what i thought would be a simple problem but turned out to be an immense headache. But the issues I encountered in figuring it out actually inspired me to build something fun and cool on purpose!
I'd already coded a mechanic that dynamically shows the text of the game letter-by-letter, and also allows for extra pauses mid-text.
As of yesterday, I started learning a lot more about TextMesh Pro in Unity, and wanted to experiment with changing styles/fonts mid-text. There are specific use cases for this in Amadeus that I think I can have a lot of fun with.
...This is a problem, because with my dynamic text mechanic, it would literally start typing the rich text codes (" <color="red"><font=... ") on screen like it did with all of the other text, and is not interpreted as code until all of the letters of the text codes have been written one-by-one.
Tumblr media
^ Not the user experience you want for your visual novel.
So I spent all day completely re-working how my text appearance mechanic works so that it still does the dynamic pauses, still can read rich text tags, and also doesn't show any of the rich text tags (it types them all at once so you don't see them appear). You might think this would be simple but let me tell you: it was not.
Anyway, when I was 90% of the way there I encountered this funky glitch, because I hadn't properly rewritten my new text appearance coroutine. It made this kind of stuttery spooky text appear:
Tumblr media
....and I thought it was really cool, although decidedly not what I was trying to do.
I did eventually get it to do what I actually want it to do! [You'll just have to imagine that it is appearing letter by letter, with dramatic pauses, and that the text codes were not drawn on-screen.]
Tumblr media
.....but I really thought I might want to keep the stuttery spooky text in my back pocket for later, so I actually created a switch I can toggle if I want to make fucked up text on purpose!
Tumblr media
Anyway, I'm not sure precisely where I will actually use this but I fully intend to. [rubs hands together evilly]
13 notes · View notes
blake447 · 1 year ago
Text
Alright! We've made a little more progress on the Dungeon Generation. And we threw it onto a coroutine so we can watch the triangulation in action. Now what I'm doing here is just brute forcing over all triangles after we've added a new point, and we calculate a value based on this matrices' determinant (image courtesy of wikipedia).
Tumblr media
Now, what this is supposed to do is find some kind of "optimal" triangulation that minimizes the minimum angle, but you can see from the video that it's having a hard time deciding how to flip some triangles, which shouldn't happen.
Tumblr media
We'll get back to that later, but for now, lets go into detail about how I'm flipping these triangles. Time to bust out the Remarkable2 again
Tumblr media
We start with our previous representation of the triangles. Recall a tri is a pointer to 3 edges, which are themselves an array of 2 pointers to a set of vertices. The order matters and determines the orientation, but we can always calculate that on the fly and optimize it with clever tricks later. I start by brute forcing to see if they share any pairs of vertices in each edge. Note that the edges are non-unique and have repeating arrays, but the vertices are singular and absolute, so we can just compare their references for matching.
Tumblr media
Next we want to begin swapping the triangulation. By brute forcing (yeah look, I'm just trying to get this working lol) a search to find the local index of the edge the triangles share, for each triangle. Once we have the shared edges, we need to find the two points that are not shared. We can do this by taking advantage of the orientation of the triangles and moving on to the next edge in the circuit, then taking the endpoint of that edge.
Tumblr media
From here, we replace the shared edges with a new edge consisting of the two non-shared vertices, and arbitrarily choose to preserve the next segment after the old shared edge entirely. Mapping out what each edge now belongs to, we see we need to swap the previous edges to the old shared one, and we will get ourselves a new swapped triangulation. Note that non-convex triangles will cause complications, and run the risk of overlapping other already existing triangles. Additionally, we will need to recalculate the orientation of the triangle, which I covered along with the ground work in Part I of the post here
As for what comes next, I have to fix the triangulation calculations so that it actually functions correctly, because as of right now it appears to be about a 50-50 tossup that any given triangle ends up correct, which is slightly better than all of them being wrong I guess
Tumblr media
Here I though this would be quick and easy, in and out lol
20 notes · View notes
ceausescue · 2 months ago
Text
i feel like it's probably possible to have full go-style coroutines with a correct borrow checker. just stacks innit
4 notes · View notes
kawaoneechan · 3 months ago
Text
So I recently watched an old video about unsafe Lua in emulators. Teal deer, the main issue was that the Lua interpreters those emulators use apparently have the IO and OS libraries loaded, which lets the script shown in the video write an .exe file and run it.
In Project Special K, I recently extended Lua to load more than just the coroutines library, including the base library, but not IO or OS. Because I may be a dumbass, but I'm not stupid. And you may notice looking at that commit that I'm disabling some of the base functions like dofile, load, loadfile, and loadstring.
The ones that take a file path are the most obvious as to why I'd disable them: PSK has a virtual file system and any Lua scripts running in there absolutely should not be able to access arbitrary files outside of the VFS.
If a script needs to invoke another, surely something can be arranged. But other than that, what do you think? I could perhaps provide a means to read (but not write) files in the VFS, but should I?
Am I just stalling the skeletal animation thing again? Yes, yes I am.
6 notes · View notes
milkshakebattlecat · 8 months ago
Text
Tumblr media
I dislike using rigidbodies to move my objects because physics interactions can sometimes go ham and while that can be very amusing, I prefer things to be predictable. So for moving arrows in this game I handled the movement math myself via coroutine. Let's take a look-see, shall we? :3
Tumblr media
The goal of this coroutine is to move its symbol object in an arcing motion from its initial position, moving it upward and to either the right or left. Then it will fall downward. Rather than having each symbol object run this coroutine from an attached script, I am using a central script (my GameManager) to apply this movement to a given object, so the first thing I do is make sure the symbol still exists before proceeding with the coroutine:
Tumblr media
If we find that our symbol has been destroyed, we exit the coroutine with "yield break". You wouldn't need this check if the script is running this movement on its own object, as coroutines are ended upon an object's destruction.
There are a bunch of variables we'll define within our coroutine to calculate our desired motion; we'll start by defining an arcDuration:
Tumblr media
This determines how long the object will take to move in the arc shape. A shorter duration results in faster movement. Using a random amount between a min and max duration creates some variance in how fast different symbol objects will move. I have my minArcDuration set to 1 and maxArcDuration set to 2.5 for quick bouncy movements.
Tumblr media
These variables referencing the outermost bounds of the camera's view will be used to ensure that symbols remain within the visible area of the camera at all times. I'm not using a topBound because I'm fine with symbols possibly going off the top of the screen, but I use a maxArcHeight variable that is set low enough that they never do.
Tumblr media
For even more spawn variability, we add a little randomness to our starting point. My spawnPointVariance is set very low at 0.3; my initial symbol spawn position is low on the screen, and due to how the rest of this coroutine works, it's important that the symbols are never allowed to spawn below the bottomBound or else they will be instantly deleted (and result in a miss!)
Tumblr media
The height here is, of course, how far up the symbol will travel, and the distance refers to how far it will move to the left or right. We calculate the peak of the arc by adding our distance and height to the x and y values of our starting position. Randomizing between negative and positive distance values for our x position adds another layer of variability which includes the possibility of moving either left or right, even though our minArcDistance and maxArcDistance are both set to positive values for clarity (mine are set to 1 and 6).
Tumblr media
This is the part of the code that decides upon our symbol's speed by calculating the distance it has to cover from its start to its peak. By dividing our horizontalDistance by our arcDuration (distance divided by time), we calculate how fast the symbol needs to move to cover the entire distance in the given duration. Mathf.Abs is used to ensure that horizontalDistance is always positive, lest we get a negative value that causes us to move in the opposite of the intended direction.
Tumblr media
We'll also want a speed variable for when the arcing motion ends and the symbol starts falling, that's where downwardSpeed comes in. In earlier versions of this function, I used downwardSpeed alone to transform the object's position, but I've since refined the logic to take the current horizontalSpeed into account for more consistent motion; we'll see that later. (Also you can see I've been tweaking that arbitrary range a bit... the fall speed was brutal during those mass waves ;o;)
Tumblr media
Here we create an elapsedTime variable starting at 0. In our while loop, we will use this variable to count how much time has passed, and if it becomes greater than or equal to arcDuration, we'll change isFalling to true and begin moving down.
We create a Vector3 moveDirection which gives the vector pointing from the startPosition to the peakPosition, and then turn it into Vector3 horizontalDirection, which retains only the X-axis direction. Both values are normalized to ensure consistency. Without normalization, the magnitude (or distance) of the vector would vary depending on the distance between the start and peak positions, which could result in inconsistent speed. Normalization caps the magnitude at 1, meaning the vector represents just the direction, not the distance, allowing for consistent speed calculation later.
Tumblr media
Here's how we start our while loop: as long as our symbol object is not null and the game says we canMove, we say yield return null, which will instruct our loop to occur every frame. If either the symbol becomes null or canMove becomes false, the while loop will end and so will the coroutine - for this reason, I only set canMove false when the game ends and the symbols will never have to resume movement, rather than in cases where I want them to pause movement and resume later, such as when a player pauses the game or during level-up periods. For the latter I use an isLevelingUp bool in my while loop that waits until that bool is false before proceeding (yield return new WaitUntil(() => !isLevelingUp)), and for the former I actually change the game Time.timeScale to 0, which is not typically recommend but fuck it we doin it live, because I don't have a mechanism for resuming this function with appropriate variables if it is stopped. It could surely be done if you just store the local variables somehow.
Tumblr media
This is the first part of our movement logic that we put in the while loop; remember we already set isFalling false, so this part will proceed with the rising motion.
Tumblr media
We count our elapsedTime here by adding Time.deltaTime, a variable which represents the time in seconds that has passed since the last frame, ensuring that time calculation is frame-rate independent. Do NOT use Time.time in cases like this unless you want your users with varying computer specs to all have different experiences with your game for some insane, villainous reason
The variable 't' is looking at the elapsedTime divided by arcDuration, a ratio that tells us how far along we are in the arc movement. If elapsedTime equals arcDuration, this ratio would be 1, meaning the arc is complete. We use Mathf.Clamp01 to clamp this value between 0 and 1, ensuring that it won't ever go higher than 1, so that we can use it to calculate our desired arcPosition and be sure it never exceeds a certain point due to frame lag or some such. If 't' is allowed to exceed 1, the arcPos calculation could possibly go beyond the intended peakPos. We are going for predictable motion, so this is no good
Tumblr media
We define our Vector3 arcPos with Vector3.Lerp, short for "Linear Interpolation", a function for calculating smooth transition between two points overtime. Ours takes our startPos and peakPos and moves our symbol between the two values according to the value of 't' which is incrementing every frame with Time.deltaTime. As 't' progresses from 0 to 1, Vector3.Lerp interpolates linearly between startPos and peakPos, so when 't' is 0, arcPos is exactly at startPos. When 't' is 1, arcPos reaches peakPos. For values of 't' between 0 and 1, arcPos is smoothly positioned between these two points. Very useful function, I be lerping for days
Then we alter the y coordinate of our arcPos by adding a calculation meant to create smooth, curved arc shape on the y axis, giving our object its rounded, bouncy trajectory. Without this calculation, you'll see your symbols rising and falling sharply without any of that rounded motion. This uses some functions I am not as familiar with and an explanation of the math involved is beyond my potato brain, but here's a chatgpt explanation of how it works:
Mathf.Sin(t * Mathf.PI): This calculates a sinusoidal wave based on the value of t. Mathf.PI represents half of a full circle in radians (180 degrees), creating a smooth curve. At t = 0, Mathf.Sin(0 * Mathf.PI) is 0, so there’s no vertical displacement. At t = 0.5, Mathf.Sin(0.5 * Mathf.PI) is 1, reaching the maximum vertical displacement (the peak height of the arc). At t = 1, Mathf.Sin(1 * Mathf.PI) returns to 0, completing the arc with no vertical displacement. This scales the vertical displacement to ensure the arc reaches the desired height. If height is 10, then at the peak, the symbol moves 10 units up.
Tumblr media
With those positions calculated, we can calculate the "newX" variable which represents where we want our symbol to appear along the x axis. It adds the horizontal movement to the current x coordinate, adjusted for the time passed since the last frame.
We use Mathf.Clamp to ensure our newX value doesn't exceed either the left or right bounds of the screen. This function limits the given value to be between min and max value.
Tumblr media
Finally we tell our loop to actually reposition the symbol object by creating a new Vector3 out of newX, arcPos.y, and using our symbol's own z coordinate. That last bit is important to ensure your sprite visibility/hierarchy doesn't go out of whack! If I used arcPos.z there instead, for example, it's likely my sprites would no longer be visible to my camera. The z position the symbol spawned at is the z position I want it to retain. Your needs may vary.
Tumblr media
This part tells us our arcDuration should end, so we set isFalling to true, which will cause the secondary logic in our while loop to trigger:
Tumblr media
Previously, objects retained their x position and only had negative downwardSpeed applied to their y position, but I didn't like that behaviour as it looked a little wonky (symbols would reach their arc peak and then suddenly stop and drop in a straight line downward).
Tumblr media
By creating a new Vector3 fallDirection that retains the horizontalDirection and horizontalSpeed from the arc phase, we're able to apply smooth downward motion to the symbol that continues to the left or right.
Just below that, we once again clamp the symbol's x position to the left and right screen bounds so the symbols can't travel offscreen:
Tumblr media
The loop would continue causing the symbols to fall forever if we didn't have this check:
Tumblr media
which triggers some project specific logic and destroys the symbol, then exits the coroutine with "yield break". Although the coroutine already exits when the symbol becomes null, which it will see is the case in the next frame as we destroyed the symbol here, adding an explicit yield break is an added layer of security to ensure predictability. Once again, not super necessary if you decide to run this code from the moving object itself, but just be sure you move your Destroy() request to the bottom of any logic in that case, as nothing after that point would be able to trigger if you destroy the object which is running the coroutine!
and that's all folks. If this helps you make something, show me!
HEY, did you really make it all the way to the end of this post?! ilu :3 Do let me know if this kind of gratuitous code breakdown interests you and I will summon motivation to make more such posts. I personally like to see how the sausage is made so I hoped someone might find it neat. If ya got any questions I am happy to try and answer, the ol' inbox is always open.
3 notes · View notes
leptonbuilder · 8 months ago
Text
youtube
[Survival Industrialization] Today's results. CC:Tweaked's multi-threading mechanism using Lua language coroutines allows multiple processes to be carried out in parallel.
6 notes · View notes