# Projectile CFrame orientation issue

Right now I wanna code a CFrame based projectile system. My current method of moving a projectile and factoring in gravity is:

``````self.CFrame = self.CFrame - Vector3.new(0, self.Gravity*Delta, 0)
if self.UsingPhysics then
self.BulletSpeed = self.BulletSpeed - (self.Gravity*Delta)
end
self.CFrame = (self.CFrame + ((self.CFrame.lookVector*self.BulletSpeed)*Delta))
Velocity = (self.CFrame.p - self.LastCFrame.p)
local PredictedAngle = (Velocity.Z + Velocity.Y)/2
self.Part.Orientation = CFrame.new(self.Part.Orientation.X, PredictedAngle, self.Part.Orientation.Z):toObjectSpace(self.Part.CFrame).p
``````

The result I get is

It might seem correct but the bulletâ€™s orientation is stuck like that for the whole time so when the bullet is gonna fall the orientation makes it look like itâ€™s still going up.

Update 1
I changed up the CFrames and now I get this monstrosity

Update 2
If the velocity of an object is X: 5 Y: 10 Z: 10
Iâ€™ll need a way to stable them all out equally. Not sure how tho

Update 3

``````self.CFrame = self.CFrame - Vector3.new(0, self.Gravity*Delta, 0)
if self.UsingPhysics then
self.BulletSpeed = self.BulletSpeed - (self.Gravity*Delta)
end
self.CFrame = (self.CFrame + ((self.CFrame.lookVector*self.BulletSpeed)*Delta))
Velocity = (self.CFrame.p - self.LastCFrame.p)
local PredictedAngle = (Velocity.Z + Velocity.Y)/2
self.Part.Orientation = CFrame.new(self.Part.Orientation.X, PredictedAngle, self.Part.Orientation.Z):toObjectSpace(self.Part.CFrame).p
``````

Using a random part to rotate to a projectileâ€™s rotation shows that it isnâ€™t working correctly for some odd reason

Could you provide the script so that I could try and repo this?

The entire script or the stepping process?

Stepping script:

``````
local NewRay = Ray.new(self.LastCFrame.p, self.LastCFrame.lookVector)
self:UpdateIgnoreList()
local HitPart, HitPosition, Normal, Material = workspace:FindPartOnRayWithIgnoreList(NewRay, self.IgnoreList.IgnoreInstance, false, true)

self.CFrame = self.CFrame - Vector3.new(0, self.Gravity*Delta, 0)
self.BulletSpeed = self.BulletSpeed - (self.Gravity*Delta)
self.CFrame = CFrame.new((self.CFrame + ((self.CFrame.lookVector*self.BulletSpeed)*Delta)).p, self.CFrame.lookVector)

self.Part.ProjectileMesh.Scale = Vector3.new(1,1,(self.CFrame.p - self.LastCFrame.p).magnitude*5)
self.Part.CFrame = self.CFrame
self.LastCFrame = self.CFrame
``````

You need to make sure you cast from now to the next position, not now to 1 stud ahead. Calculate the next position and cast to that point and if it works, move it there. Also instead of using a SpecialMesh you can change its size and shift it downward from center using CFrame.new(0,0,dist/-2)

Explain in depth more in moving?

I think youâ€™re misunderstanding lookVector. lookVector is a unit vector relating the front direction of the CFrame. If your part is facing the same direction as the x-axis, then the lookVector would be (1,0,0). In your `CFrame.new(pos, lookAt)` call though, youâ€™re treating lookVector as a point directly in front of the CFrame when itâ€™s not, itâ€™s a point somewhere near the origin. You need to update your .new to be `CFrame.new(pos, pos + lookVector)`.

You calculate where the projectile should be for the next frame. Then you raycast between now and next position to check for collisions on the way. If it does not hit anything, it keeps going by moving to the calculated location and repeating all this on the next frame.

So youâ€™re saying to change my movement code? I need to worry about my orientation as of now unless the movement code has any connections. My projectile has a bullet drop factor to it too

I am talking about fixing your gun system so that it works correctly and I already mentioned orientation fixes above with `CFrame.new(currentpos,calcpos)` and the shift

So youâ€™re saying to remodel it like this:

Put it in a while true do loop:
Raycast 1 stud ahead and if it hits nothing move the bullet but if it does hit something stop the loop
Move the projectile and add bullet drop

