154 lines
3.0 KiB
C#
154 lines
3.0 KiB
C#
|
namespace TPSBR
|
||
|
{
|
||
|
using System;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Animations;
|
||
|
using UnityEngine.Playables;
|
||
|
using Fusion.Addons.KCC;
|
||
|
using Fusion.Addons.AnimationController;
|
||
|
|
||
|
using AnimationState = Fusion.Addons.AnimationController.AnimationState;
|
||
|
|
||
|
public sealed class LookState : AnimationState
|
||
|
{
|
||
|
// PRIVATE MEMBERS
|
||
|
|
||
|
[SerializeField]
|
||
|
private LookSet[] _sets;
|
||
|
|
||
|
private KCC _kcc;
|
||
|
private Weapons _weapons;
|
||
|
private Jetpack _jetpack;
|
||
|
private AnimationMixerPlayable _mixer;
|
||
|
private int _inputs;
|
||
|
|
||
|
// PUBLIC METHODS
|
||
|
|
||
|
public bool ShouldActivate()
|
||
|
{
|
||
|
return GetSetID() >= 0;
|
||
|
}
|
||
|
|
||
|
// AnimationLayer INTERFACE
|
||
|
|
||
|
protected override void CreatePlayable()
|
||
|
{
|
||
|
_mixer = AnimationMixerPlayable.Create(Controller.Graph, 0);
|
||
|
_inputs = 0;
|
||
|
|
||
|
for (int j = 0, setCount = _sets.Length; j < setCount; ++j)
|
||
|
{
|
||
|
LookSet set = _sets[j];
|
||
|
|
||
|
for (int i = 0, nodeCount = set.Nodes.Length; i < nodeCount; ++i)
|
||
|
{
|
||
|
ClipNode node = set.Nodes[i];
|
||
|
node.CreatePlayable(Controller.Graph);
|
||
|
|
||
|
_mixer.AddInput(node.PlayableClip, 0);
|
||
|
++_inputs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
AddPlayable(_mixer, 0);
|
||
|
}
|
||
|
|
||
|
protected override void OnInitialize()
|
||
|
{
|
||
|
_kcc = Controller.GetComponentNoAlloc<KCC>();
|
||
|
_weapons = Controller.GetComponentNoAlloc<Weapons>();
|
||
|
_jetpack = Controller.GetComponentNoAlloc<Jetpack>();
|
||
|
}
|
||
|
|
||
|
protected override void OnDespawned()
|
||
|
{
|
||
|
if (_mixer.IsValid() == true)
|
||
|
{
|
||
|
_mixer.Destroy();
|
||
|
}
|
||
|
|
||
|
for (int j = 0, setCount = _sets.Length; j < setCount; ++j)
|
||
|
{
|
||
|
LookSet set = _sets[j];
|
||
|
|
||
|
for (int i = 0, nodeCount = set.Nodes.Length; i < nodeCount; ++i)
|
||
|
{
|
||
|
ClipNode node = set.Nodes[i];
|
||
|
node.DestroyPlayable();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void OnFixedUpdate()
|
||
|
{
|
||
|
Refresh(_kcc.FixedData.LookPitch);
|
||
|
}
|
||
|
|
||
|
protected override void OnInterpolate()
|
||
|
{
|
||
|
Refresh(_kcc.RenderData.LookPitch);
|
||
|
}
|
||
|
|
||
|
// PRIVATE METHODS
|
||
|
|
||
|
private void Refresh(float pitch)
|
||
|
{
|
||
|
int setID = GetSetID();
|
||
|
if (setID < 0)
|
||
|
return;
|
||
|
|
||
|
for (int i = 0, count = _inputs; i < count; ++i)
|
||
|
{
|
||
|
_mixer.SetInputWeight(i, 0.0f);
|
||
|
}
|
||
|
|
||
|
int node = 0;
|
||
|
float angle = (pitch + 720.0f + _sets[setID].Offset) % 360.0f;
|
||
|
|
||
|
if (angle > 180.0f)
|
||
|
{
|
||
|
node = 1;
|
||
|
angle = 360.0f - angle;
|
||
|
}
|
||
|
|
||
|
angle = Mathf.Clamp(Mathf.Pow(angle, _sets[setID].Power), 0.0f, 90.0f);
|
||
|
|
||
|
if (angle.IsNaN() == true)
|
||
|
{
|
||
|
angle = 0.0f;
|
||
|
}
|
||
|
|
||
|
int clipIndex = setID * 2 + node;
|
||
|
|
||
|
_sets[setID].Nodes[node].PlayableClip.SetTime(angle / 90.0f);
|
||
|
|
||
|
_mixer.SetInputWeight(clipIndex, 1.0f);
|
||
|
}
|
||
|
|
||
|
private int GetSetID()
|
||
|
{
|
||
|
if (_jetpack.IsActive == true)
|
||
|
return -1;
|
||
|
|
||
|
int currentWeaponSlot = _weapons.CurrentWeaponSlot;
|
||
|
if (currentWeaponSlot > 2)
|
||
|
{
|
||
|
currentWeaponSlot = 1; // For grenades we use pistol set
|
||
|
}
|
||
|
|
||
|
if (currentWeaponSlot < 0)
|
||
|
return -1;
|
||
|
|
||
|
return currentWeaponSlot;
|
||
|
}
|
||
|
|
||
|
[Serializable]
|
||
|
private sealed class LookSet
|
||
|
{
|
||
|
public ClipNode[] Nodes;
|
||
|
public float Offset;
|
||
|
public float Power = 1.0f;
|
||
|
}
|
||
|
}
|
||
|
}
|