def update(self, vertices): if len(self.vertexArray) != len(vertices) and len( self.vertexArray) * 3 != len(vertices): print( "***** update vertices number not equal to original************" ) return uvArray = self.uvArray colorArray = self.colorArray # optimize this later vertices2D = [] vertexArray = [] for i in range(0, len(vertices), 3): vertexArray.append( FVector(vertices[i], vertices[i + 1], vertices[i + 2])) vertices2D.append([vertices[i], vertices[i + 1], vertices[i + 2]]) # update normla with naive method, cost lots of time normalArray = self.update_normal(vertices2D) normalArrayForRender = [] for i in range(0, len(normalArray)): normalArrayForRender.append( FVector(normalArray[i][0], normalArray[i][1], normalArray[i][2])) self.UpdateMeshSection(self.CurrentMeshSectionIndex, vertexArray, normalArrayForRender, UV0=uvArray, VertexColors=colorArray)
def load_map(self): """Loads the file and creates appropriate assets in unreal""" #self.filepath = ImporterSettings.map_file_path self.filepath = self.uobject.mappath MAPFile = MAPLevelReader.MAPLevelFile() MAPFile.read_file(self.filepath) numGeoObjects = len(MAPFile.geometryObjects) ue.log("Num geoObjects: {}".format(numGeoObjects)) ue.log("material definitions: " + str(len(MAPFile.materials))) self.materialDefinitions = MAPFile.materials self.LoadMaterials() usedNames = [] self.objectComponents = [] self.objectsToShift = [] self.worldOffsetVec = FVector(0, 0, 0) for _, geoObjectDefinition in enumerate(MAPFile.geometryObjects): name = geoObjectDefinition.nameString if name in usedNames: ue.log("Duplicate name! " + name) else: usedNames.append(name) print("Processing geoobj: " + name) geoObjComponent = self.uobject.add_actor_component( SceneComponent, name, self.defaultSceneComponent) self.uobject.add_instance_component(geoObjComponent) self.uobject.modify() self.objectComponents.append(geoObjComponent) if MAPFile.gameVersion == RSEGameVersions.RAINBOW_SIX: self.import_rainbow_six_geometry_object( geoObjectDefinition, geoObjComponent) else: # Rogue spear self.import_rogue_spear_geometry_object( geoObjectDefinition, geoObjComponent) if self.shift_origin: print("Recentering objects") # Once all meshes have been imported, the WorldAABB will properly encapsulate the entire level, # and an appropriate offset can be calculated to bring each object back closer to the origin worldOffset = self.worldAABB.get_center_position() self.worldOffsetVec = FVector(worldOffset[0], worldOffset[1], worldOffset[2]) self.worldOffsetVec = KismetMathLibrary.RotateAngleAxis( self.worldOffsetVec, 90.0, FVector(1.0, 0.0, 0.0)) for geoObjComponent in self.objectsToShift: # Only shift static elements if geoObjComponent.get_relative_location().length() > 1000.0: newLoc = geoObjComponent.get_relative_location( ) - self.worldOffsetVec geoObjComponent.set_relative_location(newLoc) self.import_lights(MAPFile) self.refresh_geometry_flag_settings() ue.log("Finished loading map")
def arrayvector_to_fvector(position, performRotation=False): """Converts a list of 3 floats into an unreal FVector class""" newVec = FVector(position[0], position[1], position[2]) if performRotation: newVec = KismetMathLibrary.RotateAngleAxis(newVec, 90.0, FVector(1.0, 0.0, 0.0)) return newVec
def import_renderable(self, filename): """Adds the specified renderable as a mesh section to this procedural mesh component""" # obj = ObjLoader.OBJ(filename) obj = ObjLoader.OBJ(filename) self.vertexArray = obj.vertices self.indexArray = obj.faces self.faces = [] for i in range(0, len(obj.faces), 3): self.faces.append( [obj.faces[i], obj.faces[i + 1], obj.faces[i + 2]]) # here is a trick, make sure vertex index same as normal index self.normalArray = [] for nor in obj.normals: self.normalArray.append(FVector(nor[0], nor[1], nor[2])) self.uvArray = [] self.colorArray = [] self.Tangents = [] vertexArray = [] for i in range(0, len(self.vertexArray)): vertexArray.append( FVector(self.vertexArray[i][0], self.vertexArray[i][1], self.vertexArray[i][2])) self.CreateMeshSection(self.CurrentMeshSectionIndex, vertexArray, self.indexArray, self.normalArray, UV0=self.uvArray, VertexColors=self.colorArray, bCreateCollision=True) print("*************ProceduralMesh Imported!**************")
def test_default_values(self): transform0 = FTransform() self.assertEqual( transform0.translation, FVector(0, 0, 0)) self.assertEqual( transform0.rotation.roll, 0) self.assertEqual( transform0.rotation.pitch, 0) self.assertEqual( transform0.rotation.yaw, 0) self.assertEqual( transform0.scale, FVector(1, 1, 1))
def test_is_a(self): new_actor = self.world.actor_spawn(Character, FVector(100, 200, 300)) self.assertTrue(new_actor.is_a(Actor)) self.assertTrue(new_actor.is_a(Character)) new_actor2 = self.world.actor_spawn(Actor, FVector(100, 200, 300)) self.assertTrue(new_actor2.is_a(Actor)) self.assertFalse(new_actor2.is_a(Character))
def observe(delta_time, state, path, driver, pawn): from unreal_engine import FVector global speedlimit, throttle, speed_integral, last_speed_error, didx, didxmax, diag if speedlimit == None: speedlimit = calc_speedlimit(path) #print("state {} path {} pawn {} {}".format(state["delta_time"],path,driver.location,pawn)) l0 = driver.location forward = pawn.get_actor_forward() closest = path.component.FindLocationClosestToWorldLocation(l0) offpath = (closest - l0) pathoffset = offpath.length() key = path.component.FindInputKeyClosestToWorldLocation(l0) frac = key % 1 key = int(key + 1) % len(speedlimit) key1 = int(key + 1) % len(speedlimit) d0 = path.component.GetDistanceAlongSplineAtSplinePoint(key) d1 = path.component.GetDistanceAlongSplineAtSplinePoint(key1) d = d0 + frac * (d1 - d0) sd0 = path.component.GetDirectionAtSplinePoint(key) sd1 = path.component.GetDirectionAtSplinePoint(key1) sd = sd1 * frac + sd0 * (1 - frac) angle = -FVector.cross(forward, sd).z adjust = FVector.cross(forward, offpath).z * .001 adjust = min(0.2, max(-0.2, adjust)) angle -= adjust #a0=-FVector.cross(forward, sd0).z #a1=-FVector.cross(forward, sd1).z if key < len(speedlimit): goal_speed = speedlimit[key] * (1 - frac) + speedlimit[key1] * frac else: goal_speed = 300 speed = driver.speed speed_error = goal_speed - speed speed_integral = speed_integral + speed_error speed_delta = speed_error - last_speed_error throttle = speed_error * 0.002 + speed_delta * 0.009 + speed_integral * 0.00002 #print("key {:3.0f} angle {:-1.3f} throttle {:-0.3f} goal {:4.0f} speed {:4.0f} offpath {:3.0f} odometer {:6.0f} lap {:3.0f} ".format(key,angle,throttle,goal_speed,speed,pathoffset,driver.odometer,driver.lapcnt)) last_speed_error = speed_error #state['observation'][1].append(sensor_data) info = state['info'] info['ec'] = [goal_speed, speed_delta, speed_integral] info['delta_time'] = delta_time info['PIDsteering'] = -angle info['PIDthrottle'] = throttle info['pathoffset'] = pathoffset return throttle, angle
def import_renderable(newRSEGeoComp, renderable: RenderableArray, materials: List[RSEMaterialDefinition]): """Adds the specified renderable as a mesh section to the supplied procedural mesh component""" vertexArray = [] #Repack vertices into array of FVectors, and invert X coordinate for vertex in renderable.vertices: tempVertex = FVector(vertex[0], vertex[1], vertex[2]) #tempVertex = tempVertex - FVector(32611.490234, 31651.273438, 32911.394531) tempVertex = KismetMathLibrary.RotateAngleAxis(tempVertex, 90.0, FVector(1.0, 0.0, 0.0)) vertexArray.append(tempVertex) normalArray = [] for normal in renderable.normals: tempVertex = FVector(normal[0], normal[1], normal[2]) tempVertex = KismetMathLibrary.RotateAngleAxis(tempVertex, 90.0, FVector(1.0, 0.0, 0.0)) normalArray.append(tempVertex) uvArray = [] if renderable.UVs is not None: for UV in renderable.UVs: uvArray.append(FVector2D(UV[0], UV[1] + 1.0)) colorArray = [] if renderable.vertexColors is not None: for color in renderable.vertexColors: newColor = [] for element in color: newColor.append(int(element * 255)) colorArray.append(FColor(newColor[0], newColor[1], newColor[2])) indexArray = [] #Repack face vertex indices into flat array for face in renderable.triangleIndices: indexArray.append(face[2]) indexArray.append(face[1]) indexArray.append(face[0]) newMeshSectionIdx = newRSEGeoComp.AutoCreateMeshSection( vertexArray, indexArray, normalArray, UV0=uvArray, VertexColors=colorArray, bCreateCollision=True) newMeshSectionIdx = newRSEGeoComp.GetLastCreatedMeshIndex() if renderable.materialIndex != R6Constants.UINT_MAX: newRSEGeoComp.SetMaterial(newMeshSectionIdx, materials[renderable.materialIndex])
def build_skeleton(self, pkg_name, obj_name): pkg = ue.get_or_create_package('{0}_Skeleton'.format(pkg_name)) skel = Skeleton('{0}_Skeleton'.format(obj_name), pkg) # add a root bone from which all of the others will descend # (this trick will avoid generating an invalid skeleton [and a crash], as in UE4 only one root can exist) skel.skeleton_add_bone('root', -1, FTransform()) # iterate bones in the json file, note that we move from opengl axis to UE4 # (y on top, x right, z forward right-handed) to (y right, x forward left-handed, z on top) for bone in self.model['bones']: # assume no rotation quat = FQuat() # give priority to quaternions # remember to negate x and y axis, as we invert z on position if 'rotq' in bone: quat = FQuat(bone['rotq'][2], bone['rotq'][0] * -1, bone['rotq'][1] * -1, bone['rotq'][3]) elif 'rot' in bone: quat = FRotator(bone['rot'][2], bone['rot'][0] - 180, bone['rot'][1] - 180).quaternion() pos = FVector(bone['pos'][2] * -1, bone['pos'][0], bone['pos'][1]) * self.scale # always set parent+1 as we added the root bone before skel.skeleton_add_bone(bone['name'], bone['parent'] + 1, FTransform(pos, quat)) skel.save_package() return skel
def __init__(self, actor, label, sz, offset, rot): print(actor) self.width = sz[0] self.height = sz[1] #print("before attach",actor.get_actor_components()) mesh = actor.get_actor_component_by_type(SkeletalMeshComponent) # we need three parts, SceneCaptureActor, ATextureReader, RenderTargetTextures self.rendertarget = TextureRenderTarget2D() self.rendertarget.set_property("SizeX", self.width) self.rendertarget.set_property("SizeY", self.height) xform = FTransform() xform.translation = FVector(offset[0], offset[1], offset[2]) xform.rotation = FRotator(rot[0], rot[1], rot[2]) ue.log("vcam xlate {} rot {}".format(xform.translation, xform.rotation)) self.scene_capture = actor.get_actor_component_by_type( SceneCaptureComponent2D) self.scene_capture.set_relative_location(offset[0], offset[1], offset[2]) self.scene_capture.set_relative_rotation(rot[0], rot[1], rot[2]) self.scene_capture.set_property("TextureTarget", self.rendertarget) # add reader last self.reader = actor.add_actor_component( ue.find_class('ATextureReader'), label + "_rendertarget") self.reader.set_property('RenderTarget', self.rendertarget) self.reader.SetWidthHeight(sz[0], sz[1])
def create_blueprint_from_mesh(self): new_blueprint = ue.find_asset(self.path_to_output_asset + '/main_mesh') if new_blueprint is None: ue.log("blueprint class doesn't exists") new_blueprint = ue.create_blueprint( Character, self.path_to_output_asset + '/main_mesh') else: ue.log("blueprint class exists") new_blueprint = ue.find_asset(self.path_to_output_asset + '/main_mesh') # new_blueprint.GeneratedClass.get_cdo().Mesh.RelativeLocation = FVector(0, -200, 150) # new_blueprint.GeneratedClass.get_cdo().Mesh.RelativeRotation = FRotator(0, 0, 0) # add empty static mesh component to blueprint class new_blueprint.GeneratedClass.get_cdo( ).CapsuleComponent.CapsuleHalfHeight = 150 new_blueprint.GeneratedClass.get_cdo( ).CapsuleComponent.CapsuleRadius = 50 st_component = ue.add_component_to_blueprint(new_blueprint, StaticMeshComponent, 'dicom_mesh') ue.log("self.mesh.get_name() = " + self.mesh.get_name()) st_component.StaticMesh = ue.load_object( StaticMesh, self.path_to_output_asset + "/test_test") ue.compile_blueprint(new_blueprint) # saves uasset on the hard disk new_blueprint.save_package() world = ue.get_editor_world() new_actor = world.actor_spawn(new_blueprint.GeneratedClass, FVector(0, 0, 150))
def import_rooms(self, MAPFile: MAPLevelReader.MAPLevelFile): """Imports room volumes to for portals and occlusion checking""" for room in MAPFile.roomList.rooms: for levelDef in room.shermanLevels: aabb = levelDef.get_aabb() vertex = aabb.get_center_position() center = FVector(vertex[0], vertex[1], vertex[2]) center = KismetMathLibrary.RotateAngleAxis( center, 90.0, FVector(1.0, 0.0, 0.0)) center = center - self.worldOffsetVec vertex = aabb.get_size() scale = FVector(vertex[0], vertex[1], vertex[2]) scale = KismetMathLibrary.RotateAngleAxis( scale, 90.0, FVector(1.0, 0.0, 0.0)) self.uobject.AddRoomTrigger(levelDef.name_string.string, center, scale) # type: ignore self.uobject.RefreshRoomTriggersDebug() # type: ignore
def AddSequencerSectionTransformKeysByIniFile(SequencerSection, SectionFileName, FileLoc): Config = configparser.ConfigParser() Config.read(FileLoc) for option in Config.options(SectionFileName): frame = float(option)/float(frameRateNumerator) #FrameRate list = Config.get(SectionFileName, option) list = list.split(',') transform = FTransform(FVector(float(list[0]), float(list[1]), float(list[2])), FRotator(float(list[3]), float(list[4]), float(list[5]))) SequencerSection.sequencer_section_add_key(frame,transform)
def test_event(self): new_blueprint = ue.create_blueprint( Character, '/Game/Tests/Blueprints/Test3_' + self.random_string) uber_page = new_blueprint.UberGraphPages[0] x, y = uber_page.graph_get_good_place_for_new_node() test_event = uber_page.graph_add_node_custom_event('TestEvent', x, y) x, y = uber_page.graph_get_good_place_for_new_node() node_set_actor_location = uber_page.graph_add_node_call_function( Actor.K2_SetActorLocation, x, y) test_event.node_find_pin('then').make_link_to( node_set_actor_location.node_find_pin('execute')) node_set_actor_location.node_find_pin( 'NewLocation').default_value = '17,30,22' ue.compile_blueprint(new_blueprint) new_actor = self.world.actor_spawn(new_blueprint.GeneratedClass) self.assertEqual(new_actor.get_actor_location(), FVector(0, 0, 0)) ue.allow_actor_script_execution_in_editor(True) new_actor.TestEvent() self.assertEqual(new_actor.get_actor_location(), FVector(17, 30, 22))
def get_target_angle(self): location = self.actor.get_actor_location() angle = self.actor.GetTargetAngleFromPos( FVector(self.target_x, self.target_y, location.z))[0] nangle = angle / 360 + .5 # xd = location.x-self.target_x # yd = location.y-self.target_y # rangle = math.atan2(yd,xd) # nangle = rangle+math.pi # nangle = nangle/(math.pi*2) return nangle
def shift_origin_of_new_renderables(self, renderables): """Calculates the combined bounds of the new renderables and shifts the origin Returns an offset vector in Unreal correct space""" if self.shift_origin: geometryBounds = shift_origin_of_renderables(renderables, 1000.0) offsetAmount = geometryBounds.get_center_position() offsetVec = FVector(offsetAmount[0], offsetAmount[1], offsetAmount[2]) # Rotate offset to match unreals coordinate system offsetVec = KismetMathLibrary.RotateAngleAxis( offsetVec, 90.0, FVector(1.0, 0.0, 0.0)) # Adjust the world AABB # Only consider objects very far away for the world AABB, since dynamic objects like doors are very close to the origin, whereas static elements are over 50,000 units away # TODO: Use a similar check to set elements to static or moveable if offsetVec.length() > 1000.0: self.worldAABB = self.worldAABB.merge(geometryBounds) return offsetVec return FVector(0.0, 0.0, 0.0)
def build_animation(self, pkg_name, obj_name): factory = AnimSequenceFactory() factory.TargetSkeleton = self.skeleton new_anim = factory.factory_create_new('{0}_Animation'.format(pkg_name)) new_anim.NumFrames = self.model['animation']['length'] * \ self.model['animation']['fps'] new_anim.SequenceLength = self.model['animation']['length'] # each bone maps to a track in UE4 animations for bone_index, track in enumerate(self.model['animation']['hierarchy']): # retrieve the bone/track name from the index (remember to add 1 as we have the additional root bone) bone_name = self.skeleton.skeleton_get_bone_name(bone_index + 1) positions = [] rotations = [] scales = [] for key in track['keys']: t = key['time'] if 'pos' in key: positions.append( (t, FVector(key['pos'][2] * -1, key['pos'][0], key['pos'][1]) * 100)) if 'rotq' in key: rotations.append((t, FQuat( key['rotq'][2], key['rotq'][0] * -1, key['rotq'][1] * -1, key['rotq'][3]))) elif 'rot' in key: # is it a quaternion ? if len(key['rot']) == 4: rotations.append( (t, FQuat(key['rot'][2], key['rot'][0] * -1, key['rot'][1] * -1, key['rot'][3]))) else: rotations.append( (t, FRotator(key['rot'][2], key['rot'][0] - 180, key['rot'][1] - 180).quaternion())) pos_keys = [] rot_keys = [] # generate the right number of frames for t in numpy.arange(0, self.model['animation']['length'], 1.0 / self.model['animation']['fps']): pos_keys.append(self.interpolate_vector(positions, t)) rot_keys.append(self.interpolate_quaternion( rotations, t).get_normalized()) track_data = FRawAnimSequenceTrack() track_data.pos_keys = pos_keys track_data.rot_keys = rot_keys new_anim.add_new_raw_track(bone_name, track_data) # if we have curves, just add them to the animation if self.curves: new_anim.RawCurveData = RawCurveTracks(FloatCurves=self.curves) new_anim.save_package() return new_anim
def build_soft_vertex(self, index): # create a new soft skin vertex, holding tangents, normal, uvs, influences... v = FSoftSkinVertex() v_index = self.model['faces'][index] * 3 # here we assume 2 bone influences, technically we should honour what the json influencesPerVertex field exposes b_index = self.model['faces'][index] * 2 v.position = FVector(self.model['vertices'][v_index + 2] * -1, self.model['vertices'] [v_index], self.model['vertices'][v_index + 1]) * self.scale v.influence_weights = ( self.model['skinWeights'][b_index], self.model['skinWeights'][b_index + 1]) v.influence_bones = ( self.model['skinIndices'][b_index] + 1, self.model['skinIndices'][b_index + 1] + 1) # return the json index too, as we will need it later for computing morph targets return (v, v_index)
def updateself(self): uvArray = self.uvArray colorArray = self.colorArray normalArray = self.normalArray vertexArray = self.vertexArray for i in range(len(vertexArray)): vertexArray[i] += FVector(0, 0.00001, 0) self.UpdateMeshSection(self.CurrentMeshSectionIndex, vertexArray, normalArray, UV0=uvArray, VertexColors=colorArray)
def FixMeshData(self): # move from collada system (y on top) to ue4 one (z on top, forward decreases over viewer) for i in range(0, len(self.vertices), 3): xv, yv, zv = self.vertices[i], self.vertices[i + 1], self.vertices[i + 2] # invert forward vec = FVector(zv * -1, xv, yv) * self.ImportOptions.DefaultRotation self.vertices[i] = vec.x self.vertices[i + 1] = vec.y self.vertices[i + 2] = vec.z xn, yn, zn = self.normals[i], self.normals[i + 1], self.normals[i + 2] nor = FVector(zn * -1, xn, yn) * self.ImportOptions.DefaultRotation # invert forward self.normals[i] = nor.x self.normals[i + 1] = nor.y self.normals[i + 2] = nor.z # fix uvs from 0 on bottom to 0 on top for i, uv in enumerate(self.uvs): if i % 2 != 0: self.uvs[i] = 1 - uv
def calc_speedlimit(path): from unreal_engine import FVector limits = [] npoints = path.component.GetNumberOfSplinePoints() for n in range(npoints): p = path.component.GetDirectionAtSplinePoint(n) d0 = path.component.GetDistanceAlongSplineAtSplinePoint(n) A = 100 if n != 0: speedlimit = sqrt(abs(A * (d1 - d0) / FVector.cross(p, p1).z)) #print("n {} d {} sl {} {} {}".format(n,d0,speedlimit,FVector.cross(p,p1).z,speedlimit)) limits.append(min(speedlimit, 1400)) p1 = p d1 = d0 return limits
def interpolate_vector(self, timeline, t): keys = [] x_values = [] y_values = [] z_values = [] for key, value in timeline: keys.append(key) x_values.append(value[0]) y_values.append(value[1]) z_values.append(value[2]) x = numpy.interp(t, keys, x_values) y = numpy.interp(t, keys, y_values) z = numpy.interp(t, keys, z_values) return FVector(x, y, z)
def loadAndSpawnObjects(self): ue.log("+++++++++++++++++++") ue.log("loadAndSpawnObjects") ue.log("checking for " + self.datapath) if os.path.exists(self.datapath): with codecs.open(self.datapath, "r", "utf-8") as f: data = json.loads(f.read()) ue.log(data) for obj in data: objclass = ue.find_class(obj["type"]) #ue.log(str(type(objclass))+str(objclass)+"="+obj["json"]) objinst = self.uobject.actor_spawn(objclass, FVector(0, 0, 0), FRotator(0, 0, 0)) jsonstr = obj["json"] self.objects.append(objinst) objinst.call_function("loadjson", jsonstr) ue.log("------------------")
def build_morph_targets(self): # when we build the skeletal mesh LOD by passing soft skin vertices # UE4 will internally optimize the vertices to reduce duplicates # for this reason the vertex index we built is different from the one stored into UE4 # the skeletal_mesh_to_import_vertex_map() returns the original mapping given the new one import_map = self.mesh.skeletal_mesh_to_import_vertex_map() # we will fill animation curves for later usage curves = [] for morph_item in self.model['morphTargets']: # ensure the MorphTarget has the SkeletalMesh as outer morph = MorphTarget('', self.mesh) deltas = [] for idx, import_index in enumerate(import_map): # get the original json vertex index vertex_index = self.vertex_map[import_index] # get the original soft skin vertex vdata = self.vertices[import_index] x = morph_item['vertices'][vertex_index + 2] * -1 y = morph_item['vertices'][vertex_index] z = morph_item['vertices'][vertex_index + 1] delta = FMorphTargetDelta() delta.source_idx = idx # store the difference between original vertex position and the morph target one delta.position_delta = (FVector(x, y, z) * self.scale) - vdata.position deltas.append(delta) # check for the return value, as sometimes morph targets # in json files do not generate any kind of modification # so unreal will skip it if morph.morph_target_populate_deltas(deltas): # register the morph target self.mesh.skeletal_mesh_register_morph_target(morph) # add curve, not required, we can use it later for skeletal-based animations curves.append( FloatCurve(Name=SmartName(DisplayName=morph.get_name()), FloatCurve=RichCurve(Keys=[ RichCurveKey(Time=0.0, Value=0.0), RichCurveKey(Time=1.0, Value=1.0) ]))) self.mesh.save_package() return curves
def auto_move_update(self): t = self.t w = self.w z_t_1 = self.z_last_1_auto z_t_2 = self.z_last_2_auto sub_w = w[t, :] # model prediction and update mesh predict, x_recovery = self.model_predict(z_t_2, z_t_1, sub_w) self.Procedural_mesh.update(x_recovery.tolist()) # update sphere transform(location) y_transform_mat = self.y_transform_mat y_mean = self.y_mean y_recovery = np.matmul(sub_w, y_transform_mat.T) + y_mean y_list = y_recovery.tolist() scale = self.scale_factor self.sphere_actor.set_actor_location(FVector(y_list[0]*scale, y_list[1]*scale, y_list[2]*scale)) self.z_last_2_auto = self.z_last_1_auto self.z_last_1_auto = predict self.t += 1
import unreal_engine as ue from unreal_engine.classes import Actor, Character from unreal_engine import FVector, FRotator #use ue.exec('WorldActor.py') world = ue.get_editor_world() actor000 = world.actor_spawn(Actor, FVector(0, 0, 0), FRotator(0, 0, 0)) character000 = world.actor_spawn(Character, FVector(100, 100, 100), FRotator(0, 0, 0)) # select an actor unreal_engine.editor_select_actor(actor000) ''' # get access to the editor world editor = unreal_engine.get_editor_world() # get the list of selected actors selected_actors = unreal_engine.editor_get_selected_actors() # deselect actors unreal_engine.editor_deselect_actors() # import an asset new_asset = unreal_engine.import_asset(filename, package[, factory_class]) # get a factory class factory = ue.find_class('TextureFactory')
def tick(self, delta_time): #############get observation############# # ue.log(vel) self.ep_frame += 1 obs = [self.VehicleMovement.GetForwardSpeed() / 6000 + 0.5 ] # vel.x/1000+.5, vel.y/1000+.5] # LIDAR location = self.uobject.get_actor_location() + FVector(0, 0, 40) if (trace_num): rangle = self.get_angle_rads() for trace_id in range(trace_num): angle = trace_id / trace_num * math.pi * 2.0 + rangle ltarget = location + FVector( math.cos(angle) * trace_length, math.sin(angle) * trace_length, 0) is_hitting_something, _, hit_result = KismetSystemLibrary.LineTraceSingle( self.uobject, location, ltarget, ETraceTypeQuery.TraceTypeQuery1, DrawDebugType=EDrawDebugTrace.ForOneFrame, bIgnoreSelf=True) dist = trace_length if is_hitting_something: dist = hit_result.distance dist = dist / trace_length obs.append(dist) # TARGET ANGLE target_angle = self.get_target_angle() obs.append(target_angle) ##show target self.uobject.draw_debug_line( location, FVector(self.target_x, self.target_y, location.z), FLinearColor(0, 1, 0), 0, 2) # DIST obs.append(min(self.get_target_dist() / 5000, 1)) # CURRENT STEERING obs.append(self.actor.GetSteerAngle() * .5 + .5) state = np.array(obs) # env.render()##BIPEDAL # state = self.gstate ##BIPEDAL #############get action from policy############### action = self.policy.select_action(state) origaction = action if not self.actor.autodrive: # print("MANUAL") action[1] = self.actor.FIN action[0] = self.actor.RIN action[2] = 1 if self.actor.HBR else -1 fwd = self.actor.get_actor_forward() rt = self.actor.get_actor_right() draw_debug_lines = False if draw_debug_lines: actionx = action[0] * 1000 # -.5 actiony = action[1] * 1000 # -.5 target_vec = location + fwd * actiony + rt * actionx self.uobject.draw_debug_line( location, target_vec, # FVector(location.x+action[0]*2000,location.y+action[1]*2000,location.z), FLinearColor(0, 0, 1), 0, 2) if self.actor.autodrive: random_normal = np.random.normal(0, exploration_noise, size=action_dim) action = action + random_normal action = action.clip([-1, -1, -1], [1, 1, 1]) # action = action.clip(env.action_space.low, env.action_space.high)##BIPEDAL if draw_debug_lines: actionx = action[0] * 1000 # -.5 actiony = action[1] * 1000 # -.5 target_vec = location + fwd * actiony + rt * actionx self.uobject.draw_debug_line( location, target_vec, # FVector(location.x+action[0]*2000,location.y+action[1]*2000,location.z), FLinearColor(1, 0, 0), .05, 2) ######### apply action ########## if self.actor.autodrive: self.actor.FIN = action[1] self.actor.RIN = action[0] self.actor.HBR = True if action[2] > .9 else False ###############apply action################ self.VehicleMovement.SetThrottleInput(action[1]) self.VehicleMovement.SetSteeringInput(action[0]) self.VehicleMovement.SetHandbrakeInput(self.actor.HBR) ########## calc reward ########### new_dist = self.get_target_dist() diffd = self.last_dist - new_dist reward = diffd - 0.4 # reward = self.greward##BIPEDAL self.last_dist = new_dist # self.last_done = self.gdone#False # if self.gdone: ##BIPEDAL # env.reset() # al, c1l, c2l, prl = self.policy.update(self.replay_buffer, 200, batch_size, gamma, polyak, policy_noise,noise_clip, policy_delay) done = 0 if self.ep_frame > max_timesteps: done = 1 angle_reward = abs(target_angle - .5) reward -= angle_reward # if (target_angle > .97 or target_angle < .03): # print("DED") # #done = 1 # reward -= 50 if self.actor.Punish: self.actor.Punish = False reward -= 50 print("PUNISH") if self.actor.Reward: self.actor.Reward = False reward += 50 print("REWARD") if self.actor.Train: self.actor.Train = False al, c1l, c2l, prl = self.policy.update(self.replay_buffer, 200, batch_size, gamma, polyak, policy_noise, noise_clip, policy_delay) print("Train") if self.actor.Reset: self.actor.Reset = False al, c1l, c2l, prl = self.policy.update(self.replay_buffer, 5000, batch_size, gamma, polyak, policy_noise, noise_clip, policy_delay) done = 1 print("Reset") self.ep_reward += reward if done: # self.actor.set_physics_linear_velocity(FVector(0,0,0)) # self.actor.set_physics_angular_velocity(FVector(0,0,0)) al, c1l, c2l, prl = self.policy.update(self.replay_buffer, self.ep_frame, batch_size, gamma, polyak, policy_noise, noise_clip, policy_delay) ep_reward_avg = self.ep_reward / self.ep_frame self.writer.add_scalar('actor_loss', al, self.episode) self.writer.add_scalar('critic1_loss', c1l, self.episode) self.writer.add_scalar('ep_reward', self.ep_reward, self.episode) self.writer.add_scalar('ep_avg_reward', ep_reward_avg, self.episode) self.policy.save(directory, filename) if ep_reward_avg > self.ep_reward_avg_BEST: self.ep_reward_avg_BEST = ep_reward_avg self.policy.save(directory, filename + "_best") self.reset_ep() ####### record action ############ if len(self.last_state): self.replay_buffer.add((self.last_state, self.last_action, reward, state, float(done))) self.last_state = state self.last_action = action # self.last_reward = reward self.frame += 1 if self.frame > 2 and self.frame % 30 == 0: # self.actor.AutoDrive = True # al, c1l, c2l, prl = self.policy.update(self.replay_buffer, 5, batch_size, gamma, polyak, policy_noise, # noise_clip, policy_delay) if self.frame % 60 == 0: eval = self.policy.eval_action(state, action) print(state) print( "ep_frame{}:, action:{}, directaction:{}, eval:{}, reward: {}, memory:{}, ep:{}, interaction:{}" .format(self.ep_frame, action, origaction, eval, reward, self.replay_buffer.size, self.episode, self.frame)) if new_dist < 500: self.gen_target() self.last_dist = self.get_target_dist() ue.log("NEW TARGET!!!!!")
def get_target_angle(self): location = self.actor.get_actor_location() angle = self.actor.GetTargetAngleFromPos(FVector(self.target_x, self.target_y, location.z))[0] nangle = angle / 360 + .5 return nangle
def tick(self, delta_time): #############get observation############# # ue.log(vel) self.ep_frame+=1 obs = [self.VehicleMovement.GetForwardSpeed() / 6000 + 0.5] # vel.x/1000+.5, vel.y/1000+.5] # LIDAR location = self.uobject.get_actor_location() + FVector(0, 0, 40) if (trace_num): rangle = self.get_angle_rads() for trace_id in range(trace_num): angle = trace_id / trace_num * math.pi * 2.0 + rangle ltarget = location + FVector(math.cos(angle) * trace_length, math.sin(angle) * trace_length, 0) is_hitting_something, _, hit_result = KismetSystemLibrary.LineTraceSingle(self.uobject, location, ltarget, ETraceTypeQuery.TraceTypeQuery1, DrawDebugType=EDrawDebugTrace.ForOneFrame, bIgnoreSelf=True) dist = trace_length if is_hitting_something: dist = hit_result.distance dist = dist / trace_length obs.append(dist) # TARGET ANGLE target_angle = self.get_target_angle() obs.append(target_angle) ##show target self.uobject.draw_debug_line(location, FVector(self.target_x, self.target_y, location.z), FLinearColor(0, 1, 0), 0, 30) # DIST obs.append(min(self.get_target_dist() / 5000, 1)) # CURRENT STEERING obs.append(self.actor.GetSteerAngle() * .5 + .5) state = np.array(obs) # env.render()##BIPEDAL # state = self.gstate ##BIPEDAL #############get action from policy############### action = self.policy.select_action(state) origaction = action if not self.actor.autodrive: # print("MANUAL") action[1] = self.actor.FIN action[0] = self.actor.RIN action[2] = 1 if self.actor.HBR else -1 fwd = self.actor.get_actor_forward() rt = self.actor.get_actor_right() draw_debug_lines = False if draw_debug_lines: actionx = action[0] * 1000 # -.5 actiony = action[1] * 1000 # -.5 target_vec = location + fwd * actiony + rt * actionx self.uobject.draw_debug_line(location, target_vec, # FVector(location.x+action[0]*2000,location.y+action[1]*2000,location.z), FLinearColor(0, 0, 1), 0, 2) if self.actor.autodrive: random_normal = np.random.normal(0, exploration_noise, size=action_dim) action = action + random_normal action = action.clip([-1, -1, -1], [1, 1, 1]) # action = action.clip(env.action_space.low, env.action_space.high)##BIPEDAL if draw_debug_lines: actionx = action[0] * 1000 # -.5 actiony = action[1] * 1000 # -.5 target_vec = location + fwd * actiony + rt * actionx self.uobject.draw_debug_line(location, target_vec, # FVector(location.x+action[0]*2000,location.y+action[1]*2000,location.z), FLinearColor(1, 0, 0), .05, 2) ######### apply action ########## if self.actor.autodrive: self.actor.FIN = action[1] self.actor.RIN = action[0] self.actor.HBR = True if action[2] > .9 else False ###############apply action################ self.VehicleMovement.SetThrottleInput(action[1]) self.VehicleMovement.SetSteeringInput(action[0]) self.VehicleMovement.SetHandbrakeInput(self.actor.HBR) ########## calc reward ########### reward = 0 #getting closer to target new_dist = self.get_target_dist() diffd = self.last_dist - new_dist reward += diffd - 0.4 # reward = self.greward##BIPEDAL self.last_dist = new_dist #timeout, new EP done = 0 if self.ep_frame > max_timesteps: done = 1 #punish if not facing target angle_reward = abs(target_angle-.5) reward -= angle_reward # if (target_angle > .97 or target_angle < .03): # print("DED") # #done = 1 # reward -= 50 self.boredom = self.boredom * .99 + obs[0] * .01 if(self.boredom < 0.506): print("{} is bored: {}".format(self.my_id, self.boredom)) reward -= 30 done = 1 speedlerp = obs self.ep_reward += reward ####### record action ############ if len(self.last_state): self.replay_buffer.add((self.last_state, self.last_action, reward, state, float(done))) self.last_state = state self.last_action = action if done: ep_reward_avg = self.ep_reward/self.ep_frame master.write_data(self.ep_reward, ep_reward_avg) self.reset_ep() master.transfer_buffer(self.replay_buffer) self.replay_buffer = ReplayBuffer() self.frame += 1 if new_dist < 500: self.gen_target() self.last_dist = self.get_target_dist() ue.log("NEW TARGET!!!!!")
def CreateTask_SK_Armature(): ################[ Import Armature as SkeletalMesh type ]################ print( '================[ New import task : Armature as SkeletalMesh type ]================' ) FilePath = os.path.join( r'D:\Repos\Piroots2\Other Files\ExportedFbx\SkeletalMesh\Armature\SK_Armature.fbx' ) AdditionalParameterLoc = os.path.join( r'D:\Repos\Piroots2\Other Files\ExportedFbx\SkeletalMesh\Armature\SK_Armature_AdditionalParameter.ini' ) AssetImportPath = (os.path.join(unrealImportLocation, r'').replace('\\', '/')).rstrip('/') task = PyFbxFactory() task.ImportUI.MeshTypeToImport = EFBXImportType.FBXIT_SkeletalMesh task.ImportUI.bImportMaterials = True task.ImportUI.bImportTextures = False task.ImportUI.bImportAnimations = False task.ImportUI.bCreatePhysicsAsset = True task.ImportUI.bImportAnimations = False task.ImportUI.bImportMesh = True task.ImportUI.bCreatePhysicsAsset = True task.ImportUI.TextureImportData.MaterialSearchLocation = EMaterialSearchLocation.Local task.ImportUI.SkeletalMeshImportData.bImportMorphTargets = True print('================[ import asset : Armature ]================') try: asset = task.factory_import_object(FilePath, AssetImportPath) except: asset = None if asset == None: ImportFailList.append( 'Asset "Armature" not found for after inport') return print( '========================= Imports of Armature completed ! Post treatment started... =========================' ) skeleton = asset.skeleton current_sockets = skeleton.Sockets new_sockets = [] sockets_to_add = GetOptionByIniFile(AdditionalParameterLoc, 'Sockets', True) for socket in sockets_to_add: #Create socket new_socket = SkeletalMeshSocket('', skeleton) new_socket.SocketName = socket[0] print(socket[0]) new_socket.BoneName = socket[1] l = socket[2] r = socket[3] s = socket[4] new_socket.RelativeLocation = FVector(l[0], l[1], l[2]) new_socket.RelativeRotation = FRotator(r[0], r[1], r[2]) new_socket.RelativeScale = FVector(s[0], s[1], s[2]) new_sockets.append(new_socket) skeleton.Sockets = new_sockets lods_to_add = GetOptionByIniFile(AdditionalParameterLoc, 'LevelOfDetail') for x, lod in enumerate(lods_to_add): pass print( '========================= Post treatment of Armature completed ! =========================' ) asset.save_package() asset.post_edit_change() ImportedList.append([asset, 'SkeletalMesh'])