Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

Clopen

Adding Custom Components to Existing Prefabs

Recommended Posts

Clopen    12

As part of my effort to mark who (i.e. which character prefab) crafted/cooked a certain item, I tried adding a tag to the item, and when that didn't work, a custom component that just has the name of the creator's prefab.

Adding the component did at least save the added data, but it doesn't load it.
My guess is that after instantiation, the saved data is passed to the OnLoad function of all the object's components, and since the prefab itself (in my tests, just a normal axe) doesn't add that component on its own, the data doesn't get loaded, even though the component data is there.

The question therefore is: how do I add custom data, in any way, to an instance of an existing prefab without making changes to the code of that prefab?
I want to add this "creator" tag/component to every item with finite uses and every cooked item.
I don't want to change all of the relevant existing prefabs or components for this for obvious reasons.

Any help would be greatly appreciated. =)

Share this post


Link to post
Share on other sites
Leonardo Cox    529

you want to use prefab postinits, heres an example of one I used in one of my mods:

local function FriendlyWaspInit(prefab)
	local function OnNearBy(prefab, target)
	if prefab.components.childspawner ~= nil and not target:HasTag("bee") then
        prefab.components.childspawner:ReleaseAllChildren(target, "killerbee")
    end

	end
	
	if prefab.components.playerprox then
	prefab.components.playerprox:SetOnPlayerNear(OnNearBy)
	end
end

AddPrefabPostInit("wasphive", FriendlyWaspInit)

Note: Make sure you check if the components exist even if you're sure they do, as sometimes when the code is ran the components aren't loaded in quite yet.

Share this post


Link to post
Share on other sites
Clopen    12

Thank you! ^_^

Indeed, that was exactly what I needed, though I ended up using the component postinits.
In case it'll be of use to someone, here is how I added save/load capabilities to a new field I made for the inventoryitem component:

local function InventoryItemInit(component)
	if component ~= nil then
		local oldSaveFunction = component.OnSave
		if oldSaveFunction == nil then oldSaveFunction = function(self) return nil end end
		component.OnSave = function(self)
			data = oldSaveFunction(self)
			if self.creator ~= nil then
				if data == nil then data = {} end
				if data.creator == nil then
					data.creator = self.creator
				end
			end
			return data
		end
		
		local oldLoadFunction = component.OnLoad
		if oldLoadFunction == nil then oldLoadFunction = function(self, data) end end
		component.OnLoad = function(self, data)
			oldLoadFunction(data)
			if data ~= nil and data.creator ~= nil and self.creator == nil then
				self.creator = data.creator
			end
		end
	end
end

AddComponentPostInit("inventoryitem", InventoryItemInit)

Oh, and of course, I always make sure I don't access nil.
A game is much less fun when it crashes.

Share this post


Link to post
Share on other sites