Verifying Value is Not Equal Before Assigning Value - swift

Is there any point checking to see if a value has already been assigned to a variable or is it better to just simply assign the value? For example, if X is going to equal 1, is there any point checking to see if X already equals 1? Example code below:
if X != 1 {
X = 1
}
I ask this question become I'm looping through a bunch of children sprites and changing the alpha values to 0, which most are already set at 0. So I'm seeing if there is any benefit in checking the children's alpha value first (I can't see the benefit).
parent.enumerateChildNodes(withName: "*", using: {
node, stop in
// if node.alpha != 0 {
node.alpha = 0
// }
})

Just set the value normally.
What even is the point of checking whether the value is already 0 before setting it? What difference does it make? After the line of code:
node.alpha = 0
No matter what value alpha has before, it will always be 0 after the above line!
If you are worried about performance, don't, until you encounter one.
Setting alpha is just like setting any other variable. It doesn't do much apart from setting the value. It won't immediately change the alpha of the sprite on the screen. It will only do it in the next frame.
Say you do this a bunch of times:
for _ in 0...10000 {
node.alpha = 0
node.alpha = 1
}
The node's alpha on the screen won't be flashing like crazy. Eventually it will be 1 so the node will be drawn with alpha = 1 in the next frame.

Related

my shader is ignoring my worldspace height

