• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by GeorgeRigato · Dec 17, 2012 at 10:10 PM · iosmobileperformancecoinmagnet

Coin Magnet Performance Issue Mobile

Another question about performance on mobile (iOS):

I've managed to implement a "coin magnet" system where the player attract the coins dropped by dead enemies.

The basic mechanics are:

-Each coin is pulled towards the player if the distance between them both is less than X. (magnet range) -The amount of movement towards the player each frame is based on a constant "magnet power" and distance over magnet range. So the closer the coin gets, more "force" is applied to it.

The problem is when I got lots of coins in screen the game fps drops lower than 20. The two main reasons I think are doing a FindObjectcsWithTag every frame to get all coins and a getComponent to each coin, every frame.

The possible solituon I first thought was to let the coins handle the magnet behavior instead of the player. But my question is:

Will all coins have a player reference and all the coins have an update cycle each give the same performance drop symptom?

Thanks in advance.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image GeorgeRigato · Dec 18, 2012 at 10:47 PM 0
Share

The thing is that the coin movement depends on data that is stored on player (or at least should be by design as the magnet is a feature of the player). So if I'm not wrong at least at the creation of each coin a getComponent must be used to see the player's magnet values so the coin can move itself. Anyone?

3 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by aldonaletto · Dec 19, 2012 at 02:11 AM

FindGameObjectsWithTag each Update isn't a good idea, for sure. You could try OverlapSphere to find the objects inside the range, and keep the coins in some special layer (layer 8, for instance) to restrict the search (player script):

 var magnetRange: float = 5;
 var minDistance: float = 0.5;
 
 function Update(){
   var coins: Collider[];
   var here = transform.position;
   // find colliders inside range and in layer 8:
   coins = Physics.OverlapSphere(here, magnetRange, 1<<8);
   for (var coin: Collider in coins){
     var tfCoin = coin.transform;
     var dist = Vector3.Distance(tfCoin.position, here);
     if (dist < minDistance){ // closer than minDistance: grab the coin
       Destroy(tfCoin.gameObject);
       // add the points to your score
     }
     else 
     if (dist <= magnetRange){ // inside range: attract it
       var vel = magnetRange / dist; // velocity inversely proportional to distance
       // move coin to the player
       tfCoin.position = Vector3.MoveTowards(tfCoin.position, here, vel * Time.deltaTime);
     }
   }
 }

Only the coins should be kept in layer 8 - other objects in this layer would be attracted too.
NOTE: Since OverlapSphere only verifies the collider bounds, some of them may actually be a little out if range - that's why the distance is verified inside the loop.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image GeorgeRigato · Dec 19, 2012 at 10:02 AM 0
Share

I'll try that out. Thanks.

avatar image GeorgeRigato · Dec 20, 2012 at 08:50 PM 0
Share

I implemented this suggestion of yours. It works, but my performance problems are still there. The thing is, when the coin is within range of the magnet, I call one GetComponent().getHookedBy$$anonymous$$agnet(); to warn it. This is needed because when the coin gets instantiated it has an initial movement to a random nearby position inside a sphere. So when multiple coins are instantiated it creates an explosion effect. But if the magnet gets too close to the coin BEFORE it reaches it final destination, the initial coin movement must be called off, thats the reason of the GetComponent call. Any ideas? $$anonymous$$aybe put the movement on the coin.

avatar image aldonaletto · Dec 21, 2012 at 12:36 AM 1
Share

If you already have some movement script in each coin, maybe moving the attraction code to the coins could improve the performance. Anyway, post the relevant parts of your code in the question - it would be easier to find some way to improve its performance.

avatar image
0

Answer by GeorgeRigato · Dec 21, 2012 at 10:45 AM

