using System.Collections; using System.Xml.Serialization; using Managers; using PrimeTween; using UnityEngine; using static AffectingForcesManager; public class HitFeedbackTestObjectBehavior : MonoBehaviour { // Private variables public AffectingForcesManager forceManager; public TargetSpawner spawner; public MeshRenderer meshRenderer1; public MeshRenderer meshRenderer2; private MaterialPropertyBlock materialProperties; private ManageableAudio hitSound; [SerializeField] private int scoreValue = 150; [SerializeField] private float normalMaxVelocity = 10; [SerializeField] private float absolutMaxVelocity = 20; [SerializeField] private bool useAntiDrift = false; [SerializeField] private float antiDriftAmount = 20; [SerializeField] private float minAntiDriftFactor = 0.2f; [SerializeField] private float normalDrag = 0.1f; [SerializeField] private float maximumDrag = 0.3f; [SerializeField] private float torqueDrag = 0.2f; [SerializeField] private float tackleStunTime = 0.6f; // The time in Seconds the player is allowed to boost for private Rigidbody body; private Vector3 currentGravity = new Vector3(); // Current Zone the player occupies private Zone zone = Zone.NimbleZone; private int instanceID; private bool isTackled; private float tackledTime; void Awake() { if (forceManager == null) { forceManager = GameObject.FindGameObjectWithTag("ForceManager"). GetComponent(); } materialProperties = new MaterialPropertyBlock(); UpdateBurnOut(0.3f); } // Start is called before the first frame update void Start() { body = GetComponent(); instanceID = gameObject.GetInstanceID(); hitSound = AudioManager.G.GetLocalSound("target_hit", 1, transform); } // Update is called once per frame void FixedUpdate() { zone = forceManager.GetZoneOfInstance(instanceID); //BoostStateUpdate(Time.deltaTime); // Rotate the vehicle with the current steer velocity // Calculate the magnitude of the acceleration with the current thrust UpdateMovement(); UpdateTackleResponse(); } void UpdateMovement() { // Get and apply the current Gravity Transform gravitySource = forceManager.GetGravitySourceForInstance(instanceID); currentGravity = forceManager.GetGravityForInstance(instanceID)(gravitySource, transform); body.AddForce(currentGravity, ForceMode.Acceleration); Vector3 currentVelocity = body.velocity; if (useAntiDrift && !isTackled) { Vector3 driftDampeningAcceleration = DriftDampeningAcceleration(currentVelocity, zone); // Add anti drift acceleration body.AddForce(driftDampeningAcceleration, ForceMode.Acceleration); } if (currentVelocity.magnitude >= absolutMaxVelocity && !isTackled) { body.velocity = body.velocity.normalized * absolutMaxVelocity; } // Add drag if (!isTackled) { Vector3 dragDecceleration = DragDecceleration(currentVelocity, zone); body.AddForce(dragDecceleration, ForceMode.Acceleration); } // Default torque drag body.AddTorque(body.angularVelocity * -torqueDrag, ForceMode.Acceleration); Debug.DrawRay(transform.position, currentVelocity * 0.5f, Color.black); } Vector3 DriftDampeningAcceleration(Vector3 currentVelocity, Zone zone) { Vector3 antiDriftVelocity = new Vector3(); float antiDriftFactor = 1f; // Cancel out inertia/drifting if (zone == Zone.NimbleZone) { Vector3 rotation = transform.rotation.eulerAngles; Vector3 driftVelocity = currentVelocity - Vector3.Project(currentVelocity, rotation); antiDriftVelocity = Vector3.Reflect(-driftVelocity, transform.up) - driftVelocity; antiDriftFactor = Mathf.InverseLerp(absolutMaxVelocity, normalMaxVelocity, currentVelocity.magnitude); antiDriftFactor = Mathf.Max(antiDriftFactor, minAntiDriftFactor); Debug.DrawRay(transform.position, driftVelocity.normalized * 5, Color.red); } Debug.DrawRay(transform.position, antiDriftVelocity.normalized * 5, Color.green); return antiDriftVelocity * antiDriftAmount * antiDriftFactor; } Vector3 DragDecceleration(Vector3 currentVelocity, Zone zone) { Vector3 drag = new Vector3(); float minDragFactor = Mathf.InverseLerp(absolutMaxVelocity, normalMaxVelocity, currentVelocity.magnitude); float normalDragFactor = Mathf.InverseLerp(normalMaxVelocity, 0, currentVelocity.magnitude); if (zone == Zone.NimbleZone) { drag -= currentVelocity.normalized * normalDrag; } if (currentVelocity.magnitude >= normalMaxVelocity && zone == Zone.NimbleZone) { drag -= currentVelocity.normalized * maximumDrag; } return drag; } void UpdateTackleResponse(bool gotTackled = false) { if (gotTackled) { isTackled = true; tackledTime = tackleStunTime; return; } tackledTime -= Time.deltaTime; if (tackledTime <= 0) { isTackled = false; tackledTime = 0; } } void OnTriggerEnter(Collider collider) { if (collider.tag == "Zone" || isTackled) { return; } Vector3 colliderVelocity = collider.attachedRigidbody.velocity; Vector3 tackleDirection = body.transform.position - collider.transform.position; float colliderMass = collider.attachedRigidbody.mass; body.AddForce(colliderVelocity.magnitude * tackleDirection * (colliderMass / body.mass), ForceMode.Acceleration); UpdateTackleResponse(true); hitSound.PlayAudio(false); Destruction(); StatisticsManager.G.AddFreeFlightScore(150); } async void Destruction() { await Tween.Custom(0.33f, 0.5f, 1.2f, onValueChange: value => { UpdateBurnOut(value); }). OnComplete(() => Destroy(gameObject)); } private void UpdateBurnOut(float value) { materialProperties.SetFloat("_Burnout", value); meshRenderer1.SetPropertyBlock(materialProperties); meshRenderer2.SetPropertyBlock(materialProperties); } private void OnDestroy() { spawner.TargetDestroyed(gameObject); } }