I want to change the colour of a part when a player stands on it but instead of putting the script inside the part can i put the script in the workspace and identify the part from an event, like Humanoid touched or something?
The reason is that i have 100's of parts which need to react to a touch event so i don't want to put the same script in each part.
Pseudo-code might be
Player touch part event fired
Identify part from event and change colour of part
Thanks
As M. Ziegenhorn wrote, you could put the script in the character or in the foot directly. That would be the "easiest" way of achieveing this.
However, you could also connect a function to each part easily.
In the code below, we check through a model in workspace named 'TouchParts' which (assumingly) contains the parts you want to tie the touch-function up to.
function Touched(self, Hit)
if Hit and Hit.Parent and Hit.Parent:FindFirstChildOfClass'Humanoid' then
-- We know it's a character (or NPC) since it contains a Humanoid
-- Do your stuff here
print(Hit.Parent.Name, 'hit the brick', self:GetFullName())
self.BrickColor = BrickColor.new('Bright red')
end
end
for _, object in pairs(workspace.TouchParts:GetChildren()) do
if object:IsA'BasePart' then
object.Touched:connect(function(Hit)
Touched(object, Hit)
end)
end
end
Doing it this way means anything in your character touching the part(s) will fire the Touched-event, so you would have to add in a check to see whether if tie part touching is a leg or not.
The pros of binding the function to each part instead of to the leg is that the function is only called when you actually touch one of the intended parts, instead of ANYTHING you touch. However, with an increased amount of parts you connect it to, there's also an increased amount of events which will be triggered and is stored in memory. Probably not noticeable on the scale you're working with, but worth keeping in mind.
Been a while since I coded something on roblox so please excuse any blunders I make.
local parent = workspace.Model --This is the model that contains all of that parts you are checking.
local deb = 5 --Simple debounce variable, it's the minimum wait time in between event fires, in seconds.
local col = BrickColor.new("White") --The color you want to change them to once touched.
for _,object in next,parent:GetChildren() do --Set up an event for each object
if object:IsA("BasePart") then --Make sure it's some sort of part
spawn(function() --Create a new thread for the event so that it can run separately and not yield our code
while true do --Create infinite loop so event can fire multiple times
local hit = object.Touched:wait() --Waits for the object to be touched and assigns what touched it to the variable hit
local player = game.Players:GetPlayerFromCharacter(hit.Parent) --Either finds the player, or nil
if player then --If it was indeed a player that touched it
object.BrickColor = BrickColor.new(col) --Change color; note this is also where any other code that should run on touch should go.
end
wait(deb) --Wait for debounce
end
end)
end
end
This is probably one of the most, if not the most efficient way of doing this.
When a player stands on a block, the value "FloorMaterial" (which is in Humanoid) will be telling you what material the user is standing on, but if the user isn't standing on anything, this value will be nil.
Another efficient method is to use Rays. You would need to create a ray from your HumanoidRootPart.
Example:
IsOnGround=function()
local b=false;
local range=6;
local char=game:service("Players").LocalPlayer.Character;
local root=char:WaitForChild("HumanoidRootPart",1);
if root then
local ray=Ray.new(root.CFrame.p,((root.CFrame*CFrame.new(0,-range,0)).p).unit*range);
local ignore={char};
local hit,pos=workspace:FindPartOnRayWithIgnoreList(ray,ignore,false,false);
pcall(function()
if hit then
b=true;
end
end)
else
print("root not found");
end
return b;
end
This would cast a ray from the HumanoidRootPart, towards the direction where the ground should be, with a distance of 6 studs.
Sadly, this method isn't very effective with R15 characters as far as I know.
Related
I've altered one of the popular clock skins for Rainmeter to be exactly how I want it. However, the only issue is that the '1' in the clock for hours 10, 11, and 12 gets cut off by the edge of the skin with the current margins.
I know exactly which value needs to be altered at the given times, so all I need to figure out now is how to run a Lua script to change it when the clock hits them. Problem is, after much searching I don't have the slightest clue how. It definitely seems like something that should be easily possible.
You need to run your lua script as a cron job.
In order to achieve this I'd suggest you use this cron.lua module which has the functionality you want. One example of what you can do is the following:
local clock = cron.every(time, callback, ...).
--Creates a clock that will execute callback every time, periodically. Additional parameters are passed to the callback too.
The callback variable is the code you want to be executed at every interval.
So I'm playing around with a tutorial script, and I have a turret added that follows the player's movement. This turret should be shooting at the player every few seconds. Before I added collisions or timed shots or anything like that, I found out that the bullet shots actually aren't being shown. So I set it to a key press just to test, and nope, not working.
Full Code
Anything you see wrong? NOTE: I don't get an error when I run it, the bullets just don't show up!
love.keyreleased(key) treats the shift key as a separate and independent key so "X" will never happen. Instead use "x" to trigger a shot.
function love.keyreleased(key)
if key == 'x' then
shoot()
end
end
Once that is fixed you will have issues in your collision detection:
player is not being used as an array as line 52 for ii, vv in ipairs(player) do suggests.
There is nothing stopping a bullet from having a negative velocity and hitting a player or a player being hit by more than one bullet and so they may be added to the remEnemy and remShot table multiple times which will mess up deleting later.
The index shifts that happen when you delete an entry (mentioned by Etan Reisner) also exist.
For your use case, marking an object to be removed by adding it to a set seems like the best approach to me:
local remShots = {}
then if there is a collision or the bullet has negative velocity then
remShots[i] = true
and to remove, iterate in reverse to avoid shifted indices.
for i=#enemyShots,1,-1 do
if remShots[i] then
table.remove(enemyShots, i)
end
end
Performance
A table.remove shifts all the elements above the index down to fill the gap. In the code here the loop removes multiple elements so they are shifted more than once, but as long as your tables aren't huge, this removal process is fine.
I'm note sure what you were going for with the first bullet point, but you can also use the remPlayer to avoid checking for collisions with players that have already been marked for removal when you get that worked out:
if not remPlayer[ii] and CheckCollision...
I was wondering whether or not it's possible to implement the following.
What do I want to do?. Imagine the Big Ben's melody. I want to play a fourth of the melody every quarter of an hour. I want a FSM which has the following states:
Whole hour (so xx:00) = (input = 01)
Quarter past/ Quarter to (so xx:15 / xx:45) = (input = 10)
Half past (so xx:30) = (input = 11).
(xx = dont care)
For each state, i have another FSM. This FSM will make sure the music will play correctly.
If(state = whole hour)
{
switch music_state
case A
{ play 1 sec, next_music_state = F}
case and so on ......
Does this work? Can I make a FSM which has the different states of an hour, and for each state have another FSM?
If something is unclear, let me know, and I will try to clarify it. I know this part is not that hard, but I am still wondering whether or not this implementation will work. I hope, and also think, it will, though I want to be certain of it.
Thanks a lot in advance!
Meta-state machines with both an "inner state" and an "outer state" are certainly possible. I have done something similar for a while but it was only last week that the penny dropped and I finally wrote a state machine with two separate states. In a single process SM, it worked like a dream.
The "inner state machine" runs just like a normal state machine but in its last state, you test the meta-state or outer state, to determine which part of the outer sequence to despatch to next.
You could make single FSM to keep it simple...
The default state will be IDLE: This will check for the time (whole hour, quarters or half past), if one of them happens, you'll just run proper states like:
MUSIC_FOR_WHOLE_HOUR, MUSIC_FOR_HALF_PAST ...
Those states will run their different chain of states that will play their music and will return back to the IDLE state to wait for next proper time to play again.
Assume I have a function which is called often, say by an ODE-solver or similar. Is it faster to use a persistent variable than to reallocate it each time?
That is, which function would be faster and what is best practice?
function ret=thisfunction(a,b,c)
A = zeros(3)
foo = 3;
bar = 34;
% ...
% process some in A
% ...
ret = A\c;
end
or
function ret=thatfunction(a,b,c)
persistent A foo bar
if isempty(A);
A=zeros(3);
foo = 3;
bar = 34;
end
% ...
% process some in A
% ...
ret = A\c;
end
Which one is faster can only be proven by test, as it may depend on variable size etc. However, I would say that if it is not required, it is usually also not recommended to use persistent variables.
Therefore I would definately recommend you to use option number one.
Sidenote: You probably want to check whether it exists rather than whether it is empty. Furthermore I don't know what happens to your A when you leave the function scope, if you want to define it as persistent or global you may have to do it one level higher.
When you have a single function such as this to test I have found that it's very easy to setup a parent function, run the function you are testing say, 10 million times and time the results. Then consider the difference in time AND the possible trade off or side effects of using a persistent variable here. It may not be worth it if the difference is a few percent over 10 million calls and you are actually only going to call the function 10 thousand times in application. YMMV.
In regards to best practice, I would dissuade you from using persitent variables in this manner, for two reasons.
Persitent variables can be cleared externally, e.g. running clear('thatfunction') from any other function that has "thatfunction" on the path would reset your persitent variables in "thatfunction". As such, it's possible that they'll be unwittingly reset elsewhere. This may not be a problem for you in this context, but if you want to keep results between function calls (which is the primary point of persitent variables) this can cause you headaches.
Also, if you modify them, you'll have to remember to clear them when you're done running in-order to reset your workspace to a clean state. Otherwise if you (or someone else) runs your program again without clearing your persitent variable(s) first, the results from the previous run. This isn't an issue if they're read-only, but you cannot enforce that they will be.
I have a Simulink model that uses an embedded MATLAB function for a block, and I haven't been able to figure out how to move data between the embedded MATLAB block and a GUI in real-time (i.e. while the model is running). I tried to implement a "to workspace" block in my model but I don't know how to correctly use it.
Does anyone know how to move data from a Simulink block into a GUI in real-time?
Non-real-time solution:
If you want to set parameters in a GUI, simulate a model with those parameters, and then display the simulation output in the GUI, there is a good tutorial on blinkdagger.com. One solution they describe is using the SIMSET function to define which workspace the Simulink model interacts with. You should be able to supersede the base workspace so that data is instead sent to and from the workspace of the GUI functions that are calling the Simulink model.
Real-time solution
As suggested by MikeT, you can use a RuntimeObject. You first have to use the get_param function to get the RuntimeObject from the block:
rto = get_param(obj,'RuntimeObject');
Where obj is either a block pathname or a block-object handle. You can get the pathname of the most recently selected block using the GCB function (in which case you can replace obj with gcb). You can then get the block's output with the following:
blockData = rto.OutputPort(1).Data
One additional caveat from the documentation:
To ensure the Data field contains the
correct block output, turn off the
Signal storage reuse option (see
Signal storage reuse) on the
Optimization pane in the Configuration Parameters dialog box.
You would likely end up with a loop or a timer routine running in your GUI that would continuously get the output data from the RuntimeObject for as long as the simulation is running. The documentation also states:
A run-time object exists only while
the model containing the block is
running or paused. If the model is
stopped, get_param returns an empty
handle. When you stop or pause a
model, all existing handles for
run-time objects become empty.
Your loop or timer routine would thus have to keep checking first that the RuntimeObject exists, and either stop (if it doesn't) or get the data from it (if it does). I'm unsure of exactly how to check for existence of a RuntimeObject, but I believe you would either check if the object is empty or if the BlockHandle property of the object is empty:
isempty(rto) % Check if the RuntimeObject is empty
%OR
isempty(rto.BlockHandle) % Check if the BlockHandle property is empty
From your responses, I'm guessing you want to see the results while the simulation is running, is that correct? The blinkdagger.com tutorial lets you view the results of a simulation after it is done, but not while it is running. Do you basically want to embed something like a scope block into your GUI?
There's a few ways to do this, the best is probably using the EML block's runtime object. If you use this, you should be able to look at the output of the EML block while it is running.