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".
Related
I'm wondering if its possible to add Spawn locations only for experience teleported players.
let me explain.. i join game A and get teleported to game B But what i want is that when i get teleported from game A to B that in game B i spawn at a difrent location than the location for players that just joined Game B. can someone help me whit this idk any code that can do this
Assuming you use TeleportAsync instead of Teleport (you should), you can create a TeleportOptions instance using Instance.new. I also assume that the SpawnLocation is not too special, because this way of doing it is exploitable. A safer but also more complicated way of doing this is using Memory Stores.
Using the first way mentioned, a TeleportOptions instance has two functions you can use to achieve this: GetTeleportData and SetTeleportData.
You would have two spawn point indicating parts. They should be floating, so that people won't get stuck in the middle of the floor. Make sure to anchor them.
You would then have a script calling Player:GetJoinData when they join. If there is relevant data, you should teleport the player to one part, whereas other data would teleport the player to the other part.
In pseudo-code:
players.PlayerAdded:Connect(function(player)
if not player.Character then player.CharacterAdded:Wait() end
local part = workspace.SpawnPartNormal
if player:GetJoinData().TeleportData.TeleportedFromGameA then
part = workspace.SpawnPartFromGameA
end
move_characterof_to(player, part)
end)
The safer way of doing it will unfortunately not work if the two places are not of the same experience (game). Here is the safer way:
local store = memorystoreserv:GetSortedStore("PlayerFromGameA")
players.PlayerAdded:Connect(function(player)
if not player.Character then player.CharacterAdded:Wait() end
local part = workspace.SpawnPartNormal
if store:GetAsync(player.UserId) then
part = workspace.SpawnPartFromGameA
end
move_characterof_to(player, part)
end)
Both of these are nearly identical. In the safer one, I used a MemoryStoreSortedMap object's GetAsync function.
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.
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:
I'm developing a simple game in swift, but using GamePlayer (on Cydia, a cheat-enginelike), I am able to locate, track and modify my score.
I was wondering how can I prevent this kind of cheats... I tried to create a new instance of the element whenever it changes, example:
score = Int(score + 1)
I also tried to reset the var to nil and re-assign it:
let tmp = score + 1
score = nil
score = tmp
But it is not working...
My first question is: Is it possible to change a variable's address in swift ? And will it prevent address tracking?
My second question is: Another thing that can work, encoding my score, but is it worth the work ?
You can put your score variable in a struct and use copy-on-write. Then, when you change a value, you get a fresh copy of the score. The possibilities and how copy-on-write works, is described here with examples: copy-on-write
Compared to the solution, were you actually encrypt the number it has advantages and disadvantages. Just some of them from the top of my head (I'm curious what your points are)
encryption needs more cpu power and therefore more battery. Whereas the copy-on-write is implemented deep on iOS level, where we can assume, that it is very well optimised.
The copy-on-write solution is less secure, as one might find the right address just at the beginning and can track it (now, that I think about it, not really...)
The copy-on-write adds more complexity to your source code as you need to trigger it on every change.
What is the difference between those two methods? Why should i prefer one?
1)
GameObject.FindGameObjectWithTag("").GetComponent<Rocket>().active = true;
2)
GameObject.FindGameObjectWithTag("").GetComponent<Rocket>().SendMessage("setActive");
thanks!
Sending a message searches through all the components of the gameObject and invokes any function that has the same name as the message. Not a 100% sure but Im sure this uses reflection which is generally considered slow.
SetActive() or the active variable set the gameObject as active or not. If its not active it wont render in the scene and vice versa.
First of all it seems there are several inconsistencies with your code above:
1) Components (and MonoBehavior) don't have an active property (active belongs to GameObject), so the first line of code shouldn't compile. In addition the most recente version of unity don't have active anymore, it's substitued with activeSelf and activeInHierarchy.
And btw, both activeSelf and activeInHierarchy are read only, so you can't assing directly a value to them. For changing their value use SetActive method.
2)
The second line of code shouldn't work either (unless Unity does some magic behind the scenes) because SetActive methods belong to GameObject and not to your Rocket Component.
Now, I suppose your question was the difference between:
gameObject.SetActive(true);
and
gameObject.SendMessage("SetActive",true);
The result is the same, but in the second way Unity3D will use reflection to find the proper method to be called, if any. Reflection has an heavy impact on performance, so I suggest you to avoid it as much as possible.