Learn Unity - Scripts(中级教程)
来源:互联网 发布:广告优化师 编辑:程序博客网 时间:2024/05/22 15:01
Properties
如何创建Properties去访问类中的私有成员变量
这个方法一般用于隐藏类中的变量而又开放出读取或设置的权限,见示例:
using UnityEngine;using System.Collections;public class Player{ //Member variables can be referred to as fields. private int experience; //Experience is a basic property public int Experience { get { //Some other code return experience; } set { //Some other code experience = value; } } //Level is a property that converts experience //points into the leve of a player automatically public int Level { get { return experience / 1000; } set { experience = value * 1000; } } //This is an example of an auto-implemented //property public int Health{ get; set;}}
using UnityEngine;using System.Collections;public class Game : MonoBehaviour { void Start () { Player myPlayer = new Player(); //Properties can be used just like variables myPlayer.Experience = 5; int x = myPlayer.Experience; }}
三元运算符(*?:)
如何用三元运算符快速建立一个if-else语句
例:
message = health > 0 ? "Player is Alive" : "Player is Dead";
?前面是判定条件,?和:中间是条件为true的结果,:后面是条件为false的结果
静态(Static)
可以设置类,函数,属性为静态,静态即不能被实例化,唯一
重载方法(Method Overloading)
using UnityEngine;using System.Collections;public class SomeClass{ //The first Add method has a signature of //"Add(int, int)". This signature must be unique. public int Add(int num1, int num2) { return num1 + num2; } //The second Add method has a sugnature of //"Add(string, string)". Again, this must be unique. public string Add(string str1, string str2) { return str1 + str2; }}
重写方法,函数名相同而传入参数不同,方法会寻找最匹配类型的方法执行,若找不到,则返回错误
泛型(Generics)
泛型方法
当然可以不止是T,也可以是U,V等多个范类型,若需要规定类型的范围,可以如下一样添加where语句来规定
using UnityEngine;using System.Collections;public class SomeClass { //Here is a generic method. Notice the generic //type 'T'. This 'T' will be replaced at runtime //with an actual type. public T GenericMethod<T>(T param) where T : int { return param; }}
泛型类
using UnityEngine;using System.Collections;//Here is a generic class. Notice the generic type 'T'.//'T' will be replaced with an actual type, as will also //instances of the type 'T' used in the class.public class GenericClass <T>{ T item; public void UpdateItem(T newItem) { item = newItem; }}
继承(Inheritance)
面向对象思想编程
父类
using UnityEngine;using System.Collections;//This is the base class which is//also known as the Parent class.public class Fruit { public string color; //This is the first constructor for the Fruit class //and is not inherited by any derived classes. public Fruit() { color = "orange"; Debug.Log("1st Fruit Constructor Called"); } //This is the second constructor for the Fruit class //and is not inherited by any derived classes. public Fruit(string newColor) { color = newColor; Debug.Log("2nd Fruit Constructor Called"); } public void Chop() { Debug.Log("The " + color + " fruit has been chopped."); } public void SayHello() { Debug.Log("Hello, I am a fruit."); }}
子类
using UnityEngine;using System.Collections;//This is the derived class whis is//also know as the Child class.public class Apple : Fruit { //This is the first constructor for the Apple class. //It calls the parent constructor immediately, even //before it runs. public Apple() { //Notice how Apple has access to the public variable //color, which is a part of the parent Fruit class. color = "red"; Debug.Log("1st Apple Constructor Called"); } //This is the second constructor for the Apple class. //It specifies which parent constructor will be called //using the "base" keyword. public Apple(string newColor) : base(newColor) { //Notice how this constructor doesn't set the color //since the base constructor sets the color that //is passed as an argument. Debug.Log("2nd Apple Constructor Called"); }}
- 子类会继承父类public和protect的属性和方法,而对于private则不行
- 子类构造函数使用base关键字来说明使用了父类哪个构造函数,使用用类似于java的super,因为C#不支持多继承,父类用base即可,C++支持多继承,所以要写父类名字说明,也是两者区别之一。
多态(Polymorphism)
using UnityEngine;using System.Collections;public class Fruit { public Fruit() { Debug.Log("1st Fruit Constructor Called"); } public void Chop() { Debug.Log("The fruit has been chopped."); } public void SayHello() { Debug.Log("Hello, I am a fruit."); }}
using UnityEngine;using System.Collections;public class Apple : Fruit { public Apple() { Debug.Log("1st Apple Constructor Called"); } //Apple has its own version of Chop() and SayHello(). //When running the scripts, notice when Fruit's version //of these methods are called and when Apple's version //of these methods are called. //In this example, the "new" keyword is used to supress //warnings from Unity while not overriding the methods //in the Apple class. public new void Chop() { Debug.Log("The apple has been chopped."); } public new void SayHello() { Debug.Log("Hello, I am an apple."); }}
using UnityEngine;using System.Collections;public class FruitSalad : MonoBehaviour{ void Start () { //Notice here how the variable "myFruit" is of type //Fruit but is being assigned a reference to an Apple. This //works because of Polymorphism. Since an Apple is a Fruit, //this works just fine. While the Apple reference is stored //in a Fruit variable, it can only be used like a Fruit Fruit myFruit = new Apple(); myFruit.SayHello(); myFruit.Chop(); //This is called downcasting. The variable "myFruit" which is //of type Fruit, actually contains a reference to an Apple. Therefore, //it can safely be turned back into an Apple variable. This allows //it to be used like an Apple, where before it could only be used //like a Fruit. Apple myApple = (Apple)myFruit; myApple.SayHello(); myApple.Chop(); }}
- new关键字是当子类没有重写父类方法的时候提供来自unity的警告
- 当子类引用储存在父类变量中,只能像父类一样使用,当强制安全降级到子类变量中,就可以像子类一样使用
成员隐藏(Member Hiding)
using UnityEngine;using System.Collections;public class Humanoid{ //Base version of the Yell method public void Yell() { Debug.Log ("Humanoid version of the Yell() method"); }}
using UnityEngine;using System.Collections;public class Enemy : Humanoid{ //This hides the Humanoid version. new public void Yell() { Debug.Log ("Enemy version of the Yell() method"); }}
using UnityEngine;using System.Collections;public class WarBand : MonoBehaviour { void Start () { Humanoid human = new Humanoid(); Humanoid enemy = new Enemy(); //Notice how each Humanoid variable contains //a reference to a different class in the //inheritance hierarchy, yet each of them //calls the Humanoid Yell() method. human.Yell(); enemy.Yell(); }}
- new关键字显式隐藏从父类继承来的成员,不然unity会有警告
重写/覆盖(Overriding)
using UnityEngine;using System.Collections;public class Fruit { public Fruit () { Debug.Log("1st Fruit Constructor Called"); } //These methods are virtual and thus can be overriden //in child classes public virtual void Chop () { Debug.Log("The fruit has been chopped."); } public virtual void SayHello () { Debug.Log("Hello, I am a fruit."); }}
using UnityEngine;using System.Collections;public class Apple : Fruit { public Apple () { Debug.Log("1st Apple Constructor Called"); } //These methods are overrides and therefore //can override any virtual methods in the parent //class. public override void Chop () { base.Chop(); Debug.Log("The apple has been chopped."); } public override void SayHello () { base.SayHello(); Debug.Log("Hello, I am an apple."); }}
using UnityEngine;using System.Collections;public class FruitSalad : MonoBehaviour { void Start () { Apple myApple = new Apple(); //Notice that the Apple version of the methods //override the fruit versions. Also notice that //since the Apple versions call the Fruit version with //the "base" keyword, both are called. myApple.SayHello(); myApple.Chop(); //Overriding is also useful in a polymorphic situation. //Since the methods of the Fruit class are "virtual" and //the methods of the Apple class are "override", when we //upcast an Apple into a Fruit, the Apple version of the //Methods are used. Fruit myFruit = new Apple(); myFruit.SayHello(); myFruit.Chop(); }}
- 当子类重写了父类后,子类需要通过base关键字来调用父类
- 重写也用于多态,父类方法有virtual关键字时,子类相同方法添加override关键字,这样,即使子类引用上升了父类变量,依旧会使用子类的方法
接口(Interfaces)
using UnityEngine;using System.Collections;//This is a basic interface with a single required//method.public interface IKillable{ void Kill();}//This is a generic interface where T is a placeholder//for a data type that will be provided by the //implementing class.public interface IDamageable<T>{ void Damage(T damageTaken);}
using UnityEngine;using System.Collections;public class Avatar : MonoBehaviour, IKillable, IDamageable<float>{ //The required method of the IKillable interface public void Kill() { //Do something fun } //The required method of the IDamageable interface public void Damage(float damageTaken) { //Do something fun }}
- 接口不能实例化,只能进行简单的定义
- 继承与接口类似,至于为什么不使用继承而使用接口,区别就是C#支持实现多个接口而不支持继承多个父类,而继承与接口使用的方向也不同,继承的父类大多指的是物体,而接口大多指的是状态
扩展方法(extension methods)
using UnityEngine;using System.Collections;//It is common to create a class to contain all of your//extension methods. This class must be static.public static class ExtensionMethods{ //Even though they are used like normal methods, extension //methods must be declared static. Notice that the first //parameter has the 'this' keyword followed by a Transform //variable. This variable denotes which class the extension //method becomes a part of. public static void ResetTransformation(this Transform trans) { trans.position = Vector3.zero; trans.localRotation = Quaternion.identity; trans.localScale = new Vector3(1, 1, 1); }}
using UnityEngine;using System.Collections;//It is common to create a class to contain all of your//extension methods. This class must be static.public static class ExtensionMethods{ //Even though they are used like normal methods, extension //methods must be declared static. Notice that the first //parameter has the 'this' keyword followed by a Transform //variable. This variable denotes which class the extension //method becomes a part of. public static void ResetTransformation(this Transform trans) { trans.position = Vector3.zero; trans.localRotation = Quaternion.identity; trans.localScale = new Vector3(1, 1, 1); }}
- 扩展方法方便为已有的类中添加方法,其中有三个条件:
1.静态类
2.静态方法
3.静态方法的第一个参数带有this关键字
命名空间(Namespaces)
using UnityEngine;using System.Collections;namespace SampleNamespace{ public class SomeClass : MonoBehaviour { void Start () { } }}
- using也就是使用哪些命名空间里,方便使用里面类或方法,设置命名空间为了避免同名方法的混淆
列表和字典(Lists and Dictionaries)
using UnityEngine;using System.Collections;using System; //This allows the IComparable Interface//This is the class you will be storing//in the different collections. In order to use//a collection's Sort() method, this class needs to//implement the IComparable interface.public class BadGuy : IComparable<BadGuy>{ public string name; public int power; public BadGuy(string newName, int newPower) { name = newName; power = newPower; } //This method is required by the IComparable //interface. public int CompareTo(BadGuy other) { if(other == null) { return 1; } //Return the difference in power. return power - other.power; }}
using UnityEngine;using System.Collections;using System.Collections.Generic;public class SomeClass : MonoBehaviour{ void Start () { //This is how you create a list. Notice how the type //is specified in the angle brackets (< >). List<BadGuy> badguys = new List<BadGuy>(); //Here you add 3 BadGuys to the List badguys.Add( new BadGuy("Harvey", 50)); badguys.Add( new BadGuy("Magneto", 100)); badguys.Add( new BadGuy("Pip", 5)); badguys.Sort(); foreach(BadGuy guy in badguys) { print (guy.name + " " + guy.power); } //This clears out the list so that it is //empty. badguys.Clear(); }}
using UnityEngine;using System.Collections;using System.Collections.Generic;public class SomeOtherClass : MonoBehaviour { void Start () { //This is how you create a Dictionary. Notice how this takes //two generic terms. In this case you are using a string and a //BadGuy as your two values. Dictionary<string, BadGuy> badguys = new Dictionary<string, BadGuy>(); BadGuy bg1 = new BadGuy("Harvey", 50); BadGuy bg2 = new BadGuy("Magneto", 100); //You can place variables into the Dictionary with the //Add() method. badguys.Add("gangster", bg1); badguys.Add("mutant", bg2); BadGuy magneto = badguys["mutant"]; BadGuy temp = null; //This is a safer, but slow, method of accessing //values in a dictionary. if(badguys.TryGetValue("birds", out temp)) { //success! } else { //failure! } }}
- List跟C++中List相似,而Dictionary是键值对的形式,跟map相似,以上是相应的使用范例
协程(Coroutines)
using UnityEngine;using System.Collections;public class CoroutinesExample : MonoBehaviour{ public float smoothing = 1f; public Transform target; void Start () { StartCoroutine(MyCoroutine(target)); } 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."); }}
- StartCoroutine开启协程
- StopCoroutine停止协程
- 协程方法要返回IEnumerator接口类型
- yield跟return类似,不过是等待一定延迟后继续执行
四元数(quaternion)
Quaternion是Unity中处理旋转的常用类,下面是一些代码例子
using UnityEngine;using System.Collections;public class GravityScript : MonoBehaviour { public Transform target; void Update () { Vector3 relativePos = (target.position + new Vector3(0, 1.5f, 0)) - transform.position; Quaternion rotation = Quaternion.LookRotation(relativePos); Quaternion current = transform.localRotation; transform.localRotation = Quaternion.Slerp(current, rotation, Time.deltaTime); transform.Translate(0, 0, 3 * Time.deltaTime); }}
- Quaternion.LookRotation得出朝向目标的旋转
- Quaternion.Slerp现有旋转角度转到目标角度取插值,使平滑
Delegate
delegate就是方法的容器
using UnityEngine;using System.Collections;public class DelegateScript : MonoBehaviour { delegate void MyDelegate(int num); MyDelegate myDelegate; void Start () { myDelegate = PrintNum; myDelegate(50); myDelegate = DoubleNum; myDelegate(50); } void PrintNum(int num) { print ("Print Num: " + num); } void DoubleNum(int num) { print ("Double Num: " + num * 2); }}
using UnityEngine;using System.Collections;public class MulticastScript : MonoBehaviour { delegate void MultiDelegate(); MultiDelegate myMultiDelegate; void Start () { myMultiDelegate += PowerUp; myMultiDelegate += TurnRed; if(myMultiDelegate != null) { myMultiDelegate(); } } void PowerUp() { print ("Orb is powering up!"); } void TurnRed() { renderer.material.color = Color.red; }}
- delegate容器可以存一个或多个同一类型的方法,方便同时调用不同的方法,使用之前最好判断下是否为null
Attributes
using UnityEngine;using System.Collections;public class SpinScript : MonoBehaviour { [Range(-100, 100)] public int speed = 0; void Update () { transform.Rotate(new Vector3(0, speed * Time.deltaTime, 0)); }}
- 此处的attribute就是限定了speed的范围,在inspector界面也只能在此范围内调节,更多attribute请参考官方文档
事件(Events)
events也是主要靠delegate实现委托的,不过添加event关键字增强了代码的安全性,使其他类只能订阅或者取消订阅事件,而不能执行或者复写事件
using UnityEngine;using System.Collections;public class EventManager : MonoBehaviour { public delegate void ClickAction(); public static event ClickAction OnClicked; void OnGUI() { if(GUI.Button(new Rect(Screen.width / 2 - 50, 5, 100, 30), "Click")) { if(OnClicked != null) OnClicked(); } }}
using UnityEngine;using System.Collections;public class TeleportScript : MonoBehaviour { void OnEnable() { EventManager.OnClicked += Teleport; } void OnDisable() { EventManager.OnClicked -= Teleport; } void Teleport() { Vector3 pos = transform.position; pos.y = Random.Range(1.0f, 3.0f); transform.position = pos; }}
- 事件推荐设置为静态,这样在其他类中订阅事件就不必实例化
0 0
- Learn Unity - Scripts(中级教程)
- Learn Unity - Scripts(新手教程)
- linux中级教程-中级shell
- Ogre中级教程(六): 投影贴图
- Ogre中级教程(九): 深入CEGUI
- Learn Unity(0)——basic C# for Unity
- Unity学习日记-Creating Scripts
- Unity 回合制战斗系统(中级篇)
- Unity 回合制战斗系统(中级篇)-进阶
- CSS中级教程 背景图片
- 正则表达式中级教程
- Ogre中级教程
- Ogre 中级教程六
- selenium中级教程
- springMVC教程中级(四)Controller中级篇1(回传、批量)
- springMVC教程中级(四)Controller中级篇2(传图、json)
- Ogre中级教程(五): 静态图元
- Ogre中级教程(七):资源与资源管理器
- HashSet和TreeSet
- 1041. 考试座位号
- Activity绑定自定义视图
- HDU 1017 A Mathematical Curiosity
- [Usaco2015 FEB Gold][2016-2-21]考试总结
- Learn Unity - Scripts(中级教程)
- sgu499
- 飞思卡尔智能车摄像头矫正方案
- iOS的主要框架介绍
- 【Android】Cannot reload AVD list问题
- 转自百度百科
- Lucene —— 搜索结果高亮显示
- vector资料
- Android四大启动模式