Giter Site home page Giter Site logo

Comments (27)

rdeioris avatar rdeioris commented on July 3, 2024 1

ue.blueprint_add_member_variable(bp, 'name', 'type'[, is_array])

has been added.

Type is one of 'bool', 'int', 'string', 'object', 'float' (as string)... It is a preliminary version as we need to allow specifying classes too.

In the mean time you may be interested in this api:

https://docs.unrealengine.com/latest/INT/API/Editor/UnrealEd/Kismet2/FBlueprintEditorUtils/index.html

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Hi blueprints are not 'plain classes' so you need additional steps to work with them. Lucky enough we already have a blueprint api, i will post here an example in the next few hours

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

So, creating a blueprint is pretty easy:

import unreal_engine as ue
from unreal_engine.classes import Actor

new_bp = ue.create_blueprint(Actor, '/Game/MyNewFunnyBlueprint')

you should suddenly see your just created blueprint in the content browser.

Now to add components, you need a temporary actor:

tmp_actor = ue.get_editor_world().actor_spawn(Actor)
new_component = tmp_actor.add_actor_component(StaticMeshComponent, 'foobar')

once you have a valid component (to be valid it must be mapped to an actor living in a world) you can add it to the blueprint (unreal will take rid of copying it)

ue.add_components_to_blueprint(new_bp, [new_component])

as you can see add_components_to_blueprint() takes an array of valid components.

Now you can open the blueprint editor and you will see the new components.

If you want to programmatically generate blueprints, you can compile them directly from python too:

ue.compile_blueprint(new_bp)

finally, rememebr to destroy the tmp actor:

tmp_actor.destroy()

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Currently i am working on adding variables/properties to blueprints too

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

Hi,
I tried the adding of components to a new blueprint.
This does not seem to work, when I try to add multiple components at a time:

>>> ue.add_components_to_blueprint(new_bp, [new_components]) # with a length of 3
the component list has to contains only UActorComponent classes or objects

When I stick to adding lists with a length of 1, then it works - though the newly added components don't have a static mesh attached to them! - how can I achieve this?`

The other problem that I had was, that I wanted to add to an existing blueprint actor:
ue.load_object(Actor, "Game/TestActor") # does not work

Using Blueprint instead ist not accepted by the ue.add_components_to_blueprint method;:
bp. = ue.load_object(Blueprint, "Game/TestActor")

So how do I get a reference to my blueprint as Actor?

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Hi, ensure to always pull the latest code. And be sure to use /Game/... and not Game/ (the slash before is required).

Regarding multiple components add can you paste the whole code ?

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

Latest Code was pulled.

Regarding "/Game/" --> that was just a typo:

>>> ue.load_object(Actor, "/Game/TestActor")
Can't find file '/Game/TestActor'
Failed to find object 'Actor None./Game/TestActor'
unable to load object /Game/TestActor
Traceback (most recent call last):
  File "<string>", line 1, in <module>
Exception: unable to load object /Game/TestActor

Ragarding multiple components:

def add_static_meshes_to_blueprint(bp_actor, paths):
    # paths in the form ["/Game/Meshes/Static_Mesh_01", "/Game/Meshes/Static_Mesh_02", "/Game/Meshes/Static_Mesh_03"]

    new_components = []
    tmp_actor = ue.get_editor_world().actor_spawn(Actor)

    for path in paths:
        new_components.append(tmp_actor.add_actor_component(StaticMeshComponent, path))

    for nc in new_components:
        ue.log(nc)

    ue.add_components_to_blueprint(bp_actor, [new_components])
    ue.compile_blueprint(bp_actor)

And then the error occurs.
If works, when I rewrite it to:

def add_static_meshes_to_blueprint(bp_actor, paths):

    new_components = []
    tmp_actor = ue.get_editor_world().actor_spawn(Actor)

    for path in paths:
        new_components.append(tmp_actor.add_actor_component(StaticMeshComponent, path))

    for nc in new_components:
        ue.log(nc)
        ue.add_components_to_blueprint(bp_actor, [nc])

    ue.compile_blueprint(bp_actor)

Though the components within the actor have the whole path as name and no meshes attached to them.

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Ok, if /Game/TestActor is a blueprint, use

bp = ue.load_object(Blueprint, '/Game/TestActor')

if you get error use this trick:

  • select the asset from the content browser
  • get a reference to it and print its full name
bp = ue.get_selected_assets()[0]
ue.log(bp.get_full_name())

Regarding new_components is already an array, you do not need to place it in square :)

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

Regarding new_components is already an array, you do not need to place it in square :)

Ok, Im so sorry! - I think I should stop working for today!

And I just realized, that I expected the wrong result from
tmp_actor.add_actor_component(StaticMeshComponent, path)

It only creates a new static mesh component. The second paramter is just a name and not the path to an existing asset - my bad, sorry for that as well! I suppose I need to set my mesh on that component then and everything ist fine!

Ok, if /Game/TestActor is a blueprint, use

bp = ue.load_object(Blueprint, '/Game/TestActor')

I tried that before - I think unreal either crashed or I got an error - I will try!

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Yes, once you get reference to the component just start setting its properties. When you add it to the blueprint, properties will be copied.

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

Thanks! I tried to use Blueprint with ue.load_object. I get a valid instance but unreal crashes when
calling "ue.add_components_to_blueprint" - I suspect as it expects an instance of type Actor, and not Blueprint. Here is the exact code, that I used:

import unreal_engine as ue
from unreal_engine.classes import Actor, Blueprint, StaticMeshComponent
bp = ue.load_object(Blueprint, "/Game/MyActor")
tmp_actor = ue.get_editor_world().actor_spawn(Actor)
new_component = tmp_actor.add_actor_component(StaticMeshComponent, "TestName")
ue.add_components_to_blueprint(bp, [new_component])

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Ok, i will check it and i will back to you. Thanks

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

