using System; using System.Collections; using System.Linq; using Assets.CoreScripts; using Hazel; using InnerNet; using PowerTools; using UnityEngine; // 带player的都是场景内角色的同步数据,不属于host独有 public class PlayerPhysics : InnerNetObject { public float TrueSpeed { get { return this.Speed * PlayerControl.GameOptions.PlayerSpeedMod; } } public float TrueGhostSpeed { get { return this.GhostSpeed * PlayerControl.GameOptions.PlayerSpeedMod; } } public float Speed = 4.5f; public float GhostSpeed = 3f; [HideInInspector] private Rigidbody2D body; [HideInInspector] private SpriteAnim Animator; [HideInInspector] private SpriteRenderer rend; [HideInInspector] private PlayerControl myPlayer; public AnimationClip RunAnim; public AnimationClip IdleAnim; public AnimationClip GhostIdleAnim; public AnimationClip EnterVentAnim; public AnimationClip ExitVentAnim; public AnimationClip SpawnAnim; public SkinLayer Skin; public void Awake() { this.body = base.GetComponent(); this.Animator = base.GetComponent(); this.rend = base.GetComponent(); this.myPlayer = base.GetComponent(); } private void FixedUpdate() { this.HandleAnimation(); if (base.AmOwner && this.myPlayer.CanMove && GameData.Instance) { DestroyableSingleton.Instance.WritePosition(this.myPlayer.PlayerId, base.transform.position); GameData.PlayerInfo data = this.myPlayer.Data; if (data == null) { return; } bool isDead = data.IsDead; this.body.velocity = DestroyableSingleton.Instance.joystick.Delta * (isDead ? this.TrueGhostSpeed : this.TrueSpeed); } } private void LateUpdate() { Vector3 position = base.transform.position; position.z = position.y / 1000f; base.transform.position = position; } public Vector3 Vec2ToPosition(Vector2 pos) { return new Vector3(pos.x, pos.y, pos.y / 1000f); } public void SetSkin(uint skinId) { this.Skin.SetSkin(skinId); if (this.Animator.IsPlaying(this.SpawnAnim)) { this.Skin.SetSpawn(this.Animator.Time); } } public void ResetAnim(bool stopCoroutines = true) { if (stopCoroutines) { this.myPlayer.StopAllCoroutines(); base.StopAllCoroutines(); } base.enabled = true; this.myPlayer.inVent = false; this.myPlayer.Visible = true; GameData.PlayerInfo data = this.myPlayer.Data; if (data == null || !data.IsDead) { this.Skin.SetIdle(); this.Animator.Play(this.IdleAnim, 1f); this.myPlayer.Visible = true; this.myPlayer.SetHatAlpha(1f); return; } this.Skin.SetGhost(); this.Animator.Play(this.GhostIdleAnim, 1f); this.myPlayer.SetHatAlpha(0.5f); } private void HandleAnimation() { if (this.Animator.IsPlaying(this.SpawnAnim)) { return; } if (!GameData.Instance) { return; } Vector2 velocity = this.body.velocity; AnimationClip currentAnimation = this.Animator.GetCurrentAnimation(); GameData.PlayerInfo data = this.myPlayer.Data; if (data == null) { return; } if (!data.IsDead) { if (velocity.sqrMagnitude >= 0.05f) { if (currentAnimation != this.RunAnim) { this.Animator.Play(this.RunAnim, 1f); this.Skin.SetRun(); } if (velocity.x < -0.01f) { this.rend.flipX = true; } else if (velocity.x > 0.01f) { this.rend.flipX = false; } } else if (currentAnimation == this.RunAnim || currentAnimation == this.SpawnAnim || !currentAnimation) { this.Skin.SetIdle(); this.Animator.Play(this.IdleAnim, 1f); this.myPlayer.SetHatAlpha(1f); } } else { this.Skin.SetGhost(); if (currentAnimation != this.GhostIdleAnim) { this.Animator.Play(this.GhostIdleAnim, 1f); this.myPlayer.SetHatAlpha(0.5f); } if (velocity.x < -0.01f) { this.rend.flipX = true; } else if (velocity.x > 0.01f) { this.rend.flipX = false; } } this.Skin.Flipped = this.rend.flipX; } public IEnumerator CoSpawnPlayer(LobbyBehaviour lobby) { if (!lobby) { yield break; } Vector3 spawnPos = this.Vec2ToPosition(lobby.SpawnPositions[(int)this.myPlayer.PlayerId % lobby.SpawnPositions.Length]); this.myPlayer.nameText.gameObject.SetActive(false); this.myPlayer.Collider.enabled = false; KillAnimation.SetMovement(this.myPlayer, false); bool amFlipped = this.myPlayer.PlayerId > 4; this.myPlayer.GetComponent().flipX = amFlipped; this.myPlayer.transform.position = spawnPos; SoundManager.Instance.PlaySound(lobby.SpawnSound, false, 1f).volume = 0.75f; this.Skin.SetSpawn(0f); this.Skin.Flipped = this.rend.flipX; yield return new WaitForAnimationFinish(this.Animator, this.SpawnAnim); base.transform.position = spawnPos + new Vector3(amFlipped ? -0.3f : 0.3f, -0.24f); this.ResetAnim(false); Vector2 b = (-spawnPos).normalized; yield return this.WalkPlayerTo((Vector2)spawnPos + b, 0.01f); this.myPlayer.Collider.enabled = true; KillAnimation.SetMovement(this.myPlayer, true); this.myPlayer.nameText.gameObject.SetActive(true); yield break; } public void ExitAllVents() { this.ResetAnim(true); this.myPlayer.moveable = true; Vent[] allVents = ShipStatus.Instance.AllVents; for (int i = 0; i < allVents.Length; i++) { allVents[i].SetButtons(false); } } private IEnumerator CoEnterVent(int id) { Vent vent = ShipStatus.Instance.AllVents.First((Vent v) => v.Id == id); this.myPlayer.moveable = false; yield return this.WalkPlayerTo(vent.transform.position, 0.01f); vent.EnterVent(); this.Skin.SetEnterVent(); yield return new WaitForAnimationFinish(this.Animator, this.EnterVentAnim); this.Skin.SetIdle(); this.Animator.Play(this.IdleAnim, 1f); this.myPlayer.Visible = false; this.myPlayer.inVent = true; yield break; } private IEnumerator CoExitVent(int id) { Vent vent = ShipStatus.Instance.AllVents.First((Vent v) => v.Id == id); this.myPlayer.Visible = true; this.myPlayer.inVent = false; vent.ExitVent(); this.Skin.SetExitVent(); yield return new WaitForAnimationFinish(this.Animator, this.ExitVentAnim); this.Skin.SetIdle(); this.Animator.Play(this.IdleAnim, 1f); this.myPlayer.moveable = true; yield break; } // 移动位置 public IEnumerator WalkPlayerTo(Vector2 worldPos, float tolerance = 0.01f) { worldPos -= base.GetComponent().offset; Rigidbody2D body = this.body; do { Vector2 vector2; Vector2 vector = vector2 = worldPos - (Vector2)base.transform.position; if (vector2.sqrMagnitude <= tolerance) { break; } float d = Mathf.Clamp(vector.magnitude * 2f, 0.01f, 1f); body.velocity = vector.normalized * this.Speed * d; yield return null; } while (body.velocity.magnitude >= 0.0001f); body.velocity = Vector2.zero; yield break; } // 无同步数据 public override bool Serialize(MessageWriter writer, bool initialState) { return false; } public override void Deserialize(MessageReader reader, bool initialState) { } public void RpcEnterVent(int id) { if (AmongUsClient.Instance.AmClient) { base.StartCoroutine(this.CoEnterVent(id)); } MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 0, SendOption.Reliable); messageWriter.WritePacked(id); messageWriter.EndMessage(); } public void RpcExitVent(int id) { if (AmongUsClient.Instance.AmClient) { base.StartCoroutine(this.CoExitVent(id)); } MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 1, SendOption.Reliable); messageWriter.WritePacked(id); messageWriter.EndMessage(); } private enum RpcCalls { EnterVent, ExitVent } public override void HandleRpc(byte callId, MessageReader reader) { if (callId == 0) { int id = reader.ReadPackedInt32(); base.StartCoroutine(this.CoEnterVent(id)); return; } if (callId != 1) { return; } int id2 = reader.ReadPackedInt32(); base.StartCoroutine(this.CoExitVent(id2)); } }