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
Screenshot_577
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
Screenshot_578

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

Tried it and my projectiles are falling through the ground. I made a new system instead of rotation check my updates for more info

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

Note the above comments about hit detection.

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