Пятница, 29 Марта 2024, 05:31

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » наследование и полиморфизм
наследование и полиморфизм
polousДата: Понедельник, 18 Августа 2014, 11:38 | Сообщение # 1
частый гость
Сейчас нет на сайте
Ребята, пожалуйста, дайте подсказку.

Как правильно создать копию/аналог/дубликат объекта с одним и тем же классом, чтобы для каждого из этих копий параметры этого класса были уникальными? Я прочитал о полиморфизме, наследовании, посмотрел на эту тему примеры, но не понимаю, как все-таки реализовать это:
В сцене есть персонаж и есть 2 бота. На ботах висит скрипт, в котором есть параметры, например, одни из паблик параметров - положение бота (или лежит, или сидит, или стоит). Когда я меняю этот параметр в инспекторе, у обоих ботов меняется этот параметр. Мне, как вы поняли, хотелось бы, чтоб не было этого зависимого копирования параметров. Можете подсказать, что для этого нужно сделать?
RvachДата: Понедельник, 18 Августа 2014, 12:09 | Сообщение # 2
частый гость
Сейчас нет на сайте
Не о том, видимо, читал ты.

Вероятно поля ты объявил как static, в итоге и получил поля, общие для целого класса. Убери модификатор static в скрипте у полей и всё должно будет работать.


Мой блог: rvach.blogspot.com
polousДата: Понедельник, 18 Августа 2014, 12:33 | Сообщение # 3
частый гость
Сейчас нет на сайте
Нет, увы, но поля не статик
public int Bla;

Создавал объекты таким образом:
Create -> Cube (это бот №1), затем еще раз Create -> Cube (это бот №2), ну и на каждого один и тот же скрипт с переменной Bla... т.е. я не делал копию первого куба, не делал дубликат, не делал инстэнтиейт в скрипте, не делал префабов и их копий... Иными словами, я не делал родителя и потомка (я так во всяком случае думаю, что не делал потомков, но, видимо, у меня неверная логика).
Так как же сделать объекты с одним скриптом, но с уникальными значениями параметров? О, опытные программисты, подскажите же начинающему)


Сообщение отредактировал polous - Понедельник, 18 Августа 2014, 12:37
SnakeRДата: Понедельник, 18 Августа 2014, 12:43 | Сообщение # 4
постоянный участник
Сейчас нет на сайте
polous, задавать нужные (разные) параметры не в скрипте, а в инспекторе. Кроме того использовать префабы в данном случае очень полезно.

Unity3D Developer
Ваш лучший помощник при разработке в Unity3D
DantorSДата: Понедельник, 18 Августа 2014, 12:58 | Сообщение # 5
заслуженный участник
Сейчас нет на сайте
Inheritance
Каждый раз, когда исходный префаб меняется, эти изменения применяются ко всем его экземплярам. Для примера, если добавить новый скрипт к префабу, то все экземпляры будут тоже содержать этот скрипт. Однако, можно изменять свойства экземпляра не затрагивая префаб и связи с ним. При простом изменении свойства экземпляра имя этого свойства будет написано жирным начертанием. Если затем изменить это свойство в префабе, то на экземпляре это не скажется.

Можно изменять экземпляры и создавать уникальные объекты, не нарушая связей с префабом.


Сообщение отредактировал DantorS - Понедельник, 18 Августа 2014, 12:58
RvachДата: Понедельник, 18 Августа 2014, 13:02 | Сообщение # 6
частый гость
Сейчас нет на сайте
Цитата SnakeR ()
polous, задавать нужные (разные) параметры не в скрипте, а в инспекторе.

Он же и написал, что задаёт параметры в инспекторе.

polous, странно, всё у тебя должно работать корректно, проделал твои действия сам, но с твоей проблемой не столкнулся.

ЗЫ в данной ситуации наследованием и тем более полиморфизмом и не пахнет


Мой блог: rvach.blogspot.com

Сообщение отредактировал Rvach - Понедельник, 18 Августа 2014, 13:05
ArtanielДата: Понедельник, 18 Августа 2014, 13:09 | Сообщение # 7
частый гость
Сейчас нет на сайте
Конечно хотелось бы видеть код скрипта полностью. Отладка кода которого не видел это всегда тыканье пальцами в небо.

