Thank you. I have included several scripts: DamageSource, ActiveWeapon, PlayerController, Sword, and IWeapon.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DamageSource : MonoBehaviour
{
private int damageAmount;
private void Start()
{
MonoBehaviour currentActiveWeapon = ActiveWeapon.Instance.CurrentActiveWeapon;
damageAmount = (currentActiveWeapon as IWeapon).GetWeaponInfo().weaponDamage;
}
private void OnTriggerEnter2D(Collider2D other)
{
EnemyHealth enemyHealth = other.gameObject.GetComponent<EnemyHealth>();
enemyHealth?.TakeDamage(damageAmount);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ActiveWeapon : Singleton<ActiveWeapon>
{
public MonoBehaviour CurrentActiveWeapon { get; private set; }
PlayerControls playerControls;
private float timeBetweenAttacks;
bool attackButtonDown, isAttacking = false;
protected override void Awake()
{
base.Awake();
playerControls = new PlayerControls();
}
private void OnEnable()
{
playerControls.Enable();
}
// Start is called before the first frame update
private void Start()
{
playerControls.Combat.Attack.started += _ => StartAttacking();
playerControls.Combat.Attack.canceled += _ => StopAttacking();
//AttackCooldown();
}
// Update is called once per frame
private void Update()
{
Attack();
}
public void NewWeapon(MonoBehaviour newWeapon)
{
CurrentActiveWeapon = newWeapon;
AttackCooldown();
timeBetweenAttacks = (CurrentActiveWeapon as IWeapon).GetWeaponInfo().weaponCooldown;
}
private void AttackCooldown()
{
isAttacking = true;
StopAllCoroutines();
StartCoroutine(TimeBetweenAttacksRoutine());
}
private IEnumerator TimeBetweenAttacksRoutine()
{
yield return new WaitForSeconds(timeBetweenAttacks);
isAttacking = false;
}
public void WeaponNull()
{
CurrentActiveWeapon = null;
}
private void StartAttacking()
{
attackButtonDown = true;
}
private void StopAttacking()
{
attackButtonDown = false;
}
private void Attack()
{
if (attackButtonDown && !isAttacking && CurrentActiveWeapon)
{
AttackCooldown();
(CurrentActiveWeapon as IWeapon).Attack();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : Singleton<PlayerController>
{
public bool FacingLeft { get { return facingLeft; } }
//public static PlayerController Instance; no longer needed when used as a Singleton
[SerializeField] float moveSpeed = 1f;
[SerializeField] float dashSpeed = 4f;
[SerializeField] TrailRenderer myTrailRenderer;
[SerializeField] Transform weaponCollider;
PlayerControls playerControls;
Vector2 movement;
Rigidbody2D rb;
Animator myAnimator;
SpriteRenderer mySpriteRenderer;
private KnockBack knockBack;
float startingMoveSpeed;
bool facingLeft = false;
bool isDashing = false;
protected override void Awake()
{
base.Awake();
//Instance = this; No longer needed when used as a Singleton
playerControls = new PlayerControls();
rb = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
mySpriteRenderer = GetComponent<SpriteRenderer>();
knockBack = GetComponent<KnockBack>();
}
private void Start()
{
playerControls.Combat.Dash.performed += _ => Dash();
startingMoveSpeed = moveSpeed;
ActiveInventory.Instance.EquipStartingWeapon();
}
private void OnEnable()
{
playerControls.Enable();
}
private void OnDisable()
{
playerControls.Disable();
}
private void Update()
{
PlayerInput();
myAnimator.SetFloat("moveX", movement.x);
myAnimator.SetFloat("moveY", movement.y);
}
private void FixedUpdate()
{
AdjustPlayerFacingDirection();
Move();
}
public Transform GetWeaponCollider()
{
return weaponCollider;
}
private void PlayerInput()
{
movement = playerControls.Movement.Move.ReadValue<Vector2>();
}
private void Move()
{
if (knockBack.GettingKnockedBack || PlayerHealth.Instance.IsDead)
{
return;
}
rb.MovePosition(rb.position + movement * (moveSpeed * Time.fixedDeltaTime));
}
private void AdjustPlayerFacingDirection()
{
Vector3 mousePos = Input.mousePosition;
Vector3 playerScreenPoint = Camera.main.WorldToScreenPoint(transform.position);
if(mousePos.x < playerScreenPoint.x)
{
mySpriteRenderer.flipX = true;
facingLeft = true;
}
else
{
mySpriteRenderer.flipX = false;
facingLeft = false;
}
}
private void Dash()
{
if(!isDashing && Stamina.Instance.CurrentStamina > 0)
{
Stamina.Instance.UseStamina();
isDashing = true;
moveSpeed *= dashSpeed;
myTrailRenderer.emitting = true;
StartCoroutine(EndDashRoutine());
}
}
private IEnumerator EndDashRoutine()
{
float dashTime = .2f;
float dashCD = .25f;
yield return new WaitForSeconds(dashTime);
moveSpeed = startingMoveSpeed;
myTrailRenderer.emitting = false;
yield return new WaitForSeconds(dashCD);
isDashing = false;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Sword : MonoBehaviour, IWeapon
{
[SerializeField] private WeaponInfo weaponInfo;
[SerializeField] private GameObject slashAnimPrefab;
[SerializeField] private Transform slashAnimationSpawnPoint;
private Transform weaponCollider;
Animator myAnimator;
GameObject slashAnim;
private void Awake()
{
myAnimator = GetComponent<Animator>();
}
private void Start()
{
weaponCollider = PlayerController.Instance.GetWeaponCollider();
slashAnimationSpawnPoint = GameObject.Find("SlashAnimationSpawnPoint").transform;
}
private void Update()
{
MouseFollowWithOffset();
}
public WeaponInfo GetWeaponInfo()
{
return weaponInfo;
}
public void Attack()
{
myAnimator.SetTrigger("Attack");
weaponCollider.gameObject.SetActive(true);
slashAnim = Instantiate(slashAnimPrefab, slashAnimationSpawnPoint.position, Quaternion.identity);
slashAnim.transform.parent = this.transform.parent;
}
public void DoneAtackingAnimEvent()
{
weaponCollider.gameObject.SetActive(false);
}
public void SwingUpFlipAnimEvent()
{
slashAnim.gameObject.transform.rotation = Quaternion.Euler(-180, 0, 0);
if(PlayerController.Instance.FacingLeft)
{
slashAnim.GetComponent<SpriteRenderer>().flipX = true;
}
}
public void SwingDownFlipAnimEvent()
{
slashAnim.gameObject.transform.rotation = Quaternion.Euler(0, 0, 0);
if (PlayerController.Instance.FacingLeft)
{
slashAnim.GetComponent<SpriteRenderer>().flipX = true;
}
}
private void MouseFollowWithOffset()
{
Vector3 mousePos = Input.mousePosition;
Vector3 playerScreenPoint = Camera.main.WorldToScreenPoint(PlayerController.Instance.transform.position);
float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
if (mousePos.x < playerScreenPoint.x)
{
ActiveWeapon.Instance.transform.rotation = Quaternion.Euler(0, -180, angle);
weaponCollider.transform.rotation = Quaternion.Euler(0, -180, 0);
}
else
{
weaponCollider.transform.rotation = Quaternion.Euler(0, 0, 0);
ActiveWeapon.Instance.transform.rotation = Quaternion.Euler(0, 0, angle);
}
}
}
interface IWeapon
{
public void Attack();
public WeaponInfo GetWeaponInfo();
}