-- drones ModuleScript in the ReplicatedStorage area
-- drones ModuleScript in the ReplicatedStorage area
local drones = {}
drones.__index = drones
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local s = require(ReplicatedStorage.genericShapes)
local TweenService = game:GetService("TweenService")
local defaultColor = Color3.new(0.0117647, 0.984314, 1)
local defaultBorderThickness = 0.5
drones.zDirection = -1
-- collection {}
-- This is an array used to store the collection of drones.
-- When the moveDrones() function is called, a collection of drones is passed into the function.
-- Only those drones in the collection are moved.
-- Each element of the array stores an Instance of a "union" created by joining the two parts of the drone together.
drones.collection = {}
drones.actions = {}
-- forwardSpeedAdjustment --------------------------
-- This number is multiplied to the speed requested. Because of the algorithm used and the scale of units in Roblox,
-- it is desireable to adjust the speed to 1/5th of what was requested. This will allow the user to more clearly
-- see the movement of the drone.
drones.forwardSpeedAdjustment = 0.1
-- allGyroSensorsOffset -------------------
-- A variable used to keep track of the difference between the Roblox world and the orientation used for the compass shown under the Avatar
drones.allVectorsOffset = 270;
local blockSize = 64
local halfBlock = 32
local colorName={
["pink"]={["RGB"]="FFC0CB", ["DEC"]={255,192,203}},
["lightpink"]={["RGB"]="FFB6C1", ["DEC"]={255,182,193}},
["hotpink"]={["RGB"]="FF69B4", ["DEC"]={255,105,180}},
["deeppink"]={["RGB"]="FF1493", ["DEC"]={255,20,147}},
["palevioletred"]={["RGB"]="DB7093", ["DEC"]={219,112,147}},
["mediumvioletred"]={["RGB"]="C71585", ["DEC"]={199,21,133}},
["lightsalmon"]={["RGB"]="FFA07A", ["DEC"]={255,160,122}},
["salmon"]={["RGB"]="FA8072", ["DEC"]={250,128,114}},
["darksalmon"]={["RGB"]="E9967A", ["DEC"]={233,150,122}},
["lightcoral"]={["RGB"]="F08080", ["DEC"]={240,128,128}},
["indianred"]={["RGB"]="CD5C5C", ["DEC"]={205,92,92}},
["crimson"]={["RGB"]="DC143C", ["DEC"]={220,20,60}},
["firebrick"]={["RGB"]="B22222", ["DEC"]={178,34,34}},
["darkred"]={["RGB"]="8B0000", ["DEC"]={139,0,0}},
["red"]={["RGB"]="FF0000", ["DEC"]={255,0,0}},
["orangered"]={["RGB"]="FF4500", ["DEC"]={255,69,0}},
["tomato"]={["RGB"]="FF6347", ["DEC"]={255,99,71}},
["coral"]={["RGB"]="FF7F50", ["DEC"]={255,127,80}},
["darkorange"]={["RGB"]="FF8C00", ["DEC"]={255,140,0}},
["orange"]={["RGB"]="FFA500", ["DEC"]={255,165,0}},
["yellow"]={["RGB"]="FFFF00", ["DEC"]={255,255,0}},
["lightyellow"]={["RGB"]="FFFFE0", ["DEC"]={255,255,224}},
["lemonchiffon"]={["RGB"]="FFFACD", ["DEC"]={255,250,205}},
["lightgoldenrodyellow"]={["RGB"]="FAFAD2", ["DEC"]={250,250,210}},
["papayawhip"]={["RGB"]="FFEFD5", ["DEC"]={255,239,213}},
["moccasin"]={["RGB"]="FFE4B5", ["DEC"]={255,228,181}},
["peachpuff"]={["RGB"]="FFDAB9", ["DEC"]={255,218,185}},
["palegoldenrod"]={["RGB"]="EEE8AA", ["DEC"]={238,232,170}},
["khaki"]={["RGB"]="F0E68C", ["DEC"]={240,230,140}},
["darkkhaki"]={["RGB"]="BDB76B", ["DEC"]={189,183,107}},
["gold"]={["RGB"]="FFD700", ["DEC"]={255,215,0}},
["cornsilk"]={["RGB"]="FFF8DC", ["DEC"]={255,248,220}},
["blanchedalmond"]={["RGB"]="FFEBCD", ["DEC"]={255,235,205}},
["bisque"]={["RGB"]="FFE4C4", ["DEC"]={255,228,196}},
["navajowhite"]={["RGB"]="FFDEAD", ["DEC"]={255,222,173}},
["wheat"]={["RGB"]="F5DEB3", ["DEC"]={245,222,179}},
["burlywood"]={["RGB"]="DEB887", ["DEC"]={222,184,135}},
["tan"]={["RGB"]="D2B48C", ["DEC"]={210,180,140}},
["rosybrown"]={["RGB"]="BC8F8F", ["DEC"]={188,143,143}},
["sandybrown"]={["RGB"]="F4A460", ["DEC"]={244,164,96}},
["goldenrod"]={["RGB"]="DAA520", ["DEC"]={218,165,32}},
["darkgoldenrod"]={["RGB"]="B8860B", ["DEC"]={184,134,11}},
["peru"]={["RGB"]="CD853F", ["DEC"]={205,133,63}},
["chocolate"]={["RGB"]="D2691E", ["DEC"]={210,105,30}},
["saddlebrown"]={["RGB"]="8B4513", ["DEC"]={139,69,19}},
["sienna"]={["RGB"]="A0522D", ["DEC"]={160,82,45}},
["brown"]={["RGB"]="A52A2A", ["DEC"]={165,42,42}},
["maroon"]={["RGB"]="800000", ["DEC"]={128,0,0}},
["darkolivegreen"]={["RGB"]="556B2F", ["DEC"]={85,107,47}},
["olive"]={["RGB"]="808000", ["DEC"]={128,128,0}},
["olivedrab"]={["RGB"]="6B8E23", ["DEC"]={107,142,35}},
["yellowgreen"]={["RGB"]="9ACD32", ["DEC"]={154,205,50}},
["limegreen"]={["RGB"]="32CD32", ["DEC"]={50,205,50}},
["lime"]={["RGB"]="00FF00", ["DEC"]={0,255,0}},
["lawngreen"]={["RGB"]="7CFC00", ["DEC"]={124,252,0}},
["chartreuse"]={["RGB"]="7FFF00", ["DEC"]={127,255,0}},
["greenyellow"]={["RGB"]="ADFF2F", ["DEC"]={173,255,47}},
["springgreen"]={["RGB"]="00FF7F", ["DEC"]={0,255,127}},
["mediumspringgreen"]={["RGB"]="00FA9A", ["DEC"]={0,250,154}},
["lightgreen"]={["RGB"]="90EE90", ["DEC"]={144,238,144}},
["palegreen"]={["RGB"]="98FB98", ["DEC"]={152,251,152}},
["darkseagreen"]={["RGB"]="8FBC8F", ["DEC"]={143,188,143}},
["mediumaquamarine"]={["RGB"]="66CDAA", ["DEC"]={102,205,170}},
["mediumseagreen"]={["RGB"]="3CB371", ["DEC"]={60,179,113}},
["seagreen"]={["RGB"]="2E8B57", ["DEC"]={46,139,87}},
["forestgreen"]={["RGB"]="228B22", ["DEC"]={34,139,34}},
["green"]={["RGB"]="008000", ["DEC"]={0,128,0}},
["darkgreen"]={["RGB"]="006400", ["DEC"]={0,100,0}},
["aqua"]={["RGB"]="00FFFF", ["DEC"]={0,255,255}},
["cyan"]={["RGB"]="00FFFF", ["DEC"]={0,255,255}},
["lightcyan"]={["RGB"]="E0FFFF", ["DEC"]={224,255,255}},
["paleturquoise"]={["RGB"]="AFEEEE", ["DEC"]={175,238,238}},
["aquamarine"]={["RGB"]="7FFFD4", ["DEC"]={127,255,212}},
["turquoise"]={["RGB"]="40E0D0", ["DEC"]={64,224,208}},
["mediumturquoise"]={["RGB"]="48D1CC", ["DEC"]={72,209,204}},
["darkturquoise"]={["RGB"]="00CED1", ["DEC"]={0,206,209}},
["lightseagreen"]={["RGB"]="20B2AA", ["DEC"]={32,178,170}},
["cadetblue"]={["RGB"]="5F9EA0", ["DEC"]={95,158,160}},
["darkcyan"]={["RGB"]="008B8B", ["DEC"]={0,139,139}},
["teal"]={["RGB"]="008080", ["DEC"]={0,128,128}},
["lightsteelblue"]={["RGB"]="B0C4DE", ["DEC"]={176,196,222}},
["powderblue"]={["RGB"]="B0E0E6", ["DEC"]={176,224,230}},
["lightblue"]={["RGB"]="ADD8E6", ["DEC"]={173,216,230}},
["skyblue"]={["RGB"]="87CEEB", ["DEC"]={135,206,235}},
["lightskyblue"]={["RGB"]="87CEFA", ["DEC"]={135,206,250}},
["deepskyblue"]={["RGB"]="00BFFF", ["DEC"]={0,191,255}},
["dodgerblue"]={["RGB"]="1E90FF", ["DEC"]={30,144,255}},
["cornflowerblue"]={["RGB"]="6495ED", ["DEC"]={100,149,237}},
["steelblue"]={["RGB"]="4682B4", ["DEC"]={70,130,180}},
["royalblue"]={["RGB"]="041690", ["DEC"]={65,105,225}},
["blue"]={["RGB"]="0000FF", ["DEC"]={0,0,255}},
["mediumblue"]={["RGB"]="0000CD", ["DEC"]={0,0,205}},
["darkblue"]={["RGB"]="00008B", ["DEC"]={0,0,139}},
["navy"]={["RGB"]="000080", ["DEC"]={0,0,128}},
["midnightblue"]={["RGB"]="191970", ["DEC"]={25,25,112}},
["lavender"]={["RGB"]="E6E6FA", ["DEC"]={230,230,250}},
["thistle"]={["RGB"]="D8BFD8", ["DEC"]={216,191,216}},
["plum"]={["RGB"]="DDA0DD", ["DEC"]={221,160,221}},
["violet"]={["RGB"]="EE82EE", ["DEC"]={238,130,238}},
["orchid"]={["RGB"]="DA70D6", ["DEC"]={218,112,214}},
["fuchsia"]={["RGB"]="FF00FF", ["DEC"]={255,0,255}},
["magenta"]={["RGB"]="FF00FF", ["DEC"]={255,0,255}},
["mediumorchid"]={["RGB"]="BA55D3", ["DEC"]={186,85,211}},
["mediumpurple"]={["RGB"]="9370DB", ["DEC"]={147,112,219}},
["blueviolet"]={["RGB"]="8A2BE2", ["DEC"]={138,43,226}},
["darkviolet"]={["RGB"]="9400D3", ["DEC"]={148,0,211}},
["darkorchid"]={["RGB"]="9932CC", ["DEC"]={153,50,204}},
["darkmagenta"]={["RGB"]="8B008B", ["DEC"]={139,0,139}},
["purple"]={["RGB"]="800080", ["DEC"]={128,0,128}},
["indigo"]={["RGB"]="4B0082", ["DEC"]={75,0,130}},
["darkslateblue"]={["RGB"]="483D8B", ["DEC"]={72,61,139}},
["slateblue"]={["RGB"]="6A5ACD", ["DEC"]={106,90,205}},
["mediumslateblue"]={["RGB"]="7B68EE", ["DEC"]={123,104,238}},
["white"]={["RGB"]="FFFFFF", ["DEC"]={255,255,255}},
["snow"]={["RGB"]="FFFAFA", ["DEC"]={255,250,250}},
["honeydew"]={["RGB"]="F0FFF0", ["DEC"]={240,255,240}},
["mintcream"]={["RGB"]="F5FFFA", ["DEC"]={245,255,250}},
["azure"]={["RGB"]="F0FFFF", ["DEC"]={240,255,255}},
["aliceblue"]={["RGB"]="F0F8FF", ["DEC"]={240,248,255}},
["ghostwhite"]={["RGB"]="F8F8FF", ["DEC"]={248,248,255}},
["whitesmoke"]={["RGB"]="F5F5F5", ["DEC"]={245,245,245}},
["seashell"]={["RGB"]="FFF5EE", ["DEC"]={255,245,238}},
["beige"]={["RGB"]="F5F5DC", ["DEC"]={245,245,220}},
["oldlace"]={["RGB"]="FDF5E6", ["DEC"]={253,245,230}},
["floralwhite"]={["RGB"]="FFFAF0", ["DEC"]={255,250,240}},
["ivory"]={["RGB"]="FFFFF0", ["DEC"]={255,255,240}},
["antiquewhite"]={["RGB"]="FAEBD7", ["DEC"]={250,235,215}},
["linen"]={["RGB"]="FAF0E6", ["DEC"]={250,240,230}},
["lavenderblush"]={["RGB"]="FFF0F5", ["DEC"]={255,240,245}},
["mistyrose"]={["RGB"]="FFE4E1", ["DEC"]={255,228,225}},
["gainsboro"]={["RGB"]="DCDCDC", ["DEC"]={220,220,220}},
["lightgrey"]={["RGB"]="D3D3D3", ["DEC"]={211,211,211}},
["silver"]={["RGB"]="C0C0C0", ["DEC"]={192,192,192}},
["darkgray"]={["RGB"]="A9A9A9", ["DEC"]={169,169,169}},
["gray"]={["RGB"]="808080", ["DEC"]={128,128,128}},
["dimgray"]={["RGB"]="696969", ["DEC"]={105,105,105}},
["lightslategray"]={["RGB"]="778899", ["DEC"]={119,136,153}},
["slategray"]={["RGB"]="708090", ["DEC"]={112,128,144}},
["darkslategray"]={["RGB"]="2F4F4F", ["DEC"]={47,79,79}},
["black"]={["RGB"]="000000", ["DEC"]={0,0,0}}
}
local materialNames = {
"Plastic",
"Wood",
"Slate",
"Concrete",
"CorrodedMetal",
"DiamondPlate",
"Foil",
"Grass",
"Ice",
"Marble",
"Granite",
"Brick",
"Pebble",
"Sand",
"Fabric",
"SmoothPlastic",
"Metal",
"WoodPlanks",
"Cobblestone",
"Air",
"Water",
"Rock",
"Glacier",
"Snow",
"Sandstone",
"Mud",
"Basalt",
"Ground",
"CrackedLava",
"Neon",
"Glass",
"Asphalt",
"LeafyGrass",
"Salt",
"Limestone",
"Pavement",
"ForceField"
}
print("Clearing the droneActions array")
drones.actions = {}
drones.collection = {}
function drones.moveTo2(compassParts, updatedPosition)
--print("Updating position. Has a type of: "..typeof(updatedPosition))
local difference = updatedPosition - (compassParts[1]:GetPivot()).p -- Calculate the difference between the current avatar and the compass
compassParts[1]:PivotTo(compassParts[1]:GetPivot() + difference) -- Add the difference to the compass's CFrame.
compassParts[2]:PivotTo(compassParts[2]:GetPivot() + difference) -- Add the difference to the compass's CFrame.
end
function drones.moveDrones(droneCollection)
-- move the drones that need moved
--print("There are "..tostring(#droneCollection).." drones in the collection")
--print(typeof(droneCollection[1]))
for i=1,#droneCollection do
-- look to see if there is an action required
--print("checking drone " .. tostring(i) .. " droneActions has a length of " .. tostring(#drones.actions))
if drones.actions[i] then
--print("Prior to TweenService:Play(): droneCollection[i] is an "..typeof(droneCollection[i]).." Position: "..tostring(drones.actions[i].Position))
--print("droneActions[i] is of a type: "..typeof(drones.actions[i]).. " " .. tostring(drones.actions[i]))
if drones.actions[i].Action == "MoveTo" then
local deltaX = droneCollection[i].Position.x - droneCollection[i]:GetAttribute("lastPositionX")
local deltaZ = droneCollection[i].Position.z - droneCollection[i]:GetAttribute("lastPositionZ")
local distanceTraveled = math.sqrt((deltaX*deltaX)+(deltaZ*deltaZ))
droneCollection[i]:SetAttribute("encoderValue", droneCollection[i]:GetAttribute("encoderValue") + distanceTraveled)
droneCollection[i]:SetAttribute("lastPositionX", droneCollection[i].Position.x)
droneCollection[i]:SetAttribute("lastPositionZ", droneCollection[i].Position.z)
drones.actions[i].Completed = true
end
if drones.actions[i].Action == "Forward" and drones.actions[i].Speed ~= 0 then
local MoveInfo = TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out, 0, false, 0) -- parameters here include repeatCount and Reversible
-- get the current orientation in degrees from the CFrame
-- use sine and cosine to determine the deltaX and deltaZ needed for the new position
-- add to the current position to get the new position
local currentOrientation = droneCollection[i]:GetPivot()
local cfa = droneCollection[i].CFrame.LookVector
local arcTangent = (math.atan2(cfa.x, cfa.z)*180/math.pi) - 90
local deltaX = math.sin(math.rad((currentOrientation.Rotation.Y-arcTangent) + 90)) * drones.actions[i].Speed
local deltaZ = math.cos(math.rad((currentOrientation.Rotation.Y-arcTangent) + 90)) * drones.actions[i].Speed * -1 -- Multiplying z by -1 to correct the axis to make it more like a cartesian coordinate system
local newPosition = Vector3.new(currentOrientation.Position.X + deltaX, currentOrientation.Position.Y, currentOrientation.Position.Z + deltaZ)
local MovePart = TweenService:Create(droneCollection[i], MoveInfo, {Position = newPosition})
MovePart:Play()
MovePart.Completed:Connect(function()
drones.actions[i].Completed = true
end)
-- Add to the encoder value
local deltaX = droneCollection[i].Position.x - droneCollection[i]:GetAttribute("lastPositionX")
local deltaZ = droneCollection[i].Position.z - droneCollection[i]:GetAttribute("lastPositionZ")
local distanceTraveled = math.sqrt((deltaX*deltaX)+(deltaZ*deltaZ))
droneCollection[i]:SetAttribute("encoderValue", droneCollection[i]:GetAttribute("encoderValue") + distanceTraveled)
droneCollection[i]:SetAttribute("lastPositionX", droneCollection[i].Position.x)
droneCollection[i]:SetAttribute("lastPositionZ", droneCollection[i].Position.z)
end
if drones.actions[i].Action == "RotateBy" and drones.actions[i].Rotation ~= 0 then -- The ~= is "not equal to"
local newCFrame = drones.collection[i].CFrame * CFrame.Angles(0, math.rad(drones.actions[i].Rotation), 0) -- A positive value for Rotation means counter-clockwise
--droneCollection[i].CFrame = drones.collection[i].CFrame * CFrame.Angles(0, math.rad(drones.actions[i].Rotation), 0)
local MoveInfo = TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out, 0, false, 0) -- parameters here include repeatCount and Reversible
local MovePart = TweenService:Create(droneCollection[i], MoveInfo, {CFrame = newCFrame })
MovePart:Play()
MovePart.Completed:Connect(function()
drones.actions[i].Completed = true
end)
local axis, angle = droneCollection[i].CFrame:ToAxisAngle()
local x,y,z = drones.collection[i]:GetPivot():ToOrientation()
-- Going to make an adjustment to the value of the gyro.
-- Only going to change the value by the change in vectors observed in the drone.
-- The change in vectors observed in the drone is the difference from the previous vector value and the current vector value
-- Add this difference to the current gyro value to obtain a new gyro value which will represent the amount that the drone has rotated
local lastGyroSensorValue = droneCollection[i]:GetAttribute("gyroSensor")
local lastVectorValue = droneCollection[i]:GetAttribute("lastVectorValue")
local currentVectorValue = drones.vectorValue(i)
local changeInVectors = currentVectorValue - lastVectorValue
if drones.actions[i].Rotation > 0 then
if currentVectorValue < lastVectorValue then
-- looped past the zero point, subtract 360 from lastVectorValue
changeInVectors = currentVectorValue - (lastVectorValue - 360)
end
else -- turning clockwise
if currentVectorValue > lastVectorValue then
-- looped past the zero point, add 360 to lastVectorValue
changeInVectors = (lastVectorValue + 360) - currentVectorValue
end
end
local newGyroSensorValue = lastGyroSensorValue + changeInVectors
droneCollection[i]:SetAttribute("gyroSensor", newGyroSensorValue)
droneCollection[i]:SetAttribute("lastVectorValue", currentVectorValue) -- Update with the current value
--print("drone[" .. tostring(i) .. "].gyroSensor is: " .. tostring(droneCollection[i]:GetAttribute("gyroSensor")) .. " Drone vector is: " .. tostring(drones.vectorValue(i)) .. "; " .. tostring(drones.actions[i].Rotation/2))
--print(tostring(((270+math.abs((axis.Y*180)+(angle*180/math.pi)))%360)))
end
--print("Post to TweenService:Play()")
end
end
end
--[[
stopMoving()
This function will stop the drone from turning or moving.
Parameters (optional): drone index
Examples: d.stopMoving(droneN)
]]
function drones.stopMoving(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
if #arguments > 0 then targetDroneIndex = arguments[1] end
--print("Stopping the drone")
drones.rotateBy(targetDroneIndex, 0) -- stops turning
drones.moveForward(targetDroneIndex, 0) -- stops moving forward
drones.actions[targetDroneIndex] = {Action = "Stop"}
--print("All stopped")
end
--[[
rotateBy()
This low-level function causes the drone to start rotating either clockwise or counter-clockwise at a speed set by the specified parameter.
Parameters are: drone index, and rotation speed
Parameters passed should be a scalar numeric variable. The rotation speed parameter has a range from -20 to +20.
A rotation value of zero causes the drone to stop rotating.
Negative values cause the drone to rotate clockwise.
Positive values cause the drone to rotate counter-clockwise.
Examples: d.rotateBy(droneN, 20) d.rotateBy(droneN, -20)
Examples: d.rotateBy(20) d.rotateBy(-20) -- Rotate the default drone
]]
function drones.rotateBy(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
local targetDroneRotationSpeed = 20 -- Default value
if #arguments == 1 then targetDroneRotationSpeed = arguments[1] end -- If only one argument is supplied, use that as the speed
if #arguments >= 2 then
targetDroneIndex = arguments[1]
targetDroneRotationSpeed = arguments[2]
end
--print("Setting the rotation to: " .. tostring(targetDroneRotationSpeed))
drones.actions[targetDroneIndex] = {Action = "RotateBy", Rotation = targetDroneRotationSpeed, Completed = false}
end
--[[
gyroSensorValue()
This function will get the gyro value.
Parameter: drone index (optional)
Examples: d.gyroSensorValue() -- Get the gyroSensorValue from the default drone (#1)
Examples: d.gyroSensorValue(droneN) -- Get the gyroSensorValue from the specified drone
]]
function drones.gyroSensorValue(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
if #arguments >= 1 then targetDroneIndex = arguments[1] end
return drones.collection[targetDroneIndex]:GetAttribute("gyroSensor")
end
-- ------------------------------------------------------------------------
--[[
vectorValue()
This function will get the vector value for the drone (i.e., where it is pointing from 0-359 degrees.
Parameter: drone index (optional)
Examples: d.vectorValue()
Examples: d.vectorValue(droneN)
]]
function drones.vectorValue(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
if #arguments >= 1 then targetDroneIndex = arguments[1] end
local currentOrientation = drones.collection[targetDroneIndex]:GetPivot()
local cfa = drones.collection[targetDroneIndex].CFrame.LookVector
local currentVector = (math.atan2(cfa.x, cfa.z)*180/math.pi) + drones.allVectorsOffset
--print("curr vector 1: "..tostring(currentVector))
--print("curr vector 2: "..tostring(currentVector%360))
return currentVector % 360
end
-- ------------------------------------------------------------------------
--[[
resetGyroSensor()
This function will reset the gyro to zero.
Parameters required: drone index
Parameter: Gyro value (optional) - You can initialize the gyro to a specific value by specifying it as the second argument
Examples: d.resetGyroSensor(1) -- Reset the gyro for drone #1
Examples: d.resetGyroSensor(1, 90) -- Set drone #1's gyro to 90 degrees.
]]
function drones.resetGyroSensor(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
if #arguments > 0 then targetDroneIndex = arguments[1] end
drones.collection[targetDroneIndex]:SetAttribute("gyroSensor", 0)
if #arguments >= 2 then drones.collection[targetDroneIndex]:SetAttribute("gyroSensor", arguments[2]) end
local currentOrientation = drones.collection[targetDroneIndex]:GetPivot()
local cfa = drones.collection[targetDroneIndex].CFrame.LookVector
local degreeOffsetFromZero = (math.atan2(cfa.x, cfa.z)*180/math.pi)
print("Resetting gyro. Difference from absolute zero is: ".. tostring(drones.collection[targetDroneIndex]:GetAttribute("gyroSensorOffsetFromTrueZero")))
--if degreeOffsetFromZero < 0 then degreeOffsetFromZero = degreeOffsetFromZero + 360 end
drones.collection[targetDroneIndex]:SetAttribute("gyroSensorOffsetFromTrueZero", degreeOffsetFromZero)
end
-- ------------------------------------------------------------------------
--[[
moveForward()
This function will reset start the drone moving forward.
Parameters (optional): droneIndex, speed
Examples: d.moveForward(40) -- Move the default drone forward at 40% power
Examples: d.moveForward(1, 50) -- Move drone #1 forward at 50% power
Examples: d.moveForward(4, 80) -- Move drone #4 forward at 80% power
]]
function drones.moveForward(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
local targetDroneForwardSpeed = 20 -- Default value
if #arguments == 1 then targetDroneForwardSpeed = arguments[1] end
if #arguments >= 2 then
targetDroneIndex = arguments[1]
targetDroneForwardSpeed = arguments[2]
end
--print("Setting the speed to: " .. tostring(targetDroneForwardSpeed))
drones.actions[targetDroneIndex] = {Action = "Forward", Speed = targetDroneForwardSpeed * drones.forwardSpeedAdjustment, Completed = false}
end
-- ------------------------------------------------------------------------
--[[
encoderValue()
This function will return the drone's encoderValue.
Parameters (optional): drone index
Examples: d.encoderValue(droneN)
]]
function drones.encoderValue(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
if #arguments > 0 then targetDroneIndex = arguments[1] end
return drones.collection[targetDroneIndex]:GetAttribute("encoderValue")
end
-- ------------------------------------------------------------------------
--[[
resetEncoder()
This function will reset the drone's encoderValue.
Parameters (optional): drone index
Examples: d.resetEncoder(droneN)
]]
function drones.resetEncoder(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
if #arguments > 0 then targetDroneIndex = arguments[1] end
drones.collection[targetDroneIndex]:SetAttribute("encoderValue", 0)
end
-- ------------------------------------------------------------------------
--[[
getPosition()
This function will return the position of the drone
Parameters (optional): drone index
Examples: d.resetEncoder(droneN)
]]
function drones.getPosition(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
if #arguments > 0 then targetDroneIndex = arguments[1] end
return drones.collection[targetDroneIndex].Position
end
-- ------------------------------------------------------------------------
--[[
moveTo()
This function will move the drone to a coordinate.
Parameter: drone index (optional)
Parameter: Vector3 coordinate (required)
Examples: d.moveTo(droneN, Vector3.new(0, 4, 0)) -- Move specified drone to coordinates 0, 0
Examples: d.moveTo(Vector3.new(0, 4, 0)) -- Move default drone (1) to coordinates 0, 0
]]
function drones.moveTo(...)
--print("In the moveTo()")
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
local xCoordinate = 0
local targetY = 0
local zCoordinate = 0
local targetLocation = Vector3.new(xCoordinate,targetY,zCoordinate)
for i = 1, #arguments do
if typeof(arguments[i]) == "Vector3" then targetLocation = Vector3.new(arguments[i].X, arguments[i].Y, arguments[i].Z * drones.zDirection) end
if i == 1 and typeof(arguments[i]) == "number" then targetDroneIndex = arguments[i] end
if i == 2 and typeof(arguments[i]) == "number" then
xCoordinate = arguments[i]
targetLocation = Vector3.new(xCoordinate,targetY,zCoordinate)
end
if i == 3 and typeof(arguments[i]) == "number" then
targetY = arguments[i]
targetLocation = Vector3.new(xCoordinate,targetY,zCoordinate)
end
if i == 4 and typeof(arguments[i]) == "number" then
zCoordinate = arguments[i]
targetLocation = Vector3.new(xCoordinate,targetY,zCoordinate * drones.zDirection)
end
end
--print("Setting up action for drone at: "..tostring(targetDroneIndex))
drones.actions[targetDroneIndex] = {Action = "MoveTo", Position = targetLocation, Completed = false}
--print("Position is going to be "..tostring(drones.actions[targetDroneIndex].Position))
--print("droneActions has a length of: " .. tostring(#drones.actions))
local MoveInfo = TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out, 0, false, 0) --Parameters showin here include RepeatCount and Reversible
local MovePart = TweenService:Create(drones.collection[targetDroneIndex], MoveInfo, {Position = drones.actions[targetDroneIndex].Position})
drones.actions[targetDroneIndex].MovePart = MovePart
drones.actions[targetDroneIndex].MovePart:Play()
MovePart.Completed:Connect(function()
drones.actions[targetDroneIndex].Completed = true
end)
while drones.actions[targetDroneIndex].Completed == false do
task.wait(0.1)
end
drones.actions[targetDroneIndex] = {Action = "None"}
MovePart:Destroy()
task.wait(0.1)
end
-- ------------------------------------------------------------------------
--[[
roadSensor()
This function will return the distance to the nearest road piece.
]]
function drones.roadSensor(...)
local arguments = table.pack(...)
local targetDroneIndex = 1 -- Default value
for i = 1, #arguments do
if i == 1 and typeof(arguments[i]) == "number" then targetDroneIndex = arguments[i] end
end
local Children = game.Workspace:GetChildren()
local droneCoordinate = { X=drones.collection[targetDroneIndex].Position.x, Z=drones.collection[targetDroneIndex].Position.z }
local lineWidth = 20 -- The width of the imaginary line
local lineBlur = 20 -- Added to the width is a gradient. This gradient is added to each side of the line
-- For line following, the target value of 50% would be obtained at the 50% point in the lineBlur
for i = 1, #Children do
if (Children[i].name == "StraightRoad" or Children[i].name == "CornerRoad") then
local roadPosition = Children[i]:GetBoundingBox().Position
local rx, ry, rz = Children[i]:GetPivot():ToOrientation()
local dx, dy, dz = math.deg(rx), math.deg(ry), math.deg(rz)
local roadOrientation = Vector3.new(dx, dy, dz)
--print(roadPosition.X, " ", roadPosition.Z, " ", roadOrientation.Y )
if math.abs(roadPosition.X - droneCoordinate.X) < halfBlock and math.abs(roadPosition.Z - droneCoordinate.Z) < halfBlock then
-- We have found the road part that the drone is on
-- Now determine the orientation of the road part
if Children[i].name == "StraightRoad" then
-- local point1 = { X=0, Z=0 }
-- local point2 = { X=0, Z=0 }
-- Is the current coordinates inside the object
--print("Straight road y-orientation: " .. tostring(roadOrientation.Y))
if roadOrientation.Y == 0 or roadOrientation.Y == 180 then
-- point1 = { X=roadPosition.X - halfBlock, Z=roadPosition.Z }
-- point2 = { X=roadPosition.X + halfBlock, Z=roadPosition.Z }
-- Road part is moving along x axis
-- Sensor value is related to the distance on Z between math.abs(Children[i].Position.Z - droneCoordinate.Z)
if droneCoordinate.Z*drones.zDirection > (roadPosition.Z*drones.zDirection - lineWidth/2) and droneCoordinate.Z*drones.zDirection < (roadPosition.Z*drones.zDirection + lineWidth/2) then
print("H")
return 0
end
if droneCoordinate.Z*drones.zDirection > ((roadPosition.Z*drones.zDirection - lineWidth/2) - lineBlur) and droneCoordinate.Z*drones.zDirection <= (roadPosition.Z*drones.zDirection - lineWidth/2) then
print("I: " .. tostring(roadPosition.Z*drones.zDirection) .. " " .. tostring(droneCoordinate.Z*drones.zDirection))
return 100 * (droneCoordinate.Z*drones.zDirection - (roadPosition.Z*drones.zDirection - lineWidth/2)) / lineBlur
end
if droneCoordinate.Z*drones.zDirection > (roadPosition.Z*drones.zDirection + lineWidth/2) and droneCoordinate.Z*drones.zDirection <= (roadPosition.Z*drones.zDirection + lineWidth/2 + lineBlur) then
print("J")
return 100 * (droneCoordinate.Z*drones.zDirection - (roadPosition.Z*drones.zDirection + lineWidth/2)) / lineBlur
end
return 100
--return math.min( math.abs((roadPosition.Z - lineWidth/2) - droneCoordinate.Z), math.abs((roadPosition.Z + lineWidth/2) - droneCoordinate.Z))
else
-- point1 = { X=roadPosition.X, Z=roadPosition.Z - halfBlock }
-- point2 = { X=roadPosition.X, Z=roadPosition.Z + halfBlock }
-- Road part is moving along z axis
-- Sensor value is related to the distance on X between math.abs(Children[i].Position.X - droneCoordinate.X)
if droneCoordinate.X > (roadPosition.X - lineWidth/2) and droneCoordinate.X < (roadPosition.X + lineWidth/2) then return 0 end
if droneCoordinate.X > ((roadPosition.X - lineWidth/2) - lineBlur) and droneCoordinate.X <= (roadPosition.X - lineWidth/2) then
return 100 * (droneCoordinate.X - (roadPosition.X - lineWidth/2)) / lineBlur
end
if droneCoordinate.X > (roadPosition.X + lineWidth/2) and droneCoordinate.X <= (roadPosition.X + lineWidth/2 + lineBlur) then
return 100 * (droneCoordinate.X - (roadPosition.X + lineWidth/2)) / lineBlur
end
return 100
--return math.min( math.abs((roadPosition.X - lineWidth/2) - droneCoordinate.X), math.abs((roadPosition.X + lineWidth/2) - droneCoordinate.X))
end
--s.cube({X=point1.X, Z=point1.Z*-1, Y=2, size=4, color=Color3.new(1, 0.666667, 0)})
--s.cube({X=point2.X, Z=point2.Z*-1, Y=2, size=4, color=Color3.new(0, 1, 1)})
end
if Children[i].name == "CornerRoad" then
local cornerOrigin = { X=0, Z=0 }
if math.abs(roadOrientation.Y) < 5 then
cornerOrigin = { X=roadPosition.X + halfBlock, Z=roadPosition.Z - halfBlock }
elseif math.abs(roadOrientation.Y - 90) < 5 or math.abs(roadOrientation.Y + 270) < 5 then
cornerOrigin = { X=roadPosition.X - halfBlock, Z=roadPosition.Z - halfBlock }
elseif math.abs(roadOrientation.Y - 180) < 5 or math.abs(roadOrientation.Y + 180) < 5 then
cornerOrigin = { X=roadPosition.X - halfBlock, Z=roadPosition.Z + halfBlock }
elseif math.abs(roadOrientation.Y - 270) < 5 or math.abs(roadOrientation.Y + 90) < 5 then
cornerOrigin = { X=roadPosition.X + halfBlock, Z=roadPosition.Z + halfBlock }
else
end
s.cube({X=cornerOrigin.X, Z=cornerOrigin.Z*-1, Y=2, size=4, color=Color3.new(0, 0.666667, 0)})
local deltaX = cornerOrigin.X - droneCoordinate.X -- Distance from the corner
local deltaZ = cornerOrigin.Z - droneCoordinate.Z -- Distance from the corner
local droneDistanceFromCorner = math.sqrt(deltaX*deltaX + deltaZ*deltaZ)
if droneDistanceFromCorner >= 32 - lineWidth/2 and droneDistanceFromCorner <= 32 + lineWidth/2 then
return 0
end
if droneDistanceFromCorner < (32 - lineWidth/2) - lineBlur or droneDistanceFromCorner > 32 + lineWidth/2 + lineBlur then
return 100
end
if droneDistanceFromCorner >= (32 - lineWidth/2) - lineBlur and droneDistanceFromCorner <= 32 then
return 100 * ((32 - lineWidth/2) - droneDistanceFromCorner) / lineBlur
end
if droneDistanceFromCorner >= (32 + lineWidth/2) and droneDistanceFromCorner <= 32 + lineWidth/2 + lineBlur then
return 100 * ( droneDistanceFromCorner - (32 + lineWidth/2)) / lineBlur
end
return 100
-- Sensor value is the math.sqrt(deltaX*deltaX + deltaZ*deltaZ)
--return math.abs(32 - math.sqrt(deltaX*deltaX + deltaZ*deltaZ))
end
else
-- Off the grid. Just go straight
end
end
end
return 100
end
-- ------------------------------------------------------------------------
function drones.new(...)
local arguments = table.pack(...)
local x, y, z = 0, 0, 0
local needToCreateYvalue = true
local color = defaultColor
local material = Enum.Material.Plastic
local mainPart = Instance.new("Part")
local enginePart = Instance.new("Part")
local leftRotorPart = Instance.new("Part")
local rightRotorPart = Instance.new("Part")
local leftRearRotorPart = Instance.new("Part")
local rightRearRotorPart = Instance.new("Part")
local luminosityValue = 30
local luminosityHue = Color3.new(1, 1, 1)
local luminosityType = "PointLight"
local luminosityRange = 20
mainPart.Anchored = true
mainPart.Shape = Enum.PartType.Block
mainPart.TopSurface = Enum.SurfaceType.Smooth
mainPart.BottomSurface = Enum.SurfaceType.Smooth
mainPart.Transparency = 0
mainPart.Reflectance = 0.6
mainPart.Parent = workspace
enginePart.Shape = Enum.PartType.Block
enginePart.Material = Enum.Material.Glass
enginePart.Transparency = 0.9
enginePart.Parent = workspace
enginePart.Anchored = true
enginePart.Color = Color3.new(1,0,0)
leftRotorPart.Anchored = true
leftRotorPart.Shape = Enum.PartType.Cylinder
leftRotorPart.TopSurface = Enum.SurfaceType.Smooth
leftRotorPart.BottomSurface = Enum.SurfaceType.Smooth
leftRotorPart.Transparency = 0.99
leftRotorPart.Reflectance = 0.4
leftRotorPart.Parent = workspace
rightRotorPart.Anchored = true
rightRotorPart.Shape = Enum.PartType.Cylinder
rightRotorPart.TopSurface = Enum.SurfaceType.Smooth
rightRotorPart.BottomSurface = Enum.SurfaceType.Smooth
rightRotorPart.Transparency = 0.99
rightRotorPart.Reflectance = 0.4
rightRotorPart.Parent = workspace
leftRearRotorPart.Anchored = true
leftRearRotorPart.Shape = Enum.PartType.Cylinder
leftRearRotorPart.TopSurface = Enum.SurfaceType.Smooth
leftRearRotorPart.BottomSurface = Enum.SurfaceType.Smooth
leftRearRotorPart.Transparency = 0.99
leftRearRotorPart.Reflectance = 0.4
leftRearRotorPart.Parent = workspace
rightRearRotorPart.Anchored = true
rightRearRotorPart.Shape = Enum.PartType.Cylinder
rightRearRotorPart.TopSurface = Enum.SurfaceType.Smooth
rightRearRotorPart.BottomSurface = Enum.SurfaceType.Smooth
rightRearRotorPart.Transparency = 0.99
rightRearRotorPart.Reflectance = 0.4
rightRearRotorPart.Parent = workspace
local numNumericArguments = 0
for i = 1, #arguments do
if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
end
local workingNumber = 0
for i = 1, #arguments do
if typeof(arguments[i]) == "table" then
for key, value in pairs(arguments[i]) do
--print(key)
local lkey = string.lower(key)
if lkey == "anchored" then mainPart.Anchored = value end
if lkey == "x" then x = value end
if lkey == "y" then y,needToCreateYvalue = value, false end
if lkey == "z" then z = value end
if lkey == "position" and typeof(value) == "Vector3" then x,y,z,needToCreateYvalue=value.X,value.Y,value.Z,false end
if lkey == "transparency" then mainPart.Transparency = value end
if lkey == "opacity" then mainPart.Transparency = 1 - value end
if lkey == "reflectance" then mainPart.Reflectance = value end
if lkey == "rotateby" then mainPart.Orientation = value end
if lkey == "material" then material = value end
if lkey == "luminosityvalue" or lkey == "luminosity" then luminosityValue = value end
if lkey == "luminosityrange" then luminosityRange = value end
if lkey == "luminosityhue" then
if typeof(value) == "Color3" then luminosityHue = value end
if typeof(value) == "string" then
local luminosityColor = string.lower(value)
local red = colorName[luminosityColor]["DEC"][1]/255 --rescale from 0-255 to 0-1
local green = colorName[luminosityColor]["DEC"][2]/255 --rescale from 0-255 to 0-1
local blue = colorName[luminosityColor]["DEC"][3]/255 --rescale from 0-255 to 0-1
luminosityHue = Color3.new(red, green, blue)
end
end
if lkey == "luminositytype" then luminosityType = value end
if lkey == "color" then
if typeof(value) == "Color3" then color = value end
if typeof(value) == "string" then
color = string.lower(value)
local red = colorName[color]["DEC"][1]/255 --rescale from 0-255 to 0-1
local green = colorName[color]["DEC"][2]/255 --rescale from 0-255 to 0-1
local blue = colorName[color]["DEC"][3]/255 --rescale from 0-255 to 0-1
color = Color3.new(red, green, blue)
end
end
end
for key, value in pairs(arguments[i]) do -- Check to see if there is any luminosity to this object
local lkey = string.lower(key)
if lkey == "luminosity" or lkey == "luminosityvalue" or lkey == "luminosityhue" or lkey == "luminosityrange" or lkey == "luminositytype" then -- If there is luminosity, then install the surface light
--print(`Creating luminosity: {luminosityType} {luminosityHue} {luminosityValue}`)
local lightOfPart = Instance.new(luminosityType)
lightOfPart.Color = luminosityHue
lightOfPart.Brightness = luminosityValue
lightOfPart.Range = luminosityRange
lightOfPart.Parent = mainPart
end
end
end
if typeof(arguments[i]) == "Color3" then
color = arguments[i]
end
if typeof(arguments[i]) == "string" then
local color = string.lower(arguments[i])
local red = colorName[color]["DEC"][1]/255 --rescale from 0-255 to 0-1
local green = colorName[color]["DEC"][2]/255 --rescale from 0-255 to 0-1
local blue = colorName[color]["DEC"][3]/255 --rescale from 0-255 to 0-1
color = Color3.new(red, green, blue)
end
if typeof(arguments[i]) == "EnumItem" then mainPart.Material = arguments[i] end
if typeof(arguments[i]) == "number" then
if numNumericArguments > 1 then
workingNumber += 1
if workingNumber == 1 then x = arguments[i] end
if workingNumber == 2 then y,needToCreateYvalue = arguments[i],false end
if workingNumber == 3 then z = arguments[i] end
end
end
end
mainPart.Color = color
mainPart.Size = Vector3.new(0.8, 0.2, 3) -- fixed size of the drone
mainPart.Position = Vector3.new(x,y,z+1)
enginePart.Size = Vector3.new(0.4, 0.4, 0.03) -- fixed size of the drone
enginePart.Position = Vector3.new(x, y, z+0.2)
leftRotorPart.Size = Vector3.new(0.02,1.5,1.5) -- must stay thickness, size, size
leftRotorPart.Position = Vector3.new(x-1.2,y,z)
leftRotorPart.Orientation = Vector3.new(0,0,90)
leftRotorPart.Material = Enum.Material.Glass
leftRotorPart.Color = Color3.new(1, 0, 0.498039)
rightRotorPart.Size = Vector3.new(0.02,1.5,1.5) -- must stay thickness, size, size
rightRotorPart.Position = Vector3.new(x+1.2,y,z)
rightRotorPart.Orientation = Vector3.new(0,0,90)
rightRotorPart.Material = Enum.Material.Glass
rightRotorPart.Color = Color3.new(1, 0, 0.498039)
leftRearRotorPart.Size = Vector3.new(0.02,1.5,1.5) -- must stay thickness, size, size
leftRearRotorPart.Position = Vector3.new(x-1.2,y,z+2)
leftRearRotorPart.Orientation = Vector3.new(0,0,90)
leftRearRotorPart.Material = Enum.Material.Glass
leftRearRotorPart.Color = Color3.new(1, 0, 0.498039)
rightRearRotorPart.Size = Vector3.new(0.02,1.5,1.5) -- must stay thickness, size, size
rightRearRotorPart.Position = Vector3.new(x+1.2,y,z+2)
rightRearRotorPart.Orientation = Vector3.new(0,0,90)
rightRearRotorPart.Material = Enum.Material.Glass
rightRearRotorPart.Color = Color3.new(1, 0, 0.498039)
local otherParts = { enginePart, leftRotorPart, rightRotorPart, leftRearRotorPart, rightRearRotorPart }
local success, newDrone = pcall(function()
return mainPart:UnionAsync(otherParts)
end)
-- If operation succeeds, position it at the same location and parent it to the workspace
if success and newDrone then
newDrone.Position = mainPart.Position
newDrone.Parent = workspace
newDrone:SetAttribute("gyroSensor", 0) -- Keeps track of the degrees rotated
local currentOrientation = newDrone:GetPivot()
local cfa = newDrone.CFrame.LookVector
local degreeOffsetFromZero = (math.atan2(cfa.x, cfa.z)*180/math.pi)+270
print("Initial degree offset from zero: "..tostring(degreeOffsetFromZero))
newDrone:SetAttribute("gyroSensorOffsetFromTrueZero", degreeOffsetFromZero)
newDrone:SetAttribute("lastVectorValue", degreeOffsetFromZero)
newDrone:SetAttribute("encoderValue", 0) -- Keeps track of the distances travelled
newDrone:SetAttribute("lastPositionX", newDrone.Position.x) -- Keeps track of the distances travelled
newDrone:SetAttribute("lastPositionZ", newDrone.Position.z) -- Keeps track of the distances travelled
end
-- Destroy original parts which remain intact after operation
mainPart:Destroy()
for i = 1, #otherParts do
otherParts[i]:Destroy()
end
return newDrone
--return completeDrone
--[[]]
end
function objectWrapper(Instance)
end
-- ---------------------------------------------------------------------------------------------------------------------------------
-- Compass Functions
--
local showCompass = true -- This variable is local to this module
function drones.showingCompass(...)
local arguments = table.pack(...) -- If any arguments were passed, put them into an array
if #arguments == 0 then return showCompass end -- If no argument is passed, then just return the current value. Similar to a .get() method
print("In ShowingCompass " .. tostring(#arguments) .. " " )
if typeof(arguments[1]) == "boolean" then -- If there is an argument and it is boolean, then
showCompass = arguments[1] -- set the current value to the boolean that was passed
local Children = game.Workspace:GetChildren() -- While you're at it, let's get all the child elements and set their Transparency property
if showCompass then -- If you're supposed to show the compass, then Search the workspace for Compass models and turn them visible
for i = 1, #Children do -- For each child in "workspace"
if Children[i].name == "Compass" then
toggleTransparency(Children[i], 0) -- A transparency of zero means they are visible
end
end
else -- Search the workspace for Compass models and turn them transparent
for i = 1, #Children do
if Children[i].name == "Compass" then
toggleTransparency(Children[i], 1) -- A transparency of one means invisible
end
end
end
end
return false
end
function toggleTransparency(model, transparency)
for i, part in pairs (model:GetChildren()) do -- Loop through each part in this model
if hasProperty(part,"Transparency") then part.Transparency = transparency end -- only set the transparency if there is a property called "Transparency". This is similar to JavaScript's hasOwnProerty()
if part:GetChildren() then toggleTransparency(part, transparency) end -- Uses recursion if there are children in this part
end
end
function hasProperty(object, propertyName) -- Does this part have a specific property
local success, _ = pcall(function() -- create a function to return true or false depending if the propertyName exists
object[propertyName] = object[propertyName]
end)
return success
end
function drones.newCompass(...)
local compassGroup = Instance.new("Model")
compassGroup.Name = "Compass"
local compassLabelsGroup = Instance.new("Model")
for j = 1, 36 do
local xCoordinate = 20 * math.cos((j*10) * math.pi/180)
local zCoordinate = 20 * math.sin((j*10) * math.pi/180)
local hashMark = Instance.new("Part")
hashMark.Size = Vector3.new(4,.2,.3)
hashMark.Position = Vector3.new(xCoordinate, 0.1, zCoordinate)
hashMark.Rotation = Vector3.new(0, j*-10, 0)
hashMark.Anchored = true
hashMark.CanCollide = false
hashMark.Color = Color3.new(0, 0, 0)
hashMark.Name = "Hash" .. tostring(j)
hashMark:SetAttribute("xOffset", xCoordinate)
hashMark:SetAttribute("zOffset", zCoordinate)
hashMark.Parent = compassGroup
end
for j = 0, 359, 30 do
local xCoordinate = 20 * math.cos((j) * math.pi/180)
local zCoordinate = 20 * math.sin((j) * math.pi/180)
local valLabel = s.drawText({ x=xCoordinate*-0.8, y=2, z=zCoordinate*0.8, width=1.8, height=1, text=tostring((j+180)%360), fontSize=20, font=Enum.Font.Code, Opacity=0.9, color="red", backgroundColor=Color3.new(1, 1, 1), RotateBy=Vector3.new(0, j-90, 0), textRotate=0 })
valLabel.Parent = compassLabelsGroup
end
compassLabelsGroup.Name = "Compass"
compassLabelsGroup.Parent = workspace
local aCompass = s.disc( {radius=50, color="white", x=0, y=0, z=0, RotateBy=Vector3.new(0, 0, 90)} )
aCompass.Parent = compassGroup
aCompass:SetAttribute("numHashes", 36)
compassGroup.Parent = workspace
compassGroup:PivotTo(compassGroup:GetPivot() * CFrame.Angles( math.rad(0), math.rad(0), math.rad(0)))
toggleTransparency(compassGroup, 1)
toggleTransparency(compassLabelsGroup, 1)
drones.showCompass = false
local retVal = {compassGroup, compassLabelsGroup}
return retVal -- You are returning a Model called Compass
end
function drones.moveCompassTo(...)
local arguments = table.pack(...)
local x, y, z = 0, 0, 0
local locationValue = 0
local mainPart = arguments[1]
if #arguments == 2 then
mainPart = arguments[1]
locationValue = arguments[1]
elseif #arguments == 4 then locationValue = Vector3.new(arguments[2],arguments[3],arguments[4])
else
end
if typeof(locationValue) == "Vector3" then
mainPart.Position = locationValue
else
print("Error in the moveTo method. You need to pass a Vector3. You passed a: "..typeof(locationValue))
end
return mainPart
end
return drones