Тыкну вот сюда:
Если включить выполнение программы, изменить чтото в инспекторе, потом выключить, изменения вернутся в то состояние, которое было на момент запуска. Возможно этот эффект виноват. Если пытаться настраивать параметры после запуска приложения, даже на паузе, все отменится при остановке выполнения.
Может еще каким то образом были выделены оба объекта во время правки. Юнити достаточно хитрож...умная среда чтобы самостоятельно распихать переменные по схожим скриптам.


Сообщение отредактировал Artaniel - Понедельник, 18 Августа 2014, 13:20
MANMANAДата: Понедельник, 18 Августа 2014, 14:02 | Сообщение # 8
почти ветеран
Сейчас нет на сайте
В скрипте нет поиска объекта(ов) по имени/тагу и изменения его переменных?

http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
polousДата: Понедельник, 18 Августа 2014, 14:19 | Сообщение # 9
частый гость
Сейчас нет на сайте
Ок, не думал просто, что до этого дойдет, выкладываю скрипты

здесь скрипт, который висит на 2х ботах:
Код

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {
  public GameObject enemy;
  public int EnemyPosition = 2;
  // EnemyPosition = 2 - враг стоит
  // EnemyPosition = 1 - враг сидит
  // EnemyPosition = 0 - враг лежит

  void Start () {
  }

  void Update () {
  }
}


а вот скрипт, который висит на другом объекте (игрок):
Код

using UnityEngine;
using System.Collections;

public class FindEnemies : MonoBehaviour {
  public Player plr; // переменная-ссылка на класс Player (далее это будет ссылка на объект player)
  public Player _aov; // переменная-ссылка на класс Player (далее это будет ссылка на переменную aov)
  public Player _dov; // переменная-ссылка на класс Player (далее это будет ссылка на переменную dov)
  float distance; // расстояние между положением игрока и положением врага
  float angle; // угол между игроком взглядом игрока в направлении "вперед" и положением врага
  float offset; // поправка к дальности обзора игрока при смене позиции врага
  GameObject[] enemies;
  // метод, который ищет объект с именем "Enemy", затем ищет у него компонент (скрипт) Enemy и  
  // читает из скрипта переменную EnemyPosition (позиция врага)
  // далее он перебирает все возможные варианты переменной EnemyPosition (стоит, сидит, лежит) и
  // изменяет переменную offset - поправка к дальности обзора игрока при попытке обнаружения врага
  public void EnemyPosition()  
  {
   switch (GameObject.Find ("Enemy").GetComponent<Enemy> ().EnemyPosition) {
    case 0:  
    offset = 8f;
    //Debug.Log("Lying enemy;  offset = " + offset);
    break;
    case 1:
    offset = 4f;
    //Debug.Log("Sitting enemy;  offset = " + offset);
    break;
    case 2:
    offset = 0f;
    //Debug.Log("Standing enemy;  offset = " + offset);
    break;
   }
  }

  //public void RayCastToCover() {
  //}

  public void EnemyFinder(){
   //GameObject enemy = GameObject.FindGameObjectWithTag("Enemies");
   //Transform ass = enemy.GetComponent<Transform> ();
   enemies = GameObject.FindGameObjectsWithTag("Enemies");
   foreach (GameObject i in enemies) {
    //Debug.Log(i.transform.position);
    
    distance = Vector3.Distance (plr.player.transform.position, i.transform.position);
    angle = Vector3.Angle (plr.player.transform.forward, i.transform.position - plr.player.transform.position);
    //Debug.Log(i.name);

   Debug.DrawRay(plr.player.transform.position, plr.player.transform.TransformDirection(1,0,1)*_dov.dov/Mathf.Sqrt(2f), Color.red);
   Debug.DrawRay(plr.player.transform.position, plr.player.transform.TransformDirection(0,0,1)*_dov.dov, Color.red);
   Debug.DrawRay(plr.player.transform.position, plr.player.transform.TransformDirection(-1,0,1)*_dov.dov/Mathf.Sqrt(2f), Color.red);
   Debug.DrawRay(plr.player.transform.position, i.transform.position - plr.player.transform.position, Color.blue);
    
   if (angle < _aov.aov && (int) distance < (_dov.dov - offset) && Physics.Raycast (plr.player.transform.position, i.transform.position - plr.player.transform.position, distance - 1f) == false ) {
    i.renderer.enabled = true;
   }
    
   else {
    i.renderer.enabled = false;
   }
   }
  }
}


