I don't need a "Global" variable but I need a variable that can be changed from different subroutines and functions!

The problem is that the function IS changing the latestX and latestY values successfully but the main thread doesn't read the changes and still thinks its 0.0, 0.0.

  • xyz replied to this.

    What are min and max?

    You should use static typing. One of its advantages is to make the code more predictable.
    E.g., var latestX: float = 0.0

    Try printing the values using more precision:
    print("%.8f" % x)

      Cakestax What happens if you print the values after calling GetNextShake() in SingleShake() ?

        xyz Well I have a while loop which constantly calls SingleShake() so the variables wouldn't change. There isn't anything setting it to 0.0 either so I'm just not sure why it's still 0.0 but clearly being set.

        • xyz replied to this.

          DaveTheCoder Made no difference. Thanks for the tip though!

          Do you know any way I can still access and change these variables from the subroutine?

          xyz

          Here it is in text format.

          	var latestX : float = 0.0
          	var latestY : float = 0.0
          
          	var GetNextShake = func():
          		while true:
          			var X = randf_range(min, max) * [-1, 1].pick_random()
          			var Y = randf_range(min, max) * [-1, 1].pick_random()
          			
          			if X != latestX and Y != latestY:
          				latestX = X
          				latestY = Y
          				print(latestX, ", ", latestY)
          				break
          	
          	var SingleShake = func():
          		print("New tween", ", pos = ", latestX, ", ", latestY)
          		
          		GetNextShake.call()
          		
          		#Tween camera position to new coordinate
          		await physics.tween({"object" : camera, "property" : "position", "final" : originalCameraPos + Vector3(latestX, latestY, 0), "time" : 1.0 / speed})
          	
          	if index: #Make sure index exists
          		if data["mode"] is int: #This means shake has a time limit on it (Should end after x seconds)
          			pass
          		elif data["mode"] is bool: #This means shake is on toggle mode (Most likely a suttle and long shake like elevator scene)
          			if data["mode"] == true: #Starting a shake
          				print("true loop")
          				while index["mode"] == true:
          					await SingleShake.call()
          					
          				camera.position = originalCameraPos

          DaveTheCoder

          Min and max change with the function but here in this case Min = 0.01 and Max = 0.01
          As this function is to shake the users screen, its just finding a random value between Min, -Min and Max, -Max for camera position, then just tweeting using a tween function I made.

          xyz Hang on, here is actually EVERYTHING related, my bad the previous one was actually just a snippet

          var shakeList = {}
          	
          func Shake(camera, data):
          	shakeList[data["name"]] = data #Add shake into shakeList (with all of its data)
          	
          	var index = shakeList[data["name"]] #Get the shake in the shakeList
          	
          	#Customisable stats for shake
          	
          	var min = data["min"] / 100
          	var max = data["max"] / 100
          	var speed = data["speed"] #Speed = shakes/second
          	
          	var originalCameraPos = camera.position
          	var latestX : float = 0.0
          	var latestY : float = 0.0
          
          	var GetNextShake = func():
          		while true:
          			var X = randf_range(min, max) * [-1, 1].pick_random()
          			var Y = randf_range(min, max) * [-1, 1].pick_random()
          			
          			if X != latestX and Y != latestY:
          				latestX = X
          				latestY = Y
          				print(latestX, ", ", latestY)
          				break
          	
          	var SingleShake = func():
          		print("New tween", ", pos = ", latestX, ", ", latestY)
          		
          		GetNextShake.call()
          		
          		#Tween camera position to new coordinate
          		await physics.tween({"object" : camera, "property" : "position", "final" : originalCameraPos + Vector3(latestX, latestY, 0), "time" : 1.0 / speed})
          	
          	if index: #Make sure index exists
          		if data["mode"] is int: #This means shake has a time limit on it (Should end after x seconds)
          			pass
          		elif data["mode"] is bool: #This means shake is on toggle mode (Most likely a suttle and long shake like elevator scene)
          			if data["mode"] == true: #Starting a shake
          				print("true loop")
          				while index["mode"] == true:
          					await SingleShake.call()
          					
          				camera.position = originalCameraPos

          Now if you run this with a camera and Shake(camera, {"speed" : elevatorShakeSpeed, "min" : 1.0, "max" : 1.0, "mode" : true, "name" : "elevator"}) it will work and print all the results (if it's working your camera should be tweening and shaking)

          • xyz replied to this.

            Cakestax it will work and print all the results

            Where's the problem then?

            DaveTheCoder Yes but it won't make a difference to the problem. I literally just need a way to change those two variables from within the function. If you don't know, I have another solution I may need. Which is just to instead await GetNextShake.call() and then return the result of X and Y.

            However, for this I will need to figure out how to "wait" for the function to return as it's not going to return a number instantly due to the while loop.

            If you know I can wait for a function to return a value before continuing the code, please let me know!

            • xyz replied to this.

              Cakestax You should redo the whole thing without using await. This implementation you have looks too convoluted. Can you describe in plain language what exact behavior you need to implement?

                The issue here is the lambda scope, which captures the local environment. Variables are captured by value so any update doesn't apply to scope outside of the lambda; the lambda doesn't belong to the class (docs).

                Why [not] just use functions defined in the class?

                • xyz replied to this.

                  spaceyjase It's not lambdas per se but the way they are used as coroutines here. It's a very confusing solution on top of being buggy. And yeah, using regular class methods and properties would be preferable, and eliminating coroutines completely would be even better.

                  xyz I need my screen to shake in random positions but I made the GetNextShake() function so I could get a new random position for the next shake (BUT IT CANNOT BE THE SAME AS THE PREVIOUS SHAKE) Hence why I made it a subroutine so that it wouldn't interfere with the main thread. I am getting the next shake while the current one is still moving to it's position, that way there wouldn't be any stutters or stops while the code tries to find the next shake position.

                  • xyz replied to this.

                    Cakestax I still don't really understand what effect are you trying to implement. Can you give an example described in plain language without abstractions and technicalities?

                    Btw subroutine and coroutine are two quite different things.

                      xyz Not sure if this helps but here basically my base system

                      • xyz replied to this.