using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
public class AICharacterControl2 : UdonSharpBehaviour
{
public UnityEngine.AI.NavMeshAgent agent { get; private set; }
public ThirdPersonCharacter2 character { get; private set; }
public Animator animator { get { return GetComponent<Animator>(); } }
[SerializeField] public GameObject[] _target = new GameObject[9];
[SerializeField] public AudioSource _ashioto_sound;
[SerializeField, Range(0f, 2f)] float _nyaa_high = 2.00f;
[SerializeField, Range(0f, 2f)] float _nyaa_mid = 0.98f;
[SerializeField, Range(0f, 2f)] float _nyaa_low = 0.37f;
[SerializeField, Range(0f, 90f)] float _nyaa_angle = 30f;
[SerializeField, Range(0f, 2f)] float _nyaa_distance = 0.5f;
[SerializeField, Range(0f, 2f)] float _nyaa_hdistance = 0.2f;
[SerializeField, Range(1,99)] int _delay = 15;
[SerializeField, Range(0f, 5f)] float _agent_speed_item = 3.0f;
[SerializeField, Range(0f, 5f)] float _agent_speed_roomba = 2.05f;
[SerializeField, Range(0f, 2f)] float _roomba_stop = 0.5f;
[SerializeField, Range(0f, 2f)] float _roomba_run = 1.2f;
float _ikall = 1.00f;
float _ikall_default = 1.00f;
float _ikbody = 0.36f;
float _ikhead = 0.55f;
float _ikeye = 1.0f;
float _ikmotion = 1.0f;
int _selected = 0;
int _next_select = -1;
float _next_cooltime = 0f;
Vector3[] _dtargetpos_hists = new Vector3[100];
Vector3 _dtargetpos;
private void Start()
{
agent = GetComponentInChildren<UnityEngine.AI.NavMeshAgent>();
character = GetComponent<ThirdPersonCharacter2>();
agent.updateRotation = false;
agent.updatePosition = true;
}
private void Update()
{
bool skip = false;
if (_next_select == -1)
{
for (var i=0; i<_target.Length; i++)
{
if (_target[i] != null && _target[i].activeSelf)
{
skip = true;
if (_selected != i + 1)
{
_next_select = i + 1;
_next_cooltime = (i == (_target.Length-1)) ? 0.7f : 0.2f;
}
break;
}
}
if (_next_select == -1 && !skip) _selected = 0;
}
else
{
_next_cooltime -= Time.deltaTime;
if (_next_cooltime < 0f)
{
_selected = _next_select;
_next_select = -1;
fill_delay_target_buffer(_target[_selected-1].transform.position);
_ikall = _ikall_default;
}
else
{
_ikall -= Time.deltaTime / 0.15f;
if (_ikall < 0f)
{
_ikall = 0f;
_selected = 0;
}
}
}
if (_selected > 0)
{
agent.SetDestination(_dtargetpos);
if (agent.remainingDistance > agent.stoppingDistance)
{
character.Move2(agent.desiredVelocity, 0);
ashioto(true);
}
else
{
int nyaa = check_target_near();
character.Move2(Vector3.zero, nyaa);
ashioto(false);
}
}
else
{
agent.SetDestination(agent.transform.position);
character.Move2(Vector3.zero, 0);
ashioto(false);
}
if (_selected > 0)
{
if (_selected == 1)
{
agent.speed = _agent_speed_item;
agent.stoppingDistance = 1.0f;
}
else if (_selected == 9)
{
agent.speed = _agent_speed_roomba;
if (agent.stoppingDistance == _roomba_stop && agent.remainingDistance <= _roomba_stop + 0.2f)
{
agent.stoppingDistance = _roomba_run;
}
else if (agent.stoppingDistance == _roomba_run && agent.remainingDistance > _roomba_run - 0.2f)
{
agent.stoppingDistance = _roomba_stop;
}
else if (agent.stoppingDistance != _roomba_stop && agent.stoppingDistance != _roomba_run)
{
agent.stoppingDistance = _roomba_run;
}
}
else
{
agent.speed = _agent_speed_item;
agent.stoppingDistance = 0.65f;
}
}
}
private void FixedUpdate()
{
delay_target();
}
private void delay_target()
{
if (_selected > 0 && _target[_selected-1] != null)
{
_dtargetpos = _dtargetpos_hists[0];
for (var i = 1; i < _dtargetpos_hists.Length; i++)
{
_dtargetpos_hists[i - 1] = _dtargetpos_hists[i];
}
_dtargetpos_hists[_delay] = _target[_selected-1].transform.position;
if (_dtargetpos == null) _dtargetpos = _target[_selected-1].transform.position;
}
}
private void fill_delay_target_buffer(Vector3 pos)
{
for (var i = 0; i < _dtargetpos_hists.Length; i++)
{
_dtargetpos_hists[i] = pos;
}
}
private int check_target_near()
{
int nyaa = 0;
Vector3 eyeDir = this.transform.forward;
Vector3 playerPos = this.transform.position;
Vector3 targetPos = _target[_selected-1].transform.position;
float height = targetPos.y - playerPos.y;
eyeDir.y = 0;
playerPos.y = 0;
targetPos.y = 0;
float angle = Vector3.Angle((targetPos - playerPos).normalized, eyeDir);
float distance = Vector3.Distance(playerPos, targetPos);
if (distance >= 0.1f && distance < _nyaa_distance && angle < _nyaa_angle)
{
if (height > _nyaa_mid && height <= _nyaa_high) nyaa = 1;
else if (height > _nyaa_low && height <= _nyaa_mid) nyaa = 2;
}
else if (height > _nyaa_mid && height <= _nyaa_high && distance < _nyaa_hdistance)
{
nyaa = 1;
}
return nyaa;
}
private void ashioto(bool newstat)
{
if (_ashioto_sound != null)
{
if (newstat && !_ashioto_sound.isPlaying)
{
_ashioto_sound.pitch = (agent.speed / 3.0f);
_ashioto_sound.Play();
}
else if (!newstat && _ashioto_sound.isPlaying)
{
_ashioto_sound.Stop();
}
}
}
private void OnAnimatorIK(int layerIndex)
{
if (_selected > 0 && _target[_selected-1] != null && _selected > 0 && agent.remainingDistance < 3.0f)
{
animator.SetLookAtWeight(_ikall, _ikbody, _ikhead, _ikeye, _ikmotion);
animator.SetLookAtPosition(_dtargetpos);
}
}
}