The Cinemachine Camera is not snapping to the player after scene load (Cinemachine 3.1.4, Unity 6)
This is part of the Unity 2.5D Turn-Based RPG: Build Your Own Turn-Based Battles & Environments course.
Heading into battle > Changes scene to battle scene > defeat/win > load back to the overworld scene with the correct player position works all fine.
When running the game directly from the overworld scene, the problem doesn’t exist, and everything works.
The issue is apparent when I start the game from another scene (the main menu scene > prologue scene > overworld scene) as I enter a battle and load back, the camera races forward from its original start position (at the start of the overworld scene) all the way to the player (where the player had the battle), creating a noticeable delay, and furthermore, the player doesnt load in the correct postion either which is weird.
I’m not sure exactly what the problem is, since it works when loading straight from the overworld scene.
Perhaps it’s an initialisation order or something to do with cinemachine.
I tried many things, such as turning the xyz position damping to 0, which cut the camera straight to the player (which is good), but it created a small glitch where it momentarily shows the last frame of the battle.
I would really appreciate any help as I’ve been trying to troubleshoot this for a while
I added a visual fade out from the battle scene which hides the glitch!
Now, the spawning issue.
At the moment, it seems like wherever I enter a battle in the overworld scene, and then enter the battle scene and load back into the overworld, I’m always loading in the same place, and it’s always where I initiated my first battle.
And another issue, when I recruit another character, she doesn’t load back with me in the overworld scene and ends up back in her original position in the overworld before I recruit her. Also, a dublicate ends up following me after returning out of nowhere a few seconds later.
That was going to be my suggestion. Not much else you can do to stop that first frame buffer. I’ve always stuck to using a transition. You’ll find this in lots of games between scenes.
At the end of the battle, you should be spawning in the location where you were when you entered the battle, so this is normal… unless you’re meaning that in successive battles, you’re going back to that first location, that’s not normal.
The position is stored in PartyManager when you change scenes, and should be getting set every time you start an encounter in PlayerController.FixedUpdate()
This one I"m not sure at all about, since the JoinableCharacterScript should be checking with the PartyManager to see if the character is in the party. If it is, then it should be SetActive(false). That’s called on Start (and PartyManager is a Singleton, so it should already be there if a character had already been recruited).
I doubly can’t explain the actual follow character being spawned a few seconds later, this should be happening right away. That almost sounds like a coroutine is managing it (which it should’t be).
Paste in your CharacterManager.SpawnOverworldMembers() method.
Thank you very much for the response both on the video and here.
Yeah, it also makes the battle seem smoother between transitions. I need to add a fade-in for the transition to the battle scene next!
Sorry if I didn’t word it well. I meant that the character is indeed returning to the first location, which, as you said, is not normal. It’s either not updating the saved player position correctly before entering battle or not restoring that position properly after loading back into the overworld, since it’s always where the first battle commenced.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class CharacterManager : MonoBehaviour
{
[SerializeField] private GameObject joinPopup;
[SerializeField] private TextMeshProUGUI joinPopupText;
private bool infrontOfPartyMember;
private GameObject joinableMember;
private PlayerControls playerControls;
private List<GameObject> overworldCharacters = new List<GameObject>();
private const string PARTY_JOINED_MESSAGE = " Joined The Party!";
private const string NPC_JOINABLE_TAG = "NPCJoinable";
private void Awake()
{
playerControls = new PlayerControls();
}
// Start is called before the first frame update
void Start()
{
playerControls.Player.Interact.performed += _ => Interact();
}
// Public method to be called once PartyManager is initialized
public void InitCharacterVisuals()
{
Debug.Log("CharacterManager: InitCharacterVisuals()");
// clear any old visuals
foreach (var go in overworldCharacters) Destroy(go);
overworldCharacters.Clear();
// now spawn fresh
SpawnOverworldMembers();
}
private void OnEnable()
{
playerControls.Enable();
}
private void OnDisable()
{
playerControls.Disable();
}
// Update is called once per frame
void Update()
{
}
private void Interact()
{
if (infrontOfPartyMember == true && joinableMember != null)
{
MemberJoined(joinableMember.GetComponent<JoinableCharacterScript>().MemberToJoin);//add member
infrontOfPartyMember = false;
joinableMember = null;
}
}
private void MemberJoined(PartyMemberInfo partyMember)
{
GameObject.FindFirstObjectByType<PartyManager>().AddMemberToPartyByName(partyMember.MemberName);// add party member
joinableMember.GetComponent<JoinableCharacterScript>().CheckIfJoined();// disable joinable member
// join pop up
joinPopup.SetActive(true);
joinPopupText.text = partyMember.MemberName + PARTY_JOINED_MESSAGE;
SpawnOverworldMembers(); // adding an overworld member
}
private void SpawnOverworldMembers()
{
List<PartyMember> currentParty = GameObject.FindFirstObjectByType<PartyManager>().GetCurrentParty();
Debug.Log(" Current party count: " + currentParty.Count);
Debug.Log("SpawnOverworldMembers called.");
for (int i = 0; i < overworldCharacters.Count; i++)
{
Destroy(overworldCharacters[i]);
}
overworldCharacters.Clear();
for (int i = 0; i < currentParty.Count; i++)
{
if (i==0) // first member will be the player
{
GameObject player = gameObject; // get the player
GameObject playerVisual = Instantiate(currentParty[i].MemberOverworldVisualPrefab,
transform.position, Quaternion.identity); // spawn the member visual
playerVisual.transform.SetParent(player.transform); // settting the parent to the player
player.GetComponent<PlayerController>().SetOverworldVisuals(playerVisual.GetComponent<Animator>(),
playerVisual.GetComponent<SpriteRenderer>()); // assign the player controller values
playerVisual.GetComponent<MemberFollowAI>().enabled = false;
overworldCharacters.Add(playerVisual); // add the overworld character visual to the list
}
else // any other will be a follower
{
Vector3 positionToSpawn = transform.position;// get the followers spawn position
positionToSpawn.x -= i;
GameObject tempFollower = Instantiate(currentParty[i].MemberOverworldVisualPrefab,
positionToSpawn, Quaternion.identity);// spawn the follower
tempFollower.GetComponent<MemberFollowAI>().SetFollowDistance(i); // set follow ai settings
overworldCharacters.Add(tempFollower); // add the follower visual to our list
}
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == NPC_JOINABLE_TAG)
{
//enable our prompt
infrontOfPartyMember = true;
joinableMember = other.gameObject;
joinableMember.GetComponent<JoinableCharacterScript>().ShowInteractPrompt(true);
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == NPC_JOINABLE_TAG)
{
//disable our prompt
infrontOfPartyMember = false;
joinableMember.GetComponent<JoinableCharacterScript>().ShowInteractPrompt(false);
joinableMember = null;
}
}
}
I re-saved the player’s position inside a new FadeManager script just before loading the battle scene, which seems to have fixed the player position problem. Now, to fix the duplication of the character!
Apologies, I misunderstood and thought your isssues had been resolved.
In terms of the download you sent, I never received said email (or it was filtered out so that I never saw it).
Be sure to zip the project and remove the Library folder to conserve space.
Be sure to tag me (Brian T) as the requesting instructor and include a link back to this topic.
I’m still having trouble with my character reappearing after scene load. I think the game is having trouble saving preferences and is instead restarting the scene after loading back from the battle scene, which reinstates the recruited character.
That upload website just does not work for me at all. The upload portion always gives me an error, so I’ve copied the necessary information and pasted it in an email alongside a link to my zip file.