313 lines
9.9 KiB
C#
313 lines
9.9 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
//using Mono.Cecil;
|
|
using PixelCrushers.DialogueSystem;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Beyond
|
|
{
|
|
public class DirectioIndicator : MonoBehaviour
|
|
{
|
|
// Start is called before the first frame update
|
|
private Renderer m_renderer;
|
|
private Material m_material;
|
|
public Color m_baseColor;
|
|
public float m_minDistance = 5f;
|
|
public float m_FadeDistance = 10f;
|
|
public float m_refreshDistance = 2f;
|
|
public float m_fadeTime = 1f;
|
|
public float m_timeOut = 5f;
|
|
// public bool m_showNewTarget = false;
|
|
private NavMeshPath m_lastPath;
|
|
private Vector3 m_lastPlayerPos;
|
|
private Quaternion m_lastDirection;
|
|
private Transform m_lastTarget;
|
|
private float m_lastDistance;
|
|
private float lerpRate = 1f;
|
|
private float m_timer;
|
|
private float m_refreshTimer = 0f;
|
|
[SerializeField]
|
|
private float m_distanceTh = 1f;
|
|
|
|
[SerializeField] private float m_distanceUpdateTime = 2;
|
|
public State m_state = State.IDLE;
|
|
public bool m_showAllTheTime = false;
|
|
|
|
public enum State
|
|
{
|
|
IDLE,
|
|
FADE_IN,
|
|
TARGET,
|
|
TARGET_TIMEOUT,
|
|
FADE_OUT,
|
|
}
|
|
|
|
void SetState(State s)
|
|
{
|
|
Debug.Log("State: " + s);
|
|
switch (s)
|
|
{
|
|
case State.IDLE:
|
|
m_lastDistance = Single.MaxValue;
|
|
if (!m_showAllTheTime)
|
|
m_renderer.enabled = false;
|
|
break;
|
|
case State.FADE_IN:
|
|
m_renderer.enabled = true;
|
|
m_material.color = Color.black;
|
|
break;
|
|
case State.FADE_OUT:
|
|
break;
|
|
case State.TARGET:
|
|
//m_lastDistance = Single.MaxValue;
|
|
if (m_showAllTheTime)
|
|
{
|
|
m_renderer.enabled = true;
|
|
}
|
|
break;
|
|
case State.TARGET_TIMEOUT:
|
|
break;
|
|
}
|
|
|
|
m_timer = 0f;
|
|
m_state = s;
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
m_renderer = GetComponentInChildren<Renderer>();
|
|
m_material = m_renderer.material;
|
|
m_lastPath = new NavMeshPath();
|
|
SetState(State.IDLE);
|
|
}
|
|
|
|
void GetTargetPoint(Vector3 target)
|
|
{
|
|
var playerTrans = Player.Instance.transform;
|
|
|
|
NavMesh.CalculatePath(playerTrans.position, target, NavMesh.AllAreas, m_lastPath);
|
|
|
|
}
|
|
|
|
bool ShouldRefreshPath(Transform target)
|
|
{
|
|
if (m_lastTarget != target)
|
|
return true;
|
|
Vector3 diff = m_lastPlayerPos - target.position;
|
|
diff.y = 0f;
|
|
m_refreshTimer += Time.deltaTime;
|
|
bool result = diff.magnitude > m_refreshDistance || m_refreshTimer > 1f;
|
|
if (result)
|
|
{
|
|
m_refreshTimer = 0f;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Vector3 GetDirection(Transform target, Vector3 playerPos, out float distance)
|
|
{
|
|
distance = Single.MaxValue;
|
|
Vector3 targetPos = target.position;
|
|
Vector3 diff = targetPos - playerPos;
|
|
diff.y = 0f;
|
|
distance = diff.magnitude;
|
|
diff /= distance;
|
|
if (distance < m_FadeDistance)
|
|
{
|
|
return diff;
|
|
}
|
|
|
|
if (ShouldRefreshPath(target))
|
|
{
|
|
if (NavMesh.CalculatePath(playerPos, targetPos, NavMesh.AllAreas, m_lastPath))
|
|
{
|
|
m_lastPlayerPos = playerPos;
|
|
}
|
|
else
|
|
{
|
|
return diff;
|
|
}
|
|
}
|
|
|
|
if (m_lastPath == null || m_lastPath.corners.Length == 0)
|
|
{
|
|
return diff;
|
|
}
|
|
|
|
float pointDist = 0f;
|
|
|
|
|
|
for (int id=0; id<m_lastPath.corners.Length; id++)
|
|
{
|
|
diff = m_lastPath.corners[id] - playerPos;
|
|
diff.y = 0f;
|
|
pointDist = diff.magnitude;
|
|
diff /= pointDist;
|
|
if (pointDist > m_minDistance)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return diff;
|
|
}
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (Compass.Instance == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var playerTrans = Player.Instance.transform;
|
|
var target = Compass.Instance.FindClosestIndicator(playerTrans);
|
|
float distance = Single.MaxValue;
|
|
|
|
if (target != null)
|
|
{
|
|
var direction = GetDirection(target, playerTrans.position, out distance);
|
|
if (distance > m_minDistance)
|
|
{
|
|
var dir = Quaternion.LookRotation(direction.normalized);
|
|
transform.rotation = Quaternion.Slerp(m_lastDirection, dir,
|
|
1f - MathF.Pow(2, -Time.deltaTime * lerpRate));
|
|
m_lastDirection = transform.rotation;
|
|
}
|
|
|
|
if (target != m_lastTarget)
|
|
m_lastDistance = distance;
|
|
}
|
|
|
|
|
|
float a = 0f;
|
|
switch (m_state)
|
|
{
|
|
case State.IDLE:
|
|
if (target != null)
|
|
{
|
|
if (m_lastDistance == Single.MaxValue)
|
|
m_lastDistance = distance;
|
|
if (GameStateManager.Instance.CurrentState == GameStateManager.State.COMBAT)
|
|
return;
|
|
|
|
if (m_showAllTheTime)
|
|
{
|
|
SetState(State.TARGET);
|
|
break;
|
|
}
|
|
|
|
if (distance > m_FadeDistance && distance > m_lastDistance + m_distanceTh)
|
|
{
|
|
SetState(State.FADE_IN);
|
|
}
|
|
else if (m_timer > m_distanceUpdateTime)
|
|
{
|
|
m_timer = 0f;
|
|
m_lastDistance = distance;
|
|
}
|
|
}
|
|
break;
|
|
case State.FADE_IN:
|
|
a = (m_timer / m_fadeTime);
|
|
if (a < 1)
|
|
{
|
|
m_material.color = m_baseColor * a;
|
|
}
|
|
else
|
|
{
|
|
m_material.color = m_baseColor;
|
|
SetState(State.TARGET);
|
|
}
|
|
|
|
break;
|
|
case State.TARGET:
|
|
if (m_showAllTheTime)
|
|
break;
|
|
|
|
if (target != null)
|
|
{
|
|
if (distance < m_FadeDistance || (m_timer > m_timeOut && distance + m_distanceTh < m_lastDistance))
|
|
{
|
|
SetState(State.FADE_OUT);
|
|
m_lastDistance = distance;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetState(State.FADE_OUT);
|
|
|
|
}
|
|
|
|
break;
|
|
case State.FADE_OUT:
|
|
a = (m_timer / m_fadeTime);
|
|
if (a < 1)
|
|
{
|
|
m_material.color = m_baseColor * (1-a);
|
|
}
|
|
else
|
|
{
|
|
m_material.color = Color.black;
|
|
SetState(State.TARGET_TIMEOUT);
|
|
/*
|
|
if (!m_showNewTarget)
|
|
{
|
|
m_lastDistance = distance;
|
|
}
|
|
*/
|
|
}
|
|
break;
|
|
case State.TARGET_TIMEOUT:
|
|
if (m_timer > m_timeOut)
|
|
{
|
|
/*
|
|
if (distance > m_lastDistance + m_distanceTh)
|
|
{
|
|
SetState(State.FADE_IN);
|
|
}
|
|
else
|
|
{
|
|
m_timer = 0f;
|
|
m_lastDistance = distance;
|
|
}
|
|
*/
|
|
SetState(State.IDLE);
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
m_timer += Time.deltaTime;
|
|
m_lastTarget = target;
|
|
}
|
|
|
|
private void OnDrawGizmos()
|
|
{
|
|
if (Player.Instance == null)
|
|
return;
|
|
var playerTrans = Player.Instance.transform;
|
|
var target = Compass.Instance.FindClosestIndicator(playerTrans);
|
|
float distance = 0f;
|
|
if (target != null)
|
|
{
|
|
var direction = GetDirection(target, playerTrans.position, out distance);
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawRay(playerTrans.position, direction*distance);
|
|
|
|
Gizmos.color = Color.blue;
|
|
|
|
if (m_lastPath != null && m_lastPath.corners.Length > 1)
|
|
{
|
|
for (int id = 0; id < m_lastPath.corners.Length-1; id++)
|
|
{
|
|
Gizmos.DrawLine(m_lastPath.corners[id], m_lastPath.corners[id+1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
} |