Access variable of same script with many instances
Hello guys , I have a script called movement. This script contains a variable called Height. The Movement script is placed on two gameObjects in the scene. I have another script called Manager. At some point the Manager script has to access the Height from the two Movement scripts and change it. What i did is the following in the manager script public Movement [] Movement; And dragged and dropped the two Objects that has the Movement scripts. I think this way is not good and would like to find a better more efficient alternative . I am not sure that a static variable will help since the Height needs to be 0 each time the player restarts the level. Any suggestions? Thanks a lot for the help!
Answer by andrew-lukasik · Jun 22, 2017 at 08:40 PM
You can try events/method groups (or whatever it's actually called). Idea here is to have a public static field to which you can subscribe/unsubscribe methods of it's matching type (here - subscribing methods must accept 1 float argument). Then you can access and execute this event/method group what will execute all subscribed methods so far (so on all instances here)
public class Manager : MonoBehaviour
{
void Start ()
{
//reset height:
if( Movement.changeHeight != null )
{
Movement.changeHeight( 0f );
}
}
void LaterOn ()
{
//set new height:
if( Movement.changeHeight != null )
{
Movement.changeHeight( 1f );
}
}
}
public class Movement : MonoBehaviour
{
float _height;
//public static event/method group to which methods can be subscribed:
public static System.Action<float> changeHeight;
void OnEnable ()
{
//subscribe to event when object is activated:
changeHeight += OnHeightChanging;
}
void OnDisable ()
{
//unsubscribe from event when object is deactivated:
changeHeight -= OnHeightChanging;
}
//method that got subscribed (handling _height change):
void OnHeightChanging ( float newHeight )
{
this._height = newHeight;
}
}
OR you can handle this with list of instances. This is imo simpler solution, you can stick to this for now and try events another time.
Idea here is to make Movements class maintain static and always up to date list of existing instances of it's type. Then any class can access those whenever needed:
/// <summary>
/// Manager class
/// </summary>
public class Manager : MonoBehaviour
{
#region monobehaviour_methods
void Start ()
{
//reset height:
foreach( var item in Movement.instances )
{
item.SetHeight( 0f );
}
}
#endregion
#region public_methods
/// <summary>
/// Some method you execute later on
/// </summary>
void LaterOn ()
{
//set new height:
foreach( var item in Movement.instances )
{
item.SetHeight( 1f );
}
}
#endregion
}
using System.Collections.Generic;
/// <summary>
/// Movement class
/// </summary>
public class Movement : MonoBehaviour
{
#region fields
/// <summary>
/// This list will store all existing instances of type Movement
/// </summary>
public static List<Movement> instances = new List<Movement>();
/// <summary>
/// height value
/// </summary>
float _height;
#endregion
#region monobehaviour_methods
void OnEnable ()
{
//add this to list of instances:
instances.Add( this );
}
void OnDisable ()
{
//remove this from list of instances:
instances.Remove( this );
}
#endregion
#region public_methods
/// <summary>
/// Sets the height.
/// </summary>
public void SetHeight ( float newHeight )
{
this._height = newHeight;
}
#endregion
}
sorry , I didn't understand . Could you please include a bit more detailed explanation ? Thank you in advance
Ok, updated. I added few more explanations and 1 whole different approach (static list of instances)
Your answer
Follow this Question
Related Questions
Array index out of range. But it doesn't appear to be. 2 Answers
Custom inspector. Pick one bool from a list. 1 Answer
Assign values to array elements 1 Answer
Get value from another script 1 Answer