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.");
}
}