I want to call things in a specific order. I'm trying to lay the foundation for my online game. Each player will have its own game object ("avatar"), which is instantiated at runtime. Each of these avatars use prefabs and have their own components.
The prefabs contain items and also styles such as gender, facial hair, etc. So my equipment manager will need to check for default style prefabs if the item slot is empty.
Please correct me if I'm going about this the wrong way.
I have 2 issues.
First off, I'll show you the code.
CreateAvatarSceneManager is attached to its own game object in the scene:
public class CreateAvatarSceneManager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
// inst avatar with position & scale
GameObject avatar = Resources.Load<GameObject>("Avatar");
avatar = Instantiate(avatar, new Vector3(-5.5f, -2.5f, 0), Quaternion.Euler(new Vector3(0, 140, 0)));
avatar.transform.localScale = new Vector3(4, 4, 4);
// set gender
avatar.GetComponent<AvatarStyle>().gender = AvatarGender.Female;
// render avatar
avatar.GetComponent<AvatarManager>().Render();
}
}
AvatarManager is attached to the avatar prefab that is instantiated via the scene manager above.
public class AvatarManager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Unrender();
}
// undrender all prefabs
public void Unrender()
{
Debug.Log("called unrender");
foreach (Renderer renderer in gameObject.GetComponentsInChildren<Renderer>())
{
renderer.enabled = false;
}
}
// render default style prefabs
public void Render()
{
Debug.Log("called render");
AvatarStyle avatarStyle = gameObject.GetComponent<AvatarStyle>();
EquipmentManager equipmentManager = gameObject.GetComponent<EquipmentManager>();
Debug.Log(avatarStyle.gender);
Debug.Log(equipmentManager.defaultPrefabs);
/*
foreach (Renderer renderer in gameObject.GetComponentsInChildren<Renderer>())
{
if (equipmentManager.defaultPrefabs[avatarStyle.gender].ContainsValue(renderer.name))
{
renderer.enabled = true;
}
}
*/
}
}
AvatarStyle is also attached to the avatar prefab that is instantiated.
public class AvatarStyle : MonoBehaviour
{
public AvatarGender gender;
}
public enum AvatarGender { Male, Female }
EquipmentManager is also attached to the avatar prefab that is instantiated.
public class EquipmentManager : MonoBehaviour
{
public Dictionary<AvatarGender, Dictionary<EquipmentSlot, string>> defaultPrefabs;
// Start is called before the first frame update
void Start()
{
SetDefaultPrefabs();
}
// set default prefabs when item not present
public void SetDefaultPrefabs()
{
Debug.Log("set default prefabs");
defaultPrefabs = new Dictionary<AvatarGender, Dictionary<EquipmentSlot, string>>();
Dictionary<EquipmentSlot, string> defaultMalePrefabs = new Dictionary<EquipmentSlot, string>
{
{ EquipmentSlot.Head, "Chr_Head_Male_00" },
{ EquipmentSlot.Torso, "Chr_Torso_Male_00" },
};
defaultPrefabs.Add(AvatarGender.Male, defaultMalePrefabs);
Dictionary<EquipmentSlot, string> defaultFemalePrefabs = new Dictionary<EquipmentSlot, string>
{
{ EquipmentSlot.Head, "Chr_Head_Female_00" },
{ EquipmentSlot.Torso, "Chr_Torso_Female_00" },
};
defaultPrefabs.Add(AvatarGender.Female, defaultFemalePrefabs);
}
}
public enum EquipmentSlot { Head, Torso }
Issue 1
It seems like my methods aren't being called in the order I want them to. If I look at the console, it is showing me this:
called render
Female
Null
called unrender
set default prefabs
You can see the Null is causing problems with the AvatarManager render function. Since its trying to call render BEFORE the default prefabs are even set, it causes an error.
I want the order to actually be more like this:
called unrender
set default prefabs
Female
(dictionary of default prefabs)
called render
Why are things firing in this order? Should it not be calling Start() BEFORE any other function call?
Issue 2
OK maybe this is actually related to issue 1. Should I actually be using singletons for the managers? If so, how do I use singletons per avatar that is instantiated?
Also, if you look at the way I am doing things, I want to turn this:
// from scene manager
avatar.GetComponent<AvatarStyle>().gender = AvatarGender.Female;
// from avatar manager
if (gameObject.GetComponent<AvatarStyle>().gender) DoStuff();
Into something like this:
// from scene manager
avatar.AvatarStyle.gender = AvatarGender.Female;
// from scene manager
if (gameObject.AvatarStyle.gender) DoStuff();
I'm more concerned with issue #1 right now. Thanks for your time and help.
Updatemethod of your Avatar could check if any of its visual properties was changed since the last update and then trigger its reconstruction itself. \$\endgroup\$