2017-01-30 3 views
1

я делаю это бить «Em Up игра на единстве, которое имеет следующий механизм (?): Когда попадает коллайдер игрока противника:Unity: Несколько геймобжекты в массиве

public GameObject obj; 
... 

void OnTriggerEnter(Collider collider){ 
obj=collider.gameObject; 
} 

Тогда, когда игрок нападает, если его расстояние до OBJ достаточно мало, противник получает урон:

void hit(){ 
    if(kicked&&close){ //if he is kicking and is close enough 
     obj.GetComponent<health>().DealDamage(damage); //this is inside a try/catch, just in case obj=null 
(...) 
} 

проблема, если 2 врагов прикоснуться к игроку, только последний будет назначена переменным OBJ, поэтому он возьмет только один удар, которого я не хочу.

Любые предложения? Должен ли я заменить

GameObject obj; 

с массивом? Как так?

а затем, по методу OnTriggerEnter, добавить объекты в массив? (Как это сделать?)

+0

размер Массив является неизменным, и вы должны структуру данных, размер которого может динамически сокращаться и расти. Вместо этого используйте «Список». – Abion47

+0

Что делать, если я использую массив больше, чем когда-либо понадобится? –

+1

Альтернативный подход. Используйте метод Physics.OverlapSphere() ', чтобы проверить во время атаки, какие враги находятся в диапазоне атаки игрока, а затем нанести им соответственно (если есть). – Serlite

ответ

-2

У вас есть списки всех объектов на экране, как враги, деревья, коробки и т.д.
И в бесконечном цикле вы делаете какие-то действия со всеми объектами:

while(true) 
{ 
    // Here non combat characters do something. 
    foreach(NonCombatCharacter character in NonCombatCharacters) 
    { 
     switch(character.Type) 
     { 
      case tinyBird: character.DoAction(Actions.Fly); break; 
      case ... 
      default:break; 
     } 
    } 
    // Here your combat character aka enemies 
    foreach(CombatCharacter character in CombatCharacters) 
    { 
     // Here you do your combat logic, cheks and etc. 
    } 
    // And then you player character change the world model, here you 
    // process all player action such as changing position, losing hp. 
    // And then world keep lifecycle again 
} 

EDIT : Таким образом, есть глобальные массивы foreach. В единстве вы их тоже получили, даже если вы не создаете массив.
Здесь вы найдете:
https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html
Использовать документацию, большинство распространенных ответов - все.

+0

Это не отвечает на вопрос. –

+0

На самом деле ответьте, если вы «получите смысл». Это объясняет основы. Я отвечаю за лучший ответ. – Sergio

+1

Как сказал Эван, это не отвечает на вопрос П.П. Массив не предназначен для отслеживания всех объектов во всем мире. Это ссылочный массив для отслеживания и обработки последних столкновений объектов. Мало того, что этот метод будет безумным количеством излишнего, но он также не решает его проблемы. (Также 'while (true)'? Серьезно?) – Abion47

1

Один простой способ состоит в том, чтобы ваш игрок держал триггерную коробку. Когда враги войти в окно запуска, они добавляются в коллекцию и удаляются при выходе:

public class PlayerAttack:MonoBehaviour 
{ 
    private HashSet<Enemy> list = null; 
    private void Awake(){ this.list = new HashSet<Enemy>(); } 
    private void OnTriggerEnter(Collider col) 
    { 
     Enemy enemy = col.transform.GetComponent<Enemy>(); 
     if(enemy != null) 
     { 
      this.list.Add(enemy); 
     } 
    } 
    private void OnTriggerExit(Collider col) 
    { 
     Enemy enemy = col.transform.GetComponent<Enemy>(); 
     if(enemy != null && this.list.Contains(enemy) == true) 
     { 
      this.list.Remove(enemy); 
     } 
    } 
    public void OnAttack() 
    { 
     foreach(Enemy enemy in this.list) 
     { 
      enemy.GetComponent<Health>.DealDamage(damage); 
     } 
    } 
} 

OnAttack вашего метод атаки, который будет перебирать все близкие враг. HashSet - хороший кандидат здесь, так как он не добавит дважды тот же предмет, поэтому не будет риска увидеть, как враг получает несколько ударов.

+0

Я попробовал это, и я получил это сообщение об ошибке Assets/Scripts/movement.cs (16,13): ошибка CS0246: Не удалось найти имя типа или пространства имен 'HashSet'1 '. Вам не хватает указаний по использованию или ссылки на сборку? @Everts это линия 16 частное HashSet list = null; –

+0

Кстати, я использую возвышенный текст, но теперь я понимаю, что monodevelop не распознает HashSet. Может, мне сначала нужно что-то импортировать? –

+0

Когда такие вещи происходят, ваше первое решение - это щелчок правой кнопкой мыши на ошибке, а затем Resolve. Скорее всего, он предложит добавить некоторую директиву использования. В Visual Studio вы можете поместить курсор на ошибку и Ctrl +. (не уверен, что ярлык работает в MonoDevelop). В случае с HashSet вам, скорее всего, не хватает System.Collections.Generic – Everts

0

Мне не удалось решить проблему. Урон никогда не будет назначен.

private HashSet<Enemy> list = null; 

private void Awake(){this.list = new HashSet<Enemy>();} 

void OnTriggerEnter(Collider col){ 

    Enemy enemy = col.transform.GetComponent<Enemy>(); 
    print(enemy); // this occurs 
    if(enemy != null && this.list.Contains(enemy) == true) 
    { 
     print(enemy); // this never occurs 
     this.list.Remove(enemy); 
    } 
    } 
    } 


void hit(){  
    print("hit"); // this occurs 

    foreach(Enemy enemy in this.list) 
    { // this never occurs 
     enemy.GetComponent<health>().DealDamage(damage); 
    } 

@Everts

Смежные вопросы