How to stop a clone from inheriting a message - mit-scratch

I have this code:
But whenever the shoot message is sent to the bullet sprite, and there is a clone on the stage that hasn't hit it's target yet, the clone will be sent back with the go to x: (xOfTower) y: (yOfTower) block. Is there some way to prevent a clone from receiving a message while the real sprite does?

Clones have their own copy of local variables!
To solve this problem you can add a new variable but be sure to check 'For this sprite only'. Otherwise there will only be 1 variable.
Now a new variable will be created for each clone. Give the variable a value to label it as clone and add a guard on your message action.

There is no way to prevent all sprites receiving the broadcast message. You have to write code to make those that shouldn't act on it, ignore it. In this case I suggest it is easier to do the following:
Suggest moving the two lines
point in direction (directionOfTower)
go to x: (xOfTower) y: (yOfTower)
into the when I start as clone block.

Yes there is. It has been a while since I have done Scratch but I remember that clones have variables, so if you give a clone a variable (something like: isClone) and then inside the messages it is inheriting have an if statement at the top so everything else runs if it is true. Then the if statement if set up correctly should check if isClone is equal to 0 and then if so then run the broadcast. The way you give clones variables is through inheritance because they inherit variables, if you change a variable inside a clone script then it will change the variable only for that clone and not the parent sprite or any other clone.

Related

why doesn't rackstore see the path to reach the palletrack?

I don't know why the resources don't follow the path in order to arrive the pallet rack. I thought it was because of the path (maybe not linked) but with a moveto block the problem disappears.What's the reason?
All the paths are bidirectional.
The problem that you have is the issue of teleportation... you move your boxes teleporting them from one node to the next by using the agent location parameter of the rackstore... This has the effect that the agents do not belong to the network as you expect.
instead you need to use a moveTo block instead as you see in the following image
Notice that I removed the agent location from the rackStore and also in the moveTo block i use JumpTo option instead of moveTo so you maintain the teleportation as you did...
Anyways, teleporting is not very good

Why is "Cast to BP_Ladder" failing all the time?

