147 lines
3.7 KiB
C#
147 lines
3.7 KiB
C#
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;
|
|
}
|
|
}
|