Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Minimap help [closed]

Asked by 10 years ago

Hi, I've having fun making a minimap. I have everything working (the dots appearing at correct distances) except I don't know how to change the position of the dot based on which way the player is looking. I'm assuming I'll have to use the player's head's look vector, but how should I make the dots on the map position according to that?

local player = script.Parent.Parent.Parent.Parent
local head = player.CharacterAdded:wait().Head
local players = game.Players:GetChildren()
repeat wait() until player.Character.Torso
local torso = player.Character.Torso
local target = nil

function x()
    return (torso.Position.X - torso2.Position.X)   
end

function y()
    return (torso.Position.Y - torso2.Position.Y)   
end


while wait(5) do
    for i = 1, #players do
        target = players[i]
        print("MINIMAP target:"..target.Name)
        torso2 = target.Character.Torso
        if (torso.Position - torso2.Position).magnitude <= 100 then
            f = Instance.new("Frame", script.Parent.Parent.GUI)
            f.BackgroundColor3 = Color3.new(255, 255, 255)
            f.BorderSizePixel = 0
            f.Size = UDim2.new(0, 5, 0, 5)
            f.Position = script.Parent.Position + UDim2.new(0, 50, 0, 50) - UDim2.new(0, 2.5 , 0, 2.5) + UDim2.new(0, x(), 0, y()) -- this is where the frame is positioned in case you can't tell
            script.Parent.BackgroundTransparency = 0.7
            if i == #players then -- I just realized I don't need this here. Don't judge ;_;
                wait(5)
                dots = script.Parent.Parent.GUI:GetChildren()
                for i = 1, #dots do
                    dots[i]:Destroy()
                end
            end
        end
    end 
end
while wait(10) do
for i = i, #players do
    print("Player:"..players[i])
    end
end

Thanks for any help, LightArceus

Locked by JesseSong

This question has been locked to preserve its current state and prevent spam and unwanted comments and answers.

Why was this question closed?

1 answer

Log in to vote
2
Answered by
adark 5487 Badge of Merit Moderation Voter Community Moderator
10 years ago

To start with, you might want to initialize torso2 below target, just so that future-you or anybody else that reads your code understands that torso2 is set during the running of the code, changing the outputs of x() and y(). Also, look into generic for loops. They're simpler to use than numeric for loops if you're iterating through a table.

An error I can see already is that your players table is only initialized and never updated for when players leave or join. This is easily fixed by re-initializing it every time your loop runs.

Also, you do need to destroy the dots every time if you recreate them every time. An easier way to do that is then your nested ifs is to move that code to outside of the first for loop, at which point 'i' will have to be the same as #players, since that is when the loop exits.

You can reduce the line f.Position = script.Parent.Position + UDim2.new(0, 50, 0, 50) - UDim2.new(0, 2.5 , 0, 2.5) + UDim2.new(0, x(), 0, y()) to simply f.Position = script.Parent.Position + UDim2.new(0, 47.5 + x(), 0, 47.5 + y()), since UDim2 is purely additive, unlike CFrame.

You can move line 28 to outside of the loop, since it is never set anywhere else. In fact, you could probably just change that in the actual GUI, unless you mean to change it elsewhere in the script.

Finally, your second while loop will never run, as the first while loop will never end. In order to run it, you'll need to run it as a coroutine.

Now on to your actual problem!

(First of all, I'm taking that your minimap is a simple, 2D, top-down minimap, not something too fancy.)

What would be easiest, in my opinion, would be to rotate script.Parent.Parent.GUI by the player's Heading converted into degrees, and then rotating each dot (including the player'ss if it's also rotated) an opposite amount so that they remain 'vertical'.

If that doesn't work for you, here's a function that will return how much to translate a secondary point around a given center point, both in Vector2 format, given the amount to rotate by in radians:

function rot(center, point, deg)
    point = (point - center)
    local point_c = point
    local len = point.magnitude
    point = point.unit
    local rad = math.atan2(point.y, point.x)+ deg
    point = Vector2.new(math.cos(rad), math.sin(rad))*len
    return (point-point_c)
end
--Note: At the moment, I can't test this. Let me know if it doesn't work!

To use this, you'll need to get the character's Heading, as shown in the above article I linked to.

After where you set f.Position, you'll need to add:

local rotMod = rot(--[['Center' of minimap]], f.AbsolutePosition, heading)
f.Position = f.Position + UDim2.new(0, rotMod.x, 0, rotMod.y)

And then you should be done!

0
I just got the time to sit down and study this, sorry XD Anyway, I need to rotate the minimap according to the player's heading, and I get the heading from the CFrame of the one of the player's parts. I'm a little bit confused about the wiki article "Converting CFrame into heading, attitude and bank" (the last but of code on the page) because it isn't in any context. How would I implement that? LightArceus 110 — 10y
0
Basically all you have to do is copy the components() line and the heading line. Where is says 'matrix' in the components line, just replace that with Character.Head.CFrame adark 5487 — 10y
Ad