Created
June 11, 2022 21:59
-
-
Save kurtdekker/be2a15216a41bef5ad39b609ff1625ef to your computer and use it in GitHub Desktop.
Unity screen-space auto-aim helper (aimbot)
This file contains 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 UnityEngine; | |
public class AimhelperTarget : MonoBehaviour | |
{ | |
// @kurtdekker - nothing to see here; just put this | |
// on target GameObjects you want to assist-aim to. | |
// | |
// All the magic happen over in BasicAimHelper.cs | |
} |
This file contains 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.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
// @kurtdekker | |
// | |
// FPS Aim helper, super-generic screenspace aimbot helper. | |
// | |
// This only needs is to be called with your actual proposed | |
// mouse inputs and to know which way it is facing. | |
// | |
// Add GameObject children with the AimhelperTarget script (just an empty marker) | |
// on every piece of your enemy you want "attraction" to work on (head, chest, etc.) | |
// | |
// You can try it out alongside the BasicFPCC script from Alucard, located here: | |
// | |
// https://forum.unity.com/threads/a-basic-first-person-character-controller-for-prototyping.1169491/ | |
// | |
// You will need the BasicFPCC.cs script above. Set it up fully as instructions explain. | |
// | |
// Add this script onto that same Player's Camera (must be on camera for alignment!) | |
// | |
// Modify the BasicFPCC script, immediately after the | |
// mouse look is read in ProcessInputs(), as follows: | |
// | |
// // code to insert in BasicFPCC.cs (or in your own mouse look script | |
// if (BasicAimHelper.I) | |
// { | |
// BasicAimHelper.I.AllowForAutoAim( ref inputLookX, ref inputLookY); | |
// } | |
// | |
// NOTE: the BasicFPCC script is hosted as a gist and may change, | |
// making these patches invalid or even breaking this script. | |
// | |
public class BasicAimHelper : MonoBehaviour | |
{ | |
[Header( "@kurtdekker")] | |
[Header( "Radius to act within (percent of minimum screen axis)")] | |
public float ActiveScreenFractionRadius = 0.15f; | |
[Header( "Choose this to be adequate but still let you break lock.")] | |
public float AimingAssistanceStrength = 10.0f; | |
[Header( "At what range does attraction max out?")] | |
public float MinimumActiveLinearRange = 20.0f; | |
[Header( "How rapidly does the effect fall off on distant enemies?")] | |
public float MaximumActiveLinearRange = 40.0f; | |
[Header( "How far can the effectiveness fall based on range?")] | |
public float FloorAttractionAtMaxRange = 0.25f; | |
public static BasicAimHelper I { get; private set; } | |
void OnEnable() | |
{ | |
I = this; | |
} | |
void OnDisable() | |
{ | |
I = null; | |
} | |
static float ScreenMinimumAxis { get { return Mathf.Min( Screen.width, Screen.height); } } | |
// returns true if the mouse was adjusted | |
public bool AllowForAutoAim( ref float mouseX, ref float mouseY) | |
{ | |
bool adjusted = false; | |
// TODO: expects to be ON the GameObject with the Camera! | |
var cam = GetComponent<Camera>(); | |
// TODO: assumes crosshairs are middle of the screen precisely | |
Vector2 screenCrosshairs = new Vector2( Screen.width, Screen.height) / 2; | |
// TODO: get these once in a far more efficient way. This is for demo only! | |
var targets = FindObjectsOfType<AimhelperTarget>(); | |
float activeRadius = ScreenMinimumAxis * ActiveScreenFractionRadius; | |
// used to only consider the drive from the closest target, not a mix of all nearby | |
float closestRadius = activeRadius; | |
// will ultimately end up being the closest to our aimpoint only. | |
Vector2 mouseAssistanceDrive = Vector2.zero; | |
foreach( var target in targets) | |
{ | |
Vector3 worldDelta = target.transform.position - transform.position; | |
// only lock onto stuff in front of us | |
if (Vector3.Dot( transform.forward, worldDelta) > 0) | |
{ | |
float targetWorldDistanceRange = worldDelta.magnitude; | |
if (targetWorldDistanceRange < MaximumActiveLinearRange) | |
{ | |
Vector2 screenTargetPos = cam.WorldToScreenPoint( target.transform.position); | |
Vector2 screenDelta = screenTargetPos - screenCrosshairs; | |
float screenDistance = screenDelta.magnitude; | |
// any attraction at all? | |
if (screenDistance < activeRadius) | |
{ | |
if (screenDistance < closestRadius) | |
{ | |
closestRadius = screenDistance; | |
// linear from 0 at radius to 1 at dead-on (0 distance) | |
float effectiveness = Mathf.InverseLerp( activeRadius, 0, screenDistance); | |
// TODO: you could look this up in a non-linear curve, such | |
// as by using a public AnimationCurve and setting it up. | |
// TODO: you could square or square-root this to change the "feel" | |
// After all the above, we have a value from 0 to 1 that | |
// tells us how much we want to drive the mouse. | |
// scale down by screen pixels | |
effectiveness /= ScreenMinimumAxis; | |
// master scaling amount | |
effectiveness *= AimingAssistanceStrength; | |
// how much is effectiveness reduced as you get far away? | |
float rangeEffectivenessAttenuation = Mathf.InverseLerp( | |
MaximumActiveLinearRange, | |
MinimumActiveLinearRange, | |
targetWorldDistanceRange); | |
// TODO: you might want range falloff to be non-linear, as above | |
// Re-lerp it to the floor attraction | |
rangeEffectivenessAttenuation = Mathf.Lerp( FloorAttractionAtMaxRange, 1.0f, rangeEffectivenessAttenuation); | |
// apply range attraction attenuation | |
effectiveness *= rangeEffectivenessAttenuation; | |
mouseAssistanceDrive = screenDelta * effectiveness; | |
adjusted = true; | |
} | |
} | |
} | |
} | |
} | |
if (adjusted) | |
{ | |
mouseX += mouseAssistanceDrive.x; | |
mouseY += mouseAssistanceDrive.y; | |
} | |
return adjusted; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment