首页 > 解决方案 > 尽管记录了碰撞并保存了检查点,但 Unity3D 玩家在子弹预制击中他后并没有死亡

问题描述

我的游戏是 Unity3D 游戏。玩家身上有 2 个碰撞器,一个角色控制器和一个角色控制器(回想起来应该是刚体)。游戏中有敌人将子弹作为弹丸射向玩家。出于某种原因,当子弹击中玩家时,玩家并没有“死亡”。它被设置为让玩家在被子弹击中时传送到 GameManager 脚本中保存的检查点,或者更确切地说,子弹在击中玩家后将玩家传送到 GameManager 脚本中保存的最后一个检查点。这是子弹脚本中的函数:

private void OnTriggerEnter(Collider smash)
{
    if (smash.gameObject.tag == "Environment")
    {
        // this prevents the bullet from going through
        // walls.
        Destroy(gameObject);
    }
    else if (smash.gameObject.tag == "Player")
    {
        // teleporting the player back to the latest 
        // checkpoint.
        smash.gameObject.transform.position = GameManager.instance.checkpoint;

        // just to check whether the collision
        // is detecting or not.
        Debug.Log("Player died");

        // just for aesthetic. Probably no purpose in
        // bothering to destroy this gameObject.
        Destroy(gameObject);
        }
    }

根据 Unity 的控制台,从 GameManager 中获取正确的检查点不是问题。那么问题是什么?还有其他需要分享的功能吗?肯定会检测到碰撞,因为每当他被子弹击中时,“玩家死亡”总是出现在我的日志中。

标签: c#unity3d

解决方案


出于碰撞目的,首先添加以下公共变量来存储玩家的健康:

public int health = 10;

要处理冲突,请添加以下方法:

void collidedWithEnemy(Enemy enemy) {
  // Enemy attack code
  if(health <= 0) {
    // Todo 
  }
}

void OnCollisionEnter (Collision col) {
    Enemy enemy = col.collider.gameObject.GetComponent<Enemy>();
    collidedWithEnemy(enemy);
}

最后对于检查点加载系统,首先使用二进制格式保存有关其位置的播放器数据,如下所示:

public int level;
public int health;
public float[] position;

public playerData (PlayerCollision player)
(

    level = player.level;
    health = player.health;

    position = new float[3];

    position[0] = player.transform.position.x;
    position[1] = player.transform.position.y;
    position[2] = player.transform.position.z;

)

要加载和启动 ckeckpoint 系统系统,请使用以下命令:

using System.Runtime.Serilization.Formatters.Binary;

    public static class CheckpointSystem
    {
        BinaryFormatter formatter = new BinaryFormatter();

        string path = Application.persistentDataPath + "/player.fun";
        FileStream stream = new Filestream(path, FileMode.Create);

        playerData data = new playerData(player);

        formatter.Serialize(stream, data);
        stream.Close();
           
    }

    public static playerData LoadPlayer()
    {
        string path = Application.persistentDataPath + "/player.fun";

        if(File.Exist(path))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream stream = new Filestream(path, FileMode.Open);

            playerData data = formatter.Deserlize(stream) as playerData;
            stream.Close();

            return data;
        }

        else
        {
            Debug.LogError("saved file not found in " + path);
            return null;
        
        }
        
    }

谢谢


推荐阅读