Forum begins after the advertisement:


[Part 7] Shade problem

Viewing 15 posts - 1 through 15 (of 15 total)
  • Author
    Posts
  • #15278
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    1.My shade show up when start game like an enemy, how can i hide it when the game start
    2.when i clear all enemy in the first map then come to second map, when i come back to first map, the enemy is still there

    #15279
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Check two things first:
    1) Your scene does not already include a shade.
    – Simply delete the shade from the scene.

    2) Your mana state is not halfMana.
    – If you’re at halfMana, it means you died. Thus, you need to kill the shade to reset your mana state and save the game again.

    Regardless, try killing the shade and then saving the game. If it doesn’t work, can you take a short video of the problem for us to take a look? Include the scene, the SaveData and Shade scripts and the shade being there in the game itself.

    #15281
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    when i respawn, the shade js stood there and i can’t interact with it and when i kill all enemy in scene_1 then come to scene_2 and comeback, all enem is alive

    View post on imgur.com

    #15282
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.IO;
    using UnityEngine.SceneManagement;
    using Unity.Mathematics;

    [System.Serializable]
    public struct SaveData
    {
    public static SaveData Instance;

    //map stuff
    public HashSet<string> sceneNames;

    //bench stuff
    public string benchSceneName;
    public Vector2 benchPos;

    //player stuff
    public int playerHealth;
    public float playerMana;
    public bool playerHalfMana;
    public Vector2 playerPos;
    public string lastScene;

    //enemy stuff
    //Shade stuff
    public Vector2 shadePos;
    public string sceneWithShade;
    public Quaternion shadeRot;

    public void Initialize()
    {
    if(!File.Exists(Application.persistentDataPath + “/save.bench.data”))//if file doesnt exist , create new file
    {
    BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + “/save.bench.data”));
    }
    if(!File.Exists(Application.persistentDataPath + “/save.player.data”))//if file doesnt exist , create new file
    {
    BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + “/save.player.data”));
    }
    if(!File.Exists(Application.persistentDataPath + “/save.shade.data”))//if file doesnt exist , create new file
    {
    BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + “/save.shade.data”));
    }

    if (sceneNames == null)
    {
    sceneNames = new HashSet<string>();
    }
    }

    public void SaveBench()
    {
    using(BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + “/save.bench.data”)))
    {
    writer.Write(benchSceneName);
    writer.Write(benchPos.x);
    writer.Write(benchPos.y);
    }
    }

    public void LoadBench()
    {
    if(File.Exists(Application.persistentDataPath + “/save.bench.data”))
    {

    using(BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + “/save.bench.data”)))
    {
    benchSceneName = reader.ReadString();
    benchPos.x = reader.ReadSingle();
    benchPos.y = reader.ReadSingle();
    }
    }
    }
    public void SavePlayerData()
    {
    using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + “/save.player.data”)))
    {
    playerHealth = Player.Instance.Health;
    writer.Write(playerHealth);

    playerMana = Player.Instance.Mana;
    writer.Write(playerMana);
    playerHalfMana = Player.Instance.halfMana;
    writer.Write(playerHalfMana);

    playerPos = Player.Instance.transform.position;
    writer.Write(playerPos.x);
    writer.Write(playerPos.y);

    lastScene = SceneManager.GetActiveScene().name;
    writer.Write(lastScene);
    }
    }
    public void LoadPlayerData()
    {
    if (File.Exists(Application.persistentDataPath + “/save.player.data”))
    {
    using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + “/save.player.data”)))
    {
    playerHealth = reader.ReadInt32();
    playerHalfMana = reader.ReadBoolean();
    playerMana = reader.ReadSingle();
    playerPos.x = reader.ReadSingle();
    playerPos.y = reader.ReadSingle();
    lastScene = reader.ReadString();

    SceneManager.LoadScene(lastScene);
    Player.Instance.transform.position = playerPos;
    Player.Instance.Health = playerHealth;
    Player.Instance.halfMana = playerHalfMana;
    Player.Instance.Mana = playerMana;

    }
    }
    else
    {
    Debug.Log(“file doesn’t exist”);
    Player.Instance.halfMana = false;
    Player.Instance.Health = Player.Instance.maxHealth;
    Player.Instance.Mana = 0.5f;
    }
    }

    public void SaveShadeData()
    {
    using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + “/save.shade.data”)))
    {
    sceneWithShade = SceneManager.GetActiveScene().name;
    shadePos = Shade.Instance.transform.position;
    shadeRot = Shade.Instance.transform.rotation;

    writer.Write(sceneWithShade);

    writer.Write(shadePos.x);
    writer.Write(shadePos.y);

    writer.Write(shadeRot.x);
    writer.Write(shadeRot.y);
    writer.Write(shadeRot.z);
    writer.Write(shadeRot.w);
    }
    }
    public void LoadShadeData()
    {
    if (File.Exists(Application.persistentDataPath + “/save.shade.data”))
    {
    using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + “/save.shade.data”)))
    {
    sceneWithShade= reader.ReadString();
    shadePos.x = reader.ReadSingle();
    shadePos.y = reader.ReadSingle();

    float rotationX = reader.ReadSingle();
    float rotationY = reader.ReadSingle();
    float rotationZ = reader.ReadSingle();
    float rotationW = reader.ReadSingle();
    shadeRot = new Quaternion( rotationX, rotationY, rotationZ,rotationW);

    }
    }
    else
    {
    Debug.Log(“shade doesnt exist”);
    }
    }
    public void DeletePlayerData()
    {
    string path = Application.persistentDataPath + “/save.player.data”;
    if (File.Exists(path))
    {
    File.Delete(path);
    Debug.Log(“Player save data deleted.”);
    }
    }

    public void DeleteShadeData()
    {
    string path = Application.persistentDataPath + “/save.shade.data”;
    if (File.Exists(path))
    {
    File.Delete(path);
    Debug.Log(“Shade save data deleted.”);
    }
    }

    public void DeleteAllSaveData()
    {
    //DeleteBenchData();
    DeletePlayerData();
    DeleteShadeData();
    }
    }

    #15283
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class Shade : Enemy
    {
    [SerializeField] private float chaseDistance;
    [SerializeField] private float stunDuration;
    float timer;

    public static Shade Instance;

    private void Awake()
    {
    if (Instance != null && Instance != this)
    {
    Destroy(gameObject );
    }
    else
    {
    Instance = this;
    }
    SaveData.Instance.SaveShadeData();
    }
    protected override void Start()
    {
    base.Start();
    ChangeState(EnemyStates.Shade_Idle);
    }
    protected override void Update()
    {
    base.Update();
    if (!Player.Instance.pState.alive)
    {
    ChangeState(EnemyStates.Shade_Idle);
    }
    }
    protected override void UpdateEnemyStates()
    {
    float _dist = Vector2.Distance(transform.position, Player.Instance.transform.position);
    switch (GetCurrentEnemyState)
    {
    case EnemyStates.Shade_Idle:
    //rb.velocity = new Vector2(0, 0);
    if (_dist < chaseDistance)
    {
    ChangeState(EnemyStates.Shade_Chase);
    }
    break;
    case EnemyStates.Shade_Chase:
    rb.MovePosition(Vector2.MoveTowards(transform.position, Player.Instance.transform.position, Time.deltaTime * speed));
    FlipShade();
    if (_dist > chaseDistance)
    {
    ChangeState(EnemyStates.Shade_Idle);
    }
    break;
    case EnemyStates.Shade_Stunned:
    timer += Time.deltaTime;
    if (timer > stunDuration)
    {
    ChangeState(EnemyStates.Shade_Idle);
    timer = 0;
    }
    break;
    case EnemyStates.Shade_Death:
    Death(Random.Range(1, 3));
    break;
    }
    }

    public override void EnemyHit(float _dameDone, Vector2 _hitDirection, float _hitForce)
    {
    base.EnemyHit(_dameDone, _hitDirection, _hitForce);
    if (health > 0)
    {
    ChangeState(EnemyStates.Shade_Stunned);
    }
    else
    {
    ChangeState(EnemyStates.Shade_Death);
    }
    }

    protected override void Death(float _destroyTime)
    {
    rb.gravityScale = 12;
    base.Death(_destroyTime);
    }
    protected override void ChangeCurrentAnimation()
    {
    if(GetCurrentEnemyState == EnemyStates.Shade_Idle)
    {
    anim.Play(“Idle”);
    }
    anim.SetBool(“Walking”, GetCurrentEnemyState == EnemyStates.Shade_Chase);
    if (GetCurrentEnemyState == EnemyStates.Shade_Death)
    {
    Player.Instance.RestoreMana();
    SaveData.Instance.SavePlayerData();
    anim.SetTrigger(“Death”);
    Destroy(gameObject, 0.5f);
    }
    }
    protected override void Attack()
    {
    anim.SetTrigger(“Attacking”);
    Player.Instance.TakeDamage(damage);

    }
    void FlipShade()
    {
    sr.flipX = Player.Instance.transform.position.x < transform.position.x;
    }
    }

    #15284
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;

    public class GameManager : MonoBehaviour
    {
    public string transitionedFromScene;
    public Vector2 platFormingRespawnPoint;
    public Vector2 respawnPoint;
    [SerializeField] Bench bench;
    public static GameManager Instance { get; private set; }

    public GameObject shade;
    private void Awake()
    {
    SaveData.Instance.Initialize();
    if (Instance != null && Instance != this)
    {
    Destroy(gameObject);
    }
    else
    {
    Instance = this;
    }
    if(Player.Instance != null)
    {
    if (Player.Instance.halfMana)
    {
    SaveData.Instance.LoadShadeData();
    if(SaveData.Instance.sceneWithShade ==SceneManager.GetActiveScene().name || SaveData.Instance.sceneWithShade == “”)
    {
    Instantiate(shade, SaveData.Instance.shadePos, SaveData.Instance.shadeRot);
    }
    }
    }
    SaveScene();

    DontDestroyOnLoad(gameObject);
    bench = FindObjectOfType<Bench>();

    /* used for del all the temp save*/
    //SaveData.Instance.DeleteAllSaveData();
    }
    private void Update()
    {
    if (Input.GetKeyDown(KeyCode.O))
    {
    SaveData.Instance.SavePlayerData();
    }
    }

    public void SaveScene()
    {
    string currentSceneName = SceneManager.GetActiveScene().name;
    SaveData.Instance.sceneNames.Add(currentSceneName);
    }
    public void RespawnPlayer()
    {
    SaveData.Instance.LoadBench();
    if(SaveData.Instance.benchSceneName != null)// load the bench’s scene if exist
    {
    SceneManager.LoadScene(SaveData.Instance.benchSceneName);
    }
    if(SaveData.Instance.benchPos != null)// set the respawn to the bench’s pos
    {
    respawnPoint = SaveData.Instance.benchPos;
    }
    else
    {
    respawnPoint = platFormingRespawnPoint;
    }
    Player.Instance.transform.position = respawnPoint;

    StartCoroutine(UIManager.Instance.DeactiveDeathSceen());
    Player.Instance.Respawned();

    }
    }

    #15287
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Taking a quick look at your code, & testing the same code you used on my end, everything seems to work. I believe the issue lies within the Unity settings setup.

    So let’s take a look at two outstanding issues:

    1) The Shade cannot be hit or touched despite having a non-trigger box collider. [And I assume it has an attack animation which it does not perform]

    For this, I could only wager there’s something on with your Layer Collision Matrix. Although, on further thought it wouldn’t make sense considering the other enemies should be on the same layer.

    Regardless, could you show this to me. Edit > Project Settings > Physics2D > Layer Collision Matrix. And can you also show me what your player Layer and Tag is.

    2) The Shade cannot move, despite it’s states changing.

    The code works on my end, but this doesn’t make sense why it doesn’t on yours. Furthermore, we can also see the Shade states changing as it goes to idle and back to chasing when you are close enough to it. We can also see that it turns around to see you, so the rb.velocity line is functioning to allow FlipShade().

    I would like you to check this by moving the rb.velocity code in chase state to the Update() method. This will check if the Rigidbody2D can be manipulated or not, and if it can, which variable is the issue in moving the Shade.

        protected override void Update()
        {
            base.Update();
            if (!Player.Instance.pState.alive)
            {
                ChangeState(EnemyStates.Shade_Idle);
            }
    
            rb.MovePosition(Vector2.MoveTowards(transform.position, Player.Instance.transform.position, Time.deltaTime * speed));
        }
        protected override void UpdateEnemyStates()
        {
            float _dist = Vector2.Distance(transform.position, Player.Instance.transform.position);
            switch (GetCurrentEnemyState)
            {
                    ...
                case EnemyStates.Shade_Chase:
                    //rb.MovePosition(Vector2.MoveTowards(transform.position, Player.Instance.transform.position, Time.deltaTime * speed));
                    FlipShade();
                    if (_dist > chaseDistance)
                    {
                        ChangeState(EnemyStates.Shade_Idle);
                    }
                    break;
                    ...
            }
        }

    If the Shade is still not moving, then swap the target parameter Player.Instance.transform.position with new Vector2(100, 0). This should force the shade to run to the right until it reaches the coordinates. If this works, then something is wrong with the Player’s position.

    —-

    This is one confusing situation so we can only try to see what isn’t the problem.

    If none of these are consequential, i’d suggest you try removing and readding fresh, unchanged, RigidBody2D & Box Collider 2D components to the Shade to see if it does anything.

    By the way, the enemies respawning after you killed them is not a problem, it’s a feature/aspect that remains unchanged. They respawn because we did not code saved data for regular enemies in scenes, like in Hollow Knight, where enemies will respawn as you re-enter the room.

    #15289
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    I try removing and readding fresh, unchanged, RigidBody2D & Box Collider 2D components to the Shade and it work, my shade is working normaly. Thank you sm!
    and i have another question, when my player comeback from scene_2 and interact with bench but not respawn in bench (it work fine in scene_1)

    View post on imgur.com

    #15291
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Here’s my thought process on what is causing this issue:

    The only reason you would spawn from a transition portal is due to the GameManager’s string variable transitionedFromScene.

    This is used by SceneTransition.cs to find which scene you came from to put you at the right position if you enter a scene with multiple instances of SceneTransition.cs. This will function as it’s in the Start() function, meaning it will activate when you enter a scene as the game object is then created and called on start of the scene.

    The string variable transitionedFromScene is also not refreshed when respawning, so it will stay the same as the scene you came from. Thus, when you respawn, you will respawn at the bench but you reloaded the scene, causing the SceneTransition.cs to take the string from GameManager.cs and respawn you at the transition point.

    So what we will need to do is to clear the transitionedFromScene variable or replace it with the current scene.

    We should be able to do this using the RespawnPlayer() method, which is called on pressing the respawn button.

    At the top of the method, just put transitionedFromScene = SceneManager.GetActiveScene().name; to change the scene to the current scene everytime you choose to respawn.

    This should cause no issue as the transitionedFromScene will always be changed anyways before you leave a scene, upon interaction with a SceneTransition.cs

    #15299
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    im adding transitionedFromScene = SceneManager.GetActiveScene().name; at top of RespawnPlayer() funcion but it only work when player die and respawn in scene_1, player respawn at the transition of scene_1 when player die in scene_2

    #15300
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Do you have a bench in Scene 2 that you have interacted with? Because if not, you will always respawn at Scene 1’s Bench since it’s the only bench you have interacted with before.

    The bench is the save point and where you respawn*

    #15301
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    i dont have bench in scene_2, what i mean is when i die from scene_2, player respawn at the transittion of scene_1 but not the bench

    #15302
    Hoang Nguyen
    Participant
    #15303
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Ah sorry, I understand why. The reason this happens is because the code i gave you would take the current scene the player died in and set it as the string value. this doesn’t mean it will set the string value to your respawn.

    So let’s try this instead:

        public void RespawnPlayer()
        {
            transitionedFromScene = SceneManager.GetActiveScene().name;
    
            SaveData.Instance.LoadBench();
            if (SaveData.Instance.benchSceneName != null) //load the bench's scene if it exists.
            {
                transitionedFromScene = SaveData.Instance.benchSceneName;
                SceneManager.LoadScene(SaveData.Instance.benchSceneName);
            }
            ...
        }

    This should get the bench scene that you need to teleport to directly if it exists when respawning.

    #15323
    Hoang Nguyen
    Participant
    Helpful?
    Up
    0
    ::

    It works, thanks sm

Viewing 15 posts - 1 through 15 (of 15 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: