[SOLVED] Creating units in a circle woes.

I’m trying to create units at a point that will move away from their starting point in a circle, like a nova in RPGs but my code is not working and I can’t figure out why.

Debug.Log ("Nova activated.");
                        for (int i = 0; i < projectiles; i++) {
                                float increment = (i * 1.0f) / projectiles;
           
                                float angle = increment * Mathf.PI * 2;
           
                                float x = Mathf.Sin (angle);
                                float y = Mathf.Cos (angle);
           
                                Vector2 newTargetPosition = new Vector2 (x, y) + (Vector2)transform.position;                       
                                Debug.Log ("Nova " + i);
                                Debug.Log (newTargetPosition);
                                Projectiles.Projectile.Create (projectilePrefab, transform.position, newTargetPosition, stats, damageRatio);
                        }

Let’s clean up this code a little bit, things like multiplying by 1.0f and what not… also so we can generalize it.

float radius = 1.0f; //size of circle that is created

for(int i = 0; i < projectiles; i++)
{
    float angle = ((float)i / (float)projectiles) * Mathf.PI * 2f;
    Vector2 pos = new Vector2(Mathf.Sin(angle), Mathf.Cos(angle));
    //expand to size of circle
    pos *= radius;
    //translate relative to this position
    pos.x += this.transform.position.x;
    pos.y += this.transform.position.y;
  
    //now this part, I don't know what it does... see comments in post
    Projectiles.Projectile.Create(projectilePrefab,
                                 transform.position,
                                 pos,
                                 stats,
                                 damageRatio);
}

I just needed that so it’s clear what’s going on… I understood your code, but your mixing of types and the sort made me unsure if type errors were going on (integer division rounding off fractions and the sort). This code I wrote I know works… with an exception.

Now, that code up to Projectiles.Project… results in a circle of some radius around the local scripts gameobject. Thing is, I don’t know what Projectiles.Projectile.Create does… you pass in both the local position, as well as the position you generated. Why? What is both used for? Are problem arising in that function?

Since it’s not a function native to Unity, I have no idea.

How about a description of the problem you are having and start with that…

Assuming everything is as it shows… you are not moving anything; instead you are creating a ton of game objects. Do they die over time? We need more information about your problem.

Hmm that code is yielding the same thing the previous one did.
I think the problem could be with Projectile.Create. here’s the function:

        public static GameObject Create (GameObject projectilePrefab, Vector2 position, Vector2 targetPosition, Stats caster, float damageRatio)
        {     
            Debug.Log (projectilePrefab + " created by " + caster);
            var projectile = Instantiate (projectilePrefab, position, Extensions.Rotate (position, targetPosition)) as GameObject;
            var stats = projectile.GetComponentInChildren<Projectile> ();
            var move = projectile.GetComponentInChildren<MoveBehaviour> ();

            Debug.Log ("Caster " + caster);
            Debug.Log ("Stats " + stats);

//            stats.teamId = caster.teamId;
//            stats.baseDamage = caster.damage * damageRatio;
            Vector2 v = (targetPosition - position).normalized;
            move.targetPosition = position + v * 30f;
            stats.Kill (stats.lifeSpan);

            return projectile;
        }

@lordofduct What ends up happening is the first 3 and last 3 projectiles are all bunched up together while the 6th one is in the middle and doesn’t move.

I honestly don’t even know how to start to begin to explain everything wrong with everything you have written there.

Your code is disorganized, named poorly, and generally enigmatic to determine what any given line of code even means.

Let me suggest some guidelines:

  1. Name a function for what it actually does. This function does not just create, it creates and does a bunch of other stuff. If what it does is too complex to describe, document what it does in a few short sentences.

  2. the parameters that get passed into the function should be named something that makes sense. What is ‘position’ and ‘targetPosition’? What do they represent?

  3. Don’t split half the work between two places arbitrarily. If Create is supposed to do the work of placing something in a circle, and applying some trajectory relative to that circle (only reason I could think of passing in the center of the circle and its around the circle), then it should do that. Not do half of that and expect the code that calls it to do all the work for you.

Naming is your big problem here. Think about it this way… when you name something, name it in a manner that you couldn’t easily open up the file and read the code inside of it. If from the name, and short sentence or 2 describing said class or function is not enough to get a general idea of what’s going on… your function is not named well… if you can’t think of a name and short description for it, then it’s designed poorly.

So your Create method.

What is the ‘position’ parameter? Because you’re passing in the position that is the center of the circle, but the Create method uses it as the position where the projectile gets instantiated.

What is the ‘targetPosition’ parameter? Because you’re passing in the calculated position on the circle that I THOUGHT was where the projectile should be spawned. But you use it as a paramter to yet another unknown function ‘Rotate’ that is used as the rotation of the instantiated projectile, as well as to determine the trajectory the projectile takes. But NEVER as the position it starts at! So of course it doesn’t appear in the position you expect, you never set it to the position you expect.

I’m not going to even get into the ‘caster’ and ‘damageRatio’ parameters, especially since you don’t even use them in the function.

Note, I’m not asking these questions for you to answer them to me. I don’t care, honestly. I’m asking in a rhetorical manner. These are things you should be asking yourself! You wrote this function, yet you called it by passing in the wrong parameters to the wrong slots.

Remember that whole about writing a function with names that make sense? Yeah… even you, the author of this function, don’t know how to call it correctly because the name and design is so convoluted. How do you expect us to know how to solve your problem, with out even seeing the code?

Your code inside of Create calls even more functions and properties (Extensions.Rotate, targetPosition, Kill). I have NO idea what these functions and properties do. Do you? Because I’m weary as to what they do as well that might cause more issues as to why your projectiles show up in weird positions.

1 Like

I fixed it. I forgot I had been playing with layers and colliders which caused the projectiles to have the wrong layer and collide with each other.

But I disagree with you that it’s badly named.
Nova is the name of the class that decided to create projectiles in a circle. To create a projectile, a class must go through Projectile.Create. There are many classes that need to create Projectiles. I have classes like “Blizzard” which creates Projectiles from the top of the screen and tells them to move towards the ground, for example.
It does more than just “Instantiate” a GameObject because if that’s all it did, I would just use Unity’s built-in function. To me Create also implies the initialization of the object so that it’s ready for use. It creates it at a position, and orders it to move to a targetPosition (which is what projectiles do). It also sets its damage from damageRatio, which is the damageRatio of the spell since only spells can create Projectiles.
Extensions.Rotate just tells it to face the targetPosition.
Position is the position the Projectile is created at. I guess I could rename it spawnPosition.

It makes sense to me. Does it not make sense to you now or do you still think my way is wrong?

Anyway, thanks for your help lordofduct, you’re a very knowledgeable poster and I don’t know what I would do without your help. :stuck_out_tongue:

I agree, if all Create did is Instantiate, it would be pretty much useless.

That’s not what I was saying though. I was saying that it’s hard to determine what it does beyond Instantiate, if its name is merely ‘Create’, and there is no short description of it attached. Especially when the parameters were as confusing as they are.

Happy your resolved your problem though.