Sorry for dragging up an old question but would you believe I'm only now able to look at this. Unfortunately I'm not geting the results I would expect and in all cases I get an output of -1
Here's my code, which is attached to a prefab which is instantiated during runtime:
public int test;
private void Start()
{
test = GetLinkedID(this.gameObject);
print(test);
}
public int GetLinkedID(GameObject prefab)
{
foreach (InvItem item in KickStarter.inventoryManager.items)
{
if (item.linkedPrefab == prefab)
{
return item.id;
}
}
Debug.LogWarning("Not found");
return -1;
}
Does the code above require a change in light of inventory updates in v1.72?
My other thought is perhaps the name of the prefab at runtime is causing problems? When the prefab is instantiated in my game it appears in the Hierarchy with a (Clone) suffix as
The "prefab" parameter in the GetLinkedID function needs to be the original prefab - not a scene instance of it, which Unity will treat as a separate object.
If you want to compare a scene instance with the "Linked prefab", you'll need to attach something else to compare them with. The Constant ID component, with Retain in prefab?, would be ideal - as you can then just compare ID values between both, i.e.:
public int GetLinkedID (GameObject sceneInstance)
{
int sceneInstanceID = sceneInstance.GetComponent <ConstantID>().constantID;
foreach (InvItem item in KickStarter.inventoryManager.items)
{
if (item.linkedPrefab == null) return;
int prefabID = item.linkedPrefab.GetComponent <ConstantID>().constantID;
if (prefabID == sceneInstanceID)
{
return item.id;
}
}
Debug.LogWarning("Not found");
return -1;
}
Thanks @ChrisIceBox. Thinking about this, it's insane to be doing a ForEach each time the prefab is instantiated (and that happens a lot in my game) - in that case just manually setting the ID value on the original prefab, which is what happens currently, would be more performant.
However, I like the code idea to diminish the risk of setup error. Is there a way in Unity to have it run such code before runtime so the values are all set on the original prefab before hitting play?
I mean, all you really need is a component with a public "ItemID" integer variable in it, that you can use to record the ID - even manually, if necessary.
To do this automatically and outside of Play Mode, you can write a function to set this value, and precede the function with ContextMenu, i.e.:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AC;
public class PlayerThrowableItem : MonoBehaviour
{
public int inventoryID; //THIS MUST MATCH AC INVENTORY ID FOR THE ITEM OTHERWISE INCORRECT INTERACTIONS WILL BE TRIGGERED
public GameObject owner;
public bool isUsed = false;
public int GetLinkedID(GameObject prefab)
{
foreach (InvItem item in KickStarter.inventoryManager.items)
{
if (item.linkedPrefab == prefab)
{
return item.id;
}
}
Debug.LogWarning("Not found");
return -1;
}
[ContextMenu("Set ID")]
void SetOwnIDValue()
{
print("ID set");
inventoryID = GetLinkedID(gameObject);
}
}
And it in action:
Does that all look solid? Any improvements I'm missing?
@ChrisIceBox Aww yeah, those sound good. Will look into those. Unity say that [ExecuteInEditMode] is being phased out because of prefab mode and that ExecuteAlways might be the ticket.
Really appreciate you introducing me to some new Unity tricks!
Comments
You can iterate through the defined items and compare their linkedPrefab variable, i.e.:
AC Ver: 1.72.2
Unity Ver: 2019.4.8f1
Sorry for dragging up an old question but would you believe I'm only now able to look at this. Unfortunately I'm not geting the results I would expect and in all cases I get an output of -1
Here's my code, which is attached to a prefab which is instantiated during runtime:
Does the code above require a change in light of inventory updates in v1.72?
My other thought is perhaps the name of the prefab at runtime is causing problems? When the prefab is instantiated in my game it appears in the Hierarchy with a (Clone) suffix as
However the setup in the inventory manager is
The "prefab" parameter in the GetLinkedID function needs to be the original prefab - not a scene instance of it, which Unity will treat as a separate object.
If you want to compare a scene instance with the "Linked prefab", you'll need to attach something else to compare them with. The Constant ID component, with Retain in prefab?, would be ideal - as you can then just compare ID values between both, i.e.:
Thanks @ChrisIceBox. Thinking about this, it's insane to be doing a ForEach each time the prefab is instantiated (and that happens a lot in my game) - in that case just manually setting the ID value on the original prefab, which is what happens currently, would be more performant.
However, I like the code idea to diminish the risk of setup error. Is there a way in Unity to have it run such code before runtime so the values are all set on the original prefab before hitting play?
I mean, all you really need is a component with a public "ItemID" integer variable in it, that you can use to record the ID - even manually, if necessary.
To do this automatically and outside of Play Mode, you can write a function to set this value, and precede the function with ContextMenu, i.e.:
That'll then allow you to trigger the function from a menu via the component's "Cog" menu in its Inspector.
Sorry I didn't mean your solution was insane, just the way I was thinking / currently trying to use it.
Oh that [ContextMenu] is very cool. I've never dabbled with that before.
It works!
Here's my setup:
And it in action:
Does that all look solid? Any improvements I'm missing?
You could mark the whole class with [ExecuteInEditMode], and then call the function from OnEnable, to have it run automatically when added.
Since it'll also run when the game begins, do a check for the ID value (i.e. -1 or not) to prevent it from running again if it's already been set.
@ChrisIceBox Aww yeah, those sound good. Will look into those. Unity say that [ExecuteInEditMode] is being phased out because of prefab mode and that ExecuteAlways might be the ticket.
Really appreciate you introducing me to some new Unity tricks!