Vector Math Examples in UE4 Python
One of the most visited/indexed posts on this site was the brief Maya vector math post, now that we are releasing Python in UE4, I thought I would port those examples to UE4 Python.
Creating Vectors
Let’s query the bounding box extents of a skeletal mesh actor. This will return two points in world space as vectors:
bbox = mesh.get_actor_bounds(False) v1, v2 = bbox[0], bbox[1] |
If we print the first vector, we see it’s a struct of type Vector
print v1 #<Struct 'Vector' (0x000001EACECEFE78) {x: 540.073303, y: 32.021194, z: 124.710869}>; |
If you want the vector as a tuple or something to export to elsewhere, you just make a tuple of its components:
print (v1.x, v1.y, v1.z) #(540.0733032226562, 32.02119445800781, 124.71086883544922) |
If you want to create your own vector, you simply do:
my_vec3 = unreal.Vector(1,2,3) Print my_vec3 #<Struct 'Vector' (0x000001EACECECA40) {x: 1.000000, y: 2.000000, z: 3.000000}> |
Length / Distance / Magnitude
The Vector struct supports many mathematical operations, let’s say we want to get the distance from v1 to v2, we would subtract them, which returns a new vector, then we would get the length (‘size’ in this case) of the vector:
new_vec = v2-v1 Print new_vec.size() #478.868011475 |
The vector struct has a lot of convenience functions built in (check out the docs here) , for instance, let’s get the distance from v1, to v2 (the diagonal across our bounding box), without doing the above by calling the dist() function:
print v1.dist(v2) #478.868011475 |
There is also a distSquared function it you just want to quickly compare which are greater and not calc real distance.
USE CASE: FIND SMALL ACTORS
Using what we got, let’s play in the default scene:
We can iterate through the scene and find actors under a certain size/volume:
for actor in static_meshes: mesh_component = actor.get_component_by_class(unreal.StaticMeshComponent) v1, v2 = mesh_component.get_local_bounds() if v1.dist(v2) < 150: print actor.get_name() #Statue |
I am querying the bounds of the static mesh components because the get_bounds() on the actor class returns the unscaled bounds, you may notice that many things in the scene, including the statue and floor are scaled. This is reflected in the get_local_bounds() of the mesh component.
DOT PRODUCT / ANGLE BETWEEN TWO VECTORS
If we wanted to know the angle between two vectors, we would use the dot product of those, let’s create two new vectors v1, and v2, because our previous were not really vectors per se, but point locations Just like in UE4, you use the ‘|’ pipe to do a vector dot product.
v1 = unreal.Vector(0,0,1) v2 = unreal.Vector(0,1,1) v1.normalize() v2.normalize() print v1 | v2 print v1 * v2 |
Notice that asterisk will multiply the vectors, pipe will return the sum of the components, or the dot product / scalar product as a float.
For the angle between, let’s import python’s math library:
import math dot = v1|v2 print math.acos(dot) #returns 0.785398180512 print math.acos(dot) * 180 / math.pi #returns 45.0000009806 |
Above I used the Python math library, but there’s also an Unreal math library available unreal.MathLibrary, you should check that out, it has vector math functions that don’t exist in the vector class:
dot = v1|v2 print unreal.MathLibrary.acos(dot) #returns 0.785398180512 print unreal.MathLibrary.acos(dot) * 180 / math.pi #returns 45.0000009806 print unreal.MathLibrary.radians_to_degrees(unreal.MathLibrary.acos(dot)) #returns: 45.0 |
USE CASE: CHECK ACTOR COLINEARITY
Let’s use the dot product to check if chairs are colinear, or facing the same direction. Let’s dupe one chair and call it ‘Chair_dupe’:
fwd_vectors = {} for actor in static_meshes: if 'Chair' in actor.get_name(): actor_vec = actor.get_actor_forward_vector() for stored_actor in fwd_vectors: if actor_vec | fwd_vectors[stored_actor] == 1.0: print actor.get_name(), 'is colinear to', stored_actor fwd_vectors[actor.get_name()] = actor_vec #returns: Chair_dupe is colinear to Chair |
I hope this was helpful, I can post some other examples later.