using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.AI; using UnityEngine.VFX; using DG.Tweening; public class LocalNPC { public NPC n; //get nav mesh agent private NavMeshAgent agent; Vector2 smoothDeltaPosition = Vector2.zero; Vector2 velocity = Vector2.zero; private float lastBiteTime; private float lastUpdateTime; private bool attacking = false; public LocalNPC(NPC n) { this.n = n; } public void Start() { //assign nav mesh agent agent = n.gameObject.AddComponent(); n.animator = n.gameObject.GetComponent(); agent.updatePosition = false; lastBiteTime = Time.time; n.forcePositionUpdate = false; //agent.speed = 4.0f; agent.radius = 1.0f; lastUpdateTime = Time.time; agent.obstacleAvoidanceType = ObstacleAvoidanceType.LowQualityObstacleAvoidance; } public void FixedUpdate() { if (Time.time - lastUpdateTime > 0.5f) { agent.destination = Player.Instance.gameObject.transform.position; lastUpdateTime = Time.time; } if (this.attacking) // don't move if attacking { return; } if (n.isDead) { agent.updateRotation = false; agent.updatePosition = false; agent.isStopped = true; return; } if (Player.Instance.IsDead()) { n.animator.SetFloat("Speed", 0.0f); agent.speed = 0.0f; agent.angularSpeed = 0.0f; return; } //get the distance from the player float distance = Vector3.Distance(Player.Instance.transform.position, n.gameObject.transform.position); if (distance > 2.0f) { Vector3 worldDeltaPosition = agent.nextPosition - n.transform.position; // Map 'worldDeltaPosition' to local space float dx = Vector3.Dot(n.transform.right, worldDeltaPosition); float dy = Vector3.Dot(n.transform.forward, worldDeltaPosition); Vector2 deltaPosition = new Vector2(dx, dy); // Low-pass filter the deltaMove float smooth = Mathf.Min(1.0f, Time.deltaTime / 0.15f); smoothDeltaPosition = Vector2.Lerp(smoothDeltaPosition, deltaPosition, smooth); // Update velocity if time advances if (Time.deltaTime > 1e-5f) velocity = smoothDeltaPosition / Time.deltaTime; bool shouldMove = velocity.magnitude > 0.5f && agent.remainingDistance > agent.radius; n.transform.position = agent.nextPosition; n.animator.SetFloat("Speed", velocity.magnitude); //Debug.Log(velocity.magnitude); } else { n.animator.SetFloat("Speed", 0.0f); if (Time.time - lastBiteTime > 4.0f) { n.animator.Play("Kick_Attack"); n.StartCoroutine(bitePlayer()); n.transform.position = agent.nextPosition; lastBiteTime = Time.time; } } } public IEnumerator bitePlayer() { this.attacking = true; Player.Instance.speedMultiplier = 0.15f; yield return new WaitForSeconds(1.2f); if (!n.isDead) { if (Vector3.Distance(agent.gameObject.transform.position, Player.Instance.transform.position) < 3f) { PacketManager.sendNPCAttack(n.type); } } this.attacking = false; Player.Instance.speedMultiplier = 1.0f; yield return null; } public void setMoveSpeed(float moveSpeed) { agent.speed = moveSpeed; } }