Add predifined components to custom component via c++ [SOLVED]

#1
In the sandbox editor, I can add predifined components to my EntityComponent. For example I have a WeaponComponent created in c++ and in the sandbox editor in the properties of the Weapon I can add a Mesh, RigidBody, Box Collider etc. Is it possible to add this to my WeaponComponent per c++ so I have access to their properties via code and as well it shows in the editor when I add a component to a level?

Allready tried something like:

Code: Select all

CBaseMeshComponent m_pMeshComponent = m_pEntity->GetOrCreateComponent<Cry::DefaultComponents::CBaseMeshComponent>();
No error but don't see this in the editor.

And like this:

Code: Select all

static void RegisterMeshComponent(Schematyc::IEnvRegistrar& registrar) { Schematyc::CEnvRegistrationScope scope = registrar.Scope(IEntity::GetEntityScopeGUID()); { Schematyc::CEnvRegistrationScope componentScope = scope.Register(SCHEMATYC_MAKE_ENV_COMPONENT(CBaseMeshComponent)); } } CRY_STATIC_AUTO_REGISTER_FUNCTION(&RegisterMeshComponent);
I get an error that I have to Reflect but that means that I have to create this on my own I guess.

Any idea if this is possible and if yes, how?

Thanks in advance
Charalampos :-)
Last edited by charalampos on Wed Jan 03, 2018 8:06 pm, edited 1 time in total.

Re: Add predifined components to custom component via c++

#2
I'm a bit confused about your question - you talk first about WeaponComponent, which already registered and can be used, but then you have problems registering CBaseMeshComponent? Or is it about automatically getting CBaseMeshComponent in entity, which already has WeaponComponent?

I assume it's second, but let's go in steps to be sure:

1. Registering CBaseMeshComponent component

Code: Select all

scope.Register(SCHEMATYC_MAKE_ENV_COMPONENT(CBaseMeshComponent));
tells engine, that there is such entity component and it can also be used in schematyc. To be registered this way, component has to have static ReflectType() function - hence the error you get. So, yes - you have to write this function yourself. See for example StaticMesh component in CryDefaultEntities:
https://github.com/CRYTEK/CRYENGINE/blo ... nent.h#L28

Based on this example, minimal ReflectType function for your CBaseMeshComponent component would probably look something like this:

Code: Select all

static void ReflectType(Schematyc::CTypeDesc<CBaseMeshComponent>& desc) { desc.SetGUID("{___replace_me_with_correct_guid___}"_cry_guid); desc.AddMember(&CBaseMeshComponent::m_filePath, 'file', "FilePath", "File", "Determines the CGF to load", "%ENGINE%/EngineAssets/Objects/Default.cgf"); }
Now you should be able to add component to any preplaced entity on the level and see your component properties.

2. Automatically getting CBaseMeshComponent to exist in entity together with WeaponComponent
It seems you would like to establish a dependency between components. Luckily, when you reflect your WeaponComponent, you can write:

Code: Select all

desc.AddComponentInteraction(SEntityComponentRequirements::EType::HardDependency, "{__guid_of_CBaseMeshComponent__}"_cry_guid);
This way engine makes sure, that whenever entity has WeaponComponent, it also has CBaseMeshComponent. And it's guaranteed that CBaseMeshComponent is initialized first. So then WeaponComponent can use GetComponent<CBaseMeshComponent> - it's already there.
Apart from HardDependency, there is also SoftDependency - component is not required, but if it's there - initialize it first.

Now, you say, that you already got working WeaponComponent. Was it registered with the new API (SCHEMATYC_MAKE_ENV_COMPONENT and ReflectType)? If no - then I'm not sure, that there was similar component dependency functionality before. You may want to change registration code or consider different options (entity classes with custom entity spawning callback). And if yes - then why registration of CBaseMeshComponent was an issue? ;)

Re: Add predifined components to custom component via c++

#3
I'm a bit confused about your question - you talk first about WeaponComponent, which already registered and can be used, but then you have problems registering CBaseMeshComponent? Or is it about automatically getting CBaseMeshComponent in entity, which already has WeaponComponent?
...
Hi pashkoff,

first of all many thanks for trying to help me. Second, I think I've caused the confusion with my "CBaseMeshComponent". This was only an example of what I have tried so far, I thought maybe is the right direction but not sure.

I made some tries with what you've suggested but no really success. Have to try more probably ;-)

Anyway, I try here again to ask more clear :-)
I followed a tutorial who shows how to create a custom component, example WeaponComponent. I put the code at the bottom, yes created with the new API.
I can use this in the sandbox editor, works ok so far. I can add it, move it etc.

