I feel you. I just finished (last week) the shops and abilities. Ive still had to go back and rewatch sections and read comments constantly to remember how it all works and where to make modifications.
Its really opened my eyes to how big a project is!
FYI, this is my combination of research to get the enemy to hit me, the only thing iād note is Iām using the unity dolly cart system to move a consistent rate.
Keep in mind the rate of fire is currently on āabsolute machine gun BulletHellā for testing purposes.
I would say the biggest help was this gentleman, i used his formula. Predictive Aim in Unity - YouTube
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LeadingAim : MonoBehaviour
{
public Rigidbody projectile;
public Transform target;
public float projectileSpeed;
Vector3 prevPos;
Vector3 prevRot;
static bool debugMode;
// Start is called before the first frame update
void Start()
{
prevPos = target.transform.position;
prevRot = target.transform.eulerAngles;
InvokeRepeating(nameof(Fire), time: 1f, repeatRate: 10f);
}
private void Update()
{
Fire();
}
public void Fire()
{
var instance = Instantiate(projectile, transform.position, rotation: Quaternion.identity);
if (debugMode)
{
Debug.Log(TargetVelociy() + " Target Velocity");
Debug.Log(projectileSpeed + " Projectile");
}
if (IntercerptionDirection(a: target.transform.position, b: transform.position, vA: TargetVelociy(), sB: projectileSpeed,
result: out var direction))
{
instance.velocity = direction * projectileSpeed * 1.8f;
}
else
{
instance.velocity = (target.transform.position - transform.position).normalized * projectileSpeed;
if (debugMode)
{
Debug.Log(instance.velocity + "Instance Velocity");
}
}
}
Vector3 TargetVelociy()
{
Vector3 newPos = target.transform.position; // each frame track the new position
Vector3 objVelocity = (newPos - prevPos) / Time.deltaTime;
prevPos = newPos; // update position for next frame calculation
return objVelocity;
}
public bool IntercerptionDirection(Vector3 a, Vector3 b, Vector3 vA, float sB, out Vector3 result )
{
var aToB = b - a;
var dC = aToB.magnitude;
var alpha = Vector3.Angle(aToB, vA) * Mathf.Deg2Rad;
var sA = vA.magnitude;
var r = sA / sB;
if (MyMath.SolveQuadratic(a: 1 - r * r, b: 2 * r * dC * Mathf.Cos(alpha), c: -(dC * dC), out var root1, out var root2) == 0)
{
Debug.Log("no solution");
result = Vector3.zero;
return false;
}
var dA = Mathf.Max(root1, root2);
var t = dA / sB;
var c = a + vA * t;
result = (c - b).normalized;
return true;
}
}
public class MyMath
{
public static int SolveQuadratic(float a, float b, float c, out float root1, out float root2)
{
var discriminant = b * b - 4 * a * c;
if(discriminant < 0)
{
root1 = Mathf.Infinity;
root2 = -root1;
return 0;
}
root1 = (-b + Mathf.Sqrt(discriminant)) / (2 * a);
root2 = (-b - Mathf.Sqrt(discriminant)) / (2 * a);
return discriminant > 0 ? 2 : 1;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyTargeting : MonoBehaviour
{
[SerializeField] float attackRange = 100f;
[SerializeField] float maxDegrees = .5f;
Transform target;
//call leading aim from this script?
//control fire rate from here?
void Start()
{
target = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update()
{
//add logic to only look at target if in a certain distance.... maybe prevent them from looking"back" at player so you don't get hit from behind?
transform.LookAt(target.position);
}
}