Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do I make a model's CFrame only affect the Y-axis orientation with CFrame.LookAt()?

I have a script for a tower defense game and the towers' attack functions use the CFrame.Lookat() functions to look at enemies, but I don't want it to look up/down, just left/right. So, I want the orientation's Y axis of the HumanoidRootPart to change but not the X axis. Here's my script (This is a module script):

function towerModule.Attack(tower, player)
	local stats = tower:WaitForChild("stats")
	local target = FindTarget(tower, info.Range.Value)
	
	if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 then
		local hum = target.Humanoid
		
		animateTowerEvent:FireAllClients(tower, "Attack")
		
		local targetCFrame = CFrame.lookAt(tower.HumanoidRootPart.Position,target.HumanoidRootPart.Position) --Here, I just need to edit the local targetCFrame to only change the Y axis orientation, but I don't know how to.
		tower.HumanoidRootPart.BodyGyro.CFrame = targetCFrame

		local oldTargetHealth = hum.Health

		if stats.Damage.Value <= hum.Health then
			hum:TakeDamage(stats.Damage.Value)
		elseif stats.Damage.Value > hum.Health then
			hum.Health = 0
		end
		
		local newTargetHealth = hum.Health
		player.Stats.Money.Value += oldTargetHealth-newTargetHealth
		
		if hum.Health <= 0 then
			player.Stats.Kills.Value += 1
		end
		
		task.wait(stats.Cooldown.Value)
	end
	
	task.wait()
	
	if tower and tower.Parent then
		towerModule.Attack(tower, player)
	end
end

1 answer

✓ Accepted answer

You can get the displacement vector of the target's position from the tower's position, which is basically just the vector to get to the target from the tower. You can project the vector on the XZ plane by making the Y component 0, then you have the direction for the tower to look to. You just need to add the look direction to the tower's position since lookDir is relative to the tower's position (originating from the tower's position), but CFrame.lookAt expects a vector originating from the world origin, so we just add the towerPos which originates from the world origin

local towerPos = tower.HumanoidRootPart.Position
local factor = Vector3.new(1, 0, 1)
local dir = (target.HumanoidRootPart.Position - towerPos) * factor
local targetCFrame = CFrame.lookAt(towerPos, towerPos + dir.Unit)

1 comment

0

This worked, thank you!

This discussion is preserved as it was. New answers, comments, and votes are closed.