Программирование Unity — средний уровень

1. Создайте атрибуты

Чтобы создать свойство, создайте методы доступа в круглых скобках после свойства.

using UnityEngine;
using System.Collections;

public class Player
{
    //成员变量可以称为
    //字段。
    private int experience;

    //Experience 是一个基本属性
    public int Experience
    {
        //访问属性的值
        get
        {
            //其他一些代码
            return experience;
        }
        //设置属性的值
        set
        {
            //其他一些代码
            experience = value;
        }
    }

    //Level 是一个将经验值自动转换为
    //玩家等级的属性
    public int Level
    {
        get
        {
            return experience / 1000;
        }
        set
        {
            experience = value * 1000;
        }
    }

    //这是一个自动实现的属性的
    //示例
    public int Health{ get; set;}
}

Создайте класс Game в другом файле:

Атрибуты в Player можно использовать как переменные в игре.

using UnityEngine;
using System.Collections;

public class Game : MonoBehaviour 
{
    void Start () 
    {
        Player myPlayer = new Player();

        //属性可以像变量一样使用
        myPlayer.Experience = 5;
        int x = myPlayer.Experience;
    }
}

Почему все же рекомендуется использовать атрибуты, когда есть публичные и приватные?

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

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

2. Статический

1. Статические переменные

В общем, каждый объект класса имеет одни и те же переменные, но каждая переменная имеет свое значение. Со статическими переменными каждый объект в классе имеет одну и ту же переменную и одно и то же значение.

Например, если вы хотите узнать, сколько объектов создано этим классом:

using UnityEngine;
using System.Collections;

public class Enemy
{
    //静态变量是在类的所有实例之间
    //共享的变量。
    public static int enemyCount = 0;

    public Enemy()
    {
        //通过递增静态变量了解
        //已创建此类的多少个对象。
        enemyCount++;
    }
}

2. Статический класс

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

статический класс:

using UnityEngine;
using System.Collections;

public static class Utilities 
{
    //可以在没有类对象的情况下调用
    //静态方法。请注意,静态方法无法访问
    //非静态成员变量。
    public static int Add(int num1, int num2)
    {
        return num1 + num2;
    }
}

Чтобы вызвать метод статического класса из нестатического класса:

using UnityEngine;
using System.Collections;

public class UtilitiesExample : MonoBehaviour 
{
    void Start()
    {
        //可以使用类名和点运算符
        //来访问静态方法。
        int x = Utilities.Add (5, 6);
    }
}

3. Покрытие

Если у подкласса есть метод с тем же именем, что и у родительского класса, при вызове этого метода будет вызываться версия родительского класса. Поскольку это объявление родительского класса, подкласс неявно преобразуется в родительский класс.

дедушка

using UnityEngine;
using System.Collections;

public class Humanoid
{
    //Yell 方法的基版本
    public void Yell()
    {
        Debug.Log ("Humanoid version of the Yell() method");
    }
}

отец

using UnityEngine;
using System.Collections;

public class Enemy : Humanoid
{
    //这会隐藏 Humanoid 版本。
    new public void Yell()
    {
        Debug.Log ("Enemy version of the Yell() method");
    }
}

Подкласс

using UnityEngine;
using System.Collections;

public class Orc : Enemy
{
    //这会隐藏 Enemy 版本。
    new public void Yell()
    {
        Debug.Log ("Orc version of the Yell() method");
    }
}

Создайте экземпляр в форме, объявленной родительским классом, и вызовите эти методы:

using UnityEngine;
using System.Collections;

public class WarBand : MonoBehaviour 
{
    void Start () 
    {
        Humanoid human = new Humanoid();
        Humanoid enemy = new Enemy();
        Humanoid orc = new Orc();

        //注意每个 Humanoid 变量如何包含
        //对继承层级视图中
        //不同类的引用,但每个变量都
        //调用 Humanoid Yell() 方法。
        human.Yell();
        enemy.Yell();
        orc.Yell();
    }
}

4. Интерфейс

Класс может наследоваться только от одного родительского класса, но может реализовывать несколько интерфейсов. Интерфейсы могут определять общую функциональность для нескольких несвязанных классов.

Реализовать интерфейс:

using UnityEngine;
using System.Collections;

//这是只有一个必需方法的基本接口
public interface IKillable
{
    void Kill();
}

//这是一个通用接口,其中 T 是将由实现类提供的数据类型的占位符。
public interface IDamageable<T>
{
    void Damage(T damageTaken);
}

Реализуйте метод в интерфейсе:

using UnityEngine;
using System.Collections;

//这是只有一个必需方法的基本接口
public interface IKillable
{
    void Kill();
}

//这是一个通用接口,其中 T 是将由实现类提供的数据类型的占位符。
public interface IDamageable<T>
{
    void Damage(T damageTaken);
}

5. Метод расширения

Если мы хотим сбросить параметры в Transform через функцию, идеальное место для этой функции — в классе Transform, но, поскольку мы не можем получить доступ к исходному коду встроенного в Unity Transform, мы можем создать для него расширения.

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

using UnityEngine;
using System.Collections;

//创建一个包含所有扩展方法的类是很常见的做法
//此类必须是静态类
public static class ExtensionMethods
{
    //扩展方法即使像普通方法一样使用,也必须声明为静态
    //注意,第一个参数具有“this”关键字,后跟一个 Transform变量
    //此变量表示扩展方法会成为哪个类的一部分
    public static void ResetTransformation(this Transform trans)
    {
        //编写重置Transform的代码
        trans.position = Vector3.zero;
        trans.localRotation = Quaternion.identity;
        trans.localScale = new Vector3(1, 1, 1);
    }
}

Следует отметить, что хотя объявление метода расширения имеет параметры, при вызове этой функции параметры не передаются. Объект Transform, вызывающий этот метод, автоматически передается в качестве первого параметра.

using UnityEngine;
using System.Collections;

public class SomeClass : MonoBehaviour 
{
    void Start () {
        //请注意,即使方法声明中
        //有一个参数,也不会将任何参数传递给
        //此扩展方法。调用此方法的
        //Transform 对象会自动作为
        //第一个参数传入。
        transform.ResetTransformation();
    }
}

5. Корутина

Функции сопрограммы можно рассматривать как функции, выполняемые через определенные промежутки времени. Функции Coroutine часто используются с оператором yield. Каждое выполнение функции сопрограммы продолжится с того места, где оно было остановлено. Использование сопрограмм не требует выполнения в каждом кадре, как Update, что повышает эффективность.

оператор доходности:

доходность возвращает ноль;

Выполнить последующий код в следующем кадре

разрыв выхода;

конец сопрограммы

yield return new WaitForSeconds (0,5f);

Выполнить последующий код после ожидания фиксированного времени

using UnityEngine;
using System.Collections;

public class CoroutinesExample : MonoBehaviour
{
    public float smoothing = 1f;
    public Transform target;


    void Start ()
    {
    	//开启协程
        StartCoroutine(MyCoroutine(target));
    }

	//返回类型为IEnumerator
	//表示函数可以返回实现IEnumerator接口的任意内容
    IEnumerator MyCoroutine (Transform target)
    {
        while(Vector3.Distance(transform.position, target.position) > 0.05f)
        {
            transform.position = Vector3.Lerp(transform.position, target.position, smoothing * Time.deltaTime);

            yield return null;
        }

        print("Reached the target.");

        yield return new WaitForSeconds(3f);

        print("MyCoroutine is now finished.");
    }
}

Guess you like

Origin blog.csdn.net/m0_63673681/article/details/128702721