Jump to content

Rotating radar thing


havenphillip
 Share

Recommended Posts

I'm trying to make this rotating radar thing. I have this script but I get the feeling I'm doing way more than necessary and it's really jumpy. I'm not that good with shaders and still pretty limited in my understanding of coding in general. You can kind of see what I'm trying to do but what's the best way to go about this?

Current script:
 

Script.target = nil -- entity "Target"
Script.dotSize = 5 -- int "Dot Size"

function Script:Start()
    self.player = self.entity:GetParent()
    self.mapPos = Vec2(200,200)
end

function Script:PostRender(context)
    x = self.mapPos.x/2
    y = self.mapPos.y/2     
    pos = self.player:GetPosition(true)
    enemy = self.target:GetPosition(true)
    a = self.player:GetRotation(true).y
    s = self.dotSize

    context:SetBlendMode(1)
    context:SetColor(1,1,1,1)

    context:DrawRect(x,y,s,s)

    context:SetColor(1,0,0,1)
    
    if a <= 30 and a >= - 30 then -- facing forward
        if pos.x < enemy.x and pos.z < enemy.z then -- lower left
            local X = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local Y = y+(-Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z < enemy.z then -- lower right
            local X = x+(-Math:Cos(-a)*(pos.x-enemy.x) - Math:Sin(-a)*(enemy.x-pos.x))
            local Y = y+(Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x < enemy.x and pos.z > enemy.z then -- upper left
            local X = x+(-Math:Cos(-a)*(pos.x-enemy.x) - Math:Sin(-a)*(enemy.x-pos.x))
            local Y = y+(Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z > enemy.z then -- upper right
            local X = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local Y = y+(-Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        end

    elseif a >= 150 and a <= 180 then -- facing backward
        if pos.x < enemy.x and pos.z < enemy.z then -- lower left
            local X = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local Y = y+(-Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z < enemy.z then -- lower right
            local X = x+(-Math:Cos(-a)*(pos.x-enemy.x) - Math:Sin(-a)*(enemy.x-pos.x))
            local Y = y+(Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x < enemy.x and pos.z > enemy.z then -- upper left
            local X = x+(-Math:Cos(-a)*(pos.x-enemy.x) - Math:Sin(-a)*(enemy.x-pos.x))
            local Y = y+(Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z > enemy.z then -- upper right
            local X = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local Y = y+(-Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        end

    elseif a >= -180 and a <= -150 then -- facing backward
        if pos.x < enemy.x and pos.z < enemy.z then -- lower left
            local X = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local Y = y+(-Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z < enemy.z then -- lower right
            local X = x+(-Math:Cos(-a)*(pos.x-enemy.x) - Math:Sin(-a)*(enemy.x-pos.x))
            local Y = y+(Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x < enemy.x and pos.z > enemy.z then -- upper left
            local X = x+(-Math:Cos(-a)*(pos.x-enemy.x) - Math:Sin(-a)*(enemy.x-pos.x))
            local Y = y+(Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z > enemy.z then -- upper right
            local X = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local Y = y+(-Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        end

    elseif a >= 30 and a <= 149 then -- facing right
        if pos.x < enemy.x and pos.z < enemy.z then -- lower left
            local Y = x+(Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local X = y+(-Math:Sin(a)*(enemy.z-pos.z) - Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z < enemy.z then -- lower right
            local Y = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local X = y+(-Math:Sin(a)*(enemy.z-pos.z) - Math:Cos(a)*(enemy.z-pos.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x < enemy.x and pos.z > enemy.z then -- upper left
            local Y = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local X = y+(-Math:Sin(a)*(enemy.z-pos.z) - Math:Cos(a)*(enemy.z-pos.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z > enemy.z then -- upper right
            local Y = x+(Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local X = y+(-Math:Sin(a)*(enemy.z-pos.z) - Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        end

    elseif a <= -30 and a >= -149 then -- facing left
        if pos.x < enemy.x and pos.z < enemy.z then -- lower left
            local Y = x+(Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local X = y+(-Math:Sin(a)*(enemy.z-pos.z) - Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z < enemy.z then -- lower right
            local Y = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local X = y+(-Math:Sin(a)*(enemy.z-pos.z) - Math:Cos(a)*(enemy.z-pos.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x < enemy.x and pos.z > enemy.z then -- upper left
            local Y = x+(-Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local X = y+(-Math:Sin(a)*(enemy.z-pos.z) - Math:Cos(a)*(enemy.z-pos.z))
            context:DrawRect(X,Y,s,s)
        elseif pos.x > enemy.x and pos.z > enemy.z then -- upper right
            local Y = x+(Math:Cos(a)*(pos.x-enemy.x) - Math:Sin(a)*(enemy.x-pos.x))
            local X = y+(-Math:Sin(a)*(enemy.z-pos.z) - Math:Cos(a)*(pos.z-enemy.z))
            context:DrawRect(X,Y,s,s)
        end
    end

    context:SetBlendMode(0)

    context:SetBlendMode(1)
    context:SetColor(1,1,1,1)
    context:DrawText(Math:Round(pos.x)..","..Math:Round(pos.z).."/"..Math:Round(enemy.x)..","..Math:Round(enemy.z), 20, 20)
    context:DrawText(a,20,50)
end

Link to comment
Share on other sites

Regardless of whether the code is right, I think your script can become a clearer/easier to read if you make use of functions. Every single if statement does more or less the same thing with only slight deviation. 

--current first if statement
local X = x+(-Math:Cos(-a)*(pos.x-enemy.x) - Math:Sin(-a)*(enemy.x-pos.x))
local Y = y+(Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
context:DrawRect(X,Y,s,s)

--Format to:
if statement
  local drawCoord = GetDrawCoordinate(Vec2(X, Y), playerPos, enemyPos, true, yRotation)
  context:DrawRect(drawCoord.x, drawCoord.y, s, s)
end

--Helper function that retrieves the right DrawCoords
function GetDrawCoordinate(mapPos, playerPos, enemyPos, isNegative, yRotation)
    local dir = 1;
    if isNegative then
        dir  = -1
    end

    local x = mapPos.x+(dir * Math:Cos(dir * yRotation)*(playerPos.x-enemy.x) - Math:Sin(dir * yRotation)*(enemyPos.x-playerPos.x))
    local y = mapPos.y+(-Math:Sin(yRotation)*(enemyPos.z-playerPos.z) + Math:Cos(yRotation)*(playerPos.z-enemyPos.z))
    return Vec2(x,y)
end

 

 

 

Link to comment
Share on other sites

Ok I'm getting an error "...error in function 'new' [argument #2 is nil...no object expected" adding variables inside a created function is still kind of a new concept to me. You don't have a video on specifically this, do you?

Here's how I have it set up. Where is 'new' argument 2?

--Helper function that retrieves the right DrawCoords
function GetDrawCoordinate(mapPos, playerPos, enemyPos, isNegative, yRotation)
    local dir = 1;
    if isNegative then
        dir  = -1
    end

    local x = mapPos.x+(dir * Math:Cos(dir * yRotation)*(playerPos.x-enemyPos.x) - Math:Sin(dir * yRotation)*(enemyPos.x-playerPos.x))
    local y = mapPos.y+(-Math:Sin(yRotation)*(enemyPos.z-playerPos.z) + Math:Cos(yRotation)*(playerPos.z-enemyPos.z))
    return Vec2(x,y)
end

function Script:PostRender(context)
    x = self.mapPos.x/2
    y = self.mapPos.y/2     
    playerPos = self.player:GetPosition(true)
    enemyPos = self.target:GetPosition(true)
    a = self.player:GetRotation(false).y
    s = self.dotSize

    context:SetBlendMode(1)
    context:SetColor(1,1,1,1)

    context:DrawRect(x,y,s,s)

    context:SetColor(1,0,0,1)

    --Format to:
    if a <= 30 and a >= - 30 then -- facing forward
      local drawCoord = GetDrawCoordinate(Vec2(X, Y), playerPos, enemyPos, true, yRotation)
      context:DrawRect(drawCoord.x, drawCoord.y, s, s)
    end

 

Link to comment
Share on other sites

Okay lets first practice by making a very basic function. Lets make basic functions that returns the calculation that happens several times in your code:

Take for instance this line: 

local Y = y+(-Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))

This line already exists 6 times in your code. So if you have an error in this calculation, you have change it 6 times. This makes your code hard to read and mistakes are easily made.

image.thumb.png.95479a430a0ae9dac2d2231e91314033.png

So lets try to turn that in to a basic function:

function GetYDrawCoordinate1(y, enemy, pos)
	return = y+(-Math:Sin(a)*(enemy.z-pos.z) + Math:Cos(a)*(pos.z-enemy.z))
end

This function now has 3 parameters that need to be filled in when you call it. I would also advice to rename the y and pos variable to something clearer. Something that tells you what exactly is stored in the variable.

 local Y = GetYDrawCoordinateTest1(y, enemy, pos)

 

A generic video on how functions with parameters work:

 

 

Let me know how that goes and we move on to the rest of the code.

  • Like 1
Link to comment
Share on other sites

Cool. Thanks. I kind of get it. It boggles my mind a bit how you can just say something like "isNegative" and go about using it without defining it anywhere. My brain will slowly absorb this.

This code works so far. I'm getting a slope on rotation rather than a  circular motion, and for some reason if I add an "if" statement I get that error again. It's a lua error or something so it doesn't highlight a line or anything. I'm totally in the dark about it.

What I think I need is to adjust these for right 90 and left -90 degree turns, which requires an "if." Not sure if I should try to get the rotation working or fiddle with the turn problem first, or if solving one of those will also solve the other. Ideally, without having to add a ton of coordinate statements the enemy dot would move down from top to center as I walk facing towards it and continue down as I walk away from it, regardless of my player position and rotation relative to the enemy position. As it is, when I turn right and walk away from the target, the dot moves left, rather than down. Where should I focus my efforts from here?

Script.target = nil -- entity "Target"
Script.dotSize = 5 -- int "Dot Size"

function Script:Start()
    self.player = self.entity:GetParent()
    self.mapPos = Vec2(300,300)
end

function GetDrawCoordinate(mapPos, playerpos, enemypos, isNegative, yRotation)
    local dir = 1;
    if isNegative then
        dir  = -1
    end

    local X = mapx+(dir * Math:Cos(dir * rot)*(player.x-enemy.x) - Math:Sin(dir * rot)*(enemy.x-player.x))
    local Y = mapy+(-Math:Sin(rot)*(enemy.z-player.z) + Math:Cos(rot)*(player.z-enemy.z))
    
    return Vec2(X,Y)
end

function Script:PostRender(context)
    mapx = self.mapPos.x/2
    mapy = self.mapPos.y/2     
    player = self.player:GetPosition(true)
    enemy = self.target:GetPosition(true)
    rot = self.player:GetRotation(true).y
    s = self.dotSize

    context:SetBlendMode(1)
    context:SetColor(1,1,1,1)
    context:DrawRect(mapx,mapy,s,s)

    context:SetColor(1,0,0,1)
    local drawCoord = GetDrawCoordinate(Vec2(mapx,mapy), player, enemy, true, rot)
    context:DrawRect(drawCoord.x, drawCoord.y, s, s)

    context:SetColor(1,1,1,1)
    context:DrawText(Math:Round(rot),20,50)
end

Link to comment
Share on other sites

4 hours ago, havenphillip said:

 It boggles my mind a bit how you can just say something like "isNegative" and go about using it without defining it anywhere. My brain will slowly absorb this.

When a function has parameters (like the 'isNegative' example), then these do have any values automatically. They only get a value assigned to them when you call the function, and pass in existing values.

Regardless if the calculations are correct and regardless whether this can all be done in a few lines with the right calculation, right now I am more concerned about how your code is structured. By organizing your code, we can find the solution faster. So lets try and break the code down from your very first post and imrove it step by step.


Looking at the if statements
Your code is currently divided in 5 if statements that check the playerY rotation. 

image.png.5aa23c51d54ca503362223df112c3de5.png

  • Your first if statement covers the forward direction: -30 and 30. That looks good.
  • Your 2nd and 3rd if statement are for the backwards direction. These can be combined to 1 if statement. Saves you 15 lines of code.
elseif (playerYRotation >= 150 and playerYRotation <= 180) or (playerYRotation >= -180 and playerYRotation <= -150) then

 

DrawRect()

Every single DrawRect you use inside the if statement does the same thing. This can be reduced to a single DrawRect() and using a single drawCoordinates variables that gets filled by 1 of the if statements. This saves you about 18 lines of code.

 

Current status of the script

We are not there yet, but here is how that code looks in the meantime: 36 lines shorter. Let me know if you have questions about what I have done so far. Once that is clear we will continue improving:

Script.target = nil -- entity "Target"
Script.dotSize = 5 -- int "Dot Size"

function Script:Start()
    self.player = self.entity:GetParent()
    self.mapPos = Vec2(200, 200)
end

function Script:PostRender(context)
    local x = self.mapPos.x / 2
    local y = self.mapPos.y / 2
    local playerPos = self.player:GetPosition(true)
    local enemyPos = self.target:GetPosition(true)
    local playerYRotation = self.player:GetRotation(true).y
    local drawCoords = Vec2(0,0) --We will use this variable to store the calculated draw position 

    context:SetBlendMode(1)
    context:SetColor(1, 1, 1, 1)
    context:DrawRect(x, y, self.dotSize, self.dotSize)
    context:SetColor(1, 0, 0, 1)

    if playerYRotation <= 30 and playerYRotation >= -30 then -- facing forward
        if playerPos.x < enemyPos.x and playerPos.z < enemyPos.z then -- lower left
            drawCoords.x = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.y = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        elseif playerPos.x > enemyPos.x and playerPos.z < enemyPos.z then -- lower right
            drawCoords.x = x + (-Math:Cos(-playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(-playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.y = y + (Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        elseif playerPos.x < enemyPos.x and playerPos.z > enemyPos.z then -- upper left
            drawCoords.x = x + (-Math:Cos(-playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(-playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.y = y + (Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        elseif playerPos.x > enemyPos.x and playerPos.z > enemyPos.z then -- upper right
            drawCoords.x = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.y = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        end
    elseif (playerYRotation >= 150 and playerYRotation <= 180) or (playerYRotation <= -150 and playerYRotation >= -180 ) then -- facing backward
        if playerPos.x < enemyPos.x and playerPos.z < enemyPos.z then -- lower left
            drawCoords.x = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.y = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        elseif playerPos.x > enemyPos.x and playerPos.z < enemyPos.z then -- lower right
            drawCoords.x = x + (-Math:Cos(-playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(-playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.y = y + (Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        elseif playerPos.x < enemyPos.x and playerPos.z > enemyPos.z then -- upper left
            drawCoords.x = x + (-Math:Cos(-playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(-playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.y = y + (Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        elseif playerPos.x > enemyPos.x and playerPos.z > enemyPos.z then -- upper right
            drawCoords.x = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.y = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        end
    elseif playerYRotation >= 30 and playerYRotation <= 149 then -- facing right
        if playerPos.x < enemyPos.x and playerPos.z < enemyPos.z then -- lower left
            drawCoords.y = x + (Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        elseif playerPos.x > enemyPos.x and playerPos.z < enemyPos.z then -- lower right
            drawCoords.y = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (enemyPos.z - playerPos.z))
        elseif playerPos.x < enemyPos.x and playerPos.z > enemyPos.z then -- upper left
            drawCoords.y = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (enemyPos.z - playerPos.z))
        elseif playerPos.x > enemyPos.x and playerPos.z > enemyPos.z then -- upper right
            drawCoords.y = x + (Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        end
    elseif playerYRotation <= -30 and playerYRotation >= -149 then -- facing left
        if playerPos.x < enemyPos.x and playerPos.z < enemyPos.z then -- lower left
            drawCoords.y = x + (Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
        elseif playerPos.x > enemyPos.x and playerPos.z < enemyPos.z then -- lower right
            drawCoords.y = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (enemyPos.z - playerPos.z))
        elseif playerPos.x < enemyPos.x and playerPos.z > enemyPos.z then -- upper left
            drawCoords.y = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (enemyPos.z - playerPos.z))
        elseif playerPos.x > enemyPos.x and playerPos.z > enemyPos.z then -- upper right
            drawCoords.y = x + (Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
            drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))   
        end
    end
    context:DrawRect(drawCoords.x, drawCoords.y, self.dotSize, self.dotSize)

    context:SetBlendMode(0)
    context:SetColor(1, 1, 1, 1)
    context:DrawText(
        Math:Round(playerPos.x) .. "," .. Math:Round(playerPos.z) .. "/" .. Math:Round(enemyPos.x) .. "," .. Math:Round(enemyPos.z),
        20,
        20
    )
    context:DrawText(playerYRotation, 20, 50)
    context:SetBlendMode(1)
end

 

Link to comment
Share on other sites

Ok. I think I see that. You created the Vec2 drawCoords variable but left it empty, basically. That allowed you to make x and y flexible depending on whatever you might want to do. And then with the "or" statements (which I was unaware of) you can reduce it down to this since some of the lines are similar:

Script.target = nil -- entity "Target"
Script.dotSize = 5 -- int "Dot Size"

function Script:Start()
    self.player = self.entity:GetParent()
    self.mapPos = Vec2(200, 200)
end

function Script:PostRender(context)
    local x = self.mapPos.x / 2
    local y = self.mapPos.y / 2
    local playerPos = self.player:GetPosition(true)
    local enemyPos = self.target:GetPosition(true)
    local playerYRotation = self.player:GetRotation(true).y
    local drawCoords = Vec2(0,0) --We will use this variable to store the calculated draw position

    context:SetBlendMode(1)
    context:SetColor(1, 1, 1, 1)
    context:DrawRect(x, y, self.dotSize, self.dotSize)
    context:SetColor(1, 0, 0, 1)

    if (playerYRotation <= 30 and playerYRotation >= -30) or
       (playerYRotation >= 150 and playerYRotation <= 180) or
       (playerYRotation <= -150 and playerYRotation >= -180 ) then -- facing forward or backward
            if (playerPos.x < enemyPos.x and playerPos.z < enemyPos.z) or
               (playerPos.x > enemyPos.x and playerPos.z > enemyPos.z) then
                drawCoords.x = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
                drawCoords.y = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
            elseif (playerPos.x > enemyPos.x and playerPos.z < enemyPos.z) or
                   (playerPos.x < enemyPos.x and playerPos.z > enemyPos.z) then
                    drawCoords.x = x + (-Math:Cos(-playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(-playerYRotation) * (enemyPos.x - playerPos.x))
                    drawCoords.y = y + (Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) + Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
            end
    elseif (playerYRotation >= 30 and playerYRotation <= 149) or
           (playerYRotation <= -30 and playerYRotation >= -149) then -- facing right/left
            if (playerPos.x < enemyPos.x and playerPos.z < enemyPos.z) or
               (playerPos.x > enemyPos.x and playerPos.z > enemyPos.z) then
                drawCoords.y = x + (Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
                drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (playerPos.z - enemyPos.z))
            elseif (playerPos.x > enemyPos.x and playerPos.z < enemyPos.z) or
                   (playerPos.x < enemyPos.x and playerPos.z > enemyPos.z) then
                    drawCoords.y = x + (-Math:Cos(playerYRotation) * (playerPos.x - enemyPos.x) - Math:Sin(playerYRotation) * (enemyPos.x - playerPos.x))
                    drawCoords.x = y + (-Math:Sin(playerYRotation) * (enemyPos.z - playerPos.z) - Math:Cos(playerYRotation) * (enemyPos.z - playerPos.z))
            end
    end

    context:DrawRect(drawCoords.x, drawCoords.y, self.dotSize, self.dotSize)

    context:SetBlendMode(0)
    context:SetColor(1, 1, 1, 1)
    context:DrawText(
        Math:Round(playerPos.x) .. "," .. Math:Round(playerPos.z) .. "/" .. Math:Round(enemyPos.x) .. "," .. Math:Round(enemyPos.z),
        20,
        20
    )
    context:DrawText(playerYRotation, 20, 50)
    context:SetBlendMode(1)
end


 

Link to comment
Share on other sites

It's great, man. It works. The rules are correct for the quadrants. The rotation sets the correct directions when walking towards or away, etc. But the dot is a bit jumpy. I have four equal quadrants and when I stand on or near the Z line (for instance) relative to the crawler and spin in a circle, the dot doesn't rotate. It just goes up and down. Same when I stand on or near the X line. I think it's because the number for the X coordinate is basically zero when I'm on the Z line so it's completely flattened. And if I walk to one of the four corners of my map I get a nice circle on rotation because the X and Z are equidistant. So as I'm walking around and rotating and stuff the dot kind of jumps around. So what I need to figure out is how to keep that circular shape from collapsing into a line when I cross between quadrants.

No video. Sorry. I don't know how to do that. I don't really have a game or anything. Just a crawler standing in the middle of a big square lol. By all means copy/paste the code if you want. You can see for yourself.

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...