someone asked me for a direction how to do a NoClip for games, so i had some fun writing a cheap little Playground with Unity(so nobody needs a specific game to play around with it) and made a sample table with 2 Basic NoClip scripts.
This Guide will contain a lots of Unity specific stuff, but a NoClip works more or less the same for every game.
note : this guide is for x64 and the Unity Playground Project is Il2CPP compiled (native code that still contains mono-infos), my sample-table does access stuff in the Unity-Engine that does not have any mono-symbols at all, so i decided to do the complete table with AOBs and Absolute Offsets without any mono-features ( everything that has a name is commented in the table)
In short -> Its not JIT so we don't need any mono-features to make sure it works for everyone
![Smile :)](./images/smilies/icon_e_smile.gif)
Lets go:
We need the players position that is stored in a Vector3, coz this we need to dive into the component system.
a class instance that derives from MonoBehaviour does have these Pointers:
0x00 = klassPtr
0x08 = monitorPtr
0x10 = nativePtr
if you try to dissect them while Cheat Engines mono features are active then you will get a big crash, coz this pointers contains no mono infos.
Any object in the Unity game-world is a GameObject (FunFact : the GameObjects name that is used in the unity-editor is stored in the 0x00 klassPtr and its hashed with FNV ) a GameObject in the 3D World also has a Transform Component, this Component contains the Vector3 with the position floats.
Lets say you are doing a Unknown-Scan for the player position, and if you found it you do a "Find out what accesses this address" then you will find the native code in the UnityPlayer.dll that handles every Vector3 from all Transforms.
So how we get a 100% safe pointer to our player Vector3?
We need to get the transform component, you can do that with any instance that belongs to the player (they all share the same components )
to find the Component you could look into the 0x10 nativePtr or call the Component.get_transform
Component.get_transform returns the native Transform component, it needs one argument.
so RCX = any class instance that belongs to the player.
So okay now we have the Transform, you could now look into it to find the Vector3 or call Transform.get_position
Transform.get_position is a __cdecl* Call so you need to use the stack or provide a address from the codecave for the first argument.
First Argument (RCX) = e.g lea rcx,[rsp+20]
Second Argument(RDX) = the address of the transform
Transform.get_position will return the address of [rsp+20] and contains now a Vector3 with the positions.
So okay now we have the player positions, we should now prevent the game from writing to our Players.
In my sample im simply using a 0xC3 (return) on the CharacterController.FixedUpdate, this blocks the game from writing to our transform but still allows free mouse movement.
In my sample im also calling Rigidbody.set_isKinematic(true) to deactivate any gravity influence for the player, its not necessary but it makes the fly feeling smoother.
note : the Rigidbody components and member functions are also native - so the mono-dissect won't show you any infos.
so next step is controlling the height with Space/CTRL, im simply using GetAsyncKeyState to detect Space/CTRL, if its pressed the following happens:
-load player Y position into a xmm register
-addss/subss the float
-write the vector3 with the new Y value into the transform.
to write the vector im using Transform.set_position, it needs two arguments:
RCX = address of the transform
RDX = address that contains a Vector3
so this causes that Space/CTRL does increase/decrease the player, cool but we can't move forward yet.
To move into the direction we want we need a normalized vector that contains a direction, normalized means that the XYZ value is between -1 and +1.
Easy way in Unity : using the forward vector from the transform component, you can find it in the component or call Transform.get_forward.
Its also a __cdecl* call, so same usage as the Transform.get_position.
With the player position and the forward vector we can start to calculate the movement (im using the W key with a GetAsyncKeyState check)
We need to decrease the floats of the forward vector otherwise the movement would be way to fast, we could also use deltaTime(for frame independent calc) but to keep it simple im just decreasing through a fixed multiplier.
in my sample im multiplying the forward vector with 0.0001f, afterwards im adding up the current player XZ floats with the XZ forward floats, and finally store the player vector3 into the transform.
The transform forward vector does not contain a Y float(its always 0) coz this while pressing *W* you can only move on the X and Z Axis, but looking up/down won't change the Y value.
Okay for backwards movement we do exactly the same but we will invert the X and Z floats of the forward vector, so we basically just multiply them with minus one.
And thats it, the NoClip based on the transform Vector is done:
-Fly Up/Down with Space/CTRL
-Fly forward into the direction you are looking with *W*
-Fly backwards with *S*
So thanks for reading and...wait in other game engines you can't find so easily a forward vector?
Okay i guess we also need to look how to do it ViewMatrix based, i try to keep it simple:
What is a ViewMatrix?
its an array of floats that represents a 4x4matrix = 4 rows and 4 columns.
Its used by the graphic API to transform from world-space to view-space, it contains the right,up,forward axis and the translation from the current projection.
(the view matrix is the inverse of the cameras transformation matrix)
So how to find the view matrix? in best case if you dont know you should look some YT videos.
but in short the memory-scan way : scan for increase/decreased floats in the range of -1 and +1 while you rotate the camera up and down.
In unity you can do it on several ways:
1) AOB that should work for the most x64 IL2CPP compiled games:
Module : UnityPlayer.dll (always completly native even if the game is compiled with C# JIT)
AOB : "000F10030F1146040F104B10"
RSI+4 starts with the RightX axis and contains the full 4x4 matrix
2) get the native camera component and search inside for the matrix.
3) call Camera.get_worldToCameraMatrix with the instance of the camera component
The viewMatrix camera spaces in Unity based game will always match the OpenGL conventions e.g camera forward is the negative z axis.
With the viewMatrix we also now can calculate a forward movement on the Y axis, so we can fly up/down without Space/CTRL.
How we use the matrix to calc our movement? lets keep it simple!
btw : if you activate the sample NoClip (ViewMatrix) then you can see all 16 floats of the viewMatrix with names.
Forward:
We need the ForwardX,UpY and RightX axis from the Matrix.
Invert ForwardX and UpY.
Multiply ForwardX,UpY,RightX with the Speed multiplier(same that used with the forward vector) and finally add it all to the player position.
Backward:
We also need ForwardX,UpY and RightX axis from the Matrix.
Invert only RightX.
Multiply ForwardX,UpY,RightX with the Speed multiplier and finally add it all to the player position.
Thats it, viewMatrix based you can now fly in any axis
![Smile :)](./images/smilies/icon_e_smile.gif)
btw : i did intentionally no keys for Left/Right, if you want see it as a challenge to modify the sample table and add a left/right key based on the viewMatrix or the transform normalized vectors.
Playground Download : [Link] (12 MB on a fast one-click hoster)
Table is inside and attached to this topic.
so okay i hope this helps to understand the basics how to do a simple fly/noclip script.
BR
cfemen
Edit: there is also a third method ( calculating sin and cos from the tilt/pan radiants ) will maybe also do a little tutorial/sample for it someday
![Smile :)](./images/smilies/icon_e_smile.gif)