I am having trouble with my Unreal Engine 4 project. I'm very new to this and i don't really understand what's going on. I have made ladder functionality so the character can climb up the ladder and stand on the Static Mesh that is on top. But when i want to go down the ladder i want to trigger the "Allow Down" function on Actor "BP_Ladder" but the cast is failing everytime. what is causing the casts to fail?
I've looked around and other people with cast failed problems have mostly had the names wrong but my ladder is called "BP_Ladder" and that is what i'm casting to so that leaves me really confused.
My BP_Dude blueprint (this is being called every tick)
My BP_Ladder blueprint (this is what i'm trying to trigger)
The goal for this function is that the collision of the static mesh will turn off and then allow me to move down the ladder like normal.
I'd really appreciate your help with this, its my first couple of days using unreal engine and the Epic Games tutorials i followed didn't show all of the blueprints so everyone was left helpless with half broken blueprints.
Understanding Casts
In its simplest form, if your Actor can be cast to BP_Ladder, then it will return the casted object on the output pin.
Just to ensure you know how a cast works, I have to point out that you can't cast a given type to some unrelated arbitrary type; it has to be "castable" to the cast destination. So if you think that the Actor object returned by your overlap is genuinely a BP_Ladder, or a blueprint class that derives from BP_Ladder, then you should be OK. But that has to be the case; otherwise it will fail every time.
https://docs.unrealengine.com/en-us/Engine/Blueprints/UserGuide/CastNodes
Sorry if I'm being patronising, but if a cast isn't working 9/10 it hasn't been used correctly.
Debugging
OK that out of the way, if you think you are genuinely casting to the correct type and it's still failing, then you'll need to debug your blueprint with the objective of finding what type is being given to the cast node which results in the failure.
Select the cast object in your blueprint.
Press F9 to create a breakpoint; a red circle should appear on the top left of your cast box
Run your game in PIE mode (Combo next to play, New Editor Window (PIE))
Put the game in a scenario where your cast will fire (I presume touch the ladder)
The breakpoint should trigger; your game window will go grey and you'll get a large red arrow pointing down towards your cast box where you placed the breakpoint
Hover over the Object pin on the input side of the cast box. It should show a alt-text containing details of the variable.
Inside the alt-text box, look for Current value; this should show you the current object type that you are about to cast. You need to ensure that this value is what you expect.
https://docs.unrealengine.com/en-US/Engine/Blueprints/UserGuide/Debugging
Example
I've taken a screenshot of a working game; in this you will see:
a Breakpoint (the red circle) is shown on the function node (the box)
the Execution node (red arrow) is Create Rolling Stock
the Current value of the variable is DepotComponent...Depot
Final thoughts
There's a couple of gotchas when using blueprints; one of them in this case could be that you can have two classes with the same name (although they might have different internal "script names" - effectively a fully qualified path). When you debugging an object variable, make sure you match the entire path to the location of your asset in your content folder; this will ensure that you are indeed attempting to cast to the object you think you really are.
Another classic gotcha is "hot reloads". Sometimes the editor needs to reload a module after an on-the-fly build but a class conflict occurs internally; this results in the new version of the class getting a different name (prefixed with HOTRELOADED). Watch out for this; it can cause you to be dealing with two distinct types when casting and you don't even realise. A real sanity-sapper. If in doubt, close and re-open the editor; it fixes it every time.
On Begin Overlap is only triggered when you START an overlap, so if you have some logic that sets your "can climb" to false you will need to move outside of the collider and back into it again for another Begin Overlap event.

ROBLOX Studio ScreenGui score display

How do I make a TextLabel's text update to a variable?
I have tried setting the text to "score: ", _G.score
but it won't update with the variable, and yes I do set the text after the variable has updated.
Code:
script.Parent.mouseClick:connect(function()
_G.score = _G.score + 1
game.StarterGui.ScreenGui.TextLabel.Text = _G.score
end)
game.StarterGui is actually a template GUI, and every time a player joins the game, a copy of it is made and given to the new player. Thus, if you try to modify it, you will not be actually modifying the copies of it that were given to all the players.
There are two solutions to this problem:
Only use relative paths—that being, only use paths to GUI objects that begin with "script." just like you said script.Parent.mouseClick:connect(…).
Iterate through all the copies that have been given out to the players. This can be found under each Player object's .PlayerGui.
You should almost never do the latter. Here's how you can decide:
If you have code that is found within the StarterGui (rather than in the Workspace or something), then you should use the former. This is because when the StarterGui gets copied into a new player's GUI (called a PlayerGui), that script will get copied along with it since it was inside of the StarterGui. Thus, a relative path like script.Parent.Something.SomethingElse.Text = "hi" will be valid; it will affect that PlayerGui.
If you have some code that is not within the StarterGui (like if it's in the Workspace), then you must use the latter. This is because such a script will not get copied into each player's PlayerGui. As a result, you must go through each player's PlayerGui in a for loop or something similar. This scenario is very rarely the case, and if it ever is, consider trying to make it not the case if possible because this is a very hairy situation to try to deal with; you have to account for special circumstances like the possibility that a player hasn't gotten a copy of the StarterGui yet.
Please let me know if this explanation was in any way confusing; I'll try my best to explain it better.
You can find some visuals to go along with this explanation and some further reading on the official ROBLOX Wiki's explanation of this topic here: "Player vs. Starter GUIs".

A Grid of Clones

My goal is to build a 5x5 grid of images. In the following code, row, col and rowcol were created as variables local to the sprite, and newcol, newrow and cats are global. (By the way, is it possible to tell which variables are local and which are global? It's easy to forget or make mistakes.)
The result is a 5x1 grid only, as seen here.
I am unclear as to the order of execution of these statements. Does when I start as a clone get called before or after add_cat gets called the second time? My tentative conclusion is that it gets called afterwards, yet the clone's global variables seem to contain their values from beforehand instead.
When I attempted to debug it with ask and say and wait commands, the results varied wildly. Adding such pauses in some places fixed the problem completely, resulting in a 5x5 grid. In other places, they caused a 1x5 grid.
The main question is: How to fix this so that it produces a 5x5 grid?
Explanation
Unfortunately, the execution order in Scratch is a little bizarre. Whenever you edit a script (by adding or removing blocks, editing inputs, or dragging the entire script to a new location in the editor), it gets placed at the bottom of the list (so it runs last).
A good way to test this out is to create a blank project with the following scripts:
When you click the green flag, the sprite will either say "script one" or "script two", depending on which runs first. Try clicking and dragging one of the when green flag clicked blocks. The next time you click the green flag, the sprite will say whichever message corresponds to the script you just dragged.
This crazy order can make execution incredibly unpredictable, especially when using clones.
The solution
The only real solution is to write code that has a definite execution order built-in (rather than relying on the whims of the editor). For simpler scripts, this generally means utilizing the broadcast and wait block to run particular events in the necessary order.
For your specific project, I see two main solutions:
Procedural Solution
This is the most straightforward script, and it's probably what I would choose to go with:
(row and col are both sprite-only variables)
Because clones inherit all sprite-only variable values when they are created, each clone will be guaranteed to have the correct row and col when it is created.
Recursive Solution
This solution is a bit harder to understand than the first, so I would probably avoid it unless you're just looking for the novelty:

runBlock not working in sequence?

I am trying to create a basic spawn sequence- the block must be created, moveDownLeft, and then removeLeft. moveDownLeft and removeLeft work fine on their own when the block is added using self.addChild(block1) previously, however I need to have self.addchild within the sequence.
The only way that I can see to do this is use runBlock, and I looked at this question when I got an error using that: Swift: SKAction.runBlock -> Missing argument for parameter 'completion' in call BUT WHY?
So now I am left with this:
block1.runAction(SKAction.sequence([SKAction.runBlock({ self.addChild(self.block1) }), moveDownLeft, removeLeft]))
And nothing in the sequence works because the block is not created in the first place. Why is this happening?
Your code fragment is too short but it looks like a typical chicken and egg problem.
node can only run actions once it has been added as child and thus becomes part of the scene graph
your node is supposed to run an action that will eventually add itself to the scene graph but it's not in the scene graph yet so it won't run that action
Add the node as child first, then run the action. If you need the node to be inactive for some time, simply set it's visible property to NO for the duration. You kay also ned to change other properties, ie postpone creation of the physics body.