Jump to content

store an entity in table


burgelkat
 Share

Recommended Posts

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

 

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

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

 

Fischflock.jpg

  • Haha 1
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...