MoveTo weirdness

Post » Wed Jun 20, 2012 9:30 am

I'm trying to make myself a Decorator Assistant mod without using any 3rd party plugins. In one part of the scripts, I use this code:

Spoiler
Function ShowPosMenu()	while (choice02 != 0)		choice02 = PosMenu.Show(ItemRef.X, ItemRef.Y, ItemRef.Z)		if (choice02 == 1)			ItemRef.MoveTo(ItemRef, pOffsetX, 0, 0)		elseif (choice02 == 2)			ItemRef.MoveTo(ItemRef, -pOffsetX, 0, 0)		elseif (choice02 == 3)			ItemRef.MoveTo(ItemRef, 0, pOffsetY, 0)		elseif (choice02 == 4)			ItemRef.MoveTo(ItemRef, 0, -pOffsetY, 0)		elseif (choice02 == 5)			ItemRef.MoveTo(ItemRef, 0, 0, pOffsetZ)		elseif (choice02 == 6)			ItemRef.MoveTo(ItemRef, 0, 0, -pOffsetZ)		endif	endwhileEndFunction

It's a menu giving you a choice in how to move an object. Only it doesn't work right because ItemRef doesn't move purely along a single axis. However, if ItemRef happens to be an actor, it works perfectly fine.

I also tried using SetPosition instead of MoveTo:

Spoiler
Function ShowPosMenu()	float TempX	float TempY	float TempZ	while (choice02 != 0)		TempX = ItemRef.X		TempY = ItemRef.Y		TempZ = ItemRef.Z		choice02 = PosMenu.Show(TempX, TempY, TempZ)		if (choice02 == 1)			ItemRef.SetPosition(TempX + pOffsetX, TempY, TempZ)		elseif (choice02 == 2)			ItemRef.SetPosition(TempX - pOffsetX, TempY, TempZ)		elseif (choice02 == 3)			ItemRef.SetPosition(TempX, TempY + pOffsetY, TempZ)		elseif (choice02 == 4)			ItemRef.SetPosition(TempX, TempY - pOffsetY, TempZ)		elseif (choice02 == 5)			ItemRef.SetPosition(TempX, TempY, TempZ + pOffsetZ)		elseif (choice02 == 6)			ItemRef.SetPosition(TempX, TempY, TempZ - pOffsetZ)		endif	endwhileEndFunction

It has the same problem with ItemRef not moving along a single axis, but movement along the other axes doesn't seem as much as when using MoveTo.
User avatar
Laurenn Doylee
 
Posts: 3427
Joined: Sun Dec 03, 2006 11:48 am

Post » Wed Jun 20, 2012 6:34 pm

I've used the 2nd method and didn't notice any skew.

Is there a north pointer in your test cell? That could skew the ingame compass off the true grid.
That wouldn't explain the actors though.
User avatar
Lauren Graves
 
Posts: 3343
Joined: Fri Aug 04, 2006 6:03 pm

Post » Wed Jun 20, 2012 5:43 am

I was experimenting in Tamriel. It's weird, I just tried using the console's MoveTo and it worked just fine with the same object I was testing earlier.

But it still doesn't work right in my script. I'm going to try testing a simpler script and see what happens.

EDIT: Still noticed skewing with this very simple script:

Scriptname TestAliasScript extends ReferenceAliasObjectReference ItemRefEvent OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)	ItemRef = akItemReference	RegisterForSingleUpdate(5)EndEventEvent OnUpdate()	ItemRef.MoveTo(ItemRef, 0, -100, 0)	Debug.Notification(ItemRef.X + ", " + ItemRef.Y + ", " + ItemRef.Z)	if !(GetActorReference().IsSneaking())		RegisterForSingleUpdate(5)	endifEndEvent
User avatar
YO MAma
 
Posts: 3321
Joined: Thu Dec 21, 2006 8:24 am

Post » Wed Jun 20, 2012 3:12 pm

I tried another test using this script:

Spoiler
Scriptname fg109TestME02 extends ActiveMagicEffectActor property Player autoActorBase property NPC autoActivator property ACTI autoWeapon property WEAP autoMiscObject property MISC autoObjectReference[] MyObjectsString[] NamesBool SpawnDisabledEvent OnEffectStart(Actor akTarget, Actor akCaster)	Debug.Notification("Test start.")	if (Player.IsSneaking())		SpawnDisabled = True	else		SpawnDisabled = False	endif	MyObjects = new ObjectReference[4]	Names = new String[4]	MyObjects[0] = Player.PlaceAtMe(NPC, 1, false, SpawnDisabled)	Names[0] = "NPC"	MyObjects[1] = Player.PlaceAtMe(ACTI, 1, false, SpawnDisabled)	Names[1] = "ACTI"	MyObjects[2] = Player.PlaceAtMe(WEAP, 1, false, SpawnDisabled)	Names[2] = "WEAP"	MyObjects[3] = Player.PlaceAtMe(MISC, 1, false, SpawnDisabled)	Names[3] = "MISC"	MoveAllTo(Player, 0, -100, 0, true)	Utility.Wait(1)	ReportAllPositions()	Utility.Wait(1)	CleanUp()	Debug.Notification("Test complete.")EndEventFunction MoveAllTo(ObjectReference Target, Float OffsetX = 0.0, Float OffsetY = 0.0, Float OffsetZ = 0.0, Bool MatchRotation = True)	int index = MyObjects.Length	while (index > 0)		index -= 1		if (!SpawnDisabled)			MyObjects[index].SetMotionType(MyObjects[index].Motion_KeyFramed, false)		endif		MyObjects[index].MoveTo(Target, OffsetX, OffsetY, OffsetZ, MatchRotation)		OffsetY -= 100	endwhileEndFunctionFunction ReportAllPositions()	Debug.Trace("[MoveTest][" + SpawnDisabled + "] Player (" + Player.X + ", " + Player.Y + ", " + Player.Z + ")")	int index = MyObjects.Length	while (index > 0)		index -= 1		Debug.Trace("[MoveTest][" + SpawnDisabled + "] " + Names[index] + " (" + MyObjects[index].X + ", " + MyObjects[index].Y + ", " + MyObjects[index].Z + ")")	endwhileEndFunctionFunction CleanUp()	int index = MyObjects.Length	while (index > 0)		index -= 1		MyObjects[index].Disable()		MyObjects[index].Delete()		MyObjects[index] = None	endwhileEndFunction

NPC: AADeleteWhenDoneTestJeremyRegular
ACTI: dunRaldbtharGearBlockLeg
WEAP: IronDagger
MISC: Gold001

My test results:

Spoiler
[03/23/2012 - 08:30:12AM] [MoveTest][TRUE] Player (135012.046875, 33826.910156, -12566.443359)[03/23/2012 - 08:30:12AM] [MoveTest][TRUE] MISC (135012.046875, 33726.910156, -12566.443359)[03/23/2012 - 08:30:12AM] [MoveTest][TRUE] weap (135012.046875, 33626.910156, -12566.443359)[03/23/2012 - 08:30:12AM] [MoveTest][TRUE] ACTI (135012.046875, 33526.910156, -12566.443359)[03/23/2012 - 08:30:12AM] [MoveTest][TRUE] NPC (135012.046875, 33426.910156, -12566.443359)[03/23/2012 - 08:30:19AM] [MoveTest][False] Player (135012.046875, 33826.910156, -12566.442383)[03/23/2012 - 08:30:19AM] [MoveTest][False] MISC (135012.031250, 33726.878906, -12566.271484)[03/23/2012 - 08:30:19AM] [MoveTest][False] weap (135012.593750, 33626.460938, -12571.461914)[03/23/2012 - 08:30:19AM] [MoveTest][False] ACTI (135012.046875, 33526.910156, -12566.443359)[03/23/2012 - 08:30:20AM] [MoveTest][False] NPC (135007.562500, 33431.460938, -12577.529297)[03/23/2012 - 08:30:30AM] [MoveTest][TRUE] Player (135030.593750, 32276.984375, -12564.448242)[03/23/2012 - 08:30:30AM] [MoveTest][TRUE] MISC (135030.593750, 32176.984375, -12564.448242)[03/23/2012 - 08:30:30AM] [MoveTest][TRUE] weap (135030.593750, 32076.984375, -12564.448242)[03/23/2012 - 08:30:30AM] [MoveTest][TRUE] ACTI (135030.593750, 31976.984375, -12564.448242)[03/23/2012 - 08:30:30AM] [MoveTest][TRUE] NPC (135030.593750, 31876.984375, -12564.448242)[03/23/2012 - 08:30:38AM] [MoveTest][False] Player (135033.453125, 32273.468750, -12564.486328)[03/23/2012 - 08:30:38AM] [MoveTest][False] MISC (135030.593750, 32176.935547, -12564.580078)[03/23/2012 - 08:30:38AM] [MoveTest][False] weap (135030.593750, 32076.984375, -12564.448242)[03/23/2012 - 08:30:38AM] [MoveTest][False] ACTI (135033.343750, 31973.554688, -12564.486328)[03/23/2012 - 08:30:38AM] [MoveTest][False] NPC (135033.390625, 31873.234375, -12570.483398)[03/23/2012 - 08:31:13AM] [MoveTest][TRUE] Player (134462.109375, 30496.224609, -12334.879883)[03/23/2012 - 08:31:13AM] [MoveTest][TRUE] MISC (134462.109375, 30396.224609, -12334.879883)[03/23/2012 - 08:31:13AM] [MoveTest][TRUE] weap (134462.109375, 30296.224609, -12334.879883)[03/23/2012 - 08:31:13AM] [MoveTest][TRUE] ACTI (134462.109375, 30196.224609, -12334.879883)[03/23/2012 - 08:31:13AM] [MoveTest][TRUE] NPC (134462.109375, 30096.224609, -12334.879883)[03/23/2012 - 08:31:20AM] [MoveTest][False] Player (134462.109375, 30496.224609, -12334.879883)[03/23/2012 - 08:31:20AM] [MoveTest][False] MISC (134462.171875, 30396.296875, -12339.021484)[03/23/2012 - 08:31:20AM] [MoveTest][False] weap (134462.093750, 30296.085938, -12338.790039)[03/23/2012 - 08:31:20AM] [MoveTest][False] ACTI (134462.109375, 30196.224609, -12334.879883)[03/23/2012 - 08:31:20AM] [MoveTest][False] NPC (134456.906250, 30100.775391, -12336.567383)


