1. Bat doesn’t stop chasing and gets recoiled infinitely.
[This is caused by missing code that lets the Bat return to an Idle state from Chase state. Furthermore, there is no velocity change code to change the Bat’s recoil velocity after being recoiled.]
In Bat.cs script, add if(_dist > chaseDistance) {ChangeState(EnemyStates.Bat_Idle);} under case EnemyStates.Bat_Chase: before break;. This should change the Bat to an Idle state if the player exits it’s chaseDistance.
Add a code under case EnemyStates.Bat_Idle to reset it’s velocity, rb.velocity = new Vector2(0, 0);. This will let the Bat stabilize its velocity and stop recoiling without needing to be stopped by a collision.
case EnemyStates.Bat_Idle:
rb.velocity = new Vector2(0, 0);
if(_dist < chaseDistance)
{
ChangeState(EnemyStates.Bat_Chase);
}
break;
case EnemyStates.Bat_Chase:
rb.MovePosition(Vector2.MoveTowards(transform.position, PlayerController.Instance.transform.position, Time.deltaTime * speed));
FlipBat();
if(_dist > chaseDistance)
{
ChangeState(EnemyStates.Bat_Idle);
}
break;
2. Hit by spikes freezes the game.
[This is caused by “IEnumerator RespawnPoint()” in Spikes.cs scaling time to 0 and using “WaitForSeconds”]
Change all “WaitForSeconds” codes in Spikes.cs to “WaitForSecondsRealTime”. This allows the enumerator to continue as intended while in stopped time without freezing the game.
IEnumerator RespawnPoint()
{
...
yield return new WaitForSeconds WaitForSecondsRealtime(1f);
...
yield return new WaitForSeconds WaitForSecondsRealtime(UIManager.Instance.sceneFader.fadeTime);
...
}
3. Bat corpse can be attacked and recoils player.
[There are different ways to solve this bug but the simplest is to change the Bat’s layer to anything other than “Attackable”.]
First, create a new layer, and call it “Ignore Player” or something identifiable.
In Bat.cs, under ChangeCurrentAnimation() add int LayerIgnorePlayer = LayerMask.NameToLayer("Ignore Player"); gameObject.layer = LayerIgnorePlayer; to the If statement for the death state:
Go to Edit > Project Settings > Physics2D > Layer Collision Matrix. Here you can set collision based on Layers.
Then, turn off collision for both “Default”, “Attackable” & “Ignore Player”. This prevents the corpse from blocking enemies, stacking on each other and player’s movement and attacks.
Note: Depending on your game setup, change the Layers to however you feel is needed.
That will be all for Part 6.
Hopefully this can help you on any issues you may have. However, if you find that your issues weren’t addressed or is a unique circumstance, you can submit a forum post to go into detail on your problem for further assistance.
[There are multiple problems that can arise from this, some listed here, that can be solved by a note found in the Forum Post:]
1. Mana isn’t being reset
2. Invincibility and time stop is non-functional
3. Hearts healed to full
Make sure that there is only one scene containing your Prefabs with singleton scripts such as the Player and Canvas. Entering a scene with a second singleton instance will cause NullReferenceException errors as scripts cannot differentiate or single out one script instance from multiple.
In our PlayerController Script, let’s make a change to reset the castOrHealTimer in the CastSpell() method instead of GetInputs(). This relocation ensures that the timer doesn’t reset when you release the Cast/Heal button before CastSpell() is called.
Note: Change the if parameter of both Heal() and CastSpell() to a higher float value if needed as 0.05f is a very limited time for a player to tap and fire a spell.
That will be all for Part 5.
Hopefully this can help you on any issues you may have. However, if you find that your issues weren’t addressed or is a unique circumstance, you can submit a forum post to go into detail on your problem for further assistance.
So far, your code seems correct. So let’s start looking through your Scene’s inspector while in this death screen that can’t be removed.
Please open up the Canvas and look through it’s inspector values while you are dead, as well as the respawn button under “Death Screen” for it’s event system to see if it still has the GameManager on it.
I’ll also need you to manually deactivate the death screen during the bug and see if the player has respawned, thus meaning for some reason, only the DeathScreen is still active, or everything for the respawn did not function.
Then, we’re going to need to see if all parts of the code are being called correctly, add print code’s to your GameManager.cs RespawnPlayer():
public void RespawnPlayer()
{
if(bench.interacted) {
respawnPoint = bench.transform.position;
} else {
respawnPoint = platformRespawnPoint;
}
playerController.Instance.transform.position = respawnPoint;
print("player position set")
StartCoroutine(UIManager.Instance.DeactivateDeathScreen());
print("deactivate death called")
playerController.Instance.Respawned();
print("player called to respawn")
}
Then do the same for your UIManager.cs:
public IEnumerator DeactivateDeathScreen() {
print("UIman deactive started")
yield return new WaitForSeconds(0.5f);
deathScreen.SetActive(false);
print("screen setactive false")
StartCoroutine(sceneFader.Fade(SceneFader.FadeDirection.Out));
print("fade called")
}
I was, in fact, missing the EventSystem in my other scenes; adding it allowed me to be able to click the respawn button, but it still did not spawn me back in. This only occurs in cave 2 and Cave 3. Cave 1 is working perfectly fine.
As I tried your “1) Move your UpdateCameraYDampForPlayerFall(); under your Move() in Update()” the character can move horizontally but other movement is not working ex) attacking, jumping, skills
and after I attached SceneFader to UIManager script, I think scene transitioning is working.
But still there are repetitive error message on console.
As can be seen in the video, your Canvas has nothing set as it’s Scene Fader.
As for the fact that you cannot move, I believe something went wrong with your RigidBody2D which is also causing the NullReferenceException Errors for your UpdateCameraYDampForPlayerFall() method.
Can you copy and paste the entire code for your UIManager.cs & your PlayerController.cs?
At the same time, check if the Scene Fader game object under your Canvas has a SceneFader.cs script on it.
Hi sorry, but I’ll need more videos, particularly, you showing how the Canvas Prefab inspector is like while in game + Moving out of the camera bounds + scene transitions. You can take one video straight, selecting different objects to show their insectors.
From the looks of the normal inspectors, either there is no SceneFader set on your UIManager.cs, or it will be automatically set by a SceneFader.instance if there is one in the scene.
In regards to the camera, can you check if your Camera parent or any object has the CameraManager.cs script on it? I feel that likely the errors in the PlayerController.cs is a separate issue where it cannot find an instance of the CameraManager.cs
As for your SceneTransition, check that your Canvas Prefab has a UIManager.cs attached to it & the “Scene Fader” assigned appropriately to it. Then ensure that the SceneFader game object in the Canvas is set to Active as an inactive one will be taken as a null.
Otherwise, if both situations don’t work, could you taking some screenshots of the inspector of your UIManager, Player, SceneTransition inspectors & a video or console of what happens when you transition scenes?
As a side note, I noticed that your SceneTransition.cs calls SceneManager.LoadScene(transitionTo); in the private void OnTriggerEnter2D(Collider2D _other) method before the StartCoroutine. You should not need the LoadScene() code itself as the coroutine you are casting will activate both the fade and LoadScene() already.
and try to solve with Youtube video, it also doesn’t work…
so i’ll bold all the line the error is occuring.
“SceneTransition.cs”
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build.Content;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneTransition : MonoBehaviour
{
[SerializeField] private string transitionTo; //Represents the scene to transition to
[SerializeField] private Transform startPoint; //Defines the player's entry point in the scene
[SerializeField] private Vector2 exitDirection; //Specifies the direction for the player's exit
[SerializeField] private float exitTime; //Determines the time it takes for the player to exit the scene transition
// Start is called before the first frame update
private void Start()
{
if (GameManager.Instance.transitionedFromScene == transitionTo)
{
PlayerController.Instance.transform.position = startPoint.position;
StartCoroutine(PlayerController.Instance.WalkIntoNewScene(exitDirection, exitTime));
}
<strong>StartCoroutine(UIManager.Instance.sceneFader.Fade(SceneFader.FadeDirection.Out));</strong>
}
private void OnTriggerEnter2D(Collider2D _other)
{
if (_other.CompareTag("Player"))
{
GameManager.Instance.transitionedFromScene = SceneManager.GetActiveScene().name;
PlayerController.Instance.pState.cutscene = true;
SceneManager.LoadScene(transitionTo);
StartCoroutine(UIManager.Instance.sceneFader.FadeAndLoadScene(SceneFader.FadeDirection.In, transitionTo));
}
}
}
“PlayerController.cs”
void Update()
{
if (pState.cutscene) return;
GetInputs();
UpdateJumpVariables();
<strong>UpdateCameraYDampForPlayerFall();</strong>
RestoreTimeScale();
if (pState.dashing) return;
Flip();
Move();
Jump();
StartDash();
Attack();
FlashWhileInvincible();
Heal();
CastSpell();
}
void UpdateCameraYDampForPlayerFall()
{
//if falling past a certain speed threshold
<strong>if(rb.velocity.y < playerFallSpeedThreshold && !CameraManager.Instance.isLerpingYDamping && !CameraManager.Instance.hasLerpedYDamping)</strong>
{
StartCoroutine(CameraManager.Instance.LerpYDamping(true));
}
//if standing still or moving up
<strong> if(rb.velocity.y >= 0 && !CameraManager.Instance.isLerpingYDamping && CameraManager.Instance.hasLerpedYDamping)</strong>
{
//reset camera function
CameraManager.Instance.hasLerpedYDamping = false;
StartCoroutine(CameraManager.Instance.LerpYDamping(false));
}
}
I just followed “Camera Bounds” & “Dynamic Camera Y Damping” and when I try to run the game, it just pauses and there are repetitive error msg on console.
NullReferenceException: Object reference not set to an instance of an object
SceneTransition.Start () (at Assets/Scripts/SceneTransition.cs:27)
NullReferenceException: Object reference not set to an instance of an object
PlayerController.UpdateCameraYDampForPlayerFall () (at Assets/Scripts/PlayerController.cs:253)
PlayerController.Update () (at Assets/Scripts/PlayerController.cs:184)
NullReferenceException: Object reference not set to an instance of an object
PlayerController.UpdateCameraYDampForPlayerFall () (at Assets/Scripts/PlayerController.cs:258)
PlayerController.Update () (at Assets/Scripts/PlayerController.cs:184)
I don’t know how to deal with “NUllReferenceException” error.
this is my error console img below.
“Scenetransition.cs”
<code>public class SceneTransition : MonoBehaviour
{
[SerializeField] private string transitionTo; //Represents the scene to transition to
[SerializeField] private Transform startPoint; //Defines the player's entry point in the scene
[SerializeField] private Vector2 exitDirection; //Specifies the direction for the player's exit
[SerializeField] private float exitTime; //Determines the time it takes for the player to exit the scene transition
// Start is called before the first frame update
private void Start()
{
if (GameManager.Instance.transitionedFromScene == transitionTo)
{
PlayerController.Instance.transform.position = startPoint.position;
StartCoroutine(PlayerController.Instance.WalkIntoNewScene(exitDirection, exitTime));
}
StartCoroutine(UIManager.Instance.sceneFader.Fade(SceneFader.FadeDirection.Out));
}
private void OnTriggerEnter2D(Collider2D _other)
{
if (_other.CompareTag("Player"))
{
GameManager.Instance.transitionedFromScene = SceneManager.GetActiveScene().name;
PlayerController.Instance.pState.cutscene = true;
SceneManager.LoadScene(transitionTo);
StartCoroutine(UIManager.Instance.sceneFader.FadeAndLoadScene(SceneFader.FadeDirection.In, transitionTo));
}
}
}
</code>
“PlayerController.cs”
<code>
void Update()
{
if (pState.cutscene) return;
GetInputs();
UpdateJumpVariables();
UpdateCameraYDampForPlayerFall();
RestoreTimeScale();
if (pState.dashing) return;
Flip();
Move();
Jump();
StartDash();
Attack();
FlashWhileInvincible();
Heal();
CastSpell();
}
void UpdateCameraYDampForPlayerFall()
{
//if falling past a certain speed threshold
if(rb.velocity.y < playerFallSpeedThreshold && !CameraManager.Instance.isLerpingYDamping && !CameraManager.Instance.hasLerpedYDamping)
{
StartCoroutine(CameraManager.Instance.LerpYDamping(true));
}
//if standing still or moving up
if(rb.velocity.y >= 0 && !CameraManager.Instance.isLerpingYDamping && CameraManager.Instance.hasLerpedYDamping)
{
//reset camera function
CameraManager.Instance.hasLerpedYDamping = false;
StartCoroutine(CameraManager.Instance.LerpYDamping(false));
}
}
</code>