Here it goes:


 //This is the script on player - the coin is only collected with an actual trigger collision.
 //And I'm more used to C#, if that is not a problem.
             
             int coinLayer = LayerMask.NameToLayer("coin");
             Vector3 here = transform.position;
             Collider [] tempCoins = Physics.OverlapSphere(here, magnetDistance, 1<<coinLayer);
             
             foreach (Collider obj in tempCoins)
             {
                 Vector3 coinPos = obj.transform.position;
                 float dist = Vector3.Distance(here, coinPos);
                 if (dist < magnetDistance)
                 {
                     obj.GetComponent<MoedaController>().getHookedByMagnet();
                     obj.transform.position = Vector3.MoveTowards(coinPos, here, Time.deltaTime * magnetForce * (magnetDistance / dist));
                 }
             }



//An this is the whole CoinController class

 using UnityEngine;
 using System.Collections;
 
 public class MoedaController : MonoBehaviour {
     
     public int coinValue=1;
     public float spinSpeed = 245;
     public float movementSpeed = 15;
     public float minDistance = 0.01f;
     public GameObject moedaEspecial;
     
     private Vector3 targetPos;
     private bool reachedPosition = false;
     private Quaternion myRotation;
      
     // Use this for initialization
     void Start () {

             //this is for a crazy random rotation behavior the coin has.
         transform.rotation = Random.rotation;//Quaternion.Euler(0, tempYRot, 0);
         myRotation = Random.rotation;
     
     }
     
     void Update () {
         
         //Rotates the coin
         transform.Rotate(myRotation.x * spinSpeed * Time.deltaTime,myRotation.y * spinSpeed * Time.deltaTime,myRotation.z * spinSpeed * Time.deltaTime, Space.Self);
                     
         //Initial movement of the coin to a random position nearby its spawn point
         if (!reachedPosition)
         {
             //move the object
             transform.position = Vector3.Lerp(transform.position, targetPos, movementSpeed * Time.deltaTime);
             
             if (Vector3.Distance(transform.position, targetPos) <= minDistance)
             {
                 reachedPosition = true;
             }
         }
     
     }

     //The object that handles all coin instantiation sends trough this method the range of the random position generation and another int that represents a small chance of this coin being a special coin worth 10x the original value.
     public void setUp(int [] _temp)
     {
         targetPos = Random.insideUnitSphere * _temp[1] + transform.position;
         
         if (Random.Range(0,100) < _temp[0]*3)
         {
             coinValue *= 10;
             transform.GetChild(0).renderer.enabled = false;
             GameObject go = (GameObject) Instantiate (moedaEspecial, transform.position, transform.rotation);
             go.transform.parent = transform;
         }
     }

     //This is maybe the source of the problem. The player calls this method for all coins within magnet range every frame. Without it the coins attracted by the magnet would have two movements at once and often get suck at a point in space.
     public void getHookedByMagnet()
     {
         reachedPosition = true;
     }
 }



And as far as I know somethings about programming, when you change something in one place, you can bet all your money that it will create other problems, I'm foreseeing one right now. The player is able to collect one "super-magnet" powerup that increases its magnet range and power for a time frame. When the code of the coin movement by the magnet get changed to the coin script, what will the best way to collect this data (stored on player?). Can't be GetComponent, as it would make this effort to improve performance useless.

Thank you very much for your help in this.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by garryking · Sep 01, 2014 at 10:56 PM

 public void magneticCoins()
 {
     float magnetForce = 1;
     float magnetDistance = 2;
     int coinLayer = LayerMask.NameToLayer("coin");
     Vector3 here = transform.position;
     Collider [] tempCoins = Physics.OverlapSphere (here, magnetDistance, 1 << coinLayer);
 
     foreach (Collider obj in tempCoins) 
     {

     Vector3 coinPos = obj.transform.position;
     float dist = Vector3.Distance (here, coinPos);
     if (dist < magnetDistance) 
     {
     obj.GetComponent<MoedaController>().getHookedByMagnet();
     obj.transform.position = Vector3.MoveTowards (coinPos, here, Time.deltaTime * magnetForce * (magnetDistance / dist));
     }

     }
 }

tha's it ?

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to improve FPS on mobile? 1 Answer

Why is there a performance discrepancy between LG G4 and iPhone 6s 0 Answers

Texture Quality - Performance for Mobile Devices 2 Answers

Why did my render time increase after lowering the vertex count? 2 Answers

GL ES1 vs ES2 (for iOS) 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges