CCCPaste

РЕШЕНИЕ ВОПРОСА С ТЕМ, ЧТО ИЗ - ЗА ВЫСОКОЙ СК...

РЕШЕНИЕ ВОПРОСА С ТЕМ, ЧТО ИЗ - ЗА ВЫСОКОЙ СКОРОСТИ ВРАГ ПРОЛЕТАЕТ ПОЛОВИНУ FROST EFFEct

using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Collider))]
public class SteeringEnemyAI : MonoBehaviour
{
[Header("Target")]
[Tooltip("Трансформ игрока")]
public Transform player;

[Header("Steering Settings")]
public float maxSpeed = 3f;
public float maxForce = 15f;
public float arrivalRadius = 1f;

[Header("Boids Settings")]
[Tooltip("Минимальное расстояние до соседей")]
public float separationRadius = 1.5f;
public float separationStrength = 7f;
[Range(0f, 1f)]
public float cohesionWeight = 0.5f;
[Range(0f, 1f)]
public float alignmentWeight = 0.5f;

[Header("Obstacle Avoidance")]
public float avoidDistance = 2f;
public float avoidStrength = 10f;
public LayerMask obstacleMask;

[Header("Rotation")]
public float angularSpeed = 10f;

private Rigidbody rb;
private static List<SteeringEnemyAI> allEnemies = new List<SteeringEnemyAI>();
private static bool collisionsIgnored = false;
[HideInInspector]
public float frostMultiplier = 1f;
private float targetMultiplier = 1f;
private float smoothVelocity;

private void Awake()
{
rb = GetComponent<Rigidbody>();
allEnemies.Add(this);
if (!collisionsIgnored)
{
int layer = LayerMask.NameToLayer("Enemy");
if (layer >= 0)
Physics.IgnoreLayerCollision(layer, layer, true);
collisionsIgnored = true;
}
}

private void OnDestroy()
{
allEnemies.Remove(this);
}

public void Init(Transform playerTransform)
{
player = playerTransform;
}

private void FixedUpdate()
{
if (player == null) return;

frostMultiplier = Mathf.SmoothDamp(frostMultiplier, targetMultiplier, ref smoothVelocity, 0.3f);
if (frostMultiplier <= 0f + 1e-4f)
{
rb.velocity = new Vector3(0f, rb.velocity.y, 0f);
return;
}

Vector3 toTarget = player.position - transform.position;
float dist = toTarget.magnitude;
Vector3 desired = toTarget.normalized * maxSpeed * frostMultiplier;
if (dist < arrivalRadius)
desired *= dist / arrivalRadius;

Vector3 sepForce = Vector3.zero;
int count = 0;
float sepRad2 = separationRadius * separationRadius;
foreach (var other in allEnemies)
{
if (other == this) continue;
Vector3 diff = transform.position - other.transform.position;
float d2 = diff.sqrMagnitude;
if (d2 < sepRad2 && d2 > 0.001f)
{
sepForce += diff.normalized / d2;
count++;
}
}
if (count > 0)
sepForce = sepForce.normalized * separationStrength * frostMultiplier;

Vector3 cohForce = Vector3.zero;
if (count > 0)
{
Vector3 center = Vector3.zero;
foreach (var other in allEnemies)
{
if (other == this) continue;
if ((other.transform.position - transform.position).sqrMagnitude < sepRad2)
center += other.transform.position;
}
center /= count;
cohForce = (center - transform.position).normalized * separationStrength * cohesionWeight * frostMultiplier;
}

Vector3 aliForce = Vector3.zero;
if (count > 0)
{
Vector3 avgVel = Vector3.zero;
foreach (var other in allEnemies)
{
if (other == this) continue;
if ((other.transform.position - transform.position).sqrMagnitude < sepRad2)
avgVel += other.rb.velocity;
}
avgVel /= count;
aliForce = (avgVel.normalized * maxSpeed * frostMultiplier - rb.velocity) * alignmentWeight * frostMultiplier;
}

Vector3 avoidForce = Vector3.zero;
Vector3 forward = rb.velocity.sqrMagnitude > 0.01f ? rb.velocity.normalized : transform.forward;
if (Physics.Raycast(transform.position, forward, out RaycastHit hit, avoidDistance, obstacleMask))
{
avoidForce = Vector3.Cross(hit.normal, Vector3.up).normalized * avoidStrength * frostMultiplier;
}

Vector3 steer = desired + sepForce + cohForce + aliForce + avoidForce - rb.velocity;
steer = Vector3.ClampMagnitude(steer, maxForce * frostMultiplier);
rb.AddForce(steer, ForceMode.Acceleration);

if (rb.velocity.magnitude > maxSpeed * frostMultiplier)
rb.velocity = rb.velocity.normalized * maxSpeed * frostMultiplier + Vector3.up * rb.velocity.y;

Vector3 lookDir = Vector3.ProjectOnPlane(toTarget, Vector3.up);
if (lookDir.sqrMagnitude > 0.001f)
{
Quaternion targetRot = Quaternion.LookRotation(lookDir.normalized);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, angularSpeed * Time.fixedDeltaTime);
}
}

public void SetMultiplier(float m)
{
// 1) Ограничиваем целевое значение
targetMultiplier = Mathf.Clamp01(m);

// 2) Сбрасываем сглаживание, чтобы frostMultiplier стал равен targetMultiplier сразу
smoothVelocity = 0f;
frostMultiplier = targetMultiplier;

// 3) Моментально корректируем текущую скорость Rigidbody
Vector3 v = rb.velocity;
// оставляем вертикальную компоненту y без изменений,
// а горизонтальную (x,z) умножаем на новый множитель
Vector3 horiz = new Vector3(v.x, 0f, v.z) * frostMultiplier;
rb.velocity = horiz + Vector3.up * v.y;
}

}