How would I go about fixing my wind circle

Heyo,

I’m currently programming some wind effects for a slide mechanic in my game; but I’ve encountered an issue which I can’t seem to wrap my head around.

The wind position is chosen based on this formula:

``````-- variables
local points = 10 -- this determines the quality of the circle; aka how many "points" it has.
local minimumRadius, maxiumumRadius = 10, 14 -- these values determine the radius of the circle given the min and max

-- actual values
local randomPoint = math.random(points)

local angle = (math.pi * 2 * randomPoint) / points

local position = Vector3.new(math.sin(angle), math.cos(angle), 0) * radius
``````

As you can see in the video below, the wind looks good and there’s no problem:

However I’m facing in the `x` direction in the video above. Take a look at what happens when I slide towards the `z` direction:

The wind is only spawning properly on the `y` axis and won’t create a circular shape like the first video. I believe the issues lies at this line here:

``````local position = Vector3.new(math.sin(angle), math.cos(angle), 0) * radius
``````

Defining a new `Vector3` variable; and the `sin` value is only changing on the `x` axis. I tried to visualize it using parts and it makes sense to why it doesn’t work:
( correct + looking in the `x` direction )

( incorrect + looking in the `z` direction )

I want to solve this mathematically and not in a hacky way. I couldn’t find any sources about “creating a circle based on the character’s lookvector” kind of thing, so I’m here. Any help would be greatly appreciated.

I think you could just multiply the position * lookVector

2 Likes

When you add the Vector3 position, its axes are relative to the world space, which doesn’t change as your character’s orientation changes, so the circle will always be pointing in the same direction. However, if instead of using `character.PrimaryPart.CFrame + position` you use `character.PrimaryPart.CFrame * CFrame.new(position)`, the position will be relative to the character’s orientation and should give you the result you need. See CFrame - Math Operations

1 Like

I’m looking into using `CFrames` however, it still doesn’t seem to function as intended. I multiplied both of the `CFrames` as such:

``````function wind:CreateFromPoint(points: number, minimumRadius: number, maximumRadius: number, from: CFrame, direction: CFrame, ...)
local randomPoint: number = math.random(points)
local angle: number = (self.fullCircle * randomPoint) / points

self:Create(from * positionOnCircle, direction, ...)
end
``````

This code is called from this function:

``````self.wind:CreateFromPoint(20, 13, 16, CFrame.new(self.humanoidRootPart.Position + self.humanoidRootPart.CFrame.LookVector * 42), CFrame.new(-self.humanoidRootPart.CFrame.LookVector), 55, (1 - force) + 0.35, Vector3.new(self.chance:RandomDouble(-2, 2), self.chance:RandomDouble(-2, 2), self.chance:RandomDouble(-2, 2)))
``````

`20` being the amount of points.
`13` and `16` being the random radius.
The next argument being where the place the actual wind part.
The one after that being the direction of the wind.
And the rest are sort of irrelevant ( just small tweaks like wind frequency etc… )

I’m honestly just stumped at this point haha. I’ll try mess around with it more and see if I can get something going.

1 Like

Instead of `CFrame.new(self.humanoidRootPart.Position + self.humanoidRootPart.CFrame.LookVector * 42)`

Try
`self.humanoidRootPart.CFrame * CFrame.new(self.humanoidRootPart.CFrame.LookVector * 42)`

Let me know what happens.

2 Likes

Apologies, the video couldn’t be longer but this is once I’ve applied the change:

And this is before the change:

I’ll also provide you with the code that I use to actually move the part/wind:

``````function wind:Create(from: CFrame, direction: CFrame, length: number, speed: number, offset: Vector3)
do
local attachmentContainer: Part = Instance.new("Part")
attachmentContainer.Name = "Wind Attachment Container"
attachmentContainer.Size = Vector3.one
attachmentContainer.Anchored = true
attachmentContainer.CanCollide = false
attachmentContainer.CanTouch = false
attachmentContainer.CanQuery = false
attachmentContainer.Transparency = 0
attachmentContainer.CFrame = from
attachmentContainer.Parent = self.camera

local attachment0: Attachment = self:InstanceAttachment("Wind Attachment0", Vector3.new(0, self.windSize, 0), attachmentContainer)
local attachment1: Attachment = self:InstanceAttachment("Wind Attachment1", Vector3.new(0, -self.windSize, 0), attachmentContainer)

local windTrail: Trail = self:InstanceWindTrail("Wind Trail", attachmentContainer, attachment0, attachment1)

for x: number = 1, length do
tweenService:Create(attachmentContainer, TweenInfo.new(speed / length, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0), {
CFrame = from * CFrame.new(direction.Position * x) * CFrame.new(0, math.sin(x / 6.5), 0)
}):Play()

end
end)

end
end
``````

I’ll hop in Studio to see if I can pinpoint the error

2 Likes

I think the issue is because you’re creating a new CFrame for your 4th argument of `self.wind:CreateFromPoint()`

``````CFrame.new(self.humanoidRootPart.Position + self.humanoidRootPart.CFrame.LookVector * 42)
``````

Creating a new CFrame will lose the Orientation the humanoidRootPart had since you’re only providing it with the Position of it.

Try:

``````(self.HumanoidRootPart.CFrame + self.humanoidRootPart.CFrame.LookVector * 42)
``````

This should preserve the Orientation of the original CFrame while also displacing it by `LookVector*42`

I was able to properly position points around a sphere using this method of placement with some basic code:

Let me know if this still doesn’t work.

1 Like

Thank you so much! Everything works as intended now.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.