Then I decided to try and move them based off of a non-actor by changing the OnEffectStart to this:
Spoiler
Event OnEffectStart(Actor akTarget, Actor akCaster)	Debug.Notification("Test start.")	if (Game.GetPlayer().IsSneaking())		SpawnDisabled = True	else		SpawnDisabled = False	endif	PlayerWeapon = Game.GetPlayer().DropObject(Game.GetPlayer().GetEquippedWeapon())	Utility.Wait(2)	MyObjects = new ObjectReference[4]	Names = new String[4]	MyObjects[0] = PlayerWeapon.PlaceAtMe(NPC, 1, false, SpawnDisabled)	Names[0] = "NPC"	MyObjects[1] = PlayerWeapon.PlaceAtMe(ACTI, 1, false, SpawnDisabled)	Names[1] = "ACTI"	MyObjects[2] = PlayerWeapon.PlaceAtMe(WEAP, 1, false, SpawnDisabled)	Names[2] = "WEAP"	MyObjects[3] = PlayerWeapon.PlaceAtMe(MISC, 1, false, SpawnDisabled)	Names[3] = "MISC"	MoveAllTo(PlayerWeapon, 0, -100, 0, true)	Utility.Wait(1)	ReportAllPositions()	Utility.Wait(1)	CleanUp()	Debug.Notification("Test complete.")EndEvent

And these were the results:

