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

How could I create a mirror image of a player's character?

How would I go about making a mirror image of a player's character?

2 comments

0

Clone, flip the Y axis, place below player

0

flip the player through the Z normal of the direction of the reflective surface facing the player. Invert mesh scales on the X axis to negative if that actually works.

1 answer

✓ Accepted answer

To mirror a part, you simply have to mirror its CFrame. That can be done something like this:

function mirrorCFrame(cf)
	local mi = Vector3.new(-1,1,1);
	local np = cf.p * mi;
	local mi = CFrame.new( np , np + cf.lookVector * mi * -1 );
	local up = CFrame.new(cf.p,cf.p + cf.lookVector);
	local from = up:toObjectSpace(cf);
	return mi:toWorldSpace(from) * CFrame.Angles(0,math.pi,0);
end

In addition to this, you must mirror textures, surfaces, and meshes.

In mirroring textures and surfaces, the left and right sides must be swapped.

function mirrorLeftRight(c)
	local left = c.LeftSurface;
	c.LeftSurface = c.RightSurface;
	c.RightSurface = left;
	local lefts = {};
	local rights = {};
	local h = c:GetChildren();
	for _,v in pairs(h) do
		if v:IsA("Decal") or v:IsA("Texture") or v:IsA("SurfaceGui") then
			if v.Face == Enum.NormalId.Left then
				table.insert(lefts,v);
			end
			if v.Face == Enum.NormalId.Right then
				table.insert(rights,v);
			end
		end
	end
	for _,v in pairs(lefts) do
		v.Face = "Right";
	end
	for _,v in pairs(rights) do
		v.Face = "Left";
	end
	print(#lefts,#rights);
end

Unfortunately, this will still not mirror Pants and Shirts. It also will not mirror the decals themselves, although I think this might be possible by implementing them in SurfaceGui's.

I'm going to experiment more and report back.

EDIT1: Yes. Using a SurfaceGui, a decal can be flipped. Here is a revised version of mirrorLeftRight which is capable of mirroring Decals only. Unfortunately mirroring textures is difficult because of repeating the image over and over (and could also be extremely slow) and mirroring SurfaceGui's is difficult because then the entire model of positioning needs to be replicated in Lua.

function mirrorLeftRight(c)
	function Flip(q)
		if q:IsA("Decal") then
			local p = Instance.new("SurfaceGui",q.Parent);
			local i = Instance.new("ImageLabel",p);
			i.Image = q.Texture;
			i.Size = UDim2.new(1,0,1,0);
			i.ImageRectOffset = Vector2.new(1e6,0);
			i.ImageRectSize = Vector2.new(-1e6,1e6);
			q:Destroy();
			return p;
		end
		return q; --Unflippable :/
	end
	local left = c.LeftSurface;
	c.LeftSurface = c.RightSurface;
	c.RightSurface = left;
	local lefts = {};
	local rights = {};
	local h = c:GetChildren();
	for _,v in pairs(h) do
		if v:IsA("Decal") or v:IsA("Texture") or v:IsA("SurfaceGui") then
			if v.Face == Enum.NormalId.Left then
				table.insert(lefts,v);
			end
			if v.Face == Enum.NormalId.Right then
				table.insert(rights,v);
			end
		end
	end
	for _,v in pairs(lefts) do
		v = Flip(v);
		v.Face = "Right";
	end
	for _,v in pairs(rights) do
		v = Flip(v);
		v.Face = "Left";
	end
	print(#lefts,#rights);
end

EDIT:

This solution does not capture Pants, Shirts, or ShirtGraphics.

ShirtGraphics would be done equivalently to decals, but they use different names, so just including them in the same as this is written wouldn't work.

The others would have to be flipped in the way that decals are (using SurfaceGui's) but only using the subsections of the image that are used in the shirt.

Also, this doesn't invert the Top and Bottom faces, which it still needs to (but which luckily isn't important to ROBLOX characters)

Finally, this doesn't flip meshes.

1 comment

3

fortunately, players' characters don't have texture objects.

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