- Home /
Function with parameters, wrong values assigned
Hello, as a beginner in Unity, I recently started developing a small 2D-shoot 'em up and came across a problem with the parameters in one of my functions.
The script is supposed to spawn a number of enemies in a certain formation, using a prefab and the Instantiate function. The formation in which they're spawned is determined by several calls of the 'SpawnEnemy'-function, where certain variables, like the position on the x-achsis or the distance from the 'core' are assigned. They will then automatically move depending on that core's position due to a separate script.
I also use the translate function on the spawned objects to construct a movement pattern, and this is where I saw what didn't work about the function. In most cases, it assigned the wrong parameters. Enemy3 and Enemy6 are spawned properly, but for the other ones the variable dis, or CoreDistance, was reversed, so -8 became 8 and as the other way around. The debug console even shows the right values, but they were still assigned wrong somehow. The wrong values cause them to move in the right pattern, but starting from the wrong position, so the pattern doesn't work the way it's supposed to.
So far I have found two workarounds, but neither one is very satisfying. One would be to copy the prefab for 'SmallEnemy' and replace 'SmallEnemy' with that one in some places. It seems calling the function several times after another with the same prefab might have caused the problem. But I don't like that solution since it defeats the purpose of prefabs entirely. The other one would be to replace the spawned enemies in the translate functions according to the place where they were spawned, instead of the one where they were supposed to be spawned. That way they would also move properly, but that solution would be even worse and turn the code into kind of a mess.
I didn't come across any similar cases, so I'm not sure if a problem like this surfaces more often, but I would be thankful for some help. I also ask you to excuse some grammatical errors you might come across, english is not my first language.
using UnityEngine;
using System.Collections;
public class FormationOne : MonoBehaviour {
public GameObject SmallEnemy = null;
public GameObject SmallEnemy2 = null;
public GameObject BigEnemy = null;
public float PlayerDis;
bool MoveDir=true;
public GameObject SupportEnemy = null;
GameObject Enemy1;
GameObject Enemy2;
GameObject Enemy3;
GameObject Enemy4;
GameObject Enemy5;
GameObject Enemy6;
//Funktion zum Spawnen von Gegnern, gleichzeitiges Zuweisen der Position anhand eines Vektors und dem individuellen Abstand vom Spieler
GameObject SpawnEnemy(GameObject Enemy, float xpos, float dis, int index)
{
GameObject E;
//Zuweisen des Mittelpunkts als "FormationCore" für den spawnenden Gegner
Enemy.GetComponent<Behavior>().FormationCore=this.gameObject;
Vector3 EPos = new Vector3 (xpos, 0, this.transform.position.z+dis);
E= (GameObject)Instantiate (Enemy, EPos, Enemy.rigidbody.rotation);
//Festlegen des Abstands zwischen Kern und Gegner
Enemy.GetComponent<Behavior>().CoreDistance=dis;
E.name = "Enemy" + index;
Debug.Log (E.name + " was spawned at " + " " + xpos + " " + dis);
return E;
}
void SpawnAll()
{
Enemy1 = SpawnEnemy (SmallEnemy, 7.5f, 8, 1);
Enemy2 = SpawnEnemy (BigEnemy, 0.0f, 8, 2);
Enemy3 = SpawnEnemy (SmallEnemy, -7.5f, 8, 3);
Enemy4 = SpawnEnemy (SmallEnemy, 7.5f, -8, 4);
Enemy5 = SpawnEnemy (BigEnemy, 0.0f, -8, 5);
Enemy6 = SpawnEnemy (SmallEnemy, -7.5f, -8, 6);
}
// Use this for initialization
void Start () {
SpawnAll ();
}
//Automatische Bewegung des Kerns mit MovePoint, Bewegung der Gegner nach festgelegtem Muster
void Update () {
GameObject player_ship = GameObject.FindGameObjectWithTag ("MovePoint");
transform.position = new Vector3 (0.0f, 0.0f, player_ship.transform.position.z + PlayerDis);
//Gegner werden teilweise mit falschen Parametern gespawnt, daher vertauschen einzelner Figuren
if(MoveDir)
{
Enemy1.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemy2.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemy3.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemy4.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemy5.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemy6.transform.Translate (Vector3.left * Time.deltaTime * 2);
if(Enemy1.transform.position.x>=10) MoveDir=false;
}
else
{
Enemy1.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemy2.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemy3.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemy4.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemy5.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemy6.transform.Translate (Vector3.right * Time.deltaTime * 2);
if(Enemy3.transform.position.x<=-10) MoveDir=true;
}
}
}
Answer by Kotano · Aug 25, 2014 at 08:08 PM
I just solved the problem by using classes instead of a function. I'll post my updated code in case someone comes across a similar problem.
using UnityEngine;
using System.Collections;
public class Formation : MonoBehaviour {
public GameObject SmallEnemy = null;
public GameObject SmallEnemy2 = null;
public GameObject BigEnemy = null;
public GameObject SupportEnemy = null;
//Distanz des 'Kerns' vom Spieler
public float PlayerDis;
public int formation;
private int i;
private int l;
private int mem;
bool MoveDir=true;
//Array aus den Gegnern, die gespawnt werden
Enemy[] Enemies;
//Gegnerklasse, gleichzeitiges Spawnen des entsprechenden Gegnertyps. In jeder der Spawn-Funktionen benutzt
public class Enemy
{
public GameObject E;
public Enemy(GameObject Type, float xpos, float dis)
{
Vector3 EPos= new Vector3(xpos,0.0f,dis);
E= (GameObject)Instantiate(Type,EPos,Type.rigidbody.transform.rotation);
E.GetComponent<Behavior>().CoreDistance=dis;
}
}
//Spawn-und Bewegungsfunktionen, jeweils in Start- und Update-Funktion benutzt
void FormationOneSpawn()
{
i = 0;
mem = 6;
Enemies=new Enemy[mem];
Enemies[0] = new Enemy (SmallEnemy, 7.5f, 8);
Enemies[1] = new Enemy (BigEnemy, 0.0f, 8);
Enemies[2] = new Enemy (SmallEnemy, -7.5f, 8);
Enemies[3] = new Enemy (SmallEnemy, 7.5f, -8);
Enemies[4] = new Enemy (BigEnemy, 0.0f, -8);
Enemies[5] = new Enemy (SmallEnemy, -7.5f, -8);
for (l=0; l<mem; l++) {
Enemies[l].E.GetComponent<Behavior>().FormationCore=this.gameObject;
}
}
void FormationOneMove()
{
GameObject player_ship = GameObject.FindGameObjectWithTag ("MovePoint");
transform.position = new Vector3 (0.0f, 0.0f, player_ship.transform.position.z + PlayerDis);
//Gegner werden teilweise mit falschen Parametern gespawnt, daher vertauschen einzelner Figuren
if(MoveDir)
{
Enemies[0].E.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemies[1].E.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemies[2].E.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemies[3].E.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemies[4].E.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemies[5].E.transform.Translate (Vector3.left * Time.deltaTime * 2);
if(Enemies[0].E.transform.position.x>=10) MoveDir=false;
}
else
{
Enemies[0].E.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemies[1].E.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemies[2].E.transform.Translate (Vector3.left * Time.deltaTime * 2);
Enemies[3].E.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemies[4].E.transform.Translate (Vector3.right * Time.deltaTime * 2);
Enemies[5].E.transform.Translate (Vector3.right * Time.deltaTime * 2);
if(Enemies[2].E.transform.position.x<=-10) MoveDir=true;
}
}
void Start()
{
switch (formation)
{
case 1: FormationOneSpawn();
break;
case 2: FormationTwoSpawn();
break;
}
}
void Update()
{
switch (formation)
{
case 1: FormationOneMove();
break;
case 2: FormationTwoMove();
break;
}
}
}
Your answer
Follow this Question
Related Questions
Stop Object From Moving After Key Release 2 Answers
Instantiate moving prefab 1 Answer
Is mixing movement types a bad thing to do? (Force and Translate) 1 Answer
Look Where You're Going 3 Answers
How to move character X and Z axis? 1 Answer