Skip to content

Instantly share code, notes, and snippets.

@LordNed
Created May 22, 2015 03:27
Show Gist options
  • Save LordNed/d8b0f7319c6e341c58c0 to your computer and use it in GitHub Desktop.
Save LordNed/d8b0f7319c6e341c58c0 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System;
using System.Collections.Generic;
public abstract class BaseDirectionalWeapon : BaseWeapon
{
protected FireDirections m_weaponDirection;
[Flags]
protected enum FireDirections
{
None = 0,
Up = 1,
Down = 2,
Left = 4,
Right = 8,
UpLeft = 16,
UpRight = 32,
DownLeft = 64,
DownRight = 128
}
private struct AimDirectionHelper
{
public FireDirections EnumDirection;
public Vector2 VectorDirection;
}
protected virtual void Awake()
{
m_weaponDirection = FireDirections.Right;
}
protected virtual void Update()
{
UpdateWeaponRotation();
}
protected virtual void UpdateWeaponRotation()
{
// Figure out which way they're currently aiming, then see if we can actually
// rotate the weapon that way.
Vector2 aimDir = new Vector2(m_input.Horizontal.Value, m_input.Vertical.Value);
// Early out if they're not pressing anything (use last known rotation)
if (aimDir.sqrMagnitude < 0.05f)
return;
aimDir.Normalize();
FireDirections canAim = GetAcceptedAimDirections();
// Get all possible fire directions and see which one their input is most aligned with.
List<AimDirectionHelper> allFireDirections = new List<AimDirectionHelper>();
Array enumVals = Enum.GetValues(typeof(FireDirections));
for (int i = 1; i < enumVals.Length; i++)
{
FireDirections potentialDir = (FireDirections)enumVals.GetValue(i);
if((potentialDir & canAim) != 0)
{
AimDirectionHelper helper;
helper.EnumDirection = potentialDir;
helper.VectorDirection = FireDirectionToDir(potentialDir);
allFireDirections.Add(helper);
}
}
// Now sort them by which one is the closest.
FireDirections closestDir = FireDirections.None;
float closestDot = Mathf.NegativeInfinity;
for (int i = 0; i < allFireDirections.Count; i++)
{
float dot = Vector2.Dot(allFireDirections[i].VectorDirection, aimDir);
if (dot > closestDot)
{
closestDir = allFireDirections[i].EnumDirection;
closestDot = dot;
}
}
// Update the weapon rotation
m_weaponDirection = closestDir;
// Finally, rotate the weapon rotation.
switch(m_weaponDirection)
{
case FireDirections.Left:
transform.rotation = Quaternion.identity;
transform.localScale = new Vector3(-1, 1, 1);
break;
case FireDirections.Right:
transform.rotation = Quaternion.identity;
transform.localScale = new Vector3(1, 1, 1);
break;
case FireDirections.Up:
transform.rotation = Quaternion.AngleAxis(90f, Vector3.forward);
transform.localScale = new Vector3(1, 1, 1);
break;
case FireDirections.Down:
transform.rotation = Quaternion.AngleAxis(-90f, Vector3.forward);
transform.localScale = new Vector3(1, 1, 1);
break;
case FireDirections.UpLeft:
transform.rotation = Quaternion.AngleAxis(135f, Vector3.forward);
transform.localScale = new Vector3(1, 1, 1);
break;
case FireDirections.UpRight:
transform.rotation = Quaternion.AngleAxis(45f, Vector3.forward);
transform.localScale = new Vector3(1, 1, 1);
break;
case FireDirections.DownLeft:
transform.rotation = Quaternion.AngleAxis(-135f, Vector3.forward);
transform.localScale = new Vector3(1, 1, 1);
break;
case FireDirections.DownRight:
transform.rotation = Quaternion.AngleAxis(-45f, Vector3.forward);
transform.localScale = new Vector3(1, 1, 1);
break;
}
}
protected virtual FireDirections GetAcceptedAimDirections()
{
return FireDirections.Left | FireDirections.Right | FireDirections.Up | FireDirections.Down
| FireDirections.UpLeft | FireDirections.UpRight | FireDirections.DownLeft | FireDirections.DownRight;
}
protected virtual Vector2 FireDirectionToDir(FireDirections dir)
{
switch (dir)
{
case FireDirections.None:
break;
case FireDirections.Left:
return -Vector2.right;
case FireDirections.Right:
return Vector2.right;
case FireDirections.Up:
return Vector2.up;
case FireDirections.Down:
return -Vector2.up;
case FireDirections.UpLeft:
return (-Vector2.right + Vector2.up).normalized;
case FireDirections.UpRight:
return (Vector2.right + Vector2.up).normalized;
case FireDirections.DownLeft:
return (-Vector2.right + -Vector2.up).normalized;
case FireDirections.DownRight:
return (Vector2.right + -Vector2.up).normalized;
}
return Vector2.zero;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment