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; /// /// Initialization /// public override void Initialization() { base.Initialization(); if (_damageArea == null) { CreateDamageArea(); DisableDamageArea(); RegisterEvents(); } _damageOnTouch.Owner = Owner.gameObject; } /// /// Creates the damage area. /// 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.offset = AreaOffset; _boxCollider2D.size = AreaSize; _damageAreaCollider = _boxCollider2D; } if (DamageAreaShape == MeleeDamageAreaShapes.Circle) { _circleCollider2D = _damageArea.AddComponent(); _circleCollider2D.transform.position = this.transform.position + this.transform.rotation * AreaOffset; _circleCollider2D.radius = AreaSize.x / 2; _damageAreaCollider = _circleCollider2D; } _damageAreaCollider.isTrigger = true; Rigidbody2D rigidBody = _damageArea.AddComponent(); rigidBody.isKinematic = true; _damageOnTouch = _damageArea.AddComponent(); _damageOnTouch.TargetLayerMask = TargetLayerMask; _damageOnTouch.DamageCaused = DamageCaused; _damageOnTouch.DamageCausedKnockbackType = Knockback; _damageOnTouch.DamageCausedKnockbackForce = KnockbackForce; _damageOnTouch.InvincibilityDuration = InvincibilityDuration; } /// /// When the weapon is used, we trigger our attack routine /// protected override void WeaponUse() { base.WeaponUse(); StartCoroutine(MeleeWeaponAttack()); } /// /// Triggers an attack, turning the damage area on and then off /// /// The weapon attack. 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; } /// /// Enables the damage area. /// protected virtual void EnableDamageArea() { _hitEventSent = false; _hitDamageableEventSent = false; _hitNonDamageableEventSent = false; _killEventSent = false; _damageAreaCollider.enabled = true; } private void Update() { 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; _controller.AddForce((newpose - mouseStartpos).normalized * forceMultiplayer); } } /// /// Triggers a weapon miss if no hit was detected last frame /// protected virtual void HandleMiss() { if (!_hitEventSent) { WeaponMiss(); } } /// /// Disables the damage area. /// protected virtual void DisableDamageArea() { _damageAreaCollider.enabled = false; } /// /// Draws the melee weapon's range /// 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); } } /// /// Draws gizmos on selected if the app is not playing /// protected virtual void OnDrawGizmosSelected() { if (!Application.isPlaying) { DrawGizmos(); } } /// /// When we get a hit, we trigger one on the main class /// protected virtual void OnHit() { if (!_hitEventSent) { WeaponHit(); _hitEventSent = true; } } /// /// When we get a HitDamageable, we trigger one on the main class /// protected virtual void OnHitDamageable() { if (!_hitDamageableEventSent) { WeaponHitDamageable(); _hitDamageableEventSent = true; } } /// /// When we get a HitNonDamageable, we trigger one on the main class /// 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); } /// /// When we get a Kill, we trigger one on the main class /// protected virtual void OnKill() { if (!_killEventSent) { WeaponKill(); _killEventSent = true; } } /// /// On enable, we reset the object's speed /// protected virtual void RegisterEvents() { if (_damageOnTouch != null) { _damageOnTouch.OnKill += OnKill; _damageOnTouch.OnHit += OnHit; _damageOnTouch.OnHitDamageable += OnHitDamageable; _damageOnTouch.OnHitNonDamageable += OnHitNonDamageable; } } /// /// On Disable we unsubscribe from our delegates /// protected virtual void OnDisable() { if (_damageOnTouch != null) { _damageOnTouch.OnKill -= OnKill; _damageOnTouch.OnHit -= OnHit; _damageOnTouch.OnHitDamageable -= OnHitDamageable; _damageOnTouch.OnHitNonDamageable -= OnHitNonDamageable; } } } }