147 lines
3.7 KiB
C#
Raw Normal View History

2025-09-06 17:17:39 +04:00
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<NavMeshAgent>();
n.animator = n.gameObject.GetComponent<Animator>();
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;
}
}