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

339 lines
9.6 KiB
C#

using MoreMountains.Tools;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.CorgiEngine
{
[AddComponentMenu("Corgi Engine/Weapons/Melee Weapon")]
public class PawWeapon : Weapon
{
/// the possible shapes for the melee weapon's damage area
public enum MeleeDamageAreaShapes { Rectangle, Circle }
[MMInspectorGroup("Damage Area", true, 65)]
[SerializeField]private int forceMultiplayer = 50;
/// the shape of the damage area (rectangle or circle)
[Tooltip("the shape of the damage area (rectangle or circle)")]
public MeleeDamageAreaShapes DamageAreaShape = MeleeDamageAreaShapes.Rectangle;
/// the size of the damage area
[Tooltip("the size of the damage area")]
public Vector2 AreaSize = new Vector2(1, 1);
/// the offset to apply to the damage area (from the weapon's attachment position
[Tooltip("the offset to apply to the damage area (from the weapon's attachment position")]
public Vector2 AreaOffset = new Vector2(1, 0);
[MMInspectorGroup("Melee Damage Area Timing", true, 70)]
/// the initial delay to apply before triggering the damage area
[Tooltip("the initial delay to apply before triggering the damage area")]
public float InitialDelay = 0f;
/// the duration during which the damage area is active
[Tooltip("the duration during which the damage area is active")]
public float ActiveDuration = 1f;
[MMInspectorGroup("Melee Damage Caused", true, 75)]
/// the layers that will be damaged by this object
[Tooltip("the layers that will be damaged by this object")]
public LayerMask TargetLayerMask;
/// The amount of health to remove from the player's health
[Tooltip("The amount of health to remove from the player's health")]
public int DamageCaused = 10;
/// the kind of knockback to apply
[Tooltip("the kind of knockback to apply")]
public DamageOnTouch.KnockbackStyles Knockback;
/// The force to apply to the object that gets damaged
[Tooltip("The force to apply to the object that gets damaged")]
public Vector2 KnockbackForce = new Vector2(10, 2);
/// The duration of the invincibility frames after the hit (in seconds)
[Tooltip("The duration of the invincibility frames after the hit (in seconds)")]
public float InvincibilityDuration = 0.5f;
[SerializeField]
private WeaponLaserSight laser;
protected Collider2D _damageAreaCollider;
protected bool _attackInProgress = false;
protected Color _gizmosColor;
protected Vector3 _gizmoSize;
protected CircleCollider2D _circleCollider2D;
protected BoxCollider2D _boxCollider2D;
protected Vector3 _gizmoOffset;
protected DamageOnTouch _damageOnTouch;
protected GameObject _damageArea;
protected bool _hitEventSent = false;
protected bool _hitDamageableEventSent = false;
protected bool _hitNonDamageableEventSent = false;
protected bool _killEventSent = false;
/// <summary>
/// Initialization
/// </summary>
public override void Initialization()
{
base.Initialization();
if (_damageArea == null)
{
CreateDamageArea();
DisableDamageArea();
RegisterEvents();
}
_damageOnTouch.Owner = Owner.gameObject;
}
/// <summary>
/// Creates the damage area.
/// </summary>
protected virtual void CreateDamageArea()
{
_damageArea = new GameObject();
_damageArea.name = this.name + "DamageArea";
_damageArea.transform.position = this.transform.position;
_damageArea.transform.rotation = this.transform.rotation;
_damageArea.transform.SetParent(this.transform);
if (DamageAreaShape == MeleeDamageAreaShapes.Rectangle)
{
_boxCollider2D = _damageArea.AddComponent<BoxCollider2D>();
_boxCollider2D.offset = AreaOffset;
_boxCollider2D.size = AreaSize;
_damageAreaCollider = _boxCollider2D;
}
if (DamageAreaShape == MeleeDamageAreaShapes.Circle)
{
_circleCollider2D = _damageArea.AddComponent<CircleCollider2D>();
_circleCollider2D.transform.position = this.transform.position + this.transform.rotation * AreaOffset;
_circleCollider2D.radius = AreaSize.x / 2;
_damageAreaCollider = _circleCollider2D;
}
_damageAreaCollider.isTrigger = true;
Rigidbody2D rigidBody = _damageArea.AddComponent<Rigidbody2D>();
rigidBody.isKinematic = true;
_damageOnTouch = _damageArea.AddComponent<DamageOnTouch>();
_damageOnTouch.TargetLayerMask = TargetLayerMask;
_damageOnTouch.DamageCaused = DamageCaused;
_damageOnTouch.DamageCausedKnockbackType = Knockback;
_damageOnTouch.DamageCausedKnockbackForce = KnockbackForce;
_damageOnTouch.InvincibilityDuration = InvincibilityDuration;
}
/// <summary>
/// When the weapon is used, we trigger our attack routine
/// </summary>
protected override void WeaponUse()
{
base.WeaponUse();
StartCoroutine(MeleeWeaponAttack());
}
/// <summary>
/// Triggers an attack, turning the damage area on and then off
/// </summary>
/// <returns>The weapon attack.</returns>
protected virtual IEnumerator MeleeWeaponAttack()
{
if (_attackInProgress) { yield break; }
_attackInProgress = true;
//Debug.Log(transform.rotation.normalized);
// Debug.Log(transform.position);
Vector3 _mousePos = Input.mousePosition;
Vector3 direction = _mousePos - Owner.transform.position;
Vector2 irect = direction.normalized;
Debug.Log(_mousePos);
Debug.Log(Owner.transform.position);
ForceWhileInUse = new Vector2(_mousePos.x - transform.position.x , _mousePos.y - transform.position.y).normalized;
Debug.Log(Input.mousePosition.magnitude);
// _controller.AddForce(irect * 50);
yield return new WaitForSeconds(InitialDelay);
EnableDamageArea();
yield return MMCoroutine.WaitForFrames(1);
HandleMiss();
yield return new WaitForSeconds(ActiveDuration);
DisableDamageArea();
_attackInProgress = false;
}
/// <summary>
/// Enables the damage area.
/// </summary>
protected virtual void EnableDamageArea()
{
_hitEventSent = false;
_hitDamageableEventSent = false;
_hitNonDamageableEventSent = false;
_killEventSent = false;
_damageAreaCollider.enabled = true;
}
private void FixedUpdate()
{
Vector3 _mousePos = Input.mousePosition;
Vector3 direction = _mousePos - Owner.transform.position;
if (Input.GetMouseButtonDown(0))
{
mouseStartpos = Input.mousePosition;
}
if (Input.GetMouseButtonUp(0))
{
Vector2 newpose = Input.mousePosition;
Debug.LogError((newpose - mouseStartpos).normalized * forceMultiplayer);
_controller.SetForce((newpose - mouseStartpos).normalized * forceMultiplayer);
}
}
/// <summary>
/// Triggers a weapon miss if no hit was detected last frame
/// </summary>
protected virtual void HandleMiss()
{
if (!_hitEventSent)
{
WeaponMiss();
}
}
/// <summary>
/// Disables the damage area.
/// </summary>
protected virtual void DisableDamageArea()
{
_damageAreaCollider.enabled = false;
}
/// <summary>
/// Draws the melee weapon's range
/// </summary>
protected virtual void DrawGizmos()
{
_gizmoOffset = AreaOffset;
Gizmos.color = Color.red;
if (DamageAreaShape == MeleeDamageAreaShapes.Circle)
{
Gizmos.DrawWireSphere(this.transform.position + _gizmoOffset, AreaSize.x / 2);
}
if (DamageAreaShape == MeleeDamageAreaShapes.Rectangle)
{
MMDebug.DrawGizmoRectangle(this.transform.position + _gizmoOffset, AreaSize, Color.red);
}
}
/// <summary>
/// Draws gizmos on selected if the app is not playing
/// </summary>
protected virtual void OnDrawGizmosSelected()
{
if (!Application.isPlaying)
{
DrawGizmos();
}
}
/// <summary>
/// When we get a hit, we trigger one on the main class
/// </summary>
protected virtual void OnHit()
{
if (!_hitEventSent)
{
WeaponHit();
_hitEventSent = true;
}
}
/// <summary>
/// When we get a HitDamageable, we trigger one on the main class
/// </summary>
protected virtual void OnHitDamageable()
{
if (!_hitDamageableEventSent)
{
WeaponHitDamageable();
_hitDamageableEventSent = true;
}
}
/// <summary>
/// When we get a HitNonDamageable, we trigger one on the main class
/// </summary>
protected virtual void OnHitNonDamageable()
{
if (!_hitNonDamageableEventSent)
{
WeaponHitNonDamageable();
_hitNonDamageableEventSent = true;
}
}
Vector2 mouseStartpos;
void OnMouseDown()
{
mouseStartpos = Input.mousePosition;
Debug.Log("dwn "+ mouseStartpos * 100);
}
void OnMouseUp()
{
Vector2 newpose = Input.mousePosition;
Debug.Log("up " + (newpose - mouseStartpos) * 100);
_controller.AddForce((newpose - mouseStartpos) * 100);
}
/// <summary>
/// When we get a Kill, we trigger one on the main class
/// </summary>
protected virtual void OnKill()
{
if (!_killEventSent)
{
WeaponKill();
_killEventSent = true;
}
}
/// <summary>
/// On enable, we reset the object's speed
/// </summary>
protected virtual void RegisterEvents()
{
if (_damageOnTouch != null)
{
_damageOnTouch.OnKill += OnKill;
_damageOnTouch.OnHit += OnHit;
_damageOnTouch.OnHitDamageable += OnHitDamageable;
_damageOnTouch.OnHitNonDamageable += OnHitNonDamageable;
}
}
/// <summary>
/// On Disable we unsubscribe from our delegates
/// </summary>
protected virtual void OnDisable()
{
if (_damageOnTouch != null)
{
_damageOnTouch.OnKill -= OnKill;
_damageOnTouch.OnHit -= OnHit;
_damageOnTouch.OnHitDamageable -= OnHitDamageable;
_damageOnTouch.OnHitNonDamageable -= OnHitNonDamageable;
}
}
}
}