Last active
April 3, 2017 22:34
-
-
Save Donnotron666/e1742aa595618b20166eb04a42321339 to your computer and use it in GitHub Desktop.
Filtering analog aim input into something more usable in Unity3d. This is pulled from my game, so ignore the obvious engine code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Client.Game.Attributes; | |
using Client.Game.Abilities.Payloads; | |
using UnityEngine; | |
using Client.Game.Actors; | |
using System.Collections.Generic; | |
using Client.Utils; | |
using Client.Game.Utils; | |
namespace Client.Game.Abilities.Scripts.Buffs | |
{ | |
public class ControllerAimFilter : BuffBase | |
{ | |
public ControllerAimFilter () | |
{ | |
} | |
bool DebugRays = false; | |
private float distance; | |
public override void Start () | |
{ | |
distance = this.Attributes[ActorAttributes.Distance]; | |
context.source.Attributes[ActorAttributes.ControllerAimAssist] += this.Attributes[ActorAttributes.ControllerAimAssist]; | |
} | |
public override bool OnPayloadSend (Payload payload) | |
{ | |
var wpnPayload = payload as WeaponFirePayload; | |
if(wpnPayload != null) { | |
Adjust(payload.Context); | |
} | |
return false; | |
} | |
void Adjust (AbilityContext firingContext) | |
{ | |
var start = VectorUtils.Vector2(context.source.HalfHeight); | |
var matches = new List<ScoredMatch>(); | |
var tolerance = context.source.Attributes[ActorAttributes.ControllerAimAssist]; | |
var direction2D = VectorUtils.Vector2(firingContext.targetDirection); | |
//a wide cast feels better than a cone-cast, cone rejection is handled by angle scoring later on. | |
var hits = Physics2D.CircleCastAll(start, 10f, direction2D, distance); | |
ScoredMatch match = null; | |
foreach( var hit in hits ) { | |
if(TryScore(start, tolerance, direction2D, hit, out match)) { | |
matches.Add(match); | |
} | |
} | |
if(matches.Count > 0) { | |
matches.Sort(MatchComparer); | |
if(DebugRays) { | |
Debug.Log("HIT ACTOR: " + matches[0].Actor.ActorType); | |
Debug.DrawRay(start, matches[0].Direction*20f, Color.green, 2f); | |
} | |
firingContext.targetDirection = matches[0].Direction; | |
} | |
} | |
bool TryScore (Vector2 start, float tolerance, Vector2 targetDirection, RaycastHit2D hit, out ScoredMatch match) | |
{ | |
if(DebugRays) { | |
Debug.DrawRay(start, targetDirection* distance, Color.red, 2f); | |
} | |
Actor actor = null; | |
//try to convert the hit info to an Actor instance | |
if (ActorUtils.TryHitToActor(hit, out actor)) { | |
//enemies only, could be replaced with a team check, but not really necessary for BF88 | |
if (actor.ActorType == Data.ActorType.Enemy) { | |
var resultDirection = (actor.HalfHeight2D - start).normalized; | |
var angle = Mathf.Abs(Vector2.Angle(resultDirection, targetDirection)); | |
//a heuristic for sorting many results, balancing things that are close -vs- extreme corrections | |
var score = angle + (hit.distance * .1f); | |
if (DebugRays) { | |
Debug.DrawLine(start, hit.point, Color.gray, 2f); | |
} | |
if (angle <= tolerance) { | |
if (DebugRays) { | |
Debug.DrawLine(start, hit.point, Color.cyan, 2f); | |
} | |
match = new ScoredMatch(); | |
match.Direction = resultDirection; | |
match.Score = score; | |
match.Actor = actor; | |
return true; | |
} | |
} | |
} | |
match = null; | |
return false; | |
} | |
private class ScoredMatch { | |
public float Score; | |
public Actor Actor; | |
public Vector2 Direction; | |
} | |
private static MatchComparator MatchComparer = new MatchComparator(); | |
private class MatchComparator: IComparer<ScoredMatch> { | |
public int Compare (ScoredMatch x, ScoredMatch y) | |
{ | |
return x.Score.CompareTo(y.Score); | |
} | |
} | |
public override void End () | |
{ | |
context.source.Attributes[ActorAttributes.ControllerAimAssist] -= this.Attributes[ActorAttributes.ControllerAimAssist]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment