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
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);
|
|
}
|
|
}
|
|
|
|
|