- Home /
How to make an organized, first-person ability system of prefabs when they can't access the main camera?
Hello everyone! I'm relatively new to Unity and C#, but I'm starting on a first-person, fantasy combat game where you essentially map abilities (weapon attacks, spells, bombs, etc) to whichever available buttons you want, enter an arena, then fight monsters with what you chose. If you die, pick new abilities if you want, and try again.
My initial idea is to have every ability be a prefab that includes a logic script which inherits from an interface called IAbility. For example, this ability would let you throw a Bomb prefab:
public class BombThrow : MonoBehaviour, IAbility
{
public float throwForce = 40f;
public GameObject bombPrefab;
public void Action()
{
GameObject bomb = Instantiate(bombPrefab, transform.position, transform.rotation);
Rigidbody rb = bomb.GetComponent<Rigidbody>();
rb.AddForce(transform.forward * throwForce, ForceMode.VelocityChange);
}
}
My Player gameobject will have an AbilityController component. That Controller contains GameObject variables that get assigned the ability prefabs I want to use. This is how I plan to keep those assigned abilities between scenes. I then search those slots for any IAbility components and run
slot1.GetComponent<IAbility>().Action();
to perform the ability.
My problem is this: since it is a first person game, I would need to reference the Main Camera so I can aim a bomb, spell or whatever else in the direction that the character (and subsequently, camera) is facing. But since all my abilities are prefabs, I can't reference the Main Camera in the ability script or prefab.
I feel like this has surely been done before, so are there any suggestions on how these pre-defined abilities could use the main camera?
Thanks for the help!
Answer by Llama_w_2Ls · Jan 03, 2021 at 09:21 PM
The Main Camera of a scene can be referenced using Camera.Main
if you can't assign it publicly, for example, a prefab. @danielgullatte
Interesting. I added Camera.$$anonymous$$ain to the instantiation line and it worked:
public void Action()
{
GameObject bomb = Instantiate(bombPrefab, Camera.main.transform.position, Camera.main.transform.rotation);
Rigidbody rb = bomb.GetComponent<Rigidbody>();
rb.AddForce(transform.forward * throwForce, Force$$anonymous$$ode.VelocityChange);
}
Before I posted this I was trying to set a Camera variable equal to Camera.main in an Awake method. But when I called slot1.GetComponent<IAbility>().Action();
it would return an error saying that the variable wasn't set.
But this works, so thank you very much for the help! @Llama_w_2Ls