Sunday, 16 September 2012

Iliya Ira Roman Alex Denis - 2

Code snippets:

C#:

Описание класса:
public class MyClass
{
    public int myIntVariable;
    public float myFloatVariable;
}

Создание экземпляра класса
MyClass m = new MyClass();

Описание класса с конструктором
public class MyClass
{
    public int myIntVariable

    //констуктор
    public MyClass(int data)
    {
         myIntVariable = data;
    }
}

Создание экземпляра класса c конструктором
MyClass m = new MyClass(10);
Debug.Log( m.myIntVariable );

Наследование:
public class A
{
    public int myIntVariable;
    public float myFloatVariable;

   public void DoSomething()
   {

   }
}

//класс B наследуеться от A
public class B : A
{   
   public void DoMore()
   {

   }
}

B myB = new B();
myB.DoSomething();  //Все что было доступно в А доступно в B поскольку B это наследник A
myB.DoMore();
myB.myIntVariable = 10;

Расширение функции в наследуемом классе:
public class A
{   
   public virtual void DoSomething()
   {
        Debug.Log("A doing stuff");
   }
}

//класс B наследуеться от A
public class B : A
{   
   public override void  DoSomething()
   {
       base.DoSomething(); //вызов функции из родительского класса
       Debug.Log("B added some more"); //добавление функционала
   }
}

B myB = new B();
myB.DoSomething();

Результат:
A doing stuff
B added some more

Статические функции
public class A
{   
   public static float CalculateDescremenant(float a, float b, float c)
   {
       return b*b - 4 * a * c;
   }
}

Вызов статической функции:
float D = A.CalculateDescremenant( 1f, 2f, 3f ); // при вызове статической функции экземпляр класса не нужен
Debug.Log ( D );

Синглтон
Синглтон єто такой класс, которій существует в единсвтенном єкземпляре. Очевидно что класс ВРАГА синглтоном не может біть, посколько обічно в играх больще чем 1 враг. Ccілка на єтот класс храниться в статической переменной, благодаря чему мі можем получать доступ к Синглтону из любой точки кода без Find. Обічно такая переменная назіваеться Instance.

using UnityEngine;
using System.Collections;

public class Singelton: MonoBehaviour
{
     public Singelton Instance;
    
     void Awake() //Awake вызываеться ДО Start
    {
          Instance = this;
     }

    public void DoStuff()
    {
        Debug.Log("Hello from singleton");
    }
}

Доступ к синглтону из другого скрипта
void Start()
{
    Singelton.Instance.DoStuff(); //нет необходимости делать Find и получать скрипт
}

Сообытия
Логика сообытий берет начало из реального мира. Предположим произошло событие - атомный взрыв. Вы узнали о событии и изменили свое поведение - пытаетесь скрыться в бункере. Вопрос в том как реализовать данную логику при помощи C#.

Итак есть некто, кто создает событие и некто, кто подписан на создателя и обрабатывает его событие. Внутри того, кто обрабатывает собітие нужна функция, которя вызывается при наступлении события, так называемій Handler. В C# событие это массив из чужых функций, которые нами вызываеються. Очевидно что такие функции должні біть стандартизировані иначе у них многие параметры будут отличаться и тот кто рассілает сообщения не будет знать какие параметрі передавать. Описание такой функции - єто делегат в с#. Описываеться он вот таким образом
public delegate void GameActionHandler( object who, EventArgs e ),  в who будет храниться кто отослал сообщения, а в e будет храниться данніе єтого сообщения например если атомній взрів произойдет в другом полушарии, то вам нет необходимости скріваться в бункере.

Теперь в том кто рассылает сообщение необходимо обьявить событие

class Hero
{
    public event GameActionHandler OnGameAction;
}

GameActionHandler - делегат, OnGameAction - событие. Все события в С# принято начанать с приставки On.

Как разослать сообщение всем тем, кто на него подписан

class Hero
{
    public event GameActionHandler OnGameAction;

    void Update()
    {
         if ( Input.GetKeyDown("a"))
         {
             if ( OnGameAction != null ) //мы проверели чтобы наш массив не был пуст
             {
                   OnGameAction( this, new EventArgs() ); //здесь с# візівает все функции из массива
              }
         }
    }
}

Итак при нажатии на клавишу герой разошлет всем собітие, a все те кто подписан на него получат уведомление в форме візова функции.

Как подписаться на собітие ?

class Enemy
{
      public Start()
      {
            GameObject.Find("Hero").GetComponent<Hero>().OnGameAction += GameActionHandler;
      }

    public void  GameActionHandler( object sender, EventArgs e )
    {
          Debug.Log("Hero have pressed key A, lets do something according to this information );
     }
}

Итак в тот момент, когда герой нажмет клавишу А он разошлет всем кто на него подписан собітие, на него в Start подписан Enemy, соответственно у Enemy візоветься функция GameActionHandler с соответствующими параметрами.

Конечно же можно обойтись без собітий. При помощи GameObject.Find можно получить обьект, далее достать его скрипт и напрямую візвать функцию как мі делали до єтого. Но данная операция делает ваш код более связаннім и менее переносимім + если в сцене есть несколько врагов, то придеться при помощи Find искать много обьектов, записать их в массив и перебором взять все скрипті и візівать функции, что с точки зрения записи длинее.