Задача
Вы можете НЕ использовать переменную для передачи ее в общую версию GetComponemt
, например
public void DoSomething(Type componemtType)
{
var component = GetComponent<componentType>();
}
, поскольку типы, используемые для реализации обобщений, должны быть постоянной времени компиляции и поэтому не могут быть переменной (или только той, которая является постоянной времени компиляции)!
Вы можете использовать неуниверсальную версию GetComponent
, такую как
public void DoSomething(Type componentType)
{
var component = GetComponent(componentType);
}
но , чем вам нужно было бы проанализировать его, чтобы иметь доступ к любым полям или методам, специфичным для этого компонента:
var parsedComponent = component as componentType;
И снова вы можете НЕ сделать это, поскольку тип, используемый для as
, также должен быть постоянной времени компиляции и поэтому не может быть переменной.
Решение 1: Общий базовый класс
В случае, если все ваши разные классы имеют общие поля, которые вы хотите сохранить, все они должны наследоваться от общего базового типа, например,
// By making a class abstract it can not be instanced itself but only be implemented by subclasses
public abstract class BaseMovement : MonoBehaviour
{
// fields that will be inherited by subclasses
public int currentWaypointIndex;
public int nextWaypointIndex;
//...
// You could also have some generic methods that are implemented
// only in the subclasses like e.g. Getters for the values
// you want to access
public abstract string SaySomething();
}
А чем наследовать ваши классы от таких как например
public class Warrior_Movement : BaseMovement
{
// Inherits all fields of BaseMovement
//... additional type specific stuff
// If you have abstract methods in the base class
// every subclass has to implement all of them
public override string SaySomething()
{
return "Harr harr, I'm a warrior!";
}
}
public class Other_Movement : BaseMovement
{
// Inherits all fields of BaseMovement
// Additional type specific stuff
// If you have abstract methods in the base class
// every subclass has to implement all of them
public override string SaySomething ()
{
return "Harr harr, I'm ... something else :'D ";
}
}
Чем вы можете использовать что-то вроде
void SaveCharacter(Character character, BaseMovent bMovement)
{
character.position = new float[] { bMovement.transform.position.x, bMovement.transform.position.y, bMovement.transform.position.z };
character.currentWaypointIndex = bMovement.currentWaypointIndex;
character.nextWaypointIndex = bMovement.nextWaypointIndex;
}
и назовите это как
GameObject g = GameObject.Find(gameObjectName);
var movement = g.GetComponemt<BaseMovement>();
SaveCharacter(someCharacter, movement);
Решение 2. Перегрузки
В качестве альтернативы, если вы используете разные значения для разных компонентов, чем не используете общий базовый класс, а вместо этого создаете перегрузки SaveCharacter
, такие как
public void SaveCharacter(Character character, Warrior_Movement wMovement)
{
// Do stuff with wMovement
// ...
}
public void SaveCharacter (Character character, Other_Movement oMovement)
{
// Do stuff with oMovement
// ...
}
, поэтому, когда вы используете SaveCharacter
, типы, которые вы передаете, будут определять, какую реализацию SaveCharacter
следует использовать.
К
Когда я использую, я не могу получить переменные скрипта gameobject.
Я не знаю, что именно вы имеете в виду, но вы можете получить доступ к GameObject
, к которому прикреплен компонент, используя gameObject
например,
bMovement.gameObject.SetActive(true);
Примечание
Если это возможно, вам следует избегать использования Find
, так как это довольно интенсивно. Попробуйте получить ссылку как можно скорее, например, либо путем ссылки на него в Инспекторе с использованием поля public GameObject
, либо, если оно установлено, сохраните его в переменной типа
var warrior = Instantiate (/*...*/);
и раздайте.