1
\$\begingroup\$

What are some ideas or ways that I can increase the efficiency of this gravity script because it is way to depending for what i want it for.

The game has a target at the center and there are objects far away all around the target and when gravity script is enabled I create an overlap sphere check which objects have a rigidbody and collision and pull them to target at a constant speed, but my FPS drops to the floor.

Would it be more efficient to have a script in each of these objects with a AddForce and direction towards target? Or any other ideas? Maybe something to change in this current script?

Am I right on the gravity script being too demanding because of the distance the gravity script is checking?

[RequireComponent(typeof(Rigidbody))]
public class Gravity : MonoBehaviour
{
private Rigidbody ownBody;
[HideInInspector]
public float maxVelocityOfInfluence;
private float rangeOfInfluence = 7000.0f;

private void OnEnable()
{
    if (ownBody == null)
    {
        ownBody = GetComponent<Rigidbody>();
    }
}

private void FixedUpdate()
{
    Collider[] cols = Physics.OverlapSphere(transform.position, rangeOfInfluence);
    List<Rigidbody> rbs = new List<Rigidbody>();

    foreach (Collider c in cols)
    {
        Rigidbody otherBody = c.attachedRigidbody;
        if (otherBody != null && otherBody != ownBody && !rbs.Contains(otherBody) && 
HasTagDownHierarchy(otherBody.transform, "Boat"))
        {
            rbs.Add(otherBody);

            Vector3 offset = transform.position - c.transform.position;
            otherBody.velocity = (offset.normalized * maxVelocityOfInfluence);
        }
    }
}

private static bool HasTagDownHierarchy(Transform transform, string tag)
{
    if (!transform)
    {
        return false;
    }

    if (transform.CompareTag(tag))
    {
        return true;
    }

    foreach (Transform child in transform)
    {
        if (HasTagDownHierarchy(child, tag))
        {
            return true;
        }
    }

    return false;
}
\$\endgroup\$
1
\$\begingroup\$

You are allocating like crazy use Physics.OverlapSphereNonAlloc

dont do List<Rigidbody> rbs = new List<Rigidbody>();

Replace with o(1) lookup HasTagDownHierarchy(otherBody.transform, "Boat") also avoid tags. Use markup classes.

edit: With look up I mean, in Boat Awake method cache the Colliders in a look up Dictionary<Collider, Boat>

\$\endgroup\$
10
  • \$\begingroup\$ I will do what you say thank you! The thing is once objects reach target, new objects get spawned again. \$\endgroup\$
    – WokerHead
    Jun 18 '20 at 15:36
  • \$\begingroup\$ What do I do instead of List<Rigidbody> ? \$\endgroup\$
    – WokerHead
    Jun 18 '20 at 15:37
  • \$\begingroup\$ You should probably use a pool then. Use a hashmap instead of the List its o(1). clear it each iteration \$\endgroup\$
    – Anders
    Jun 18 '20 at 15:40
  • \$\begingroup\$ okay so I created the HashSet, I added an Add() and Remove() on Enable() and Disable(), now how do I incorporate Physics.OverlapSphereNonAlloc and Time.fixedDeltaTime? Mind helping me out? \$\endgroup\$
    – WokerHead
    Jun 18 '20 at 18:53
  • \$\begingroup\$ Physics.OverlapSphereNonAlloc takes an array that it fills with the overlapping colliers. Make sure to make it big enough so that it can always contain all collders that you can overlap. But not too big for memory. The integer returned from it is the actual number of found colliders \$\endgroup\$
    – Anders
    Jun 18 '20 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.