After lot of digging in unreal code i decided to rip off add_components_to_blueprint(), and instead i added:

ue.add_component_to_blueprint(bp, class, name)

So your code became:

import unreal_engine as ue
from unreal_engine.classes import Actor, Blueprint, StaticMeshComponent, StaticMesh
bp = ue.load_object(Blueprint, '/Game/MyActor')
cube = ue.load_object(StaticMesh, '/Game/Cube')

new_component = ue.add_component_to_blueprint(bp,StaticMeshComponent, 'TheMesh')
new_component.StaticMesh = cube
ue.compile_blueprint(bp)

let me know how it works for you

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Just as a note, you can now avoid to re-enter all the commands one by one, use your favourite editor and ue.exec:

https://github.com/20tab/UnrealEnginePython/blob/master/PythonConsole.md#running-python-scripts

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

@rdeioris:
This is now all working fine! Thank you very much!

But how do I get a reference to the actual Actor of the Blueprint?
I am now trying to check which components already exist, but "get_components"/"get_actor_components" can't be called on the Blueprint reference.

Trying to directly get a Actor reference does not work:

>>> ue.load_object(Actor, "/Game/MyBlueprintActor")
Exception: unable to load object /Game/MyBlueprintActor

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

You need to access the "ClassDefaultObject" from the blueprint "GeneratedClass":

cdo = bg.GeneratedClass.get_cdo()

Here you find explanation about the 'CDO':

https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Objects/

you can consider it as the template of the class

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

In addition to CDO you can directly access blueprint class properties:

ue.log(bp.GeneratedClass.properties())

as you can see variables and components are exposed too

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

@rdeioris:
Thanks for the input - I understand!
Somehow I still can't access the existing components:

>>> obj = my_blueprint.GeneratedClass.get_cdo()
>>> components = obj.get_components() # get_actor_components etc. all return the same
>>> ue.log(components)
[]
>>> ue.log(my_blueprint.GeneratedClass.properties())
["My_First_Component", "My_Second_Component", ...]
# so the components are actually listet but:
>>> ue.log(obj .get_property("My_First_Component"))
None

But is it possible, that this approach is only valid for runtime and for editor scripting?
Because I need to get references to the components in editor mode, not runtime.

Sorry for being such a pain for you!

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

In your example it should be

my_blueprint.GeneratedClass.My_First_Component

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

@rdeioris
Thanks for your feedback!
But:

>>> ue.log(my_blueprint.GeneratedClass.My_First_Component)
None

I even got Unreal to crash as at the beginning as "My_First_Component" somehow became the root component of the blueprint. Afte fixing that, I could execute again, but still got None in return.

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Ok, it looks like there are no shortcuts comparing the api to C++.

You have to navigate the graph trees:

bp.SimpleConstructionScript.DefaultSceneRootNode.ChildNodes[0].ComponentTemplate.StaticMesh = cube

bp.SimpleConstructionScript -> gives you access to the blueprint tree.

ComponentTemplate gives you the component mapped to a node.

Take in account that after your report i have improved add_component_to_blueprint to take in account the eventually available root node. Now it should be consistent with the editor.

Let me know

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Does it work for you, can we close it ?

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

Hey!
Sorry for not responding. You could close it for the initial errors that I got!
But now I got into something you wrote:

ue.blueprint_add_member_variable(bp, 'name', 'type'[, is_array])

has been added.

Type is one of 'bool', 'int', 'string', 'object', 'float' (as string)... It is a preliminary version as we need to allow specifying classes too.

First of all - is there any progression for specifying classes?
And also - and this might be a different topic alltogether - is the same possible for components?
I tried:

>>> my_struct = ue.find_struct("MyStruct")
>>> ue.log(my_stuct)
<unreal_engine.UObject 'MyStruct' (0x000000003FA57200) UClass 'UserDefinedStruct'>
>>> my_component.add_property(my_struct, "Test")
Exception: uobject is not a UStruct

Do I have to some casting here? If so, how would I do this in python?

Alternatively I tried getting the struct reference in a different way:

>>> from unreal_engine.classes import Struct
>>> my_struct = ue.load_object(Struct, "/Game/Structures/MyStruct")

Which caused the same result.

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

AFAIK adding properties is only possible for classes/structs, not for instances (or component in your case). Maybe you mean adding a property with a reference to a component ?

from unrealenginepython.

LarsGroh avatar LarsGroh commented on July 3, 2024

What you write makes perfect sense:

AFAIK adding properties is only possible for classes/structs, not for instances (or component in your case).
I come from scripting in applications like Maya and Nuke, where adding attributes (properties) can be done to any kind of node. But I guess that can't be compared to how things work in Unreal, as everything is getting compiled.

What I wanted to do is add a variable (property) to my components in the actor, so the user can set these while working on the project. And then execute scripted actions on those cmpontens depending on the values of those variables. But I guess if I want to do that, I just have to implement my own StaticMeshComponent - actually Unreal doesnt' let me create a Blueprint with StaticMeshComponent as parent; so maybe the InstancedStaticMeshComponent will do.

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

InstancedStaticMeshComponent is a component allowing you to use the 'instancing' feature of your gpu. Basically you can draw multiple copy of the same (more or less) object with a single draw call.

Regarding your need, it is not a unreal pattern, i think you should create an ad-hoc component (subclassing ActorComponent) with the fields you need and use it along the standard components

from unrealenginepython.

rdeioris avatar rdeioris commented on July 3, 2024

Here you can find an example on how to override a component with python:

https://github.com/20tab/UnrealEnginePython/blob/master/docs/Subclassing_API.md#functions-and-events

from unrealenginepython.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.