修改副武连射bug
在PlayerShooting里
public class PlayerShooting : NetworkBehaviour
{
void Update()
{
if (!IsLocalPlayer) return;
//按k杀死自己
if (Input.GetKeyDown(KeyCode.K))
{
ShootServerRpc(transform.name, 10000);
}
...
}
//停止射击
public void StopShooting()
{
CancelInvoke("Shoot");
}
}
在Player里
public class Player : NetworkBehaviour
{
...
//具体的死亡逻辑,缴械
private void Die()
{
GetComponent<PlayerShooting>().StopShooting();
...
}
}
装弹
在PlayerWeapon里
public class PlayerWeapon
{
...
public int maxBullets = 30;//最大弹夹
public int bullets = 30;//现在的子弹数
public float reloadTime = 2f;
//隐藏起这一条变量
[HideInInspector]
public bool isReloading = false;
}
在WeaponManager里
public class WeaponManager : NetworkBehaviour
{
...
//重新装弹
public void Reload(PlayerWeapon playerWeapon)
{
//如果在装弹就不能装弹了
if (playerWeapon.isReloading) return;
playerWeapon.isReloading = true;
print("Reloading ...");
StartCoroutine(ReloadCoroutine(playerWeapon));
}
//延时函数, 协同函数
private IEnumerator ReloadCoroutine(PlayerWeapon playerWeapon)
{
yield return new WaitForSeconds(playerWeapon.reloadTime);
playerWeapon.bullets = playerWeapon.maxBullets;
playerWeapon.isReloading = false;
}
}
在PlayerShooting里
public class PlayerShooting : NetworkBehaviour
{
void Update()
{
...
//按k杀死自己
if (Input.GetKeyDown(KeyCode.K))
{
ShootServerRpc(transform.name, 10000);
}
// 手动换弹
if (Input.GetKeyDown(KeyCode.R))
{
weaponManager.Reload(currentWeapon);
//装弹中不能开枪要return?
return;
}
...
}
private void Shoot() {
if (currentWeapon.bullets <= 0 || currentWeapon.isReloading) return;
currentWeapon.bullets--;
print("Current bullets:" + currentWeapon.bullets);
if (currentWeapon.bullets <= 0) weaponManager.Reload(currentWeapon);
...
}
...
}
UI设计
在PlayerSetup里
public class PlayerSetup : NetworkBehaviour
{
public override void OnNetworkSpawn()
{
...
else
{
//当本地玩家进入网络时,开始绘制UI
PlayerUI.Singleton.setPlayer(GetComponent<Player>());
...
}
...
}
在PlayerUI里
public class PlayerUI : MonoBehaviour
{
//让PlayerUI做一个单例模式
public static PlayerUI Singleton;
//UI是本地玩家的UI
private Player player = null;
[SerializeField]
private TextMeshProUGUI bulletsText;
[SerializeField]
private GameObject bulletsUI;
private WeaponManager weaponManager;
private void Awake()
{
Singleton = this;
}
public void setPlayer(Player localPlayer)
{
player = localPlayer;
//将UI亮出来
bulletsUI.SetActive(true);
weaponManager = player.GetComponent<WeaponManager>();
}
void Update()
{
if (player == null) return;
var currentWeapon = weaponManager.GetCurrentWeapon();
if (currentWeapon.isReloading)
{
bulletsText.text = "Reloading ...";
}
else
{
bulletsText.text = currentWeapon.bullets + " / " + currentWeapon.maxBullets;
}
}
}
生命条
在PlayerUI里
public class PlayerUI : MonoBehaviour
{
...
//因为要缩进血条,所有用Transform
[SerializeField]
private Transform healthBarFill;
//而要显出或消失血条UI,所以是GameObject
[SerializeField]
private GameObject healthBarUI;
public void setPlayer(Player localPlayer)
{
...
//将UI亮出来
healthBarUI.SetActive(true);
}
void Update()
{
...
healthBarFill.localScale = new Vector3(player.GetHealth() / 100f, 1f, 1f);
}
}
敌方玩家的血条
给UI加上逻辑
在PlayerInfo里
public class PlayerInfo : MonoBehaviour
{
[SerializeField]
private TextMeshProUGUI playername;
[SerializeField]
private Transform playerHealth;
[SerializeField]
private GameObject playerHealthUI;
[SerializeField]
private Transform infoUI;
private Player player;
private void Start()
{
player = GetComponent<Player>();
}
void Update()
{
playername.text = transform.name;
playerHealth.localScale = new Vector3(player.GetHealth() / 100f, 1f, 1f);
//Info永远朝向camera
//将玩家的Camera设为主Camera,刚好是可以和界面的camera错开
var camera = Camera.main;
infoUI.transform.LookAt(infoUI.transform.position + camera.transform.rotation * Vector3.back, camera.transform.rotation * Vector3.up);
infoUI.Rotate(new Vector3(0f, 180f, 0f));
}
}