burgelkat Posted July 25 Share Posted July 25 Hello, long time no see ^^ at the moment i have a littel time and i try to learn more with lua. I need help with my script. Maybe my thoughts completley wrong. I have a simple map with two boxes. One box is Main the second Box i made as a child each box has the script I'm trying to find out if the box is included in table. and how i can store it. maybe i am compleatly wrong.. maybe someone can help me FlockEntity = {name = "FlockEntity"} FlockEntity.maxforce = Vec3(0) --set to 20.005 then its hoovering (Mass = 1) FlockEntity.pointforce = Vec3(0) function FlockEntity:Start() self.tbl = {} self.entity:GetParent() self.entity:FindChild("Box*") print(index) print(self.tbl) print(name) end function FlockEntity:Update() ------ Hoover ---------------------- self.entity:AddForce(self.maxforce) ------------------------------------ -----------------Flock.lua------------------------------------------------------------------------ self.radius = 1 for i=1, #self.tbl do self.elem = self.tbl[i] if (self.elem ~= self.entity) then self.vNeighborDelta = self.elem:GetPosition() - self.entity:GetPosition() self.dist = self.vNeighborDelta:Length() if (self.dist < self.radius * 2) then self.vNeighborDelta:Normalize() self.entity:GetPhysicsMode() self.entity:AddForce(self.pointforce) end end end end RegisterComponent("Flock", FlockEntity) return FlockEntity Quote Link to comment Share on other sites More sharing options...
Josh Posted July 25 Share Posted July 25 I do not understand what you are trying to do. Your script is very confusing. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
burgelkat Posted July 25 Author Share Posted July 25 I wanted to try to recreate the script in UltraEngine. Quote Link to comment Share on other sites More sharing options...
burgelkat Posted July 31 Author Share Posted July 31 new one.. but there is a problem with "otherbox" ^^ attempt to call a nil value (method "GetPosition") also math.atan2 dont works Quote Link to comment Share on other sites More sharing options...
Josh Posted July 31 Share Posted July 31 You can just call ATan(). Quote box:GetPostion Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
burgelkat Posted August 9 Author Share Posted August 9 ok thanks .. thats my solution not yet perfect but for now ok .. the boxes will be change with a fish model Quote Link to comment Share on other sites More sharing options...
burgelkat Posted August 23 Author Share Posted August 23 i have fun with that .. now i have a flock of fishes with avoid collision and different movements. at the moment there is a flicker in pitch or in avoid collision . maybe i find a solution later or someone find a solution Flock = {} Flock.name = "Flock" function Flock:Start() world = self.entity:GetWorld() self.boxes = {} self.boxProperties = {} self.offset = self.entity:GetPosition() -- Position of the pivot used as offset -- Define Y-axis limits self.minY = self.offset.y - 2.0 -- Minimum Y limit self.maxY = self.offset.y + 0.5 -- Maximum Y limit -- Initialize random seed (per instance) math.randomseed(os.time()) InitializeBoxes(self) end -- Define constants Flock.radius = 5.0 Flock.numBoxes = 8 minDistance = 3 -- Minimum distance to avoid collision avoidanceStrength = 0.2 -- Strength of the avoidance force -- Movement pattern functions movementPatterns = {} function movementPatterns.circular(self, angle) local x = self.offset.x + self.radius * math.cos(angle) local y = self.offset.y + self.radius * math.sin(angle * 0.5) -- y-movement added local z = self.offset.z + self.radius * math.sin(angle) y = math.max(math.min(y, self.maxY), self.minY) -- Clamp Y within limits return Vec3(x, y, z) end function movementPatterns.elliptical(self, angle) local a = self.radius local b = self.radius / 2 local x = self.offset.x + a * math.cos(angle) local y = self.offset.y + b * math.sin(angle * 0.5) -- y-movement added local z = self.offset.z + b * math.sin(angle) y = math.max(math.min(y, self.maxY), self.minY) -- Clamp Y within limits return Vec3(x, y, z) end function movementPatterns.spiral(self, angle) local r = self.radius + angle * 0.5 local x = self.offset.x + r * math.cos(angle) local y = self.offset.y + r * math.sin(angle * 0.5) -- y-movement added local z = self.offset.z + r * math.sin(angle) y = math.max(math.min(y, self.maxY), self.minY) -- Clamp Y within limits return Vec3(x, y, z) end function movementPatterns.zigzag(self, angle) local amplitude = 2.0 local frequency = 2.0 local x = self.offset.x + self.radius * math.cos(angle) local y = self.offset.y + amplitude * math.sin(frequency * angle) -- y-movement adjusted local z = self.offset.z + amplitude * math.sin(frequency * angle) y = math.max(math.min(y, self.maxY), self.minY) -- Clamp Y within limits return Vec3(x, y, z) end function AlignBoxWithMovement(box, previousPosition, newPosition) local direction = (newPosition - previousPosition):Normalize() -- Calculate yaw (rotation around Y-axis) and pitch (rotation around X-axis) to face the movement direction local yaw = ATan(direction.x, direction.z) -- Yaw around Y-axis local pitch = ATan(direction.y, (direction.x^2 + direction.z^2)^0.5) -- Pitch around X-axis -- Adjust yaw for model orientation if needed yaw = yaw + 180 -- Ensure pitch and yaw are numeric types before setting rotation pitch = tonumber(pitch) or 0 yaw = tonumber(yaw) or 0 -- Set the rotation of the box (yaw and pitch ) box:SetRotation(pitch, yaw, 0) end function InitializeBoxes(self) for i = 1, self.numBoxes do local patternNames = {"circular", "elliptical", "spiral", "zigzag"} local patternName = patternNames[math.random(#patternNames)] local movementFunction = movementPatterns[patternName] local speed = math.random() * 2 + 0.5 local angle = math.random() * 2 * math.pi local position = movementFunction(self, angle) local box = LoadModel(world, "H:/UltraEngine/New Project/Models/Diverses/Fish.mdl") -- or CreateBox(world,1) box:SetPosition(position) self.boxes[i] = box self.boxProperties[box] = { movementFunction = movementFunction, speed = speed, angle = angle, patternName = patternName, lastPosition = position -- Store the initial position as last position } end end function AvoidCollisions(self, box, newPosition, otherPositions) local smoothingFactor = 0.1 -- The factor by which to smooth the Y-axis movement for _, otherBox in ipairs(self.boxes) do if box ~= otherBox then local otherPosition = otherPositions[otherBox] -- Use previous position instead of current position if otherPosition then local distance = newPosition:DistanceToPoint(otherPosition) if distance < minDistance then local avoidanceDirection = (newPosition - otherPosition):Normalize() local horizontalDistance = ((newPosition.x - otherPosition.x)^2 + (newPosition.z - otherPosition.z)^2)^0.5 if horizontalDistance < minDistance then if newPosition.y < otherPosition.y then newPosition.y = math.max(newPosition.y - smoothingFactor, self.minY) -- Smooth downward movement else newPosition.y = math.min(newPosition.y + smoothingFactor, self.maxY) -- Smooth upward movement end end newPosition = newPosition + avoidanceDirection * ((minDistance - distance) / minDistance) * avoidanceStrength newPosition.y = math.max(math.min(newPosition.y, self.maxY), self.minY) -- Clamp Y within limits end end end end return newPosition end function UpdateBoxes(self, deltaTime) local newPositions = {} for _, box in ipairs(self.boxes) do local props = self.boxProperties[box] props.angle = props.angle + props.speed * 0.003 local newPosition = props.movementFunction(self, props.angle) if newPosition then newPosition = AvoidCollisions(self, box, newPosition, newPositions) newPositions[box] = newPosition end end for _, box in ipairs(self.boxes) do local newPosition = newPositions[box] local props = self.boxProperties[box] if newPosition then AlignBoxWithMovement(box, props.lastPosition, newPosition) box:SetPosition(newPosition) props.lastPosition = newPosition end end end function Flock:Update(deltaTime) UpdateBoxes(self, deltaTime) end RegisterComponent("Flock", Flock) return Flock 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.