Spoiler
[03/23/2012 - 08:55:11AM] [MoveTest][TRUE] PlayerWeapon (135466.078125, 31779.656250, -12132.393555)[03/23/2012 - 08:55:11AM] [MoveTest][TRUE] MISC (135466.078125, 31679.656250, -12132.393555)[03/23/2012 - 08:55:11AM] [MoveTest][TRUE] weap (135466.078125, 31579.656250, -12132.393555)[03/23/2012 - 08:55:11AM] [MoveTest][TRUE] ACTI (135466.078125, 31479.656250, -12132.393555)[03/23/2012 - 08:55:11AM] [MoveTest][TRUE] NPC (135466.078125, 31379.656250, -12132.393555)[03/23/2012 - 08:55:35AM] [MoveTest][False] PlayerWeapon (135464.187500, 31779.626953, -12132.390625)[03/23/2012 - 08:55:35AM] [MoveTest][False] MISC (135462.843750, 31679.496094, -12134.715820)[03/23/2012 - 08:55:35AM] [MoveTest][False] weap (135463.328125, 31579.539063, -12132.389648)[03/23/2012 - 08:55:35AM] [MoveTest][False] ACTI (135463.468750, 31479.531250, -12132.403320)[03/23/2012 - 08:55:35AM] [MoveTest][False] NPC (135468.828125, 31418.503906, -12135.353516)[03/23/2012 - 08:55:51AM] [MoveTest][TRUE] PlayerWeapon (135614.062500, 30364.078125, -12327.576172)[03/23/2012 - 08:55:51AM] [MoveTest][TRUE] MISC (135614.062500, 30264.078125, -12327.576172)[03/23/2012 - 08:55:51AM] [MoveTest][TRUE] weap (135614.062500, 30164.078125, -12327.576172)[03/23/2012 - 08:55:51AM] [MoveTest][TRUE] ACTI (135614.062500, 30064.078125, -12327.576172)[03/23/2012 - 08:55:51AM] [MoveTest][TRUE] NPC (135614.062500, 29964.078125, -12327.576172)[03/23/2012 - 08:56:02AM] [MoveTest][False] PlayerWeapon (135580.250000, 30364.287109, -12325.060547)[03/23/2012 - 08:56:02AM] [MoveTest][False] MISC (135578.953125, 30263.822266, -12330.260742)[03/23/2012 - 08:56:02AM] [MoveTest][False] weap (135579.625000, 30164.460938, -12334.021484)[03/23/2012 - 08:56:02AM] [MoveTest][False] ACTI (135579.250000, 30064.298828, -12324.986328)[03/23/2012 - 08:56:03AM] [MoveTest][False] NPC (135575.109375, 29964.271484, -12338.631836)[03/23/2012 - 08:56:16AM] [MoveTest][TRUE] PlayerWeapon (135028.234375, 29522.375000, -12572.481445)[03/23/2012 - 08:56:16AM] [MoveTest][TRUE] MISC (135028.234375, 29422.375000, -12572.481445)[03/23/2012 - 08:56:16AM] [MoveTest][TRUE] weap (135028.234375, 29322.375000, -12572.481445)[03/23/2012 - 08:56:16AM] [MoveTest][TRUE] ACTI (135028.234375, 29222.375000, -12572.481445)[03/23/2012 - 08:56:16AM] [MoveTest][TRUE] NPC (135028.234375, 29122.375000, -12572.481445)[03/23/2012 - 08:56:26AM] [MoveTest][False] PlayerWeapon (135040.265625, 29526.031250, -12572.587891)[03/23/2012 - 08:56:27AM] [MoveTest][False] MISC (135041.468750, 29425.591797, -12575.247070)[03/23/2012 - 08:56:27AM] [MoveTest][False] weap (135041.531250, 29325.714844, -12572.947266)[03/23/2012 - 08:56:27AM] [MoveTest][False] ACTI (135041.406250, 29225.648438, -12572.336914)[03/23/2012 - 08:56:27AM] [MoveTest][False] NPC (135040.968750, 29125.781250, -12566.224609)

I didn't see much of a difference between basing movement off an actor versus non-actor.


My Thoughts:

If the objects are disabled, then MoveTo is moving them exactly the way it should. When the objects are enabled, then there is a slight skew, unrelated to the amount of distance moved. The skew will always be within a few units in each axis whether the distance moved is 100 units or 400 units. (SetMotionType doesn't work on the actor, and I suspect he showed more skew because he moves a bit before the Debug.Trace kicks in.)

I don't where the skew comes from. I tried setting the motion type to key-framed, which should eliminate any havok-induced changes in positions. I had a guess that when an object is reloaded after a MoveTo, the physics engine takes a little bit before it realizes that the object is not affected by havok before freezing it in place.

But if that was true, why are some of the results showing that the object actually ended up higher than the source of the movement? So obviously the effect isn't from gravity.

Then I thought maybe it's from collision being applied to the object. But the skew occurs even when the objects are in midair and should therefore be far away from any collision from other objects.

My final guess was that there is some unseen network of nodes that the MoveTo function uses to move things around, and it moves the object to the nearest node, without 100% accuracy. But then why would it be 100% accurate when the objects are disabled?

I'm just going to resign myself to not understanding how it works at all.

EDIT: I just tried again with spawning objects as disabled, moving them while they're disabled, then displaying their locations while enabled. The positions are skewed. So I guess it's not a MoveTo problem after all, but something to do with the objects being moved slightly when they get rendered?
User avatar
Sam Parker
 
Posts: 3358
Joined: Sat May 12, 2007 3:10 am


Return to V - Skyrim