во втором скрипте много того, что не относится к теме моего вопроса. Хотя часть этого кода может кому и понадобится и будет полезной smile хотя, если я задаю здесь вопросы, то отвечающим вряд ли будет полезно, т.к. вашего опыта хватит, чтоб написать это самим.

Итак, здесь второй скрипт ищет врагов в определенной области. У ботов есть параметр "положение", который я хочу получать для каждого конкретного бота и делать поправку к области зрения игрока. Метод public void EnemyPosition() сейчас написан неверно, т.к. имена у ботов разные будут, да и вообще я по тэгу буду искать, но не суть. Проблема остается той же. Когда я задаю у одного из ботов положение сидеть, оно же передается другому боту. И мне бы не хотелось клепать для каждого бота свой отдельный класс, именно поэтому я упоминал о наследовании и полиморфизме, но этого я не умею пока делать.... есть идеи, как быть?

Добавлено (18.08.2014, 14:17)
---------------------------------------------
Да, MANMANA, есть поиск и по тэгу и по имени объекта, скрипты выше

Добавлено (18.08.2014, 14:19)
---------------------------------------------
Есть еще скрипт игрока, в котором запускаются в Update методы из второго скрипта

SarCasmДата: Понедельник, 18 Августа 2014, 14:24 | Сообщение # 10
заслуженный участник
Сейчас нет на сайте
polous, я не верю тебе ;DDD. Поменяй первый скрипт и скажи что вывело в консоль.
Код

using UnityEngine;  
using System.Collections;  

public class Enemy : MonoBehaviour {  
   public GameObject enemy;  
   public int EnemyPosition = 2;  
   // EnemyPosition = 2 - враг стоит  
   // EnemyPosition = 1 - враг сидит  
   // EnemyPosition = 0 - враг лежит  

   void Awake () {  
        print (EnemyPosition);
   }  

   void Start () {  
        EnemyPosition = Random.Range(0,3);
        print(EnemyPosition);
   }  
}  


Моя игра Gamiron#11 - Тема Скачать
polousДата: Понедельник, 18 Августа 2014, 14:40 | Сообщение # 11
частый гость
Сейчас нет на сайте
В каком смысле не веришь?) Вроде у меня не было еще повода лгать - я тут помощи ищу) ну сейчас запущу Юнити и вставлю, поглядим, будут ли у них разные позиции

Добавлено (18.08.2014, 14:40)
---------------------------------------------
SarCasm, да, все верно, позиции для двух объектов батюшка-рандом сделал разными (т.е. в инспекторе, ну и в дебаге, соответственно, сгенерировало у первого 0, у второго 1).... НО по факту у обоих стало 0... т.е. в инспекторе стоят разные цифири, а вот на деле - у первого 0 и у второго 0 (т.е. Offset в скрипте сработал так будто у обоих 0) и поправку сделал для обоих 8f, а должен был для того, у которого 1 сделать поправку 4f


Сообщение отредактировал polous - Понедельник, 18 Августа 2014, 14:40
SarCasmДата: Понедельник, 18 Августа 2014, 14:45 | Сообщение # 12
заслуженный участник
Сейчас нет на сайте
polous, Оба врага в инспекторе нвзываются Enemy ? Если так, то скорее всего вы оба раза берете одного и того же врага.

Моя игра Gamiron#11 - Тема Скачать