Im VERY new to shaders so bear with me. I have a mesh that I want to put a sand texture on below a worldspace position y of say 10 else it should be a grass texture. Apparantly it seems to be ignoring anything I put in and only selecting the grass texture. Something IS happening because my vert and tris count explodes with this function, compared to if I just return the same texture. I just dont see anything no matter what my sandStart value is
this is in my frag function:
if (input.positionWS.y < _SandStart) {
return tex2D(_MainTex, input.uv)* mainLight.shadowAttenuation;
} else {
return tex2D(_SandTex, input.uv) * mainLight.shadowAttenuation;
}
Is there also a way I can easily debug some of the values?
Please note that the OP figured out that their specific problem wasn't caused by the code in the question, but an error in their geometry function, this answer is only about the question "Is there a way to debug shader values" as this debugging method helped the OP find the problem
Debugging shader code can be quite a challenging task, depending on what it is you need to debug, and there are multiple approaches to it. Personally the approach I like best is using colours.
if we break it down there are three aspects in your code that could be faulty:
the value of input.positionWS.y
the if statement (input.positionWS.y < _SandStart)
Returning your texture return tex2D(_MainTex, input.uv)* mainLight.shadowAttenuation;
Lets walk down the list and test each individually.
checking if input.positionWS.y actually contains a value we expect it to contain. To do this we can set any of the RGB channels to its value, and just straight up returning that.
return float4(input.positionWS.y, 0, 0, 1);
Now if input.positionWS.y isn't a normalized value (a.k.a a value that ranges from 0 to 1) this is almost guaranteed to just return your texture as entirely red. To normalize it we divide the value by its max value, lets take max = 100 for the exmaple.
return float4(input.positionWS.y / 100, 0, 0, 1);
This should now make the texture full red at the top (where input.positionWS.y / 100 would be 1) and black at the bottom (where input.positionWS.y / 100 is zero), and a gradient from black to full red inbetween. (Note that since its a position in world space you may need to move the texture up/down to see the colour shift). If this doesn't happen, for example it always stays black or full red then your issue is most likely the input.positionWS.y.
The if statement. It could be that your statement (input.positionWS.y < _SandStart) always returns either true or false, meaning it'll never split. We can test this quite easily by commenting out the current return texture, and instead just return a flat colour like so:
if(input.positionWS.y < _SandStart)
{
return float4(1,0,0,1);
}
else
{
return float4(0,0,1,1);
}
if we tested the input.positionWS.y to be correct in step 1, and _SandStart is set correctly we should see the texture be divided in parts red (if true) and the other part blue (if false) (again since we're basing off world position we might need to change the material's height a bit to see it). If this division in colours doens't happen then the likely cause is that _SandStart isn't set properly, or to an incorrect value. (assuming this is a property you can inspect its value in the material editor)
if both of above steps yield the expected result then return tex2D(_MainTex, input.uv)* mainLight.shadowAttenuation; is possibly the culprit. To debug this we can return one of the textures without the if statement and shadowAttenuation, see if it applies the texture, and then return the other texture by changing which line is commented.
return tex2D(_MainTex, input.uv);
//return tex2D(_SandTex, input.uv);
If each of these textures gets applied properly seperately then it is unlikely that that was your cause, leaving either the shadowAttenutation (just add the multiplication to the above test) or something different altogether that isn't covered by the code in your question.
bonus round. If you got a shader property you want to debug you can actually do this from C# as well using the material.Get<type> function (the supported types can be found in the docs here, and include the array variants too, as well as both Get and Set). a small example:
Properties
{
_Foo ("Foo", Float) = 2
_Bar ("Bar", Color) = (1,1,1,1)
}
can be debugged from C# using
Material mat = getComponent<Material>();
Debug.LogFormat("_Foo value: {0}", mat.GetFloat("_Foo"); //prints 2
Debug.LogFormat("_Bar value: {0}", mat.GetFloat("_Bar"); //prints (1,1,1,1)

'R Cannot be assigned to' error in Roblox Lua

I am trying to change the color value of a textlabel. I am doing so using:
script.Parent.Parent.toggled2.SurfaceGui.SIGN.TextColor3.R = 0
script.Parent.Parent.toggled2.SurfaceGui.SIGN.TextColor3.G = 255
script.Parent.Parent.toggled2.SurfaceGui.SIGN.TextColor3.B = 0
basically it navigates to a button (a part, parent of the script) then to the group its in, then to a part with the text (in this case toggled2) then to the surfacegui inside then the textlabel (which is named SIGN) it then modifies the TextColor3 attribute 3 times at once, adjusting all the R,G,B values.
Why wont it let me alter the value? do i have to do something like :new() or .new()?
In order to assign a value to the TextColor3 property, you have to pass a Color3 object :
local sign = script.Parent.Parent.toggled2.SurfaceGui.SIGN
sign.TextColor3 = Color3.new(0, 255, 0)

Trying to pinpoint 4 coordinates out of a region

I created a simple macro for Piano Tiles 2 just to see if I could automate it indefinitely.
My code here:
search = true
region = {100, 500, 500, 1}
while search do
findColorTap(0, 1, region);
findColorTap(258, 1, region);
findColorTap(16758018, 1, region);
usleep(5000)
end
Works for all three tiles.
--0 being jet black notes
--258 being hold notes which have a smaller "hitbox"
--16758018 being extra notes which have an even small "hitbox"
Currently the script will check every color on the screen in a 1pixel horizontal line from start to finish (100->500), and when it returns with the color I need, it will tap that pixel once.
I'm curious how to take just 4 points from the region and check those just the same.
I'm also curious if the above is possible, would Lua be able to compile the script faster or slower than checking the region.
My thoughts would be that once findColorTap returns the value I need. The other checks are essentially wasting valuable time. But, I also know that the more intricate the code gets, the harder my phone has to work to process these commands.
I have tried:
Example 1
check = true
while check do
note1 = getColor(80,500)
note2 = getColor(240,500)
note3 = getColor(400,500)
note4 = getColor(560,500)
end
while check do
if note1 == 0 then
tap(80,500)
elseif note1 == 258 then
tap(80,500)
elseif note1 == 16758018 then
tap(80,500)
else
end
end
This ends up either not reading any notes at all or when it does catch it falls out of sync with the game.
Example 2
function fct(startX, maxX, y, increment)
for x=startX,maxX,160 do
check=getColor(x,y)
if check == 0 then
return(x)
end
tap(x,y)
end
end
v = true
repeat
fct(80,560,500) until
v == false
This one was checking correctly and much faster, but was tapping in the wrong locations.
The other checks are essentially wasting valuable time. But, I also know that the more intricate the code gets, the harder my phone has to work to process these commands.
The "other checks" you're calling are vastly more intricate than anything in your code.
You don't need to worry about how many lines of code you have, you need to worry about computationally expensive ones being executed a lot.
would Lua be able to compile the script faster or slower than checking the region.
You mean run faster. Compiling is done once on startup, and doesn't affect run speed.
And yes, it will be faster to check 4 pixels than hundreds of pixels.
I have tried
Saying what you've tried does us no good unless you tell us why it didn't work.
while check do
note1 = getColor(80,500)
note2 = getColor(240,500)
note3 = getColor(400,500)
note4 = getColor(560,500)
end
while check do
if note1 == 0 then
tap(80,500)
elseif note1 == 258 then
tap(80,500)
elseif note1 == 16758018 then
tap(80,500)
else
end
end
end
This looks like it will never leave the first loop (unless you're setting check inside getColor).
Also, every branch in the second loop produces the exactly same tap.
It's hard to tell what you're asking, but if the goal is to check the color at specified locations, then tap at another specified location depending on the color you found, you could do something like this:
-- which points to check
points = {
{ x= 80, y=500 },
{ x=240, y=500 },
{ x=400, y=500 },
{ x=560, y=500 },
}
-- map a found color to a resulting tap point
tapPoints = {
[0] = { x=80, y=500 }, -- these
[258] = { x=80, y=500 }, -- should
[16758018] = { x=80, y=500 }, -- be different!
}
while check do
for checkPoint in ipairs(points) do
local note = getColor(checkPoint.x, checkPoint.y)
local tapPoint = tapPoints[note]
tap(tapPoint.x, tapPoint.y)
end
end

Physicsjs Screen wrap

I am currently having a bit of trouble making objects in my world wrap. It sort of works, but very often objets appear to get stuck on the boundaries. My wrap code is as follows:
// Wrap our position if we are outside of the world bounds
if (this.state.pos.get(0) > 860) {
this.state.pos.set(0, this.state.pos.get(1));
}
else if (this.state.pos.get(0) < 0) {
this.state.pos.set(860, this.state.pos.get(1));
}
if (this.state.pos.get(1) > 640) {
this.state.pos.set(this.state.pos.get(0), 0);
}
else if (this.state.pos.get(1) < 0) {
this.state.pos.set(this.state.pos.get(0), 640);
}
Is there a better way of doing this? Should I use a translation on the object's position vector rather than simply setting it?
Without a jsfiddle it's a bit hard to diagnose, however this might be due to the this.state.old.pos not being set too. If the position (only) is set, then the velocity will be calculated as the difference between the current and the previous positions (in accordance with verlet integration). In that case, you're implicitly giving the body a huge velocity.
I'd recommend adding/subtracting an amount rather than setting, then you can do the same with the old position.
Here's a working example: http://labs.minutelabs.io/Relativistic-Space-Sheep/
With the relevant line of code: https://github.com/minutelabsio/Relativistic-Space-Sheep/blob/master/library/js/mediators/boilerplate.js#L743

Reseting the player position when a certain Y coordinate is reached

My problem is that whenever my character reaches a certain Y coordinate, I want his position to reset at (destination x, destination y). This is what I have so far, and it isn't working. All of the other code works, but whenever I walk to the certain Y coordinate, it doesn't do anything. I named the boolean for the certain Y coordinate "death".
boolean death = false;
if (jumper.getPosition().y == 1.0f ) {
death = true;
}
And here is where I try to reset it:
if (death == true) {
create();
}
Can't you just simplify it to this:
if (jumper.getPosition().y == 1.0f ) {
// Print something here
create();
}
And if it's not working it might be because the conditional isn't correct ... so you most likely want to make sure the type is the same so you can compare properly and that you are accessing the object you actually want to access. (You might want to make both ints if you're doing 1 because well floats are funsies and some values aren't well represented so if you're doing a bunch of computation on it you can easily throw values off).