Hello everyone, I am new to Unity and a beginner coder myself. So I am sorry if this is a stupid question.
I am creating a 2D platformer game where the player can “transform” into three different elements (Fire, Water, and Earth). Every elements have different attributes and skills. So I made three different player prefabs for each element (PlayerFire, PlayerWater, PlayerEarth). Every time the player transform into another element, I destroyed the previous object and create a new instance of the selected prefabs.
Normally, if there is only 1 player object, I can just attach the Camera to the player object. But since my player object is constantly being destroyed and created, I can’t do it anymore. Also, when the player is selecting what elements to use, there is no player object in scene because I destroy the player object, and the game will crash “no camera to render scene”.
What I currently do: I create an empty object and attach the camera to it.
The problem is: how to change the Camera position to track new object’s position in scene? Is there any better solution to this problem?
I hope I explained it well.
Thank you for your attention!
I wouldn’t destroy the gameObject’s your using as different states, I would just have everything child-ed to an empty object, that has your player script. The 3 objects you use as player, and the camera would be the children. And disabling and re-enabling the character objects as needed. Kind of like object pooling in a way.
That way your camera never gets destroyed(if you’re happy with it as is), and you would never need to worry about losing variables already set(inventory, damage boosts, gold collected, etc…). You just simply swap what player object is active at that time.
Instead you can attach a camera to your player and when you want to spawn a different player your script can detach the camera, spawn the new prefab, attach the camera to the new prefab and then destroy the old player.
Something like this:
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
SpawnPlayer(PlayerFire);
else if (Input.GetKeyDown(KeyCode.Alpha2))
SpawnPlayer(PlayerWater);
else (Input.GetKeyDown(KeyCode.Alpha3))
SpawnPlayer(PlayerEarth);
}
void SpawnPlayer(GameObject prefab)
{
GameObject newPlayer=Instantiate(prefab,player.transform.position,player.transform.rotation); // spawn new player
Camera.main.transform.parent=newPlayer.transform; // Attach camera to the new player
Destroy(player); // destroy old player
}
I agree, calling _players = GameObject.FindGameObjectWithTag("Player"); each frame is going to chew up your performance something terrible. As you make more enemies, and more collision checks, you won’t be in the realm of frames per second, you’ll be in seconds per frame…
But as kurt mentioned, it get’s pretty tricky if you want to hard code a camera, assuming you want it’s movement to lerp(move smoothly), or even find a center of a group of objects so everything is in frame. I just assumed you wanted old-school camera stares at players position, from one direction only. Unless camera was parented at a negative Z, and you rotated the parent object, then the camera would always be perfectly behind the player and rotate accordingly.
But most importantly, if you don’t want multiple cameras and making certain ones enable while all others disable as “.main”? you can just have a free floating camera, and it moves(instantly or slowly) to whatever position you want it at. And again, that get’s a little tricky, but basically you define a position and a rotation, give that data to the camera(class you create) and it does it.
But quick and simple camera? just child it to player object