using System.Collections; using System.Collections.Generic; using UnityEngine; using HQFPSWeapons; using Mirror; using System; using UnityEngine.Animations.Rigging; public class netPlayer : NetworkBehaviour { public List currentZombies; public Player player; public GameObject playerModelParent; public Animator anim; [SyncVar] public string pname; [SyncVar] public string latency; [Header("Health")] // public GameObject bloodPrefab; public GameObject BloodAttach; public GameObject[] BloodFX; public GameObject deadRagdoll; [HideInInspector] public int effectIdx; [Header("Weapons")] public tpsGunData[] guns; public meleeWeaponData[] melees; [SyncVar(hook = nameof(OnEquipmentChanged))] public int curGunIndex = -1; [SyncVar(hook = nameof(OnMeleeChanged))] public int meleeIndex = -1; public bool holdingRifle; public Rig leftArm; public Rig rightArm; public Transform weaponAim; public Transform leftHandTarget; public Transform headTarget; public Transform weaponHoldPose; public Transform weaponAimPose; [Header("WeaponAnimations")] public Animator weaponAnim; [Header("Aiming")] public Transform aimHeightTarget; public Transform aimHeightTDC; public Transform aimHeightMid; public Transform aimHeightBDC; [SyncVar(hook = nameof(OnAimChanged))] public bool aiming; public Rig headRig; public Rig chestRig; public bool showLocalChar; void Start() { if (!isLocalPlayer) { return; } //stuff only for local player netPlayerStats.localPlayer = this; Collider[] colliders = gameObject.GetComponentsInChildren(); Debug.Log($"Found ${colliders.Length} colliders and disabling them"); foreach (Collider collider in colliders) { collider.gameObject.layer = LayerMask.NameToLayer("netPlayer"); } player = FindObjectOfType(); pname = PlayerPrefs.GetString("username"); if (!isServer) { CmdUpdateName(pname); } else { RpcUpdateName(pname); } if (!showLocalChar) hideTpsCharacter(); // transform.GetChild(0).gameObject.SetActive(false); //prepare listeners player.EquippedItem.AddChangeListener((SaveableItem item) => { callChangeEquipment((item == null) ? "" : item.Name); }); player.UseContinuously.AddListener(() => { onUsedItem(); }); player.UseOnce.AddListener(() => { onUsedItem(); }); player.Aim.AddStartListener(() => { callToggleAim(true); }); player.Aim.AddStopListener(() => { callToggleAim(false); }); player.Run.AddStartListener(() => { callToggleAim(false); }); player.Death.AddListener(() => { callDeath(); }); player.Respawn.AddListener(() => { callRespawn(); }); callToggleAim(false); } #region initilaztionNetworkStuff void hideTpsCharacter() { foreach (SkinnedMeshRenderer renderer in playerModelParent.GetComponentsInChildren()) { renderer.enabled = false; } } [Command] void CmdUpdateName(string e) { pname = e; RpcUpdateName(e); } [ClientRpc] void RpcUpdateName(string e) { pname = e; } #endregion // Update is called once per frame bool jumping = false; float armWeights = 0; float bodyWeights = 0; //Update latency to server [Command] void CmdUpdateLatency(string value) { latency = value; } float t1 = 0; public float yAxis; void FixedUpdate() { //updatePlayerDirection (Regardless of isLocalPlayer) // headRig.weight = (anim.GetBool("running")) ? 0: 1; if (isLocalPlayer) {//Stuff only for local player if (t1 < 2) { t1 += Time.deltaTime; } else { Debug.Log(NetworkTime.rtt); CmdUpdateLatency((NetworkTime.rtt * 1000f).ToString("n0") + " ms"); t1 = 0; } yAxis = player.LookDirection.Val.y; float lookSmoothness = 0.1f; if (yAxis == 0) { aimHeightTarget.position = Vector3.Lerp(aimHeightTarget.position, aimHeightMid.position, lookSmoothness); } else if (yAxis > 0) { aimHeightTarget.position = Vector3.Lerp(aimHeightTarget.position, aimHeightMid.position + ((aimHeightTDC.position - aimHeightMid.position) * yAxis), lookSmoothness); } else if (yAxis < 0) { aimHeightTarget.position = Vector3.Lerp(aimHeightTarget.position, aimHeightMid.position + ((aimHeightBDC.position - aimHeightMid.position) * -yAxis), lookSmoothness); } anim.SetFloat("vX", Input.GetAxis("Horizontal")); anim.SetFloat("vY", Input.GetAxis("Vertical")); anim.SetBool("crouch", player.Crouch.Active); anim.SetBool("aiming", player.Aim.Active); // player.Aim.lis transform.position = player.transform.position; transform.rotation = player.transform.rotation; // Debug.Log($"walk status : {player.Walk.Active} , running status: {player.Run.Active}"); int animCode = 0; if (player.Run.Active) { animCode = 2; } else if (player.Walk.Active) { animCode = 1; } if (player.Jump.Active) { animCode = 3; } CallChangeAnim(animCode); if (curGunIndex >= 0) { // leftHandTarget.position = weaponAim.TransformPoint(-player.GetComponent().leftHandOffset) + (0.35f * leftHandTarget.right); } } else {//update for other peoples } if (curGunIndex >= 0) { // leftHandTarget.position = guns[curGunIndex].leftHandPosition.position; // leftHandTarget.rotation = guns[curGunIndex].leftHandPosition.rotation; headTarget.position = guns[curGunIndex].headTarget.position; if (aiming) { if (bodyWeights <= 1) { bodyWeights += 0.5f; headRig.weight = bodyWeights; chestRig.weight = bodyWeights; } weaponAim.position = Vector3.Lerp(weaponAim.position, guns[curGunIndex].aiming_rightHandPosition.position, 0.1f); weaponAim.rotation = Quaternion.Lerp(weaponAim.rotation, guns[curGunIndex].aiming_rightHandPosition.rotation, 0.1f); } else { if (bodyWeights >= 0) { bodyWeights -= 0.05f; //if (anim.GetBool("running")) { headRig.weight = bodyWeights; } headRig.weight = bodyWeights; chestRig.weight = bodyWeights; } weaponAim.position = Vector3.Lerp(weaponAim.position, guns[curGunIndex].holding_rightHandPosition.position, 0.1f); weaponAim.rotation = Quaternion.Lerp(weaponAim.rotation, guns[curGunIndex].holding_rightHandPosition.rotation, 0.1f); } } else { } } public void callToggleWeaponEquipment(bool value) { if (isServer) { toggleWeaponEquipment(value); RpcToggleWeaponEquipment(value); } else { CmdToggleWeaponEquipment(value); } } [Command] void CmdToggleWeaponEquipment(bool value) { toggleWeaponEquipment(value); RpcToggleWeaponEquipment(value); } [ClientRpc] void RpcToggleWeaponEquipment(bool value) { if (!isLocalPlayer) { return; } toggleWeaponEquipment(value); } public void toggleWeaponEquipment(bool value) { if (value) { leftArm.weight = 1; rightArm.weight = 1; callToggleAim(false); weaponAim.gameObject.SetActive(true); } else { //headRig.weight = 0; chestRig.weight = 0; leftArm.weight = 0; rightArm.weight = 0; weaponAim.gameObject.SetActive(false); } } public void callToggleAim(bool value) { if (isServer) { aiming = value; } else { CmdToggleAim(value); } } void OnAimChanged(bool oldAim, bool newAim) { if (newAim) { // headRig.weight = 1; chestRig.weight = 1; weaponAim.position = guns[curGunIndex].aiming_rightHandPosition.position; weaponAim.rotation = guns[curGunIndex].aiming_rightHandPosition.rotation; } else { Debug.Log(anim.GetBool("running")); // headRig.weight =(anim.GetBool("running")) ?0 : 1; chestRig.weight = (anim.GetBool("running")) ? 0 : 1; ; weaponAim.position = guns[curGunIndex].holding_rightHandPosition.position; weaponAim.rotation = guns[curGunIndex].holding_rightHandPosition.rotation; } } [Command] void CmdToggleAim(bool value) { aiming = value; } /* Animation Codes 0 Idle Breathing 1 Walking 2 Running 3 Jumping */ void CallChangeAnim(int code) { switch (code) { case 0: anim.SetBool("moving", false); anim.SetBool("running", false); anim.SetBool("jumping", false); break; case 1: anim.SetBool("moving", true); anim.SetBool("running", false); anim.SetBool("jumping", false); break; case 2: anim.SetBool("moving", true); anim.SetBool("running", true); anim.SetBool("jumping", false); break; case 3: anim.SetBool("jumping", true); break; } } ///Equipment change /// public void callChangeEquipment(string name) { //Get the id of weapon using name int gunId = -1; int _meleeIndex = -1; if (name == "") { callToggleWeaponEquipment(false); } else { ItemData itemData = null; ItemDatabase.Default.TryGetItem(name, out itemData); if (itemData != null) { gunId = getWeaponWithName(itemData.Name); } } if (gunId < 0) { //This means no weapon is there for that name, lets see on melees ItemData itemData = null; ItemDatabase.Default.TryGetItem(name, out itemData); if (itemData != null) { _meleeIndex = getMeleeWithName(itemData.Name); } } //UPDATE IT USING SYNCVAR if (isServer) { curGunIndex = gunId; meleeIndex = _meleeIndex; } else { SetCurGunId(gunId, _meleeIndex); } } [Command] void SetCurGunId(int gunId, int _meleeIndex) { curGunIndex = gunId; meleeIndex = _meleeIndex; } void OnEquipmentChanged(int oldIndex, int newIndex) { //Debug.Log("THE HOOK WORKS : " + newIndex); if (newIndex >= 0) { //not a melee so disable all melees foreach (tpsGunData gun in guns) { gun.gameObject.SetActive(false); } if (!isLocalPlayer) { guns[newIndex].gameObject.SetActive(true); } guns[newIndex].gameObject.SetActive(true); toggleWeaponEquipment(true); } else { toggleWeaponEquipment(false); } } void OnMeleeChanged(int oldIndex, int newIndex) { Debug.Log("Melee Hook Works"); foreach (meleeWeaponData melee in melees) { melee.gameObject.SetActive(false); } if (newIndex >= 0) { //some melee weeapon melees[newIndex].gameObject.SetActive(true); } else { //bare hands } } ///Shoot /// public void callShoot(Vector3 hitPoint, Vector3 hitNormals) { callToggleAim(true); aimHeightTarget.position = aimHeightTarget.position + new Vector3(0, 0.2f, 0); if (isServer) { broadcastShot(hitPoint, hitNormals); RpcBroadcastShot(hitPoint, hitNormals); } else { CmdBroadcastShot(hitPoint, hitNormals); } } [Command] void CmdBroadcastShot(Vector3 hitPoint, Vector3 hitNormals) { broadcastShot(hitPoint, hitNormals); RpcBroadcastShot(hitPoint, hitNormals); } [ClientRpc] void RpcBroadcastShot(Vector3 hitPoint, Vector3 hitNormals) { if (isServer) { return; } broadcastShot(hitPoint, hitNormals); } void broadcastShot(Vector3 hitPoint, Vector3 hitNormals) { // SurfaceEffects effect = (SurfaceEffects)Enum.Parse(typeof(SurfaceEffects), effectType); if (isLocalPlayer && !showLocalChar) { return; } SurfaceManager.SpawnEffect(0, SurfaceEffects.BulletHit, 1f, hitPoint, Quaternion.LookRotation(hitNormals)); //shootingEffects if (curGunIndex >= 0) { guns[curGunIndex].triggerMuzzleFlash(); } Debug.Log("Broadcasting shot"); // weaponAnim.CrossFade("shot",0.1f); } void onUsedItem() { if (!isLocalPlayer) { return; } if (curGunIndex < 0) { if (meleeIndex >= 0) { anim.CrossFadeInFixedTime(melees[meleeIndex].animName, 0.01f); } else { anim.CrossFadeInFixedTime("punch", 0.01f); } } } int getWeaponWithName(string name) { for (int i = 0; i < guns.Length; i++) { tpsGunData gunData = guns[i]; if (gunData.weaponName == name) { return i; } } return -1; } int getMeleeWithName(string name) { for (int i = 0; i < melees.Length; i++) { meleeWeaponData _melees = melees[i]; if (_melees.weaponName == name) { return i; } } return -1; } public void callDamage(float damage) { RpcDamage(damage); } [ClientRpc] public void RpcDamage(float damage) { if (isLocalPlayer) { player.GetComponentInChildren().Entity.ChangeHealth.Try(new HealthEventData(-damage)); Debug.Log("You are local player, damaging"); } else { Debug.Log("Nah you aint the local player, no damage for you sweetie"); } } [Command(requiresAuthority = false)] public void CmdDmg(float damage) { RpcDamage(damage); Debug.Log("RPC damage"); } public void hitboxDamage(HealthEventData damageData, shotType hitboxType) { float dmg = 0; switch (hitboxType) { case shotType.headshot: dmg = damageData.Delta * 5; break; case shotType.chestshot: dmg = damageData.Delta; break; case shotType.legshot: dmg = damageData.Delta / 2f; break; } dmg = -dmg; Debug.Log("Received damage from hitbox"); if (!isServer) { CmdDmg(dmg); Debug.Log("Command damage " + dmg.ToString()); } else { RpcDamage(dmg); } } public void callDeath() { Debug.Log("Calling Death"); if (isServer) { death(); RpcDeath(); } else { CmdDeath(); } } [Command] void CmdDeath() { death(); RpcDeath(); } [ClientRpc] void RpcDeath() { death(); } void death() { // if (isLocalPlayer) { return; } playerModelParent.gameObject.SetActive(false); Instantiate(deadRagdoll, transform.position, transform.rotation); } public void callRespawn() { if (isServer) { Respawn(); RpcRespawn(); } else { CmdRespawn(); } } [Command] void CmdRespawn() { Respawn(); RpcRespawn(); } [ClientRpc] void RpcRespawn() { Respawn(); } void Respawn() { if (isLocalPlayer) { return; } playerModelParent.gameObject.SetActive(true); } } public static class netPlayerStats { public static netPlayer localPlayer; }