2023-11-30 00:23:23 +08:00
using System ;
using System.Collections ;
using System.Collections.Generic ;
using System.Threading.Tasks ;
using BITKit ;
using BITKit.Entities ;
using BITKit.Entities.Player ;
using BITKit.UX ;
using UnityEngine ;
using UnityEngine.UIElements ;
namespace BITFALL.UX
{
public class UXDamageIndicator : MonoBehaviour
{
[SerializeReference, SubclassSelector] private IPlayerService playerService ;
[SerializeField] private UIDocument document ;
[SerializeField] private VisualTreeAsset indicatorAsset ;
[UXBindPath("indicator-container")]
private VisualElement indicatorContainer ;
[Inject] private IHealth _health ;
[Inject] private IEntityMovement _movement ;
private List < ( VisualElement visualElement , Vector3 position , float exitTime ) > _indicators = new ( ) ;
2023-12-15 00:08:02 +08:00
2023-11-30 00:23:23 +08:00
private void Start ( )
{
playerService . OnPlayerInitialized + = OnPlayerInitialized ;
playerService . OnPlayerDisposed + = OnPlayerDisposed ;
destroyCancellationToken . Register ( ( ) = >
{
playerService . OnPlayerInitialized - = OnPlayerInitialized ;
playerService . OnPlayerDisposed - = OnPlayerDisposed ;
} ) ;
BITKit . UX . UXUtils . Inject ( this ) ;
indicatorContainer . Clear ( ) ;
}
private void OnPlayerDisposed ( Entity obj )
{
foreach ( var x in _indicators )
{
x . visualElement . RemoveFromHierarchy ( ) ;
}
_indicators . Clear ( ) ;
}
private void OnPlayerInitialized ( Entity obj )
{
obj . Inject ( this ) ;
2023-12-15 00:08:02 +08:00
_health . OnDamageRelease + = OnDamageRelease ;
2023-11-30 00:23:23 +08:00
}
private void Update ( )
{
foreach ( var x in _indicators )
{
//
// var direction =Vector3.ProjectOnPlane(x.position - _movement.Position,Vector3.up).normalized;
//
// direction = Quaternion.LookRotation(direction) * _movement.Rotation * Vector3.forward;
//
// var rotation = Quaternion.LookRotation(direction);
// var angle =(rotation.eulerAngles.y+180)%360;
//
// x.visualElement.transform.rotation = Quaternion.Euler(0, 0, -angle);
//Calculate direction
Vector3 rhs = x . position - _movement . Position ;
Vector3 offset = x . visualElement . transform . rotation . eulerAngles ;
var forward = _movement . Forward ;
//Convert angle into screen space
rhs . y = 0f ;
rhs . Normalize ( ) ;
//Get the angle between two positions.
float angle = Vector3 . Angle ( rhs , forward ) ;
//Calculate the perpendicular of both vectors
//More information about this calculation: https://unity3d.com/es/learn/tutorials/modules/beginner/scripting/vector-maths-dot-cross-products?playlist=17117
Vector3 Perpendicular = Vector3 . Cross ( forward , rhs ) ;
//Calculate magnitude between two vectors
float dot = - Vector3 . Dot ( Perpendicular , Vector3 . up ) ;
//get the horizontal angle in direction of target / sender.
angle = AngleCircumference ( dot , angle ) ;
//Apply the horizontal rotation to the indicator.
offset . z = - angle ;
x . visualElement . transform . rotation = Quaternion . Euler ( offset ) ;
if ( Time . time > x . exitTime )
x . visualElement . RemoveFromHierarchy ( ) ;
float AngleCircumference ( float dot , float angle )
{
float ac = angle ;
float circumference = 360f ;
ac = angle - 10 ;
if ( dot < 0 )
{
ac = circumference - angle ;
}
return ac ;
}
}
_indicators . RemoveAll ( x = > x . exitTime < Time . time ) ;
}
2023-12-15 00:08:02 +08:00
private void OnDamageRelease ( DamageMessage arg1 )
2023-11-30 00:23:23 +08:00
{
2023-12-15 00:08:02 +08:00
if ( arg1 . Position . IsDefault ( ) ) return ;
2023-11-30 00:23:23 +08:00
var indicator = indicatorContainer . Create < VisualElement > ( ( ) = > indicatorAsset . CloneTree ( ) [ 0 ] ) ;
2023-12-16 23:30:08 +08:00
if ( arg1 . Damage is 0 )
{
indicator [ 0 ] . style . unityBackgroundImageTintColor = Color . black ;
}
2023-11-30 00:23:23 +08:00
_indicators . Add ( ( indicator , ( Vector3 ) arg1 . Position , Time . time + 1 ) ) ;
}
// private async void KillIndicator(VisualElement indicator)
// {
// try
// {
// await Task.Delay(500, destroyCancellationToken);
// indicator.RemoveFromHierarchy();
// }
// catch (Exception e)
// {
// Console.WriteLine(e);
// throw;
// }
// }
}
}