riversong code showcase
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
using System.Collections.Generic;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.VFX;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
[RequireComponent(typeof(Animator))]
|
||||
public class BuildingPlacementAnimation : MonoBehaviour, IAnimationClipSource
|
||||
{
|
||||
[SerializeField]
|
||||
private AnimationClip _animationClip;
|
||||
|
||||
[SerializeField]
|
||||
private float _playbackSpeed = 1;
|
||||
|
||||
[SerializeField]
|
||||
private Vector3 _positionLerpWeights = new(1.5f, 1, 1.5f);
|
||||
|
||||
[SerializeField]
|
||||
private float _rotationLerpWeight = 1.5f;
|
||||
|
||||
[SerializeField]
|
||||
private VisualEffect _impactVfxPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private float _impactIntensityDecay = 0.75f;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private float _animationProgress;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private float _bounce;
|
||||
|
||||
private PlayableGraph _playableGraph;
|
||||
|
||||
private AnimationClipPlayable _playableClip;
|
||||
|
||||
private BuildingDefinition _building;
|
||||
|
||||
private Vector3 _startPosition;
|
||||
|
||||
private Vector3 _finalPosition;
|
||||
|
||||
private Quaternion _finalRotation;
|
||||
|
||||
public bool IsPlaying { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_playableGraph = PlayableGraph.Create();
|
||||
_playableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);
|
||||
|
||||
_playableClip = AnimationClipPlayable.Create(_playableGraph, _animationClip);
|
||||
_playableClip.SetSpeed(_playbackSpeed);
|
||||
|
||||
var animator = GetComponent<Animator>();
|
||||
var output = AnimationPlayableOutput.Create(_playableGraph, nameof(BuildingPlacementAnimation), animator);
|
||||
output.SetSourcePlayable(_playableClip);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_playableGraph.Destroy();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!IsPlaying) return;
|
||||
|
||||
_playableGraph.Evaluate(Time.unscaledDeltaTime);
|
||||
|
||||
var position = transform.position;
|
||||
position.x = Mathf.Lerp(_startPosition.x, _finalPosition.x, _positionLerpWeights.x * _animationProgress);
|
||||
position.y = Mathf.Lerp(_startPosition.y, _finalPosition.y, _positionLerpWeights.y * _bounce);
|
||||
position.z = Mathf.Lerp(_startPosition.z, _finalPosition.z, _positionLerpWeights.z * _animationProgress);
|
||||
transform.position = position;
|
||||
|
||||
transform.rotation = Quaternion.Lerp(transform.rotation, _finalRotation, _rotationLerpWeight * _animationProgress);
|
||||
}
|
||||
|
||||
public async UniTask PlayAsync(BuildingDefinition building, Vector3 startPosition, Vector3 finalPosition, Quaternion finalRotation)
|
||||
{
|
||||
IsPlaying = true;
|
||||
|
||||
_building = building;
|
||||
_startPosition = startPosition;
|
||||
_finalPosition = finalPosition;
|
||||
_finalRotation = finalRotation;
|
||||
|
||||
_playableClip.SetTime(0);
|
||||
_playableClip.SetTime(0);
|
||||
_playableGraph.Play();
|
||||
|
||||
_animationProgress = 0;
|
||||
while (_animationProgress < 1) await UniTask.NextFrame();
|
||||
|
||||
_playableGraph.Stop();
|
||||
|
||||
transform.SetPositionAndRotation(finalPosition, finalRotation);
|
||||
|
||||
IsPlaying = false;
|
||||
}
|
||||
|
||||
public void GetAnimationClips(List<AnimationClip> results)
|
||||
{
|
||||
if (_animationClip) results.Add(_animationClip);
|
||||
}
|
||||
|
||||
private void OnImpact(int impact)
|
||||
{
|
||||
var impactVfx = Instantiate(_impactVfxPrefab, transform.position, transform.rotation);
|
||||
|
||||
var intensity = Mathf.Pow(_impactIntensityDecay, impact);
|
||||
var size = new Vector2(_building.Width, _building.Height);
|
||||
DustVfxProperties.Setup(impactVfx, intensity, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user