Сообщение отредактировал SarCasm - Понедельник, 18 Августа 2014, 14:45
polousДата: Понедельник, 18 Августа 2014, 14:47 | Сообщение # 13
частый гость
Сейчас нет на сайте
Т.е. я хочу сказать, что даже если после сгенерированных рандомом различных позиций для ботов изменить позицию (в данном случае цифру) на иную, то эффекта никакого не происходит, т.к. эта цифра как бы по умолчанию равна той, что у первого бота... как убрать это чертово умолчание?

Добавлено (18.08.2014, 14:47)
---------------------------------------------
Нет, первый назван Enemy, второй Enemy2

SarCasmДата: Понедельник, 18 Августа 2014, 14:49 | Сообщение # 14
заслуженный участник
Сейчас нет на сайте
polous, ну и где вы ищете Enemy2? (Вообще где эта ф-я вызывается не ясно, но она всегда берет инфу из Enemy)

Моя игра Gamiron#11 - Тема Скачать
MANMANAДата: Понедельник, 18 Августа 2014, 14:49 | Сообщение # 15
почти ветеран
Сейчас нет на сайте
скрипт отрабатывает так, как и должен отрабатывать.

только один первый case 0, с чего это он у тебя дальше должен идти?

static function Find(name: string): GameObject;


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
polousДата: Понедельник, 18 Августа 2014, 14:53 | Сообщение # 16
частый гость
Сейчас нет на сайте
ну я как бы сам могу ответить частично на свой вопрос) у меня метод ищет объект с именем Enemy и все манипуляции он должен проводить именно с Enemy и тут все логично, но это не меняет сути вопроса - когда я в объекте с именем Enemy делаю изменения, объект с именем Enemy2 (на котором, повторюсь, тот же скрипт, что и на Enemy) тоже принимает эти измнения...
ArtanielДата: Понедельник, 18 Августа 2014, 15:05 | Сообщение # 17
частый гость
Сейчас нет на сайте
В public void EnemyPosition() , в swich, GameObject.Find ("Enemy") , будет возвращать всегда один и тот же геймобжект(ну если не инстантиировать и не удалять их). А значит и offset будет высчитываться всегда для одного и того же. Даже если ты будешь вызывать этот метод столько же раз, сколько у тебя врагов, он всегда будет брать первого и смотреть его параметры.

Добавлено (18.08.2014, 15:05)
---------------------------------------------

Цитата polous ()
когда я в объекте с именем Enemy делаю изменения, объект с именем Enemy2 (на котором, повторюсь, тот же скрипт, что и на Enemy) тоже принимает эти измнения...

Где их видно, в инспекторе переменные меняются? или какой то скрипт работающий исходя из offset-а меняет его не так как надо?
MANMANAДата: Понедельник, 18 Августа 2014, 15:14 | Сообщение # 18
почти ветеран
Сейчас нет на сайте
возьми ID для всех нужных объектов, например, по имени (имена могут совпадать, как в случае с инстансами префаба).
Перебирай ID, ID - в кейсы, бери начальные координаты, выставляй оффсеты.
вуаля?


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
polousДата: Понедельник, 18 Августа 2014, 15:15 | Сообщение # 19
частый гость
Сейчас нет на сайте
Цитата Artaniel ()
В public void EnemyPosition() , в swich, GameObject.Find ("Enemy") , будет возвращать всегда один и тот же геймобжект(ну если не инстантиировать и не удалять их). А значит и offset будет высчитываться всегда для одного и того же. Даже если ты будешь вызывать этот метод столько же раз, сколько у тебя врагов, он всегда будет брать первого и смотреть его параметры.


Artaniel, понял, а если я буду искать по тэгу всех врагов, а затем для каждого из массива (foreach) я буду делать подобный switch... это изменит ситуацию?
MANMANAДата: Понедельник, 18 Августа 2014, 15:17 | Сообщение # 20
почти ветеран
Сейчас нет на сайте
ага

Цитата MANMANA ()
скрипт отрабатывает так, как и должен отрабатывать. только один первый case 0, с чего это он у тебя дальше должен идти? static function Find(name: string): GameObject;


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею


Сообщение отредактировал MANMANA - Понедельник, 18 Августа 2014, 15:18
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » наследование и полиморфизм
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг