You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

137 lines
3.7 KiB

using System;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
[SerializeField] private Collider2D collisionDetector;
[SerializeField] private float speed = 10.0f;
float maxFlyDistance = 0.0f;
float currentFlyDistance = 0.0f;
HashSet<CreatureBase> collided = new HashSet<CreatureBase>();
Action<Bullet, CreatureBase> OnCollide;
Action<Bullet> OnCompleteToTarget;
public Transform Target { get; private set; } = null;
public bool IsFired { get; private set; } = false;
public float Speed
{
get => speed;
set => speed = value;
}
public Vector2 HeadDirection
{
get
{
var zAngle = transform.eulerAngles.z;
return new Vector2(Mathf.Cos(zAngle * Mathf.Deg2Rad), Mathf.Sin(zAngle * Mathf.Deg2Rad)).normalized;
}
set
{
transform.eulerAngles = new Vector3(0, 0, Mathf.Atan2(value.y, value.x) * Mathf.Rad2Deg);
}
}
private void Update()
{
if(!IsFired) return;
float sqrtDistanceToTarget = float.MaxValue;
if (Target != null)
{
var ignoreZOfThis = transform.position;
ignoreZOfThis.z = 0.0f;
var ignoreZOfTarget = Target.position;
ignoreZOfTarget.z = 0.0f;
var toVec = ignoreZOfTarget - ignoreZOfThis;
HeadDirection = toVec;
sqrtDistanceToTarget = toVec.sqrMagnitude;
}
float moveUnit = speed * Time.deltaTime;
if (sqrtDistanceToTarget < moveUnit * moveUnit)
{
transform.position = Target.position;
BattleMgr.LoopAllCreatures(HandleCollide);
OnCompleteToTarget?.Invoke(this);
IsFired = false;
}
else if(maxFlyDistance > 0.0f && currentFlyDistance >= maxFlyDistance)
{
BattleMgr.LoopAllCreatures(HandleCollide);
OnCompleteToTarget?.Invoke(this);
IsFired = false;
}
else
{
transform.position += (Vector3)HeadDirection * moveUnit;
currentFlyDistance += moveUnit;
BattleMgr.LoopAllCreatures(HandleCollide);
}
}
public void Fire(float maxFlyDistance, Action<Bullet, CreatureBase> onCollide, Action<Bullet> onCompleteToTarget)
{
this.maxFlyDistance = maxFlyDistance;
currentFlyDistance = 0.0f;
OnCollide = onCollide;
OnCompleteToTarget = onCompleteToTarget;
collided.Clear();
IsFired = true;
}
public void Fire(Transform target, Action<Bullet, CreatureBase> onCollide, Action<Bullet> onCompleteToTarget)
{
maxFlyDistance = 0.0f;
currentFlyDistance = 0.0f;
Target = target;
OnCollide = onCollide;
OnCompleteToTarget = onCompleteToTarget;
collided.Clear();
IsFired = true;
}
private bool HandleCollide(CreatureBase creature)
{
var ignoreZOfBounds = collisionDetector.bounds;
ignoreZOfBounds.extents = new Vector3(ignoreZOfBounds.extents.x, ignoreZOfBounds.extents.y, 0.0f);
var ignoreZOfCreature = creature.transform.position;
ignoreZOfCreature.z = 0.0f;
if (collided.Contains(creature))
{
if (!ignoreZOfBounds.Contains(ignoreZOfCreature))
{
collided.Remove(creature);
}
return true;
}
if (ignoreZOfBounds.Contains(ignoreZOfCreature))
{
collided.Add(creature);
OnCollide.Invoke(this, creature);
return false;
}
return true;
}
private void OnDrawGizmosSelected()
{
Logger.DrawArrow2D(transform.position, HeadDirection, 5.0f, Color.cyan);
}
}