Download

Python: Placing actors based on height of other actors

Hi everyone,

I am currently developing in the Unreal Editor with Python. The big goal of my project is placing human actors on top of other actors in my world, like a human on a baseball field, a tribune, a bench, … automatically. I am using complete projects/environments, not build be me.

My first approach was to create a list of all possible “undergrounds” for my humans, so benches, tribunes, … and get the origin and bounding boxes of these undergrounds. Based on the boxes, I can get the expansion of the underground in x, y and z. Initially, I thought I could just choose a random point for x and y and use the heighest point of z.
My first tests were with cubes, so this obviously worked. If the objects aren’t cubes, well, it’s not working anymore and my humans are just hanging in the air.

Second idea, I get the geometry of my undergrounds. I was hoping to find something like “Oh, this is my underground/actor x, I get the mesh (component) and based on that, I get the geometry so I can enter my x and y and get the height/z (or z bounds) of this object on this point specified by my point in x and y”. Unfortunetaly, I didn’t find such a way. Maybe it’s hard to find for me, maybe it doesn’t even exists (but if it exists, I would be happy if someone tells me about it).

So that’s basically my problem. I’m new to Unreal Editor coding, so please don’t hesitate to tell me about an easier solution I didn’t see or correct me if I try to do some weird and complicated stuff. Thanks for your help!

Hello AirLea,

best thing would be to do a top down line trace (on complex collision) from above the location you want to test in x,y. Something like

import unreal

sm = unreal.EditorAssetLibrary.load_asset("/game/SM_StaticMeshToSpawn")

world = unreal.EditorLevelLibrary.get_all_level_actors()[0].get_world()
posToTest = unreal.Vector(0,0,0)

listOfObjectTypeQuery = unreal.Array(unreal.ObjectTypeQuery)
listOfObjectTypeQuery.append(unreal.ObjectTypeQuery.OBJECT_TYPE_QUERY1)
listOfObjectTypeQuery.append(unreal.ObjectTypeQuery.OBJECT_TYPE_QUERY2)
hit = unreal.SystemLibrary.line_trace_single_for_objects(world,unreal.Vector(posToTest.x,posToTest.y,500),unreal.Vector(posToTest.x,posToTest.y,0),listOfObjectTypeQuery,True,unreal.Array(unreal.Actor),unreal.DrawDebugTrace.NONE,True)
if hit != None:
    print(hit)
    print(hit.to_tuple())
    print(hit.to_tuple()[4])
    print(hit.to_tuple()[5])#impact_point
    print(hit.to_tuple()[6])
    unreal.EditorLevelLibrary.spawn_actor_from_object(sm,hit.to_tuple()[5])

I am not so sure about the Object_Type_Query as I do not get the real Enum values and reading the hitresult is not so great either, but that should work.

In that sample I am assuming the origin of my mesh is in z = 0, else you will have to add the delta between origin of your mesh and its lowest point.

1 Like

Hi Flavien,

thank you for your help, I wouldn’t found that by myself and I am really happy for your input. :slight_smile: I’m just using different x and y positions in the vector for posToTest, some random points on my underground object. And I adjusted the start and end in line_trace_single_for_objects to my environment.
But everything is working now as expected, thank you very much!