- Home /
Please help my head is burning from this problem : i have multiple gameobject , same script
Hey dears , i have multiple gameObject with the same script all alright but when i execute the script take the last instance variables , i want it to take on every gameobject the variable that i assigne it on it please help :
Edit : I'm so sorry for my bad English , yeah the problem was that I want to pair two doors so the player enter in one door and exit from the other (the other door is a transform that I have to initialize it from the inspector for every door) so the script work just for the last door but If I enter in the first one it take the transform of the last instance of the door
using UnityEngine;
using System.Collections;
public class NewDoorScript : MonoBehaviour
{
bool touchDoor;
GameObject player;
public Transform otherDoor; // this is the variable that change on every
gameobject
public bool lastLevel;
public string levelName;
Animator anim;
private static bool openTheDoor;
public static bool enter;
static bool goBack;
// Use this for initialization
void Start ()
{
touchDoor = false;
openTheDoor = false;
this.anim = GetComponent<Animator>();
goBack = true;
player = GameObject.FindGameObjectWithTag("Player");
otherDoor = this.GetComponent<NewDoorScript>().otherDoor;
}
public void enterTheDoor ( bool enterF )
{
enter = enterF;
Debug.Log("hello");
}
public static void openDoorFun ()
{
openTheDoor = true;
}
// Update is called once per frame
void Update ()
{
if (/*enter Input.GetKey("space")*/openTheDoor && touchDoor)
{
if (lastLevel)
{
Application.LoadLevel(levelName);
enter = false;
}
else
{
this.anim.SetBool("openDoor", true);
}
}
else
{
// openTheDoor = false;
}
}
public void gbf ()
{
player.transform.position = new Vector3(otherDoor.position.x, otherDoor.position.y, -1); // here it take the last gameobject's otherDoor variable not the current
goBack = false;
otherDoor.GetComponent<Animator>().SetBool("openDoor", true);
}
}
I'm not 100% sure what you're asking here.
Are you saying that every game object with this script operates on the same "otherDoor" object? If so, make sure you're setting the variable correctly in each instance of the object in the inspector.
If this is not what you are saying... please clarify
Answer by Lili-Shi · Jun 14, 2017 at 06:43 PM
Honestly, I couldn't really understand what the problem is, because I wasn't really able to extract any useful information.
Anyways, from what I did understand, you problem seem's to be, that the Transform variable "otherDoor" doesn't change it's value whatsoever, right? Did I understand correctly, that "otherDoor" is the variable, of where the player will be land, after entering the door? Do you set the "otherDoor"-value of each gameObject in the inspector (I am asking, because it's public, and you declared it empty)?
Anyways, maybe this helps: You might want to remove the following line in the "Start"-method: otherDoor = this.GetComponent().otherDoor;
because it's redundant. Also, there a few ways to accomplish the changing of the "otherDoor"-variable, for example: -1) You leave it public, so it can be changed/accessed from outside the script, ie from the inspector. -2) In a script, that may function as a sort of scene-manager, you create a List or an Array and an algorithm, which get's each GameObject with Tag or Name "Door", or something like that, and add's an instance of the "NewDoorScript" Type to those GameObjects and the List/Array. Oh, I forgot to mention: You may also want to add a publicly fetchable int-variable, that holds at which index that instance is. Then, you can use the index, to get the position, of the of other door. Let me show you what I mean:
SceneManager.cs:
using System.Collections.Generic;
using UnityEngine;
public class SceneManager : MonoBehaviour
{
List<NewDoorScript> newDoorList = new List<NewDoorScript>();
static SceneManager smInstance;
public static SceneManager Instance
{ // You may want to extend this to be a singleton pattern.
get
{
return smInstance;
}
}
private void Awake()
{
// Again, you may want to make this a proper singleton pattern.
smInstance = this;
AlgorithmOne();
/*
* Now, you might want to reverse the list, because
* the GameObjects are collected form bottom-to-top,
* viewed from the editor perspective. However, I
* advise you to put each GameObject tagged "Door"
* into a parent GameObject, which has no parent
* (in the scene)
* Example (the number of dashes represent at which
* point in the parenting the object is):
* {
* Main Camera
* Directional Light
* HUD-Canvas
* Doors
* -Door 1
* -Door 2
* -Door 3
* -Door 4
* -Door 5
* -Door 6
* Rooms
* -Room 1
* --Components
* -Room 2
* --Components
* }
* And so on.
* Now, this example implies, that you always need to have
* an even number of doors, obviously, so no triplets occur,
* also take a look into my "gbf"-method in NewDoorScript.cs!!
*/
newDoorList.Reverse();
}
void AlgorithmOne()
{
GameObject[] _doors = GameObject.FindGameObjectsWithTag("Door"); // Get every door
int _iteration = 0; // Just so we know at which iteration we are
foreach (GameObject _door in _doors)
{ // Yes, you could use a for-loop, but screw it. :3
_door.AddComponent<NewDoorScript>(); // Add a script instance
_door.GetComponent<NewDoorScript>().index = _iteration; // Set the index-value to the current iteration
_iteration++; // Increment the iteration
}
}
public NewDoorScript FetchPairedDoor(int _index)
{
NewDoorScript _pairedDoor = null;
/*
* THe following example implies, that
* i.e. the paired door of Door 1 is Door 2
* and the paired door of Door 2 is Door 1
* and the paired door of Door 5 is Door 4
* Basically, if the given index is even
* (i.e. divisible by 2 w/o remainder), the
* paired door is the index +1, otherweise
* it's the index -1
* BUT REMEMBER! This system implies you to have
* an even number of doors in total in the scene!
*/
if (_index % 2 == 0)
{
_pairedDoor = newDoorList[++_index];
}
else
{
_pairedDoor = newDoorList[--_index];
}
return _pairedDoor;
}
}
NewDoorScript.cs: using UnityEngine;
public class NewDoorScript : MonoBehaviour
{
SceneManager sceneManager;
GameObject player;
public int index;
private void Awake()
{
sceneManager = SceneManager.Instance;
player = GameObject.FindGameObjectWithTag("Player");
}
void gbf()
{
GameObject _pairedDoorObject = sceneManager.FetchPairedDoor(index).gameObject;
player.transform.position = new Vector3(_pairedDoorObject.transform.position.x, _pairedDoorObject.transform.position.y, _pairedDoorObject.transform.position.z - 2.0f);
/*
* Now, you will need to optimize that bit of code, to fit your naming-convention
* and also you need to implement the offset (_pairedDoorObject.transform.position.z - 2.0f)
* in a way, that fits your specific level-design. I only took that as a general example, bear
* that in mind!
*/
}
}
It should kind of work, haven't really tested it, but again: It's only a barebones construct, so you get an idea, of how that would work! You need to customly implement that!
Hope that helps a bit!
Thank you very much I'm so sorry for my bad English , yeah the problem was that I want to pair two doors so the player enter in one door and exit from the other (the other door is a transform that I have to initialize it from the inspector for every door) so the script work just for the last door but If I enter in the first one it take the transform of the last instance of the door . I will try your scripts and respond to you , thank you for your time .
but if I want to assign one specific door to another door how to do that
Hey, sorry for not replying anymore. I wasn't able to login for a while.
Anyways, you probably solved the issue already, but here's the concept behind what I wrote above: Your level has to be designed, so that there are only an even number of doors present, so that each and every door has at least and at maximum one (and exactly one) paired door. In order to pair up two doors, you just ahve to set them up in the correct way in the inspector. Here's what would work: Hierarchical structure in the Inspector:
{
Doors
-Cafeteria Frontdoor Outside
-Cafeteria Frontdoor Inside
-Cafeteria Backdoor Inside
-Cafeteria Backdoor Outside
}
or
{
Doors
-Cafeteria Frontdoor Inside
-Cafeteria Frontdoor Outside
-Cafeteria Backdoor Outside
-Cafeteria Backdoor Inside
}
Here, Frontdoor Inside and Frontdoor Outside get paired, because the amount of doors is even and these doors are exactly 1 step apart from each other. Backdoor Outside and Backdoor Inside also get paired, for the exact same reason the Frontdoors get paired.
Here's what would NOT work (as intended at least):
{
Doors
-Cafeteria Frontdoor Outside
-Cafeteria Backdoor Outside
-Cafeteria Frontdoor Inside
-Cafeteria Backdoor Inside
}
This wouldn't work as intended, because Frontdoor Outside and Backdoor Outside get paired, and Frontdoor Inside get's paired with Backdoor Inside. This mean's, if you'd try to use Frontdoor Outside, you'd end up at the inner rear end of the Cafeteria. If you'd try to use Backdoor Inside you'd end up at the outter front of the Cafeteria, not the outter rear end.
vv That part of the above code is responsible for knowing which doors are paired up, based on the given index. vv
public NewDoorScript FetchPairedDoor(int _index)
{
NewDoorScript _pairedDoor = null; // explicitely set _pairedDoor to null
if (_index % 2 == 0)
{
// If the given index is even, then count 1 up and that's the paired door
_pairedDoor = newDoorList[++_index];
}
else
{
// If the given index is odd, then count 1 down and that the paired door
_pairedDoor = newDoorList[--_index];
}
return _pairedDoor;
}