2025-06-22 22:31:01 +01:00

181 lines
6.4 KiB
C#

using UnityEngine;
public class ProjectileExecutionBehavior : RuntimeBehavior
{
[Header("Projectile Settings")]
public GameObject projectilePrefab;
public float projectileSpeed = 15f;
public float lifeSpan = 1.5f;
public bool canPierce = false;
public bool canHitSelf = false;
[Header("Movement Behaviour")]
public AnimationCurve speedOverLifetime = AnimationCurve.Linear(0, 1, 1, 1);
public bool useSpeedCurve = false;
public bool enableCurving = false;
public Vector3 curveAxis = Vector3.up;
public float curveStrength = 1f;
public float curveAmplitude = 45f;
public bool enableRicochet = false;
public int maxRicochets = 1;
public float ricochetSpread = 10f;
public ProjectileExecutionBehavior()
{
Trigger = BehaviorTrigger.Execute; // This replaces your Execute() override
BehaviorName = "Projectile Execution";
}
public override void Execute(RuntimeAbilityInstance ability, Taggable user, Transform target, Vector3 point)
{
// This is your old ProjectileAbility.Execute() logic!
// Get spawn location
var spawnController = user.GetComponentInChildren<ProjectileSpawnLocationController>();
Vector3 spawnPos = spawnController?.transform.position ?? user.transform.position;
Quaternion spawnRot = spawnController?.transform.rotation ?? user.transform.rotation;
// Spawn projectile
var projectileGO = Object.Instantiate(projectilePrefab, spawnPos, spawnRot);
// Setup projectile
var networkedProjectile = projectileGO.GetComponent<NetworkedProjectile>();
if (networkedProjectile != null)
{
SetupProjectileInstance(ability, networkedProjectile, user);
networkedProjectile.Init();
}
}
protected virtual void SetupProjectileInstance(RuntimeAbilityInstance ability, NetworkedProjectile networkedProjectile, Taggable user)
{
networkedProjectile.speed = projectileSpeed;
networkedProjectile.ownerTag = user;
networkedProjectile.ability = ability.SourceAbility;
networkedProjectile.lifeSpan = lifeSpan;
networkedProjectile.canPierce = canPierce;
networkedProjectile.canHitSelf = canHitSelf;
networkedProjectile.speedOverLifetime = speedOverLifetime;
networkedProjectile.useSpeedCurve = useSpeedCurve;
networkedProjectile.enableCurving = enableCurving;
networkedProjectile.curveAxis = curveAxis;
networkedProjectile.curveStrength = curveStrength;
networkedProjectile.curveAmplitude = curveAmplitude;
networkedProjectile.enableRicochet = enableRicochet;
networkedProjectile.maxRicochets = maxRicochets;
networkedProjectile.ricochetSpread = ricochetSpread;
}
public override RuntimeBehavior Clone()
{
return new ProjectileExecutionBehavior
{
// Basic settings
projectilePrefab = this.projectilePrefab,
projectileSpeed = this.projectileSpeed,
lifeSpan = this.lifeSpan,
canPierce = this.canPierce,
canHitSelf = this.canHitSelf,
// Movement behavior
speedOverLifetime = this.speedOverLifetime,
useSpeedCurve = this.useSpeedCurve,
enableCurving = this.enableCurving,
curveAxis = this.curveAxis,
curveStrength = this.curveStrength,
curveAmplitude = this.curveAmplitude,
enableRicochet = this.enableRicochet,
maxRicochets = this.maxRicochets,
ricochetSpread = this.ricochetSpread
};
}
// ========================================================================
// FACTORY METHODS - Easy Creation of Common Projectile Types
// ========================================================================
/// <summary>
/// Create a simple straight projectile
/// </summary>
public static ProjectileExecutionBehavior CreateSimple(GameObject prefab, float speed = 15f, float lifeSpan = 5f)
{
return new ProjectileExecutionBehavior
{
projectilePrefab = prefab,
projectileSpeed = speed,
lifeSpan = lifeSpan
};
}
/// <summary>
/// Create a piercing projectile
/// </summary>
public static ProjectileExecutionBehavior CreatePiercing(GameObject prefab, float speed = 15f, float lifeSpan = 5f)
{
return new ProjectileExecutionBehavior
{
projectilePrefab = prefab,
projectileSpeed = speed,
lifeSpan = lifeSpan,
canPierce = true
};
}
/// <summary>
/// Create a curved projectile (like magic missile)
/// </summary>
public static ProjectileExecutionBehavior CreateCurved(GameObject prefab, float speed = 12f, float curveStrength = 2f)
{
return new ProjectileExecutionBehavior
{
projectilePrefab = prefab,
projectileSpeed = speed,
enableCurving = true,
curveStrength = curveStrength,
curveAmplitude = 30f
};
}
/// <summary>
/// Create a ricochet projectile
/// </summary>
public static ProjectileExecutionBehavior CreateRicochet(GameObject prefab, int maxBounces = 3, float speed = 15f)
{
return new ProjectileExecutionBehavior
{
projectilePrefab = prefab,
projectileSpeed = speed,
enableRicochet = true,
maxRicochets = maxBounces,
ricochetSpread = 15f
};
}
/// <summary>
/// Create a projectile with speed curve (accelerating/decelerating)
/// </summary>
public static ProjectileExecutionBehavior CreateWithSpeedCurve(GameObject prefab, AnimationCurve curve, float baseSpeed = 15f)
{
return new ProjectileExecutionBehavior
{
projectilePrefab = prefab,
projectileSpeed = baseSpeed,
useSpeedCurve = true,
speedOverLifetime = curve
};
}
public static ProjectileExecutionBehavior CreateIceshardLikeWithCurve(GameObject prefab, float baseSpeed = 15f)
{
return new ProjectileExecutionBehavior
{
projectilePrefab = prefab,
projectileSpeed = baseSpeed,
useSpeedCurve = true,
lifeSpan = 1f,
speedOverLifetime = GameConstants.BehaviorUtils.GetIceshardProjectileCurve()
};
}
}