Now, if I go to sandbox editor and put a weapon to a level, I can simply add with the button "Add component" in the Properties panel a RigidBody to this weapon. Or a Mesh, or a Pathfinder and so on. Then I have access to all the properties of the RigiBody (or Pathfinder or Mesh or...) via Properties panel.

I only try to avoid creating all these properties on my own in c++ for my component. I thought maybe is an easy way to do the same, like "Add component" in the editor, but directly in my code.

Hope it is more clear this time.

Once again, thank you!
Charalampos :-)


WeaponComponent.h

Code: Select all

#pragma once #include "CryEntitySystem\IEntityComponent.h" #include "CryEntitySystem\IEntity.h" #include "DefaultComponents\Geometry\BaseMeshComponent.h" struct SWeaponProperties { inline bool operator==(const SWeaponProperties& rhs) const { return 0 == memcmp(this, &rhs, sizeof(rhs)); } int iRecoil; float fReloadSpeed; }; static void ReflectType(Schematyc::CTypeDesc<SWeaponProperties>& desc) { desc.SetGUID("{CF686FC1-8125-48FB-9652-96C013A8EE5D}"_cry_guid); desc.SetDescription("Weapon Properties"); desc.SetLabel("Weapon Properties"); desc.AddMember(&SWeaponProperties::iRecoil, 'irec', "Recoil", "Recoil amount", "Recoil amount for the weapon", 0); desc.AddMember(&SWeaponProperties::fReloadSpeed, 'irel', "ReloadSpeed", "Reload speed", "The reload speed of the weapon", 0.f); } class CWeaponComponent final : public IEntityComponent { public: CWeaponComponent() = default; virtual ~CWeaponComponent() {} virtual void Initialize() override; virtual uint64 GetEventMask() const override; virtual void ProcessEvent(SEntityEvent& event) override; // Reflect type to set a unique identifier for this component static void ReflectType(Schematyc::CTypeDesc<CWeaponComponent>& desc); SWeaponProperties sWeaponProps; };
WeaponComponent,cpp

Code: Select all

#include "StdAfx.h" #include "WeaponComponent.h" #include "CrySchematyc\Env\IEnvRegistrar.h" #include "CrySchematyc\Env\Elements\EnvComponent.h" static void RegisterWeaponComponent(Schematyc::IEnvRegistrar& registrar) { Schematyc::CEnvRegistrationScope scope = registrar.Scope(IEntity::GetEntityScopeGUID()); { Schematyc::CEnvRegistrationScope componentScope = scope.Register(SCHEMATYC_MAKE_ENV_COMPONENT(CWeaponComponent)); } } CRY_STATIC_AUTO_REGISTER_FUNCTION(&RegisterWeaponComponent); void CWeaponComponent::Initialize() { m_pEntity->LoadGeometry(0, "Objects/Default/primitive_sphere.cgf"); SEntityPhysicalizeParams physParams; physParams.type = PE_STATIC; physParams.mass = 100000.f; m_pEntity->Physicalize(physParams); } uint64 CWeaponComponent::GetEventMask() const { return BIT64(ENTITY_EVENT_START_GAME) | BIT64(ENTITY_EVENT_UPDATE); } void CWeaponComponent::ProcessEvent(SEntityEvent & event) { } void CWeaponComponent::ReflectType(Schematyc::CTypeDesc<CWeaponComponent>& desc) { desc.SetGUID("{EFF87E21-90C0-4A57-A26F-815934CF5069}"_cry_guid); desc.SetEditorCategory("TutorialComponents"); desc.SetDescription("Weapon component"); desc.SetLabel("WeaponComponent"); desc.SetComponentFlags({ IEntityComponent::EFlags::Transform, IEntityComponent::EFlags::Socket, IEntityComponent::EFlags::Attach }); // EDITOR MEMBERS desc.AddMember(&CWeaponComponent::sWeaponProps, 'swp', "WeaponProperties", "Weapon properties", "", SWeaponProperties()); }

Re: Add predifined components to custom component via c++

#5
.h file:

Code: Select all

Cry::DefaultComponents::CRigidBodyComponent* m_pRigidBodyComponent = nullptr;
.cpp file, you need to call this in the Initialize() function:

Code: Select all

m_pRigidBodyComponent = m_pEntity->GetOrCreateComponent<Cry::DefaultComponents::CRigidBodyComponent>();
This works for me.
This works for me too!

Have to play around with it, cool new possibilities :-)

Thank you
Charalampos :-)

Who is online

Users browsing this forum: No registered users and 2 guests