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 radius = math.random(minimumRadius, maximumRadius)

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
	local radius: number = math.random(minimumRadius, maximumRadius)
	local positionOnCircle: CFrame = CFrame.new(math.sin(angle) * radius, math.cos(angle) * radius, 0)
		
	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)

		task.spawn(function()
			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()

				task.wait(speed / length)
			end
		end)

		debris:AddItem(attachmentContainer, (speed + 10))
	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. :slight_smile:

1 Like

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