/// <summary> /// adjusts fire position to prevent remote player from shooting /// itself under lagged conditions /// </summary> protected virtual void AdjustForBodyCollider(FireEvent fireEvent) { if (m_BulletAdjusterTransform == null) { return; } if (fireEvent == null) { return; } vp_WeaponShooter shooter = GetShooterOfFireEvent(fireEvent); if (shooter == null) { return; } m_BulletAdjusterTransform.rotation = fireEvent.Rotation; shooter.SetSpread(fireEvent.Seed, m_BulletAdjusterTransform); // TODO: range should be ~ distance moved since last frame (?) //if (Physics.Linecast(fireEvent.Position, fireEvent.Position + (bulletAdjusterTransform.forward * 1000), out bulletAdjusterHit, vp_Layer.Mask.BulletBlockers)) retry: if (Physics.Raycast(fireEvent.Position, m_BulletAdjusterTransform.forward, out m_BulletAdjusterHit, 1000, vp_Layer.Mask.IgnoreWalkThru)) { if (m_BulletAdjusterHit.collider.transform.root == Transform.root /*m_BulletAdjusterHitcollider == BodyTransform.collider*/) // TODO: cache body collider { //vp_MPDebug.Log("Hit myself @ " + Time.time); fireEvent.Position = m_BulletAdjusterHit.point + (m_BulletAdjusterTransform.forward * 0.01f); goto retry; } } }
/// <summary> /// scans this player hierarchy for shooter components, hooks up their /// fire seed, position and rotation with data from the 'FireEvents' /// array and puts them in a dictionary for validation later /// </summary> public override void InitShooters() { vp_WeaponShooter[] shooters = gameObject.GetComponentsInChildren <vp_WeaponShooter>(true) as vp_WeaponShooter[]; m_Shooters.Clear(); foreach (vp_WeaponShooter f in shooters) { vp_WeaponShooter shooter = f; // need to cache shooter or delegate will only be set with values of last weapon if (m_Shooters.ContainsKey(WeaponHandler.GetWeaponIndex(shooter.Weapon))) { continue; } //Debug.Log("setting 'GetFireRotation' for: " + f); shooter.GetFireSeed = delegate { return(FireEvents[0].Seed); }; shooter.GetFirePosition = delegate { return(FireEvents[0].Position); }; shooter.GetFireRotation = delegate { return(FireEvents[0].Rotation); }; m_Shooters.Add(WeaponHandler.GetWeaponIndex(shooter.Weapon), shooter); } }
/// <summary> /// scans this player hierarchy for shooter components, hooks up /// their fire seed with the 'Shots' variable, and their firing /// delegate with a network (RPC) call. finally, puts them in a /// dictionary for validation later /// </summary> public override void InitShooters() { vp_WeaponShooter[] shooters = gameObject.GetComponentsInChildren <vp_WeaponShooter>(true) as vp_WeaponShooter[]; m_Shooters.Clear(); foreach (vp_WeaponShooter f in shooters) { vp_WeaponShooter shooter = f; // need to cache shooter or delegate will only be set with values of last weapon if (m_Shooters.ContainsKey(WeaponHandler.GetWeaponIndex(shooter.Weapon))) { continue; } shooter.GetFireSeed = delegate { return(Shots); }; shooter.m_SendFireEventToNetworkFunc = delegate() { if (!PhotonNetwork.offlineMode) { photonView.RPC("FireWeapon", PhotonTargets.All, WeaponHandler.GetWeaponIndex(shooter.Weapon), shooter.GetFirePosition(), shooter.GetFireRotation()); } //vp_MPDebug.Log("sending RPC: " + sho.gameObject.name + ", " + sho.GetFirePosition() + ", " + sho.GetFireRotation()); }; m_Shooters.Add(WeaponHandler.GetWeaponIndex(shooter.Weapon), shooter); } //Debug.Log("Stored " + m_Shooters.Count + " local weapons."); }
/// <summary> /// hooks up the object to the inspector target /// </summary> public virtual void OnEnable() { m_Component = (vp_WeaponShooter)target; if (m_Persister == null) m_Persister = new vp_ComponentPersister(); m_Persister.Component = m_Component; m_Persister.IsActive = true; if (m_Component.DefaultState == null) m_Component.RefreshDefaultState(); }
/// <summary> /// hooks up the object to the inspector target /// </summary> public virtual void OnEnable() { m_Component = (vp_WeaponShooter)target; if (m_Persister == null) { m_Persister = new vp_ComponentPersister(); } m_Persister.Component = m_Component; m_Persister.IsActive = true; if (m_Component.DefaultState == null) { m_Component.RefreshDefaultState(); } }
/// <summary> /// sets up simplified 3rd person weapon child objects based on the /// current first person weapons under the vp_FPCamera component /// </summary> public static void ConvertWeaponsTo3rdPerson(GameObject player) { int weaponsConverted = 0; Transform oldWeaponGroup = null; // typically the 'FPSCamera' object GameObject newWeaponGroup = new GameObject("Weapons"); foreach (vp_FPWeapon fpWeapon in player.transform.GetComponentsInChildren <vp_FPWeapon>()) { // detect old weapons parent and put the new one alongside it in hierarchy if (oldWeaponGroup == null) { oldWeaponGroup = fpWeapon.transform.parent; newWeaponGroup.transform.parent = oldWeaponGroup.parent; newWeaponGroup.transform.localPosition = Vector3.zero; newWeaponGroup.transform.localEulerAngles = Vector3.zero; newWeaponGroup.transform.localScale = Vector3.one; } // create a new gameobject for each weapon. this way we get rid of // any custom components that may be hard for the editor code to // delete because of component interdependencies GameObject newWeaponGO = new GameObject(fpWeapon.gameObject.name); newWeaponGO.transform.parent = newWeaponGroup.transform; // NOTE: position of this transform is irrelevant because a 3rd // person vp_Weapon is just an invisible, locigal entity, represented // by its '3rdPersonWeapon' gameobject reference in the 3d world. // still, let's place the weapons in a fairly neutral position for // clarity: say, the center of the player facing forwards newWeaponGO.transform.localPosition = Vector3.up; newWeaponGO.transform.localEulerAngles = Vector3.zero; newWeaponGO.transform.localScale = Vector3.one; // convert vp_FPWeapon component into a vp_Weapon component on the new gameobject vp_Weapon tdpWeapon = newWeaponGO.AddComponent <vp_Weapon>(); vp_EditorUtility.CopyValuesFromDerivedComponent(fpWeapon, tdpWeapon, true, true, null); if (m_CopyStates && !string.IsNullOrEmpty(m_StatePath)) { vp_EditorUtility.GenerateStatesAndPresetsFromDerivedComponent(fpWeapon, tdpWeapon, m_StatePath); } // FP shooters (used for projectile weapons) vp_FPWeaponShooter fpShooter = fpWeapon.GetComponent <vp_FPWeaponShooter>(); if (fpShooter != null) { vp_WeaponShooter tdpFpShooter = newWeaponGO.AddComponent <vp_WeaponShooter>(); vp_EditorUtility.CopyValuesFromDerivedComponent(fpShooter, tdpFpShooter, true, true, null); if (m_CopyStates && !string.IsNullOrEmpty(m_StatePath)) { vp_EditorUtility.GenerateStatesAndPresetsFromDerivedComponent(fpShooter, tdpFpShooter, m_StatePath); } } // regular shooters (used for melee weapons) vp_WeaponShooter shooter = fpWeapon.GetComponent <vp_WeaponShooter>(); if ((shooter != null) && !(shooter is vp_FPWeaponShooter)) { vp_WeaponShooter tdpShooter = newWeaponGO.AddComponent <vp_WeaponShooter>(); vp_EditorUtility.CopyValuesFromDerivedComponent(shooter, tdpShooter, true, true, null); if (m_CopyStates && !string.IsNullOrEmpty(m_StatePath)) { vp_EditorUtility.GenerateStatesAndPresetsFromDerivedComponent(shooter, tdpShooter, m_StatePath); } } // reloaders vp_FPWeaponReloader fpReloader = fpWeapon.GetComponent <vp_FPWeaponReloader>(); if (fpReloader != null) { vp_WeaponReloader tdpReloader = newWeaponGO.AddComponent <vp_WeaponReloader>(); vp_EditorUtility.CopyValuesFromDerivedComponent(fpReloader, tdpReloader, true, true, null); // reloader is no vp_Component so don't generate states & presets } // copy weapon thrower vp_FPWeaponThrower fpThrower = fpWeapon.GetComponent <vp_FPWeaponThrower>(); if (fpThrower != null) { vp_WeaponThrower tdpThrower = newWeaponGO.AddComponent <vp_WeaponThrower>(); vp_EditorUtility.CopyValuesFromDerivedComponent(fpWeapon, tdpThrower, true, true, null); } // copy item identifier vp_ItemIdentifier identifier = fpWeapon.GetComponent <vp_ItemIdentifier>(); if (identifier != null) { vp_ItemIdentifier newIdentifier = newWeaponGO.AddComponent <vp_ItemIdentifier>(); newIdentifier.Type = identifier.Type; } weaponsConverted++; } // delete the old weapon group (FPSCamera object) if (oldWeaponGroup != null) { GameObject.DestroyImmediate(oldWeaponGroup.gameObject); } EditorUtility.DisplayDialog( weaponsConverted + " weapons converted", (weaponsConverted > 0 ? ( ((m_CopyStates && !string.IsNullOrEmpty(m_StatePath)) ? ("Any states with compatible values have been retained and their presets can be found in the folder:\n\t\t'" + m_StatePath + "'") : "") ) : ""), "OK"); }