No that is definitely not what I am saying
Read what I say and deconstruct it: `"You calculate where the projectile should be for the next frame. Then you raycast between now and next position to check for collisions on the way."`

``````local currentpos = whatever
local goalpos = currentpos+bulletvel*delta
local ray = Ray.new(currentpos,goalpos-currentpos) --Origin, Direction*Magnitude
--etc hit detection
--if not hit anything or should penetrate
goto(goalpos)
--if hit something and it should stop
goalpos = hitpos
goto(goalpos)
--break out
``````
2 Likes

Alright so something along the lines of this?

``````local Velocity = (self.CFrame.p - self.LastCFrame.p) -- Velocity is the distant between point A to point B I believe.
local GoalPosition = self.CFrame+Velocity*Delta
local NewRay = Ray.new(self.CFrame.p, GoalPosition - self.CFrame.p)
local HitPart, HitPosition, Normal, Material = workspace:FindPartOnRayWithIgnoreList(NewRay, self.IgnoreList.IgnoreInstance, false, true)
if HitPart then
self.CFrame = GoalPosition
else
GoalPosition = HitPosition
self.CFrame = GoalPosition
end
``````

Sorry for not understanding as well as I still struggle with people describing things without examples

No, velocity is a constant which will change how far it travels over time and also its direction, commonly barrelLookVector*muzzleVelocity

1 Like

Your motion calculations arenâ€™t quite right. You seem to be treating Gravity as a velocity rather than acceleration. One way to model movement here would be to do something like:

``````local Gravity = Vector3.new(0, -g, 0) -- whatever your gravity constant is
local Velocity = Vector3.new(x, y, z) -- whatever your starting velocity may be
local Position = Vector3.new(x, y, z) -- whatever your starting position may be

local function Update(dt)
Velocity = Velocity + Gravity * dt -- acceleration
Position = Position + Velocity * dt -- velocity
Projectile.CFrame = CFrame.new(Position, Position + Velocity) -- visualisation
end

-- hook Update up to Heartbeat or RenderStepped
``````

2 Likes

Fyi, I am using a CFrame based projectile system and not physics based but I have a fix for bullet drop
Never mind, I already have the projectileâ€™s velocity.
Would

``````CFrame = CFrame + (Vector3.new(0, GRAVITY, 0)*Delta)
``````

work anyways?

No, because you arenâ€™t accounting for initial velocity in any way and you are treating gravity incorrectly. Have a read of the code I posted above and let me know if you have trouble understanding or implementing it!

1 Like

Oh I see

1 Like

When using your method sirc and @Wunder_Wulfeâ€™s combined the projectile flies into the air.

``````self:UpdateIgnoreList()
local Velocity = self.OriginLookvector*self.OriginSpeed
local GoalPosition = self.CFrame+Velocity*Delta
local NewRay = Ray.new(self.CFrame.p, GoalPosition.p - self.CFrame.p)
local HitPart, HitPosition, Normal, Material = workspace:FindPartOnRayWithIgnoreList(NewRay, self.IgnoreList.IgnoreInstance, false, true)

Velocity = Velocity + Vector3.new(0, -self.Gravity, 0) * Delta
self.CFrame = self.CFrame + Velocity * Delta
self.CFrame = CFrame.new(self.CFrame.p, self.CFrame.p + Velocity)

self.Part.Size = Vector3.new(self.Part.Size.X,self.Part.Size.Y,(self.CFrame.p - self.LastCFrame.p).magnitude*5)
self.Part.CFrame = self.CFrame
self.LastCFrame = self.CFrame
``````

Trying to find a fix for it. The problem is very likely from what I input into it

Update 2

``````local Velocity = self.OriginLookvector*self.OriginSpeed

Velocity = (Velocity + Vector3.new(0, -self.Gravity, 0)) * Delta
self.CFrame = self.CFrame + (Velocity * Delta)
print(Velocity * Delta, Delta)

self.Part.Size = Vector3.new(self.Part.Size.X,self.Part.Size.Y,(self.CFrame.p - self.LastCFrame.p).magnitude*5)
self.Part.CFrame = self.CFrame
self.LastCFrame = self.CFrame
``````

Still doesnâ€™t work. Sends the bullet straight down into the depths of -100K+ studs

1 Like